大家好,我是链杯子(CSDN:链上杯子)。

失业一年了,天天想着怎么翻身。最近调用 API 后发现,单次问答虽然爽,但模型完全不记得上句话说了什么。把历史消息都塞进 messages 列表里,再发给 API,模型就能“记住”上下文了。第一次看到它接上上一轮的话题继续聊,感觉像真的在和一个有记忆的 AI 助手对话。

本课目标:学会维护聊天历史(用列表存储多条消息),在每次调用 API 时把完整历史作为 messages 发送,实现带上下文的多轮对话。结合第九课的 API 调用和第八课的文件保存,构建一个简单的“有记忆的交互机器人”。

核心代码实战

1. 基础多轮对话 —— 手动维护 messages 列表

import requests

# API 配置(替换成你的)
api_url = "<https://api.deepseek.com/v1/chat/completions>"
api_key = "你的 DeepSeek API Key"

headers = {
    "Authorization": f"Bearer {api_key}",
    "Content-Type": "application/json"
}

# 初始化聊天历史(system prompt 放最前面)
messages = [
    {"role": "system", "content": "你是一个友好、幽默的聊天伙伴。回复要简洁有趣。"}
]

print("=== 多轮聊天开始(输入 'quit' 退出) ===")

while True:
    user_input = input("你:")
    if user_input.lower() == "quit":
        break

    # 添加用户消息到历史
    messages.append({"role": "user", "content": user_input})

    # 发送完整历史给 API
    data = {
        "model": "deepseek-chat",
        "messages": messages,
        "temperature": 0.8,
        "max_tokens": 500
    }

    try:
        response = requests.post(api_url, headers=headers, json=data, timeout=30)
        response.raise_for_status()
        result = response.json()
        ai_reply = result["choices"][0]["message"]["content"].strip()

        # 添加 AI 回复到历史
        messages.append({"role": "assistant", "content": ai_reply})

        print("AI:", ai_reply)

    except Exception as e:
        print("调用失败:", str(e))
        break

print("\n聊天结束。")

运行后你可以连续问问题,模型会记住前面的内容。例如:

  • 你:我喜欢看科幻小说
  • AI:哦?那你最爱哪本?《三体》还是《基地》?
  • 你:三体吧,黑暗森林理论太震撼了
  • AI:对啊!黑暗森林一出,谁还敢随便广播坐标?要不要我帮你脑暴一个黑暗森林主题的短故事?

2. 结合文件保存/加载历史 —— 下次继续聊

import json
import requests

# 加载历史(如果文件存在)
try:
    with open("chat_history.json", "r", encoding="utf-8") as f:
        messages = json.load(f)
    print("已加载上次聊天历史,继续聊吧~")
except FileNotFoundError:
    # 第一次运行,初始化
    messages = [{"role": "system", "content": "你是一个知识渊博、风趣的助手。"}]
    print("新聊天开始!")

# 调用函数(封装第九课的 call_llm)
def call_llm(messages):
    # 同第九课的请求代码,这里简化
    data = {
        "model": "deepseek-chat",
        "messages": messages,
        "temperature": 0.7,
        "max_tokens": 600
    }
    try:
        response = requests.post(api_url, headers=headers, json=data)
        response.raise_for_status()
        return response.json()["choices"][0]["message"]["content"].strip()
    except Exception as e:
        return f"错误:{str(e)}"

print("=== 继续聊天(输入 'quit' 退出,或 'clear' 清空历史) ===")

while True:
    user_input = input("你:")
    if user_input.lower() == "quit":
        break
    if user_input.lower() == "clear":
        messages = [{"role": "system", "content": "你是一个知识渊博、风趣的助手。"}]
        print("历史已清空,新开始!")
        continue

    messages.append({"role": "user", "content": user_input})

    reply = call_llm(messages)
    print("AI:", reply)

    messages.append({"role": "assistant", "content": reply})

# 退出时保存历史
with open("chat_history.json", "w", encoding="utf-8") as f:
    json.dump(messages, f, ensure_ascii=False, indent=2)

print("本次聊天已保存到 chat_history.json,下次运行可以继续。")

运行多次,历史会自动加载/保存。清空用 “clear” 命令。

3. 限制历史长度(防止 token 超限)

# 在发送前截断历史(保留 system + 最近 10 条消息)
if len(messages) > 11:  # system + 5轮对话(10条)
    messages = [messages[0]] + messages[-10:]

小练习(2 道)

练习1(基础)

复制第1段代码,修改 system prompt 为“你是一个专业 Python 导师,用鼓励语气回答问题”。

连续问 3–5 个 Python 相关问题,观察模型是否记住上下文(例如先问列表,再问怎么遍历)。

练习2(进阶)

在第2段代码基础上:

  • 加一个命令 “save”:立即保存历史到文件。
  • 加一个命令 “load”:重新从文件加载历史。
  • 加一个 “history” 命令:打印当前 messages 列表(只打印 role 和 content 前 50 字)。 测试多轮对话后用这些命令管理历史。

本课小结

本课重点维护 messages 列表作为聊天历史,每次 API 调用都带上完整(或截断)历史,实现上下文连续的多轮对话。结合文件读写,下次运行还能继续上次的话题。现在你的程序已经是一个小型“带记忆的聊天机器人”了。

下节预告

下一课:简单 AI Agent 雏形 —— 判断用户意图 + 调用不同 prompt / 工具,实现更智能的交互。

欢迎在评论区贴出练习代码、聊天截图或有趣的对话记录,有问题可以留言。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐