一个项目带你入门AI应用开发06

第 6 课:让 Agent 记住对话

6.1 你的目标

多轮对话中,AI 能记住前面说了什么:

复制代码
You: 查一下订单 ORD-001
AI: 您的订单 ORD-001(智能蓝牙耳机 Pro)已发货

You: 这个保修多久?     ← 用户期望 AI 知道说的是"耳机"
AI: 智能蓝牙耳机 Pro 提供 12 个月质保。  ← 没忘!

6.2 问题和解决方案

为什么 AI 会忘?

每次请求的 state["messages"] 都是空列表。Agent 没有上下文,每次都是"第一次见到用户"。

解法:把历史消息传进去

python 复制代码
# main.py 中
sessions: dict[str, list] = defaultdict(list)
conv_id = req.conversation_id or str(uuid.uuid4())
history = sessions[conv_id]

initial_state = {
    "user_message": req.message,
    "messages": history,         # ← 把历史传进去!
    ...
}

result = agent_graph.invoke(initial_state)

# 保存本轮对话
history.append({"role": "user", "content": req.message})
history.append({"role": "assistant", "content": result["final_response"]})

为什么不能存所有历史?

聊 50 轮后,history 会有 100 条消息,几千个 token。LLM 的上下文窗口是有限的。

解法:滑动窗口

python 复制代码
MAX_HISTORY = 10  # 最多保留 10 轮

def save_history(conv_id, user_msg, reply):
    history = sessions[conv_id]
    history.append({"role": "user", "content": user_msg})
    history.append({"role": "assistant", "content": reply})
    # 只保留最近 10 轮
    if len(history) > MAX_HISTORY * 2:
        sessions[conv_id] = history[-MAX_HISTORY * 2:]

为什么是 10 轮? 这不是一个固定的答案。取决于你的业务场景:

  • 客服对话通常 3-5 轮解决问题,10 轮足够
  • 如果是长周期跟进(如售后多次沟通),可能需要更多

6.3 Agents 怎么使用历史

之前每个 Agent 的 LLM 调用只传 user_message,现在加上历史:

python 复制代码
def tool_node(state):
    history = state.get("messages", [])      # ← 拿到历史
    msg = call_llm(
        messages=[
            {"role": "system", "content": TOOL_PROMPT},
            *history,                        # ← 展开到 prompt 中
            {"role": "user", "content": state["user_message"]},
        ],
        tools=TOOLS,
    )

Router Agent 看到历史后,能理解"这个"指的是什么。Tool Agent 看到历史后,知道用户之前已经提供过订单号。

6.4 内存存储的局限

当前会话存在 Python 进程的内存里。服务重启后所有会话丢失。

生产环境应该用 Redis 或数据库存储会话:

python 复制代码
# 当前(内存)
sessions: dict[str, list] = defaultdict(list)

# 生产(Redis)
import redis
r = redis.Redis()
history = json.loads(r.get(f"session:{conv_id}") or "[]")

但第 6 课的重点是理解"有状态"这个模式,而不是具体的存储方案。

6.5 三种记忆策略对比

方案 实现复杂度 信息保留 Token消耗 适用场景
滑动窗口 丢失早期信息 可控 短对话(<20轮)
摘要压缩 保留核心信息 中等长度对话
向量检索记忆 几乎不丢失 超长对话、知识型对话

本课使用滑动窗口,因为简单且适配电商客服的场景。

本课知识点

概念 你做了什么 为什么
有状态 conversation_id + 历史存储 LLM 无状态,上下文全靠 messages 传
滑动窗口 保留最近 N 轮 Token 消耗有上限,不会撑爆窗口
历史注入 history 展开到 messages 里 每个 Agent 都能参考上文

课后作业

  1. 把 MAX_HISTORY 改成 2,看第 3 轮还能不能记住第 1 轮的信息
  2. 给 sessions 加一个过期时间(比如 30 分钟不活跃就删除)

面试可能会问

"Agent 系统的会话管理和传统 Web 应用的 Session 有什么不同?"

Web Session 存的是用户登录状态。Agent 存的是对话历史(messages 数组),而且影响 LLM 的推理质量。管理不好 Agent 就会"失忆"。

相关推荐
liwulin05061 小时前
【ESP32S3】调用百度云语音合成接口后重启
python
m沐沐1 小时前
【机器学习】矿物识别系统实战——六种填充方法×六种模型全面对比
人工智能·python·深度学习·机器学习·矿物识别
软糖姐姐2 小时前
Python:__closure__ 详解
python·闭包·__closure__·自由变量·cell对象
月光船幽幽2 小时前
四层公理框架驱动AI健康诊断
人工智能·python·科技·算法·安全
郝学胜-神的一滴2 小时前
力扣 692:巧用小顶堆高效求解前K个高频单词
java·数据结构·python·程序人生·算法·leetcode·职场和发展
栈溢出的浪漫2 小时前
Python单元测试框架覆盖率-Coverage
python·单元测试·工具·覆盖率·coverage
淼澄研学2 小时前
Python构建AI应用:从环境配置到FastAPI部署的5个实操步骤
人工智能·python·fastapi
157092511342 小时前
优先队列:从Java源码到实战
开发语言·python
Python私教3 小时前
Django + AI 做智能工单系统:自动分类、重复合并、服务时限与人工审批实战
人工智能·python·django