Agent 为什么需要记忆?
作者:程序员马丁
Ragent AI —— 从 0 到 1 纯手工打造企业级 Agentic RAG,拒绝 Demo 玩具!AI 时代,助你拿个offer。
上一篇咱们给 ReAct 循环加上了四道终止防线——最大步数、重复调用检测、Token 预算、无进展检测——Agent 现在知道什么时候该停了。到这里,ReAct 核心部分算是告一段落:比特严选智能体有了完整的推理-行动循环、结构化的工具调用、以及稳健的终止保护。
但如果你真的拿现在的 TinyAgent 跑一个完整的客服会话,很快就会发现一个致命的问题。
用户先问了一句:
帮我查一下订单 88231 的物流到哪了。
Agent 正常工作:调 queryOrder 拿到运单号,调 queryLogistics 查到物流状态,回复“您的比特 S10 Pro 扫地机已到达杭州转运中心”。完美。
然后用户紧接着问了第二句:
那我要退款呢,这个扫地机不回充了。
这时候 Agent 懵了——“那”是哪个? “这个扫地机”是什么扫地机?退款退哪个订单?用户没说订单号,因为在他看来,上一句刚聊过订单 88231,Agent 应该知道。但 Agent 真的不知道。
打开 ReActAgent.run() 的代码看一眼,原因一目了然:
public String run(String userMessage) {
ArrayNode messages = objectMapper.createArrayNode();
// 每次 run() 都重新创建消息列表——从零开始
ObjectNode systemMsg = messages.addObject();
systemMsg.put("role", "system");
systemMsg.put("content", buildSystemPrompt());
ObjectNode userMsg = messages.addObject();
userMsg.put("role", "user");
userMsg.put("content", userMessage);
// ... 循环、调工具、返回结果
}
每次调 run(),消息列表都是全新的——只有 system 提示词和当前这句用户输入。上一轮对话里查过的订单号、工具返回的物流信息、Agent 给出的回复——全部丢失。对 Agent 来说,每次 run() 都是人生第一次见到用户。
这就像一个客服,每接一句话就失忆一次。用户说“我刚才跟你说的那个订单”,他只能反问“请问您说的是哪个订单?”——用户一定抓狂。
这就是记忆问题。
本项目中具体代码已上传 GitHub TinyAgent,大家 Clone 项目后,将代码分支切换到 1.5.x,默认主分支是最新代码。运行前复制
.env.example为.env,把自己的 API Key 填进去,默认阿里云百炼平台;.env已加入.gitignore,切分支时不会丢。