Agent记忆模块:让大模型“记住”你,还能省Token!

4 阅读4分钟

Agent记忆模块:让大模型“记住”你,还能省Token!

在人工智能飞速发展的今天,大语言模型(LLM)已经能帮我们写代码、做菜、解答问题……但你有没有想过一个问题:为什么每次和AI聊天,它好像都不记得上一句说了什么?

答案很简单:大模型本身是“无状态”的(Stateless) 。就像HTTP协议一样,每一次请求都是独立的——这是为了高并发、低延迟、节省算力而设计的。但现实中的任务往往是连续的、有上下文依赖的。比如:

“红烧肉怎么做?”
“好吃吗?”
“需要哪些食材?”

如果AI不记得前面聊过“红烧肉”,第二句“好吃吗?”它根本不知道你在问什么!

于是,Agent记忆模块(Memory) 就成了智能体(Agent)的基石。

一、为什么需要记忆模块?

1. LLM 本身没有记忆

  • 每次调用模型,只看到当前输入的 Prompt。
  • 如果你想让它“连贯对话”,必须把之前的对话历史也塞进 Prompt 里。
  • 这个“塞进去的历史”,就是 messages 数组 —— 最基础的记忆形式。

2. RAG 和微调 vs 记忆

  • RAG(检索增强生成) :用低成本(embedding + cosine 相似度)给 LLM 补充精准上下文,效果好、成本低。
  • 微调(Finetune) :虽然能提升能力,但训练成本高、流程复杂,不适合日常对话场景。
  • 记忆(Memory) :轻量、灵活、可持久化,是构建智能 Agent 的核心组件。

✅ 结论:LLM + Tool(干活) + RAG(知识库) + Memory(记忆) = 真正的 AI Agent

二、最简单的记忆:messages 数组

在 LangChain 等框架中,一次对话的上下文通常由一个 messages 数组表示:

[
  new SystemMessage("你是一个做菜助手"),
  new HumanMessage("红烧肉怎么做?"),
  new AIMessage("首先准备五花肉..."),
  new HumanMessage("好吃吗?")
]

这个数组会被完整传给 LLM,让它“知道上下文”。

但问题来了:对话越长,Token 越多,成本越高,还可能超出模型上下文窗口(比如 128K)!

三、如何解决“记忆太长”的问题?

方案1:截断(Truncation)—— 只保留最近几轮

就像手机聊天记录自动滚动,我们只保留最新的 N 条消息:

const maxMessages = 4;
const allMessages = await history.getMessages();
const trimmedMessages = allMessages.slice(-maxMessages); // 保留最后4条

这叫 滑动窗口(Sliding Window)LRU(最近最少使用)策略

💡 优点:简单高效
❌ 缺点:可能丢掉重要早期信息(比如“我叫张三”)

方案2:自动总结(Summarization)

把前面的对话压缩成一段摘要,再和新消息拼接:

原始对话:

  • 用户:我叫张三
  • AI:你好张三!
  • 用户:我喜欢编程
  • AI:用什么语言?

→ 总结为:“用户是名叫张三的程序员。”

这样既保留关键信息,又大幅减少 Token。

LangChain 支持自动触发总结(比如当 Token 使用率达 80% 时),也可以手动触发命令如 /compact

方案3:持久化 + RAG 式检索

把历史对话存到文件或数据库,下次需要时再“召回”:

  • 新任务 → 开新会话(Session)
  • 老任务 → 加载旧会话继续聊
  • 超长历史 → 不直接塞进 Prompt,而是通过 RAG 检索相关片段

这正是 Cursor、Devon 等 AI 编程工具的做法:它们不仅能记住你上次写的代码,还能跨会话理解你的编程风格!

四、实战:用文件持久化记忆

下面这段代码展示了如何用 FileSystemChatMessageHistory 把对话存到本地文件:

import { FileSystemChatMessageHistory } from "@langchain/community/stores/message/file_system";
import { HumanMessage, AIMessage, SystemMessage } from "@langchain/core/messages";

const filePath = "chat_history.json";
const sessionId = "user_session_001";

const history = new FileSystemChatMessageHistory({ filePath, sessionId });

// 用户提问
await history.addMessage(new HumanMessage("红烧肉怎么做?"));

// 获取全部历史(含系统提示)
const messages = [systemMessage, ...(await history.getMessages())];

// 调用模型
const response = await model.invoke(messages);

// 保存AI回复
await history.addMessage(response);

下次运行程序时,只需用相同的 sessionId,就能恢复整个对话上下文

🎯 这就是“有状态”(Stateful)对话的实现方式。

五、高级技巧:智能管理 Token

好的 Agent 会动态监控 Token 消耗:

import { getEncoding } from 'js-tiktoken';

const enc = getEncoding("cl100k_base");
const tokens = enc.encode(fullPrompt).length;
if (tokens / contextWindow > 0.8) {
  // 自动触发总结或截断
}

开发者甚至可以提供命令:

  • /clear:清空记忆,开启新任务(省 Token!)
  • /compact:手动压缩历史

👨‍💻 既能 vibe coding(沉浸式编程),又能控制成本——这才是聪明的 AI 工程师!

六、总结:记忆是 Agent 的灵魂

记住:

  • 无记忆 → AI 是“金鱼”,7秒就忘
  • 有记忆 → AI 是“伙伴”,越聊越懂你

通过 messages 数组 + 截断/总结 + 文件持久化 + RAG 检索,我们就能构建一个既聪明又省钱的 AI Agent。

未来,你的 AI 助手不仅能记住你爱吃的菜,还能记得你讨厌的编程风格、常用的函数命名习惯……这一切,都始于一个小小的 记忆模块


🌟 Agent 的进化 = 记忆的积累
从 Stateless 到 Stateful,从一次性问答到终身学习伙伴——
记忆,让 AI 真正“认识”你。