Skip to main content
长期记忆让您的代理能够跨不同的对话和会话存储和召回信息。 与短期记忆(其作用范围限于单个线程)不同,长期记忆可以跨线程持久化,并可随时召回。 长期记忆构建于 LangGraph 存储之上,它将数据保存为按命名空间和键组织的 JSON 文档。

用法

要为代理添加长期记忆,请创建一个存储并将其传递给 create_agent
import { createAgent } from "langchain";
import { InMemoryStore } from "@langchain/langgraph";

// InMemoryStore 将数据保存到内存字典中。在生产环境中请使用基于数据库的存储。
const store = new InMemoryStore();

const agent = createAgent({
  model: "google-genai:gemini-3.1-pro-preview",
  tools: [],
  store,
});
然后,工具可以使用 runtime.store 参数从存储中读取和写入数据。有关示例,请参阅在工具中读取长期记忆从工具写入长期记忆
要深入了解记忆类型(语义、情景、程序性)以及编写记忆的策略,请参阅记忆概念指南

记忆存储

LangGraph 将长期记忆作为 JSON 文档存储在存储中。 每条记忆都组织在一个自定义的 namespace(类似于文件夹)和一个独特的 key(类似于文件名)下。命名空间通常包含用户或组织 ID 或其他标签,以便于组织信息。 这种结构支持记忆的层次化组织。然后可以通过内容过滤器支持跨命名空间搜索。
import { InMemoryStore } from "@langchain/langgraph";

const embed = (texts: string[]): number[][] => {
  // 替换为实际的嵌入函数或LangChain嵌入对象
  return texts.map(() => [1.0, 2.0]);
};

// InMemoryStore 将数据保存到内存字典中。在生产环境中请使用基于数据库的存储。
const store = new InMemoryStore({ index: { embed, dims: 2 } });
const userId = "my-user";
const applicationContext = "chitchat";
const namespace = [userId, applicationContext];

await store.put(namespace, "a-memory", {
  rules: [
    "User likes short, direct language",
    "User only speaks English & TypeScript",
  ],
  "my-key": "my-value",
});

// 通过ID获取"记忆"
const item = await store.get(namespace, "a-memory");

// 在此命名空间内搜索"记忆",根据内容等价性进行过滤,并按向量相似度排序
const items = await store.search(namespace, {
  filter: { "my-key": "my-value" },
  query: "language preferences",
});
有关记忆存储的更多信息,请参阅持久化指南。

在工具中读取长期记忆

import * as z from "zod";
import { createAgent, tool, type ToolRuntime } from "langchain";
import { InMemoryStore } from "@langchain/langgraph";

// InMemoryStore 将数据保存到内存字典中。在生产环境中请使用基于数据库的存储。
const store = new InMemoryStore();
const contextSchema = z.object({
  userId: z.string(),
});

// 使用 put 方法将示例数据写入存储
await store.put(
  ["users"], // 用于将相关数据分组的命名空间(用户数据的 users 命名空间)
  "user_123", // 命名空间内的键(用户 ID 作为键)
  {
    name: "John Smith",
    language: "English",
  }, // 为给定用户存储的数据
);

const getUserInfo = tool(
  // 查找用户信息。
  async (_, runtime: ToolRuntime<unknown, z.infer<typeof contextSchema>>) => {
    // 访问存储 - 与提供给 `createAgent` 的相同
    const userId = runtime.context.userId;
    if (!userId) {
      throw new Error("userId is required");
    }
    // 从存储中检索数据 - 返回包含值和元数据的 StoreValue 对象
    const userInfo = await runtime.store.get(["users"], userId);
    return userInfo?.value ? JSON.stringify(userInfo.value) : "Unknown user";
  },
  {
    name: "getUserInfo",
    description: "根据 userId 从存储中查找用户信息。",
    schema: z.object({}),
  },
);

const agent = createAgent({
  model: "google-genai:gemini-3.1-pro-preview",
  tools: [getUserInfo],
  contextSchema,
  // 将存储传递给代理 - 使代理在运行工具时能够访问存储
  store,
});

// 运行代理
const result = await agent.invoke(
  { messages: [{ role: "user", content: "look up user information" }] },
  { context: { userId: "user_123" } },
);

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

/**
 * 输出:
 * 用户信息:
 * - **姓名:** John Smith
 * - **语言:** English
 */

从工具写入长期记忆

import * as z from "zod";
import { tool, createAgent, type ToolRuntime } from "langchain";
import { InMemoryStore } from "@langchain/langgraph";

// InMemoryStore 将数据保存到内存字典中。在生产环境中请使用基于数据库的存储。
const store = new InMemoryStore();

const contextSchema = z.object({
  userId: z.string(),
});

// Schema 定义了 LLM 使用的用户信息结构
const UserInfo = z.object({
  name: z.string(),
});

// 允许代理更新用户信息的工具(对聊天应用很有用)
const saveUserInfo = tool(
  async (
    userInfo: z.infer<typeof UserInfo>,
    runtime: ToolRuntime<unknown, z.infer<typeof contextSchema>>,
  ) => {
    const userId = runtime.context.userId;
    if (!userId) {
      throw new Error("userId is required");
    }
    // 将数据存储在存储中(命名空间,键,数据)
    await runtime.store.put(["users"], userId, userInfo);
    return "Successfully saved user info.";
  },
  {
    name: "save_user_info",
    description: "Save user info",
    schema: UserInfo,
  },
);

const agent = createAgent({
  model: "google-genai:gemini-3.1-pro-preview",
  tools: [saveUserInfo],
  contextSchema,
  store,
});

// 运行代理
await agent.invoke(
  { messages: [{ role: "user", content: "My name is John Smith" }] },
  // 在上下文中传递 userId 以标识正在更新谁的信息
  { context: { userId: "user_123" } },
);

// 你可以直接访问存储来获取值
const result = await store.get(["users"], "user_123");
console.log(result?.value); // 输出: { name: "John Smith" }