转自:https://weibo.com/2194035935/Qnl4ID5l6(微博:蚁工厂) 原文:https://x.com/hwchase17/status/2011814697889316930
本周,我们推出了 LangSmith Agent Builder,这是一种构建 Agent(智能体)的无代码方式。Agent Builder 的一个核心部分是它的记忆系统。在这篇博客中,我们将涵盖我们优先考虑记忆系统的理由、构建它的技术细节、构建过程中的经验教训、该记忆系统带来的可能性,以及对未来工作的讨论。
1️⃣ 什么是 LangSmith Agent Builder
LangSmith Agent Builder 是一个无代码的 Agent 构建器。它是建立在 Deep Agents harness 之上的。这是一个托管的 Web 解决方案,目标受众是那些“技术背景较轻”的平民开发者(citizen developers)。在 LangSmith Agent Builder 中,构建者将创建一个 Agent 来自动化特定的工作流程或他们日常工作的一部分。例子包括邮件助手、文档助手等。

在早期,我们就做出了一个有意识的选择,即将“记忆”作为平台的一个优先事项。这并不是一个显而易见的选择——大多数 AI 产品在发布初期都没有任何形式的记忆功能,甚至有些产品即使加入了记忆功能,也并没有像人们预期的那样给产品带来变革。我们之所以优先考虑它,是基于我们用户的使用模式。
与 ChatGPT、Claude 或 Cursor 不同,LangSmith Agent Builder 不是一个通用型 Agent。相反,它专门设计用于让构建者为特定任务定制 Agent。在通用型 Agent 中,你会执行各种各样可能完全不相关的任务,因此从一次会话中学到的东西可能与下一次会话无关。而当一个 LangSmith Agent 执行任务时,它是一遍又一遍地做同一个任务。从一次会话中获得的经验转化到下一次会话的比率要高得多。事实上,如果没有记忆功能,用户体验将会很糟糕——这意味着你必须在不同的会话中一遍又一遍地向 Agent 重复同样的要求。
在思考 LangSmith Agents 的“记忆”究竟意味着什么时,我们参考了第三方的定义。COALA 论文将 Agent 的记忆分为三类:
--程序性记忆 (Procedural):应用于工作记忆以决定 Agent 行为的一组规则。
--语义记忆 (Semantic):关于世界的事实。
--情景记忆 (Episodic):Agent 过往行为的序列。

2️⃣我们如何构建我们的记忆系统
我们在 Agent Builder 中将记忆表示为一组文件。这是一个有意的选择,旨在利用模型擅长使用文件系统这一事实。通过这种方式,我们可以轻松地让 Agent 读取和修改其记忆,而无需为它提供专门的工具——我们只需给它访问文件系统的权限!
只要可能,我们尽量使用行业标准。
--我们使用 AGENTS.md 来定义 Agent 的核心指令集。
--我们使用 agent skills(Agent 技能)为 Agent 提供针对特定任务的专门指令。
--虽然目前没有子 Agent (subagent) 的标准,但我们使用了类似于 Claude Code 的格式。
对于 MCP (Model Context Protocol) 访问,我们使用自定义的 tools.json 文件。我们使用自定义 tools.json 而不是标准 mcp.json 的原因是,我们希望允许用户只给 Agent 提供 MCP 服务器中工具的一个子集,以避免上下文溢出。
我们还允许用户(以及 Agent 自身)向 Agent 的记忆文件夹中写入其他文件。这些文件也可以包含任意知识,Agent 在运行时可以引用这些知识。Agent 会在工作过程中,“在热路径 (in the hot path) 中”编辑这些文件。

实际上,我们并没有使用真正的文件系统来存储这些文件。相反,我们将它们存储在 Postgres 数据库中,但以文件系统的形式暴露给 Agent。我们这样做是因为 LLM 擅长处理文件系统,但从基础设施的角度来看,使用数据库更容易且更高效。这种“虚拟文件系统”是 DeepAgents 原生支持的——并且是完全可插拔的,因此你可以使用任何你想要的存储层(如 S3、MySQL 等)。

之所以能够在没有任何代码或任何领域特定语言 (DSL) 的情况下构建复杂的 Agent,是因为我们在底层使用像 Deep Agents 这样的通用 Agent 框架。Deep Agents 屏蔽了(抽象掉了)许多复杂的上下文工程细节(如摘要、工具调用卸载和规划),让你通过相对简单的配置就能驾驭你的 Agent。
这些文件很好地映射到了 COALA 论文中定义的记忆类型:
--程序性记忆——驱动核心 Agent 指令的内容——是 AGENTS.md 和 tools.json。
--语义记忆是 Agent 技能和其他知识文件。
--唯一缺失的记忆类型是情景记忆,我们认为对于这类 Agent 来说,它暂时不如前两者重要。
文件系统中的 Agent 记忆长什么样
我们可以看看我们内部一直在使用的一个真实 Agent——一个基于 LangSmith Agent Builder 构建的 LinkedIn 招聘人员。
--AGENTS.md:定义核心 Agent 指令。
--subagents/:定义了唯一的子 Agent linkedin_search_worker:在主 Agent 完成搜索校准后,它将启动此 Agent 来寻找约 50 名候选人。
--tools.json:定义了一个有权访问 LinkedIn 搜索工具的 MCP 服务器。
记忆中目前还有 3 个其他文件,代表不同候选人的职位描述 (JD)。随着我们与 Agent 在这些搜索上的合作,它已经更新并维护了这些 JD。
记忆编辑是如何工作的:一个具体的例子
为了让记忆的工作原理更加具体,我们可以通过一个说明性的例子来演示。
开始: 你从一个简单的 AGENTS.md 开始:
?Summarize meeting notes.(总结会议纪要。)
第一周: Agent 生成了段落式的总结。你纠正它:“用要点(bullet points)代替。” Agent 将其 AGENTS.md 编辑为:
?Formatting Preferences
User prefers bullet points for summaries, not paragraphs.
第二周: 你要求 Agent 总结另一个会议。它读取其记忆并自动使用了要点。无需提醒。在这次会话中:“把行动项(action items)单独提取在最后。” 记忆更新为:
?Formatting Preferences
User prefers bullet points for summaries, not paragraphs.
Extract action items in separate section at end.
第四周: 两种模式都自动应用了。随着新边缘情况的出现,你继续添加改进。
三个月后: Agent 的记忆包含了更多通过使用积累下来的偏好、术语、区别、重复概念、会议处理方式和边缘情况修正。记忆文件可能看起来像这样:
?Meeting Summary Preferences
??Format
- Use bullet points, not paragraphs
- Extract action items in separate section at end
- Use past tense for decisions
- Include timestamp at top
??Meeting Types
- Engineering meetings: highlight technical decisions and rationale
- Planning meetings: emphasize priorities and timelines
- Customer meetings: redact sensitive information
- Short meetings (
??People
- Sarah Chen (Engineering Lead) - focus on technical details
- Mike Rodriguez (PM) - focus on business impact
...
AGENTS.md 是通过纠正自我构建的,而不是通过预先的文档编写。我们通过迭代达到了一个细节适度的 Agent 规范,而用户从未手动更改过 AGENTS.md。
构建此记忆系统的经验教训

3️⃣我们在这一过程中学到了几个教训
最难的部分是提示词工程 (Prompting) 构建一个能记住事情的 Agent,最难的部分是提示词。在几乎所有 Agent 表现不佳的情况下,解决方案都是改进提示词。通过这种方式解决的问题示例:
--Agent 在该记住的时候没记住。
--Agent 在不该记住的时候记住了。
--Agent 向 AGENTS.md 写入了太多内容,而不是写入到技能 (skills) 文件中。
--Agent 不知道技能文件的正确格式。
……还有很多。
我们要排一个人全职负责记忆功能的提示词工作(这对团队来说是一个很大的人力占比)。
验证文件类型 有些文件需要遵守特定的架构(schema)(tools.json 需要有有效的 MCP 服务器,技能文件需要有正确的前置元数据 frontmatter 等)。我们发现 Agent Builder 有时会忘记这一点,导致生成无效文件。我们添加了一个步骤来显式验证这些自定义形状,如果验证失败,就将任何错误抛回给 LLM,而不是提交文件。
Agent 擅长向文件添加内容,但不擅长压缩 (Compact) Agent 在工作时会编辑它们的记忆。它们非常擅长向文件添加具体内容。然而,它们不擅长的一点是意识到何时该压缩习得的知识。例如:我的邮件助手一度开始列出它应该忽略冷推销邮件的所有特定供应商,而不是更新自身规则以忽略所有冷推销邮件。
作为终端用户,显式提示仍然很有用 即使 Agent 能够在工作时更新其记忆,但在某些情况下(作为终端用户),我们发现显式提示 Agent 管理其记忆仍然很有用。一种情况是在工作结束时,提示它反思对话并更新记忆以补充任何可能遗漏的内容。另一种情况是提示它压缩记忆,以解决它只记住了具体案例而没有归纳出普遍规律的情况。
人在回路 (Human-in-the-loop) 我们将所有对记忆的编辑都设为“人在回路”——即在更新前需要明确的人工批准。这主要是为了最大限度地减少提示词注入 (prompt injection) 的潜在攻击面。我们也为用户提供了一种关闭此功能的方法(“yolo 模式”),以防他们不太担心这个问题。
4️⃣这带来了什么
除了更好的产品体验外,以这种方式表示记忆还实现了许多事情。
无代码体验 无代码构建者的问题之一是,它们通常要求你学习一种不熟悉的 DSL(领域特定语言),且这种语言难以随着复杂度的增加而扩展。通过将 Agent 表示为 Markdown 和 JSON 文件,Agent 现在处于一种 (a) 大多数非技术人员都熟悉,(b) 更具可扩展性的格式中。
更好的 Agent 构建体验 记忆实际上允许更好的 Agent 构建体验。Agent 构建是非常迭代的——很大程度上是因为在你尝试之前,你不知道 Agent 会做什么。记忆使迭代变得更容易,因为你不必每次都手动更新 Agent 配置,只需用自然语言给出反馈,它就会自我更新。
可移植的 Agent 文件非常便于移植!这使你可以轻松地将 Agent Builder 中构建的 Agent 移植到其他框架(只要它们使用相同的文件约定)。出于这个原因,我们尝试尽可能多地使用标准约定。例如,我们希望让在 Agent Builder 中构建的 Agent 能够轻松地在 Deep Agents CLI 中使用。或者完全用于其他的 Agent 框架,如 Claude Code 或 OpenCode。
5️⃣未来方向
我们还有很多想做的记忆功能改进,但没时间或没有足够的信心在发布前完成。
--情景记忆 (Episodic memory)
Agent Builder 缺失的一种 COALA 记忆类型是情景记忆:Agent 过往行为的序列。我们计划通过将以前的对话作为文件系统中的文件暴露给 Agent 来实现这一点,以便 Agent 可以与其交互。
--后台记忆进程
目前,所有记忆都是“在热路径中”更新的;也就是说,是在 Agent 运行时更新的。我们希望添加一个在后台运行的进程(可能是一些 cron job 定时任务,每天运行一次左右)来反思所有对话并更新记忆。我们认为这将捕捉到 Agent 在当下未能识别的项目,并且对于归纳特定学习成果特别有用。

--/remember 命令
我们希望暴露一个显式的 /remember 命令,这样你可以提示 Agent 反思对话并更新其记忆。我们发现自己偶尔会这样做并获益良多,因此希望让这变得更容易并鼓励使用。
--语义搜索
虽然能够使用 glob 和 grep 搜索记忆是一个很好的起点,但在某些情况下,允许 Agent 对其记忆进行语义搜索将提供一些增益。
--不同层级的记忆
目前,所有记忆都是针对特定 Agent 的。我们要引入用户级 (user-level) 或组织级 (org-level) 记忆的概念。我们计划通过向 Agent 暴露代表这些类型记忆的特定目录,并提示 Agent 相应地使用和更新这些记忆来实现这一点。
6️⃣结论
如果构建拥有记忆的 Agent 听起来很有趣,请尝试 LangSmith Agent Builder。如果你想帮助我们构建这个记忆系统,我们正在招聘。










