DeepAgents.js 教程 06—— 跨会话长期记忆(Memory与AGENTS.md)

承接上一节的数据库持久化,我们已经实现了单会话内对话历史 的长期保存。但 Checkpointer 是按 thread_id 隔离的 ------ 新开一个会话、重启程序后,智能体依然不知道你的使用偏好、项目背景和已知信息,每次都要重新说明。
本节我们学习 Deep Agents 原生的 Memory 记忆机制 ,通过 AGENTS.md 记忆文件实现跨会话、跨重启的全局长期记忆,让智能体真正做到 "越用越懂你"。


一、认识跨会话长期记忆

1.1 为什么需要跨会话记忆?

Checkpointer 解决的是「同一会话能不能记住刚才说过的话」,而 Memory 解决的是「所有会话能不能记住你的习惯和背景」。

举个例子:

  • 你告诉智能体 "我喜欢简洁回答,代码加中文注释"
  • 只用 Checkpointer:只有当前会话生效,新开对话就忘了
  • 启用 Memory:所有会话、程序重启后都记得,全程遵循你的偏好

1.2 核心概念对比:Checkpointer vs Memory

三者都是 Deep Agents 记忆体系的一部分,但定位和用途完全不同:

机制 存储内容 生效范围 加载时机 核心用途
Checkpointer 对话历史、工具调用状态、执行进度 同 thread_id 会话内 调用时自动加载 多轮对话延续、断点续跑
Memory 用户偏好、项目规范、已知事实 全局跨所有会话 智能体启动时全量加载 统一行为风格、复用背景知识

💡 两者互补不冲突,生产环境通常同时启用:Checkpointer 管对话上下文,Memory 管全局偏好。

1.3 AGENTS.md 记忆文件格式

Deep Agents 的 Memory 机制基于约定格式的 Markdown 文件实现,通常命名为 AGENTS.md。它采用结构化的二级标题分类,便于智能体识别、读取和更新。

标准结构示例:

markdown 复制代码
# Agent Memory
## User Preferences
- 回答风格:简洁明了,避免冗余客套
- 代码风格:使用中文注释,变量命名用英文
- 交流语言:默认使用中文

## Project Context
- 当前项目:DeepAgents 学习教程项目
- 技术栈:Node.js + Deep Agents

## Known Facts
- 用户正在学习 Deep Agents 框架
- 已完成环境配置、工具调用、流式输出、多轮对话章节

官方约定:文件以 # Agent Memory 开头,通过 ## 二级标题 划分板块,内容用列表形式呈现,智能体对这种格式的识别和编辑准确率最高。


二、快速上手跨会话记忆

Memory 是 Deep Agents 的内置能力,不需要安装额外依赖,只需准备记忆文件并在创建智能体时注入即可。

2.1 项目准备

沿用之前的项目目录,新建 06-cross-session-memory.js,模型复用 00-model.js。记忆文件统一存放在 ./workspace/memory/ 目录下。

2.2 核心实现三步法

步骤 1:创建记忆文件与初始内容

通过代码自动创建记忆目录和初始记忆文件,也可以手动创建编辑:

csharp 复制代码
import fs from "node:fs";
import path from "node:path";

// 准备记忆存储目录
const memoryDir = path.resolve("./workspace/memory");
fs.mkdirSync(memoryDir, { recursive: true });
const memoryFile = path.join(memoryDir, "AGENTS.md");

// 写入初始记忆内容
fs.writeFileSync(
  memoryFile,
  `# Agent Memory
## User Preferences
- 回答风格:简洁明了,不要啰嗦
- 代码风格:使用中文注释
- 偏好语言:中文交流
## Project Context
- 当前项目:deepagents 学习教程
- 技术栈:Node.js + deepagents
## Known Facts
- 用户正在学习 deepagents 框架
- 已学完基础对话、自定义工具和输出模式
`
);

步骤 2:注入记忆到智能体

通过 memory 参数传入记忆文件路径数组,支持传入多个文件:

javascript 复制代码
import { createDeepAgent } from "deepagents";
import { model } from "./00-model.js";

const agent = createDeepAgent({
  model: model,
  // 注入记忆文件,支持传入多个路径
  memory: [memoryFile],
  systemPrompt: `你是一个智能助手。你有一份记忆文件,其中记录了用户的偏好和项目信息。
请始终遵循记忆文件中的偏好来回答问题。
如果用户告诉你新的偏好或项目信息,可以使用 write_file 工具更新记忆文件。`,
});

✨ 记忆文件会在智能体初始化时自动读取并融入系统提示词,全程生效,不需要每次调用手动传入。

步骤 3:验证记忆生效

调用智能体,询问记忆中的内容,验证是否能正确读取:

javascript 复制代码
async function main() {
  const userInput = "根据你记得的信息,我当前在学什么?用的什么技术栈和模型?";
  console.log("🧑 用户:", userInput);
  console.log("📄 记忆文件:", memoryFile);
  console.log("\n🤖 助手:\n");

  const result = await agent.invoke({
    messages: [{ role: "user", content: userInput }],
  });

  console.log(result.messages.at(-1).content);
}

main().catch(console.error);

运行代码后,智能体可以准确说出记忆文件中的项目、技术栈等信息 ------ 即使你换一个 thread_id、重启程序再运行,结果依然一致,说明跨会话记忆生效了。


三、进阶:动态更新与组合使用

3.1 动态更新记忆

Memory 不是静态只读的,智能体可以在对话中根据你的反馈,自动更新记忆文件,实现记忆的持续进化。

Deep Agents 内置了虚拟文件系统工具(read_filewrite_fileedit_file),只要在系统提示词中授权,智能体就可以自主修改记忆文件。

典型流程:

  1. 用户说 "以后回答都尽量简短,不要多余的话"
  2. 智能体识别为偏好更新,自动调用 edit_file 修改 AGENTS.md 中的 User Preferences 板块
  3. 后续所有对话、所有会话都会遵循新的偏好

3.2 多记忆文件组合

memory 参数支持传入数组,可拆分不同维度的记忆文件,按顺序叠加加载:

arduino 复制代码
const agent = createDeepAgent({
  model: model,
  memory: [
    "./workspace/memory/global-prefs.md", // 全局用户偏好,所有项目通用
    "./workspace/memory/project-a.md",    // A 项目专属记忆
  ],
});

加载规则

  • 按数组顺序依次加载,后面文件的内容会补充到前面的内容中
  • 适合多项目场景:全局偏好通用,项目记忆独立

3.3 结合 Checkpointer 构建双层记忆

实际使用中,推荐同时启用 Checkpointer + Memory,形成完整的记忆体系:

  • Memory:跨会话的偏好、知识、规范(长期不变的内容)
  • Checkpointer:单会话的对话上下文、任务进度(短期动态内容)
php 复制代码
import { SqliteSaver } from "@langchain/langgraph-checkpoint-sqlite";

const checkpointer = SqliteSaver.fromConnString("./workspace/memory/conversations.sqlite");

const agent = createDeepAgent({
  model: model,
  memory: [memoryFile],       // 跨会话长期记忆
  checkpointer: checkpointer, // 单会话对话记忆
  systemPrompt: "...",
});

四、核心要点与最佳实践

4.1 记忆内容设计原则

  1. 结构化优先 :严格遵循 # Agent Memory + ## 板块 + 列表的格式,提升智能体读写准确率
  2. 粒度适中:记录偏好、规范、背景类信息,不要记录具体对话内容(那是 Checkpointer 的职责)
  3. 控制长度:记忆内容会全量进入系统提示词,避免堆砌无关信息,控制 token 占用
  4. 定期整理:过时的信息及时清理,避免记忆冗余导致智能体混淆

4.2 安全注意事项

  • 不要在记忆文件中存放密码、API 密钥、身份证号等敏感信息
  • 多用户场景不要共用同一个记忆文件,每个用户独立一份
  • 重要的记忆文件建议做好备份,避免误操作被覆盖

4.3 官方底层特性说明

根据 Deep Agents 官方文档,Memory 机制具备以下核心特性:

  • 记忆文件始终全量加载,不同于 Skills 的按需渐进式加载
  • 记忆内容存储在配置的虚拟文件系统后端中,支持磁盘、内存等多种后端
  • 智能体可以基于交互反馈自主更新记忆,无需手动编写更新逻辑

五、完整代码汇总

06-cross-session-memory.js 完整代码如下,包含记忆文件创建、流式输出、工具调用监控、记忆内容展示,可直接运行:

javascript 复制代码
/**
 * Deep Agents 教程 06:跨会话长期记忆(Memory 与 AGENTS.md)
 */
import { createDeepAgent } from "deepagents";
import fs from "node:fs";
import path from "node:path";
import { model } from "./00-model.js";

// ============================================================
// 1. 创建记忆文件与初始内容
// ============================================================
const memoryDir = path.resolve("./workspace/memory");
fs.mkdirSync(memoryDir, { recursive: true });
const memoryFile = path.join(memoryDir, "AGENTS.md");

// 文件不存在时写入初始记忆,避免重复运行被覆盖
if (!fs.existsSync(memoryFile)) {
  fs.writeFileSync(
    memoryFile,
    `# Agent Memory
## User Preferences
- 回答风格:简洁明了,不要啰嗦
- 代码风格:使用中文注释
- 偏好语言:中文交流
## Project Context
- 当前项目:deepagents 学习教程
- 技术栈:Node.js + deepagents + 智谱AI(GLM-4)
- 模型:glm-4-flash-250414
## Known Facts
- 用户正在学习 deepagents 框架
- 已学完基础对话、自定义工具和输出模式
`
  );
}

// ============================================================
// 2. 创建带跨会话记忆的智能体
// ============================================================
const agent = createDeepAgent({
  model: model,
  memory: [memoryFile],
  systemPrompt: `你是一个智能助手。你有一份记忆文件,其中记录了用户的偏好和项目信息。
请始终遵循记忆文件中的偏好来回答问题。
如果用户告诉你新的偏好或项目信息,可以使用 write_file 或 edit_file 工具更新记忆文件。`,
});

// ============================================================
// 3. 流式输出辅助函数
// ============================================================
async function streamAgent(input) {
  const stream = await agent.streamEvents(
    { messages: [{ role: "user", content: input }] },
    { version: "v3" }
  );

  await Promise.all([
    // 实时打印回答文本
    (async () => {
      for await (const message of stream.messages) {
        const text = await message.text;
        if (text) process.stdout.write(text);
      }
    })(),
    // 实时打印工具调用与结果
    (async () => {
      for await (const call of stream.toolCalls) {
        console.log(`\n🔧 [工具调用] ${call.name}(${JSON.stringify(call.input)})`);
        const status = await call.status;
        if (status === "finished") {
          console.log(`📦 [工具结果] ${await call.output}`);
        } else if (status === "error") {
          console.error(`❌ [工具错误] ${await call.error}`);
        }
      }
    })(),
  ]);
  console.log("\n");
}

// ============================================================
// 4. 主流程
// ============================================================
async function main() {
  // 支持命令行传入问题,默认使用测试问题
  const userInput =
    process.argv.slice(2).join(" ") ||
    "根据你记得的信息,我当前在学什么?应该用什么语言和模型?";

  console.log("\n🧑 用户:", userInput);
  console.log("📄 记忆文件路径:", memoryFile);
  console.log("\n🤖 助手:\n");

  await streamAgent(userInput);

  // 打印当前记忆文件内容,方便对比更新前后的变化
  console.log("--- 当前记忆文件内容 ---");
  console.log(fs.readFileSync(memoryFile, "utf-8"));
}

main().catch(console.error);

运行方式

bash 复制代码
# 运行默认测试问题,验证记忆读取
node 06-cross-session-memory.js

# 传入自定义问题,例如让智能体更新记忆
node 06-cross-session-memory.js "记住:我以后的代码都用 TypeScript 编写"

六、常见问题排查

  1. 智能体 读取不到记忆内容

    1. 检查记忆文件路径是否正确,文件是否真实存在
    2. 确认文件开头是 # Agent Memory,格式符合约定结构
    3. 可在系统提示词中补充说明 "优先参考记忆文件中的信息回答"
  2. 智能体 不会主动更新记忆文件

    1. 确认系统提示词中明确授权了更新记忆的权限
    2. 检查虚拟文件系统工具是否正常可用(默认内置,无需额外配置)
    3. 用户指令尽量明确,例如 "把这个偏好加到记忆文件里",而非模糊的 "记住"
  3. 记忆文件被错误覆盖怎么办

    1. 重要记忆建议定期备份
    2. 可在系统提示词中约束:更新记忆时只能追加和修改,不能删除原有内容
    3. 生产环境可以搭配文件权限规则,限制写入范围
  4. Memory 和 Checkpointer 同时启用会冲突吗 不会冲突,两者职责完全不同。Memory 提供全局背景偏好,Checkpointer 维护单会话对话上下文,同时启用效果最佳。


下一节我们将介绍 Deep Agents 的虚拟文件系统,学习如何让智能体具备读写本地文件、管理项目目录的能力。

相关推荐
JaydenAI1 小时前
[基于OpenEvals的自动化评估-08]对Agent的输出和输入进行安全性评估
ai·langchain·agent·evaluation·openevals
breeze jiang2 小时前
React memo、useCallback 与 useMemo:父组件多状态时如何减少无效渲染
前端·javascript·react.js
神奇霸王龙2 小时前
CC Switch 配置 Claude Desktop+ selltoken 中转 API 实测教程(2026 年 8 月更新)
人工智能·ai·aigc·agent·ai编程·claude
代码不加糖3 小时前
common.js和es6中模块引l入的区别?
前端·javascript·es6
前端开发江鸟3 小时前
Agent 已经能测、能追踪了,我才发现这还不等于能上线
aigc·agent
网易云信3 小时前
权威认可!网易智企帝王蟹入选信通院《2026 智能体创新实践汇编》
人工智能·agent
吾鳴4 小时前
用一句话需求,做完一张 9:16 的 Skill 发布海报:我把设计生图交给 Agent 试了一次
人工智能·aigc·agent
云浪4 小时前
从 0 到实战:掌握向量数据库 Milvus,构建 AI 应用的核心能力
javascript·数据库·人工智能
可乐ea4 小时前
Tool Calling 工具调用:让 Agent 查询数据库、调用接口和执行任务
数据库·prompt·agent·tool