查看: 384|回复: 0

Python调用Ollama /api/chat多轮对话CLI机器人

[复制链接]
发表于 3 小时前 | 显示全部楼层 |阅读模式
在上一篇使用 Python 调用 Ollama 的 /api/generate 接口做单轮问答时,每次请求只发送当前 prompt,模型没有上下文,因此先问“我叫小明”,再问“我叫什么名字”,模型无法记住。解决办法是改用 Ollama 的 /api/chat 接口,并在客户端维护一个 messages 消息历史列表。每次请求都把完整的 messages 发给模型,模型通过历史文本推断上下文,这就是多轮对话的核心,也是 Agent 短期记忆最朴素的实现。

/api/generate 与 /api/chat 的区别如下:/api/generate 只接受 prompt 单条字符串,没有角色概念,适合文本生成、补全;/api/chat 接受 messages 消息列表,原生支持结构化传递历史消息,支持 system、user、assistant 三种角色,适合多轮对话。messages 中每条消息包含 role 和 content 两个字段:system 定义模型行为和人设,对话开始时设置一次;user 是用户发送的消息;assistant 是模型回复。

下面用 ContinueChatBot 类实现 CLI 多轮聊天机器人。创建文件 continueChat.py:
  1. import requests
  2. import json
  3. class ContinueChatBot:
  4.     def __init__(self, model="qwen2:7b", system_prompt="你是一个有帮助的AI助手。"):
  5.         self.model = model
  6.         self.url = "http://localhost:11434/api/chat"
  7.         # 消息历史:system + 对话记录
  8.         self.messages = [
  9.             {"role": "system", "content": system_prompt}
  10.         ]
  11.     def ask(self, user_input):
  12.         # 把用户的问题加入历史
  13.         self.messages.append({"role": "user", "content": user_input})
  14.         payload = {
  15.             "model": self.model,
  16.             "messages": self.messages,
  17.             "stream": False
  18.         }
  19.         response = requests.post(self.url, json=payload)
  20.         data = response.json()
  21.         # 提取模型的回答
  22.         assistant_reply = data["message"]["content"]
  23.         # 把模型的回答也加入历史,下次对话就能记得
  24.         self.messages.append({"role": "assistant", "content": assistant_reply})
  25.         return assistant_reply
  26.     def chat_loop(self):
  27.         print("=== 多轮对话模式 ===")
  28.         print("输入你的问题,回车发送。输入 'exit' 或 'quit' 结束。\n")
  29.         while True:
  30.             user_input = input("你: ").strip()
  31.             if user_input.lower() in ("exit", "quit", "退出"):
  32.                 print("\n对话结束。")
  33.                 break
  34.             if not user_input:
  35.                 continue
  36.             print("模型思考中...")
  37.             reply = self.ask(user_input)
  38.             print(f"模型: {reply}\n")
  39. if __name__ == "__main__":
  40.     bot = ContinueChatBot(
  41.         model="qwen2:7b",
  42.         system_prompt="你是一个耐心、幽默的AI助手,喜欢用简洁的方式回答问题。"
  43.     )
  44.     bot.chat_loop()
复制代码

代码逻辑可以拆成四部分。

1. 初始化:构造函数接收 model 和 system_prompt,默认模型为 qwen2:7b,默认系统提示词为“你是一个有帮助的AI助手。”。self.messages 初始只放入一条 system 消息,系统提示词始终位于历史最前面,用来设定角色和行为风格。

2. 提问:ask 方法先追加用户消息,再构造 payload 发送 POST 请求到 http://localhost:11434/api/chat。payload 包括 model、messages,并设置 stream=False。收到响应后,从 data["message"]["content"] 取出模型回答,再把这条 assistant 消息追加到历史,最后返回回答。顺序很关键:发送前追加 user,返回前追加 assistant,这样下一轮请求就同时带上用户问题和模型回复。

3. 对话循环:chat_loop 用 while True 读取 input(),空输入直接 continue;输入 exit、quit 或“退出”时结束。每轮调用 ask 并打印模型回复。

4. 启动:实例化 ContinueChatBot 时可以替换 model 和 system_prompt。例如把 model 改成 deepseek-r1:7b 等本地已拉取的模型名,就可以切换模型。

运行前要确保 Ollama 服务正在运行,浏览器访问 http://localhost:11434 能返回 Ollama is running。然后执行:
  1. python continueChat.py
复制代码

交互效果如下:

=== 多轮对话模式 ===
输入你的问题,回车发送。输入 'exit' 或 'quit' 结束。

你: 你好,我叫小明,请记住这个名字
模型思考中...
模型: 你好,小明!很高兴遇到你。你的名字会牢牢地刻在我的记忆中。有什么我能帮你解答的问题吗?

你: 我叫什么名字?
模型思考中...
模型: 你是小明。这个名字挺有亲切感的!有什么其他问题我可以帮助你解答的吗?

你: exit
对话结束。

可以看到,模型之所以能回答“你是小明”,是因为 messages 列表记录了第一轮的用户输入和模型回复。完整流程是:system 设定 → 用户提问 → 携带全部历史请求 /api/chat → 模型回复 → 追加 assistant → 下一轮继续携带全部历史。每轮请求都会发送整个 messages 列表。

目前这个实现还有两个明显局限。第一,历史会无限增长。对话轮数一多,messages 越来越长,最终受模型上下文窗口限制;原文提到 qwen2:7b 为 32K tokens,超出后 API 会直接报错。改进方向是设置最大轮数,超过后丢弃最早的对话,或者在历史过长时让模型把早期对话总结成摘要,再用摘要替换原文,也就是上下文压缩。第二,记忆只在内存中,程序退出就丢失。重新运行脚本时 messages 会重新初始化,模型又“失忆”。改进方向是把 messages 定期保存到文件或数据库,启动时加载,这就演进为 Agent 的长期记忆。

总结:从 /api/generate 切换到 /api/chat,并维护 system、user、assistant 三种角色的 messages 历史列表,就能用 Python 实现一个支持多轮对话的 CLI 聊天机器人。这个 messages 列表就是 Agent 短期记忆的最简实现;后续可继续处理上下文压缩和记忆持久化。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-10-9 15:24 , Processed in 0.033245 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部