您的位置:首页 > 手游攻略 > Ollama API Chat 消息历史与多轮对话教程

Ollama API Chat 消息历史与多轮对话教程

作者:互联网  时间: 2026-07-23 17:11:56  

第二次给 Ollama 发提问的时候,你会不会发现模型突然把第一轮的内容全忘了?其实这问题一般不在 Chat 接口,是你请求里只塞了新问题而已。Ollama 的 Chat API 是把会话记忆的活儿交给调用方的,每次发请求,都得在 messages 数组里带上所有要保留的 systemuserassistant 消息。这份历史记录既能给 curl 用,也能交给 Python 程序来维护。

这个方法对 Windows、macOS 和 Linux 上跑的本地 Ollama 都适用。动手之前先确认服务已经在运行了,再准备好一个能用的模型。例子我就沿用官方文档里的 gemma4,你本地模型名字不一样的话替换掉就行。Chat 接口要求必须传 modelmessages 这两个字段,默认会返回逐行的流式数据。

先给你看官方页面的请求入口:中间位置写着 POST /api/chat,右边有现成的 curl 请求示例,正文区域里 modelmessages 是标了必填的。要是你自己写的请求地址、方法或者字段名对不上,先把这里对齐,别上来就去查模型的问题。

Ollama 官方 Chat API 页面显示 POST api chat、model 和 messages 必填字段

第 1 步:用单轮请求确认 Chat 端点可用

咱们先用一条最精简的请求,把服务和模型的问题先排除掉。入口位置:Windows 系统就打开 PowerShell,macOS 和 Linux 直接开终端就行。主要动作:给本地的 api/chat 发一个非流式请求,把 stream:false 设上,这样能直接看到完整的 JSON 响应:

curl -s localhost:11434/api/chat -d '{
  "model": "gemma4",
  "messages": [
    {"role": "user", "content": "用一句话解释什么是向量。"}
  ],
  "stream": false
}'

返回的对象里应该有 message.rolemessage.content 这两个字段。成功标志:角色是 assistant,同时能看到 done:true 的标记。失败处理:要是 curl 连不上服务,就先启动 Ollama 应用,或者跑一下 ollama serve 命令。碰到 404 错误,先用 ollama list 核对下模型名字对不对;要是本地没这个模型,就执行 ollama pull gemma4 拉一下。碰到 400 错误,就检查下 JSON 的引号、逗号有没有写错,还有那两个必填字段是不是都传了。

第 2 步:把首轮问答装进 messages

第二轮能不能接上之前的话题,全看这个历史数组。入口位置:就是你调用代码里构造请求体的地方。主要动作:把所有消息按实际对话的先后顺序放进数组里。system 是用来限定回答风格的,user 就是用户的提问,assistant 必须填上一轮接口实际返回的 message.content,不能自己随便写个摘要凑数。

{
  "model": "gemma4",
  "messages": [
    {"role": "system", "content": "回答面向编程初学者,控制在三句话内。"},
    {"role": "user", "content": "用一句话解释什么是向量。"},
    {"role": "assistant", "content": "把这里替换为首轮返回的完整回答。"},
    {"role": "user", "content": "再给一个二维坐标的例子。"}
  ],
  "stream": false
}

成功标志:第二轮的回答会接着“向量”的话题往下讲,不会把“二维坐标”当成一个全新的问题来答。要是回答跟第一次对话似的完全不搭边,就从三个地方排查。失败处理:先确认历史数组有没有跟着第二次请求一起发过去;再确认消息顺序有没有搞反;最后检查上一轮的回复是不是不小心填成新的 user 消息了。

官方的字段说明里,messages 就是聊天历史数组,每个元素至少得有 rolecontent 两个字段。允许的角色还有 tool,不过咱们做普通文本多轮对话的话,先把前三种角色搞明白就行。

Ollama 官方文档说明 messages 是包含 role 和 content 的聊天历史数组

第 3 步:让 Python 自动追加每轮回复

手动复制历史很容易漏了助手的回复,还是用程序来维护数组更靠谱。入口位置:你项目的 Python 虚拟环境和聊天脚本里。主要动作:先安装 Ollama 官方的 Python 库,然后全程维护同一个消息列表。每次拿到回复之后,先把真实的助手文本追加进去,再放下一条用户提问。

python -m pip install ollama
from ollama import chat
messages = [
    {"role": "system", "content": "回答面向编程初学者,控制在三句话内。"},
    {"role": "user", "content": "用一句话解释什么是向量。"},
]
first = chat(model="gemma4", messages=messages)
first_text = first["message"]["content"]
messages.append({"role": "assistant", "content": first_text})
messages.append({"role": "user", "content": "再给一个二维坐标的例子。"})
second = chat(model="gemma4", messages=messages)
print(second["message"]["content"])

成功标志:第二次调用的时候会用四条有序的消息,输出的例子也能跟上第一轮的主题对上。要是报 ModuleNotFoundError,先去检查 Python 环境对不对。失败处理:确认你执行安装命令的环境,和跑脚本的环境是同一个。要是字典取值报错,就把 first 打印出来,核对下 messagecontent 字段对不对。服务连不上的话,就回到第 1 步检查 Ollama 进程有没有在跑。

把响应页面展开就能看到,message.role 永远是 assistantmessage.content 就是助手返回的文本。程序里只需要保存这两个字段对应的内容就行,别把整个响应对象里的耗时统计啥的全都塞到下一轮的历史里去。

Ollama 官方文档展开响应 message 的 role、content 和 tool calls 字段

第 4 步:在流式与非流式之间做选择

流式这个开关只会改变解析响应的方式,可不会帮你自动保存历史哦。入口位置:就在 Chat 请求体里的 stream 字段。主要动作:要是你在调试数组或者处理结构化结果,就设成 false,这样能一次读到完整的 JSON。要是做聊天界面需要边生成边显示,就保留默认值 true。这时候程序得逐行解析 NDJSON,把每个事件里的 message.content 依次拼起来。

这两种模式的返回形式很好区分。成功标志:非流式模式只会返回一个完整的响应;流式模式会连续收到好多行事件,最后收尾的事件里 donetrue。等全部拼接完成之后,再把完整的助手文本写成一条 assistant 消息加进历史。失败处理:要是发现内容缺字,就检查下程序是不是只保留了其中一块内容。要是解析器把多行当成一个 JSON 来解析报错,就改成逐行解码。要是中途碰到带 error 的事件,就直接终止本轮请求,保留之前的历史就行,别把残缺的回复存进去。

官方页面里写了 stream 是布尔值,默认是开启的。旁边还能看到 thinkkeep_alive 和日志概率之类的字段,但这些都不影响多轮历史的功能;先把消息追加的逻辑写对了,再去研究这些可选参数就行。

Ollama 官方 Chat API 页面显示 stream 为布尔值且默认开启

第 5 步:限制历史长度并处理常见错误

历史消息越长,占的上下文空间就越多。入口位置:就是你发送请求之前整理 messages 的那个函数。主要动作:先把还生效的 system 消息保留住,再根据业务需求留下最近的几轮对话。要是较早的内容必须得保留上下文,就可以生成一条核对过的摘要,再用明确的角色放回数组里。options.num_ctx 虽然能控制上下文长度,但历史消息总不能无限往上加对吧。

裁剪完之后最好做一次连续性检查。成功标志:消息数量控制住了,后面的提问还能引用保留范围内的内容,响应里也不会混进已经删掉的旧指令。失败处理:要是发现重要的要求没了,就检查是不是不小心把 system 消息或者最近的助手回复给删了。服务返回 429 的话就降低调用频率。碰到 500 或者 502 错误,就保留当前历史等会儿再重试,别把错误对象当成助手回答存进去。

完成核对

  • 首轮请求能正常返回 assistant 角色,而且 content 内容不为空。
  • 下一轮请求会带上原来的问题、真实的助手回复和新问题,排列顺序和实际对话完全一致。
  • 用流式模式的时候会把所有内容片段都拼接起来,只有等到 done:true 之后才保存完整的回复。
  • 用非流式模式的时候能直接读取单个 JSON,并且把 message.content 追加到历史记录里。
  • 连接失败、模型不存在、JSON 格式错误和流式中断这些情况,都有明确的处理方式,错误对象不会混进正式的会话历史里。
  • 历史裁剪的时候会保留有效指令和最近的对话,消息列表不会无限制地变长。

最新游戏

更多

Copyright©2010-2019. All rights reserved | 波波三国游戏官网|[email protected]

备案编号:湘ICP备2022015115号-4