4、Ollama API使用:Ollama REST API概览、生成文本API、聊天API、嵌入API、API参数调优
好,咱们进入第四章。说实话,API 这块是我个人觉得最「值钱」的部分。你想想看,模型微调完了,总不能老在命令行里敲命令吧?得把它集成到你的应用里,让产品、让用户真正用起来。Ollama 提供了一套非常简洁的 REST API,说白了就是 HTTP 请求,谁都能调。
我刚开始接触 Ollama 时,第一反应是「这么简单?」,结果试了一下,还真就这么简单。但简单归简单,里面的参数调优门道不少。今天我就把我在项目中踩过的坑、总结的经验,一股脑儿倒给你。
4.1 Ollama REST API 概览
Ollama 默认在本地 11434 端口启动服务。你启动 Ollama 后,其实它背后就运行着一个 HTTP 服务器。所有 API 的基地址是:
http://localhost:11434
核心 API 就三个:
- 生成文本 API:
/api/generate—— 最基础,给提示词,返回补全文本 - 聊天 API:
/api/chat—— 支持多轮对话,带角色消息 - 嵌入 API:
/api/embed—— 把文本转成向量,用于 RAG 或语义搜索
嗯,这里要注意:Ollama 的 API 设计非常「克制」,没有花里胡哨的东西。每个接口都只做一件事,但做得很好。我个人习惯是先调 /api/generate 做快速验证,确认模型加载正常,再上聊天接口。
curl 直接测试 API,不需要写代码。比如 curl http://localhost:11434/api/generate -d '{"model": "llama3", "prompt": "你好"}'。这是最快验证服务是否正常的方法。
4.2 生成文本 API(/api/generate)
这个接口最直接。你给它一个 prompt,它返回生成的文本。我经常用它来做文本补全、摘要生成这类任务。
基本请求格式:
POST /api/generate
{
"model": "llama3",
"prompt": "请用一句话解释什么是大语言模型",
"stream": false
}
响应示例:
{
"model": "llama3",
"response": "大语言模型是一种基于深度学习的人工智能模型,能够理解和生成人类语言。",
"done": true,
"context": [/* 上下文向量 */],
"total_duration": 1234567890,
"load_duration": 123456,
"prompt_eval_count": 10,
"eval_count": 20,
"eval_duration": 987654321
}
这里有个关键点:stream 参数。默认是 true,也就是流式返回,像 ChatGPT 那样一个字一个字往外蹦。如果你做的是实时对话应用,流式体验更好。但如果你做的是批量处理,建议设成 false,一次性拿到完整结果。
我曾经在做一个文档摘要系统时,忘了关 stream,结果前端收到一堆碎片化的 JSON,还得自己拼。后来我直接在代码里默认 stream: false,只在需要实时展示时才开流。
4.3 聊天 API(/api/chat)
这个接口才是日常用得最多的。它支持多轮对话,消息格式和 OpenAI 的 API 几乎一样,迁移成本极低。
请求格式:
POST /api/chat
{
"model": "llama3",
"messages": [
{"role": "system", "content": "你是一个乐于助人的助手。"},
{"role": "user", "content": "你好,请问今天天气怎么样?"},
{"role": "assistant", "content": "抱歉,我无法获取实时天气信息。"},
{"role": "user", "content": "那你能做什么?"}
],
"stream": false
}
响应格式:
{
"model": "llama3",
"message": {
"role": "assistant",
"content": "我可以帮你回答问题、写作、编程、翻译等。"
},
"done": true,
"total_duration": 2345678901
}
你看,消息数组里可以带 system 角色,用来设定模型的行为。这个 system prompt 非常关键,我一般会在里面写清楚模型的角色、输出格式、限制条件等。
4.4 嵌入 API(/api/embed)
嵌入 API 可能很多人用得少,但它在 RAG(检索增强生成)里是核心。说白了,就是把一段文本转成一个向量数组,然后你可以用这个向量去做相似度搜索。
请求格式:
POST /api/embed
{
"model": "llama3",
"input": "今天天气真不错"
}
响应格式:
{
"model": "llama3",
"embeddings": [[0.123, -0.456, 0.789, ...]],
"total_duration": 123456789
}
返回的 embeddings 是一个二维数组,因为你可以一次传入多个文本。比如:
{
"model": "llama3",
"input": ["今天天气真不错", "明天可能会下雨"]
}
这样返回的就是两个向量。我一般在做知识库检索时,先把所有文档片段转成向量存到向量数据库里,用户提问时再把问题转成向量,去库里找最相似的片段。
4.5 API 参数调优
好,到了最核心的部分。API 参数调优,说白了就是让模型按你想要的方式输出。Ollama 支持很多参数,我挑几个最常用的讲。
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
temperature |
float | 0.8 | 控制随机性。值越高,输出越随机;越低,越确定 |
top_p |
float | 0.9 | 核采样。只从概率累积到 top_p 的 token 中采样 |
top_k |
int | 40 | 只从概率最高的 top_k 个 token 中采样 |
repeat_penalty |
float | 1.1 | 重复惩罚。值越大,越不容易重复 |
num_predict |
int | 128 | 最大生成 token 数 |
stop |
array | [] | 停止词。遇到这些词就停止生成 |
我来说说我的调参心得:
- temperature:做创意写作(比如写诗、写故事)时,我设到 0.9-1.2。做事实性回答(比如客服、知识问答)时,我设到 0.1-0.3。你想想看,如果客服回答问题时太「有创意」,那不得把用户气死?
- top_p 和 top_k:这两个一般二选一。我习惯用 top_p,设 0.9 左右。top_k 在需要严格控制输出时用,比如只让模型从最可能的 10 个词里选。
- repeat_penalty:这个参数我特别喜欢。模型有时候会陷入死循环,一直重复同一句话。把 repeat_penalty 调到 1.2-1.5,基本能解决。我曾经遇到一个模型,回答问题时最后总要加一句「请问还有其他问题吗?」,调高 repeat_penalty 后就好了。
- num_predict:别设太大。128 对于大多数问答足够了。设太大不仅慢,而且模型容易「跑偏」,生成一些无关内容。
- stop:这个很实用。比如你让模型生成 JSON,可以设
stop: ["\n\n"],遇到空行就停。或者设stop: ["用户:"],在对话场景里很管用。
一个完整的调优请求示例:
POST /api/generate
{
"model": "llama3",
"prompt": "写一首关于春天的五言绝句",
"stream": false,
"options": {
"temperature": 0.9,
"top_p": 0.95,
"repeat_penalty": 1.2,
"num_predict": 100,
"stop": ["\n\n", "。"],
"seed": 42
}
}
注意 seed 参数。设了固定种子后,相同输入会得到相同输出。这在调试时非常有用。我一般调试时设 seed: 42,确认效果后再去掉。
temperature 是不是太高。我见过很多新手一上来就设 1.5,结果模型像喝醉了酒一样胡言乱语。从 0.7 开始调,慢慢往上加,找到那个「既有点创意又不离谱」的平衡点。
最后,我画了一张图,帮你理清这几个 API 的关系和使用场景:
这张图把整个 API 体系串起来了。你从 Ollama API 出发,根据任务类型选择对应的接口,再配合参数调优,就能让模型输出你想要的结果。
好了,API 这块就讲到这里。记住一句话:API 是死的,参数是活的。同样的模型,参数调得好,效果天差地别。多试、多调、多总结,慢慢你就有感觉了。