> ## Documentation Index
> Fetch the complete documentation index at: https://nvd-54.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 记忆

> 为使用深度智能体构建的智能体添加持久化记忆，使其能够在对话间学习和改进

记忆让您的智能体能够跨对话学习和改进。深度智能体将记忆作为一等功能，采用基于文件系统的记忆方式：智能体以文件形式读写记忆，您通过[后端](/oss/javascript/deepagents/backends)控制这些文件的存储位置。

<Note>
  本页涵盖**长期记忆**：跨对话持久化的记忆。有关短期记忆（单次会话中的对话历史和临时文件），请参见[上下文工程](/oss/javascript/deepagents/context-engineering)指南。短期记忆作为智能体[状态](/oss/javascript/langgraph/graph-api#state)的一部分自动管理。

  <img src="https://mintcdn.com/nvd-54/u9mURd9IHXggg6bM/oss/images/deepagents/production/memory.png?fit=max&auto=format&n=u9mURd9IHXggg6bM&q=85&s=4ea833ca62856c9acd1bee48885eee86" alt="短期记忆通过检查点限定在单个线程内；长期记忆通过存储跨线程持久化" width="1920" height="1160" data-path="oss/images/deepagents/production/memory.png" />
</Note>

## 记忆工作原理

1. **将智能体指向记忆文件。** 创建智能体时向 `memory=` 传入文件路径。您也可以通过 `skills=` 传入[技能](/oss/javascript/deepagents/skills)作为程序性记忆（告诉智能体*如何*执行任务的可复用指令）。[后端](/oss/javascript/deepagents/backends)控制文件的存储位置和访问权限。
2. **智能体读取记忆。** 智能体可以在启动时将记忆文件加载到系统提示中，或在对话过程中按需读取。例如，[技能](/oss/javascript/deepagents/skills)使用按需加载：智能体在启动时仅读取技能描述，然后仅在匹配任务时读取完整的技能文件。这使上下文在能力被需要之前保持精简。
3. **智能体更新记忆（可选）。** 当智能体学到新信息时，它可以使用内置的 `edit_file` 工具更新记忆文件。更新可以在对话中（默认）或通过[后台整合](#background-consolidation)在对话之间进行。更改会被持久化并在下次对话中可用。并非所有记忆都是可写的：开发者定义的[技能](/oss/javascript/deepagents/skills)和[组织策略](#organization-level-memory)通常是只读的。详见[只读 vs 可写记忆](#read-only-vs-writable-memory)。

两种最常见的模式是[智能体作用域记忆](#agent-scoped-memory)（所有用户共享）和[用户作用域记忆](#user-scoped-memory)（按用户隔离）。

## 作用域记忆

智能体记忆可以设定作用域，使相同的记忆文件对使用该智能体的所有人可访问，或者记忆文件可以对每个用户独立。

### 智能体作用域记忆

赋予智能体随时间发展的持久身份。智能体作用域记忆在所有用户间共享，因此智能体通过每次对话积累自己的人格、知识和习得的偏好。随着它与用户交互，它发展专业知识、完善方法并记住什么有效。当具有写入权限时，它也可以学习和更新[技能](/oss/javascript/deepagents/skills)。

关键是后端命名空间：将其设置为 `(assistant_id,)` 意味着此智能体的每次对话都读写同一个记忆文件。

<Note>
  访问 `rt.serverInfo` 需要 `deepagents>=1.9.0`。在旧版本中，从 `getConfig().metadata.assistantId` 读取助手 ID。
</Note>

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import { createDeepAgent, CompositeBackend, StateBackend, StoreBackend } from "deepagents";

const agent = createDeepAgent({
  memory: ["/memories/AGENTS.md"],
  skills: ["/skills/"],
  backend: new CompositeBackend(
    new StateBackend(),
    {
      "/memories/": new StoreBackend({
        namespace: (rt) => [rt.serverInfo.assistantId],  // [!code highlight]
      }),
      "/skills/": new StoreBackend({
        namespace: (rt) => [rt.serverInfo.assistantId],  // [!code highlight]
      }),
    },
  ),
});
```

<Accordion title="完整示例：初始化记忆并调用">
  用初始记忆填充存储，然后跨两个线程调用智能体以查看它记住和更新所学内容。

  ```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { v4 as uuidv4 } from "uuid";
  import { createDeepAgent, CompositeBackend, StateBackend, StoreBackend, createFileData } from "deepagents";
  import { InMemoryStore } from "@langchain/langgraph";

  const store = new InMemoryStore();  // 部署到 LangSmith 时使用平台存储

  // 初始化记忆文件
  await store.put(
    ["my-agent"],
    "/memories/AGENTS.md",
    createFileData(`## Response style
  - Keep responses concise
  - Use code examples where possible
  `),
  );

  // 初始化技能
  await store.put(
    ["my-agent"],
    "/skills/langgraph-docs/SKILL.md",
    createFileData(`---
  name: langgraph-docs
  description: Fetch relevant LangGraph documentation to provide accurate guidance.
  ---

  # langgraph-docs

  Use the fetch_url tool to read https://docs.langchain.com/llms.txt, then fetch relevant pages.
  `),
  );

  const agent = createDeepAgent({
    memory: ["/memories/AGENTS.md"],
    skills: ["/skills/"],
    backend: (rt) => new CompositeBackend(
      new StateBackend(rt),
      {
        "/memories/": new StoreBackend(rt, {
          namespace: (rt) => ["my-agent"],
        }),
        "/skills/": new StoreBackend(rt, {
          namespace: (rt) => ["my-agent"],
        }),
      },
    ),
    store,
  });

  // 线程 1：智能体学习新偏好并保存到记忆
  const config1 = { configurable: { thread_id: uuidv4() } };
  await agent.invoke({
    messages: [{ role: "user", content: "I prefer detailed explanations. Remember that." }],
  }, config1);

  // 线程 2：智能体读取记忆并应用偏好
  const config2 = { configurable: { thread_id: uuidv4() } };
  await agent.invoke({
    messages: [{ role: "user", content: "Explain how transformers work." }],
  }, config2);
  ```
</Accordion>

### 用户作用域记忆

为每个用户提供自己的记忆文件。智能体按用户记住偏好、上下文和历史，同时核心智能体指令保持固定。如果存储在用户作用域后端中，用户也可以拥有每用户[技能](/oss/javascript/deepagents/skills)。

命名空间使用 `(user_id,)` 以便每个用户获得记忆文件的隔离副本。用户 A 的偏好永远不会泄露到用户 B 的对话中。

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import { createDeepAgent, CompositeBackend, StateBackend, StoreBackend } from "deepagents";

const agent = createDeepAgent({
  memory: ["/memories/preferences.md"],
  skills: ["/skills/"],
  backend: new CompositeBackend(
    new StateBackend(),
    {
      "/memories/": new StoreBackend({
        namespace: (rt) => [rt.serverInfo.user.identity],
      }),
      "/skills/": new StoreBackend({
        namespace: (rt) => [rt.serverInfo.user.identity],
      }),
    },
  ),
});
```

<Accordion title="完整示例：跨用户的隔离记忆">
  初始化每用户记忆并以两个不同用户调用智能体。每个用户只能看到自己的偏好。

  ```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import { v4 as uuidv4 } from "uuid";
  import { createDeepAgent, CompositeBackend, StateBackend, StoreBackend, createFileData } from "deepagents";
  import { InMemoryStore } from "@langchain/langgraph";

  const store = new InMemoryStore();  // 部署到 LangSmith 时使用平台存储

  // 为两个用户初始化偏好
  await store.put(
    ["user-alice"],
    "/memories/preferences.md",
    createFileData(`## Preferences
  - Likes concise bullet points
  - Prefers Python examples
  `),
  );
  await store.put(
    ["user-bob"],
    "/memories/preferences.md",
    createFileData(`## Preferences
  - Likes detailed explanations
  - Prefers TypeScript examples
  `),
  );

  // 为 Alice 初始化技能
  await store.put(
    ["user-alice"],
    "/skills/langgraph-docs/SKILL.md",
    createFileData(`---
  name: langgraph-docs
  description: Fetch relevant LangGraph documentation to provide accurate guidance.
  ---

  # langgraph-docs

  Use the fetch_url tool to read https://docs.langchain.com/llms.txt, then fetch relevant pages.
  `),
  );

  const agent = createDeepAgent({
    memory: ["/memories/preferences.md"],
    skills: ["/skills/"],
    backend: (rt) => new CompositeBackend(
      new StateBackend(rt),
      {
        "/memories/": new StoreBackend(rt, {
          namespace: (rt) => [rt.serverInfo.user.identity],
        }),
        "/skills/": new StoreBackend(rt, {
          namespace: (rt) => [rt.serverInfo.user.identity],
        }),
      },
    ),
    store,
  });

  // 部署后，每个经过身份验证的请求将
  // `rt.serverInfo.user.identity` 解析为调用用户，因此 Alice 和 Bob
  // 自动只看到各自的偏好。
  await agent.invoke(
    { messages: [{ role: "user", content: "How do I read a CSV file?" }] },
    { configurable: { thread_id: uuidv4() } },
  );
  ```
</Accordion>

## 高级用法

在记忆路径和作用域的基本配置选项之上，您还可以配置更高级的记忆参数：

| 维度        | 它回答什么问题    | 选项                                                                                                                                        |
| --------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| **持续时间**  | 它持续多久？     | [短期](/oss/javascript/deepagents/context-engineering)（单次对话）或[长期](#scoped-memory)（跨对话）                                                      |
| **信息类型**  | 什么类型的信息？   | [情节性](#episodic-memory)（过去的经验）、[程序性](/oss/javascript/deepagents/skills)（指令和技能）或[语义性](/oss/javascript/concepts/memory#semantic-memory)（事实） |
| **作用域**   | 谁可以查看和修改？  | [用户](#user-scoped-memory)、[智能体](#agent-scoped-memory)或[组织](#organization-level-memory)                                                    |
| **更新策略**  | 记忆何时写入？    | 对话中（默认）或[对话之间](#background-consolidation)                                                                                                 |
| **检索**    | 记忆如何读取？    | 加载到提示中（默认）或按需（例如[技能](/oss/javascript/deepagents/skills)）                                                                                  |
| **智能体权限** | 智能体能否写入记忆？ | [读写](#read-only-vs-writable-memory)（默认）或[只读](#read-only-vs-writable-memory)（用于共享策略）                                                       |

### 情节性记忆

情节性记忆存储过去经验的记录：发生了什么、按什么顺序以及结果如何。与语义记忆（存储在 `AGENTS.md` 等文件中的事实和偏好）不同，情节性记忆保留完整的对话上下文，以便智能体可以回忆*如何*解决问题，而不仅仅是从中*学到了什么*。

深度智能体已使用[检查点](/oss/javascript/langgraph/persistence#checkpoints)，这是支持情节性记忆的机制：每次对话都作为检查点线程持久化。

要使过去的对话可搜索，将线程搜索包装在工具中。`user_id` 从运行时上下文中提取而不是作为参数传入：

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import { Client } from "@langchain/langgraph-sdk";
import { tool } from "@langchain/core/tools";

const client = new Client({ apiUrl: "<DEPLOYMENT_URL>" });

const searchPastConversations = tool(
  async ({ query }, runtime) => {
    const userId = runtime.serverInfo.user.identity;  // [!code highlight]
    const threads = await client.threads.search({
      metadata: { userId },
      limit: 5,
    });
    const results = [];
    for (const thread of threads) {
      const history = await client.threads.getHistory(thread.threadId);
      results.push(history);
    }
    return JSON.stringify(results);
  },
  {
    name: "search_past_conversations",
    description: "Search past conversations for relevant context.",
  }
);
```

您可以通过调整元数据过滤器按用户或组织范围搜索线程：

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
// 搜索特定用户的对话
const userThreads = await client.threads.search({
  metadata: { userId },
  limit: 5,
});

// 搜索组织内的对话
const orgThreads = await client.threads.search({
  metadata: { orgId },
  limit: 5,
});
```

这对于执行复杂多步骤任务的智能体很有用。例如，编程智能体可以回顾过去的调试会话并直接跳到可能的根本原因。

### 组织级记忆

组织级记忆遵循与用户作用域记忆相同的模式，但使用组织范围的命名空间而非每用户命名空间。用于应适用于组织中所有用户和智能体的策略或知识。

组织记忆通常是**只读的**，以防止通过共享状态进行提示注入。详见[只读 vs 可写记忆](#read-only-vs-writable-memory)。

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import { createDeepAgent, CompositeBackend, StateBackend, StoreBackend } from "deepagents";

const agent = createDeepAgent({
  memory: [
    "/memories/preferences.md",
    "/policies/compliance.md",
  ],
  backend: new CompositeBackend(
    new StateBackend(),
    {
      "/memories/": new StoreBackend({
        namespace: (rt) => [rt.serverInfo.user.identity],
      }),
      "/policies/": new StoreBackend({
        namespace: (rt) => [rt.context.orgId],
      }),
    },
  ),
});
```

从应用程序代码填充组织记忆：

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import { Client } from "@langchain/langgraph-sdk";
import { createFileData } from "deepagents";

const client = new Client({ apiUrl: "<DEPLOYMENT_URL>" });

await client.store.putItem(
  [orgId],
  "/compliance.md",
  createFileData(`## Compliance policies
- Never disclose internal pricing
- Always include disclaimers on financial advice
`),
);
```

使用[权限](/oss/javascript/deepagents/permissions)确保组织级记忆为只读，或使用[策略钩子](/oss/javascript/deepagents/backends#add-policy-hooks)进行自定义验证逻辑。

### 后台整合

默认情况下，智能体在对话过程中写入记忆（热路径）。另一种选择是在**对话之间**作为后台任务处理记忆，有时称为**休眠时间计算**。一个单独的深度智能体审查最近的对话，提取关键事实，并将它们与现有记忆合并。

| 方法           | 优点                 | 缺点                   |
| ------------ | ------------------ | -------------------- |
| **热路径**（对话中） | 记忆立即可用，对用户透明       | 增加延迟，智能体需要多任务        |
| **后台**（对话之间） | 无用户感知的延迟，可以跨多个对话综合 | 记忆在下次对话前不可用，需要第二个智能体 |

对于大多数应用，热路径就足够了。当您需要减少延迟或提高跨多个对话的记忆质量时，添加后台整合。

推荐的模式是在主智能体旁部署一个**整合智能体**——一个读取最近对话历史、提取关键事实并将其合并到记忆存储中的深度智能体——并在[定时计划](#cron)上触发它。选择反映用户实际交互频率的节奏：日常流量稳定的聊天产品可能每几小时整合一次，而每周仅使用少数几次的工具只需每晚或每周运行。整合频率远高于用户对话频率只会在无操作运行上浪费 Token。

#### 整合智能体

整合智能体读取最近的对话历史并将关键事实合并到记忆存储中。在 `langgraph.json` 中与主智能体一起注册它：

```typescript src/consolidation-agent.ts theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import { createDeepAgent } from "deepagents";
import { Client } from "@langchain/langgraph-sdk";
import { tool } from "@langchain/core/tools";

const sdkClient = new Client({ apiUrl: "<DEPLOYMENT_URL>" });

const searchRecentConversations = tool(
  async ({ query }, runtime) => {
    const userId = runtime.serverInfo.user.identity;  // [!code highlight]

    const since = new Date(Date.now() - 6 * 60 * 60 * 1000).toISOString();
    const threads = await sdkClient.threads.search({
      metadata: { userId },
      updatedAfter: since,
      limit: 20,
    });
    const conversations = [];
    for (const thread of threads) {
      const history = await sdkClient.threads.getHistory(thread.threadId);
      conversations.push(history.values.messages);
    }
    return JSON.stringify(conversations);
  },
  {
    name: "search_recent_conversations",
    description: "Search this user's conversations updated in the last 6 hours.",
  }
);

const agent = createDeepAgent({
  model: "google_genai:gemini-3.1-pro-preview",
  systemPrompt: `Review recent conversations and update the user's memory file.
Merge new facts, remove outdated information, and keep it concise.`,
  tools: [searchRecentConversations],
});

export { agent };
```

```json langgraph.json theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
{
  "dependencies": ["."],
  "graphs": {
    "agent": "./src/agent.ts:agent",
    "consolidation_agent": "./src/consolidation-agent.ts:agent"
  },
  "env": ".env"
}
```

#### 定时任务

[定时任务](/langsmith/cron-jobs)按固定计划运行整合智能体。智能体搜索最近的对话并将它们综合到记忆中。匹配计划与您的使用模式，以便整合运行大致跟踪实际活动。

```mermaid theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
graph LR
    Store[(记忆存储)] -.->|reads| Conv1[对话 1]
    Store -.->|reads| Conv2[对话 2]
    Cron[定时计划] -->|periodic| Agent[整合智能体]
    Agent -->|writes| Store

    classDef trigger fill:#F6FFDB,stroke:#6E8900,stroke-width:2px,color:#2E3900
    classDef process fill:#E5F4FF,stroke:#006DDD,stroke-width:2px,color:#030710
    classDef output fill:#EBD0F0,stroke:#885270,stroke-width:2px,color:#441E33
    classDef schedule fill:#FDF3FF,stroke:#7E65AE,stroke-width:2px,color:#504B5F

    class Conv1,Conv2 trigger
    class Agent process
    class Store output
    class Cron schedule
```

使用定时任务调度整合智能体：

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import { Client } from "@langchain/langgraph-sdk";

const client = new Client({ apiUrl: "<DEPLOYMENT_URL>" });

const cronJob = await client.crons.create(
  "consolidation_agent",
  {
    schedule: "0 */6 * * *",
    input: { messages: [{ role: "user", content: "Consolidate recent memories." }] },
  },
);
```

<Note>
  所有定时计划都以 **UTC** 解释。详见[定时任务](/langsmith/cron-jobs)了解管理和删除定时任务。
</Note>

<Warning>
  定时间隔必须与整合智能体内的回溯窗口匹配。上面的示例每 6 小时运行一次（`0 */6 * * *`），智能体的 `search_recent_conversations` 工具回溯 `timedelta(hours=6)` — 保持这些同步。如果定时比回溯更频繁，您会重复处理相同的对话；如果不够频繁，您会丢失落在窗口之外的记忆。
</Warning>

有关部署带后台进程的智能体的更多信息，请参见[走向生产环境](/oss/javascript/deepagents/going-to-production)。

### 只读 vs 可写记忆

默认情况下，智能体可以读写记忆文件。对于组织策略或合规规则等共享状态，您可能希望将记忆设为**只读**，以便智能体可以引用但不能修改。这可以防止通过共享记忆进行提示注入，并确保只有您的应用程序代码控制文件内容。

| 权限         | 使用场景                                                          | 工作方式                                                                                                                                                                            |
| ---------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **读写**（默认） | 用户偏好、智能体自我改进、已学习的[技能](/oss/javascript/deepagents/skills)      | 智能体通过 `edit_file` 工具更新文件                                                                                                                                                        |
| **只读**     | 组织策略、合规规则、共享知识库、开发者定义的[技能](/oss/javascript/deepagents/skills) | 通过应用程序代码或[存储 API](/langsmith/custom-store)填充。使用[权限](/oss/javascript/deepagents/permissions)拒绝对特定路径的写入，或使用[策略钩子](/oss/javascript/deepagents/backends#add-policy-hooks)进行自定义验证逻辑。 |

**安全注意事项：** 如果一个用户可以写入另一个用户读取的记忆，恶意用户可能会向共享状态注入指令。要缓解这一点：

* **默认使用用户作用域** `(user_id)` 除非您有特定原因需要共享
* 对共享策略使用**只读记忆**（通过应用程序代码填充，而非智能体）
* 在智能体写入共享记忆前添加**人机协作**验证。使用[中断](/oss/javascript/langgraph/interrupts)要求人工批准对敏感路径的写入。

要强制执行只读记忆，使用[权限](/oss/javascript/deepagents/permissions)声明式拒绝对特定路径的写入。对于自定义验证逻辑（速率限制、审计日志、内容检查），使用[后端策略钩子](/oss/javascript/deepagents/backends#add-policy-hooks)。

### 并发写入

多个线程可以并行写入记忆，但对**同一文件**的并发写入可能导致最后写入者覆盖冲突。对于用户作用域记忆，这很少见，因为用户通常一次只有一个活跃对话。对于智能体作用域或组织作用域记忆，考虑使用[后台整合](#background-consolidation)来序列化写入，或将记忆按主题构造为独立文件以减少竞争。

实际上，如果写入因冲突而失败，大语言模型(LLM)通常足够智能来重试或优雅恢复，因此单次丢失的写入不是灾难性的。

### 同一部署中的多个智能体

要在共享部署中为每个智能体提供自己的记忆，在命名空间中添加 `assistant_id`：

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
new StoreBackend({
  namespace: (rt) => [
    rt.serverInfo.assistantId,  // [!code highlight]
    rt.serverInfo.user.identity,
  ],
})
```

如果只需要按智能体隔离而无需按用户作用域，单独使用 `assistant_id`。

<Tip>
  使用 [LangSmith 追踪](/langsmith/trace-with-langgraph)审计智能体写入记忆的内容。每次文件写入都作为追踪中的工具调用出现。
</Tip>

***

<div className="source-links">
  <Callout icon="terminal-2">
    [通过 MCP 连接这些文档](/use-these-docs)到 Claude、VSCode 等以获取实时解答。
  </Callout>

  <Callout icon="edit">
    [在 GitHub 上编辑此页面](https://github.com/langchain-ai/docs/edit/main/src/oss/deepagents/memory.mdx) 或 [提交 issue](https://github.com/langchain-ai/docs/issues/new/choose)。
  </Callout>
</div>
