Skip to content

长期记忆 (Long-term memory) ​

为 LangChain 智能体添加长期记忆,以在跨会话和不同对话中持久化存储和召回数据

长期记忆能让你的智能体在不同的对话和会话之间存储与召回信息。 与仅限于单个线程作用域的短期记忆不同,长期记忆可以跨线程持久化,并能随时被召回。

长期记忆构建于 LangGraph stores 之上,它将数据组织为按命名空间(namespace)和键(key)划分的 JSON 文档进行保存。

使用方法 ​

要为智能体添加长期记忆,请创建一个 store 并将其传递给 create_agent:

InMemoryStore

ts
import { createAgent } from "langchain";
import { InMemoryStore } from "@langchain/langgraph";

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

const agent = createAgent({
  model: "google:gemini-3.6-flash",
  tools: [],
  store,
});
ts
import { createAgent } from "langchain";
import { InMemoryStore } from "@langchain/langgraph";

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

const agent = createAgent({
  model: "openai:gpt-5.5",
  tools: [],
  store,
});
ts
import { createAgent } from "langchain";
import { InMemoryStore } from "@langchain/langgraph";

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

const agent = createAgent({
  model: "anthropic:claude-sonnet-5",
  tools: [],
  store,
});
ts
import { createAgent } from "langchain";
import { InMemoryStore } from "@langchain/langgraph";

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

const agent = createAgent({
  model: "openrouter:z-ai/glm-5.2",
  tools: [],
  store,
});
ts
import { createAgent } from "langchain";
import { InMemoryStore } from "@langchain/langgraph";

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

const agent = createAgent({
  model: "fireworks:accounts/fireworks/models/glm-5p2",
  tools: [],
  store,
});
ts
import { createAgent } from "langchain";
import { InMemoryStore } from "@langchain/langgraph";

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

const agent = createAgent({
  model: "baseten:zai-org/GLM-5.2",
  tools: [],
  store,
});
ts
import { createAgent } from "langchain";
import { InMemoryStore } from "@langchain/langgraph";

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

const agent = createAgent({
  model: "ollama:north-mini-code-1.0",
  tools: [],
  store,
});

PostgreSQL

shell
npm install @langchain/langgraph-checkpoint-postgres
ts
import { createAgent } from "langchain";
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI);
await store.setup();

const agent = createAgent({
  model: "google:gemini-3.6-flash",
  tools: [],
  store,
});
ts
import { createAgent } from "langchain";
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI);
await store.setup();

const agent = createAgent({
  model: "openai:gpt-5.5",
  tools: [],
  store,
});
ts
import { createAgent } from "langchain";
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI);
await store.setup();

const agent = createAgent({
  model: "anthropic:claude-sonnet-5",
  tools: [],
  store,
});
ts
import { createAgent } from "langchain";
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI);
await store.setup();

const agent = createAgent({
  model: "openrouter:z-ai/glm-5.2",
  tools: [],
  store,
});
ts
import { createAgent } from "langchain";
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI);
await store.setup();

const agent = createAgent({
  model: "fireworks:accounts/fireworks/models/glm-5p2",
  tools: [],
  store,
});
ts
import { createAgent } from "langchain";
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI);
await store.setup();

const agent = createAgent({
  model: "baseten:zai-org/GLM-5.2",
  tools: [],
  store,
});
ts
import { createAgent } from "langchain";
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI);
await store.setup();

const agent = createAgent({
  model: "ollama:north-mini-code-1.0",
  tools: [],
  store,
});

NOTE

有关包括 Redis 和 MongoDB 在内的其他 store 后端,请参阅 store integrations 列表。有关 MongoDB 的使用演练,请参阅 long-term memory with MongoDB。

随后,工具可以使用 runtime.store 参数从 store 中读取和写入数据。相关示例请参阅在工具中读取长期记忆与从工具中写入长期记忆。

TIP

若要深入了解记忆类型(语义记忆、情景记忆、程序记忆)以及写入记忆的策略,请参阅记忆概念指南。

记忆存储 ​

LangGraph 将长期记忆作为 JSON 文档保存在 store 中。

每条记忆都在自定义的 namespace(命名空间,类似于文件夹)和唯一的 key(键,类似于文件名)下进行组织。命名空间通常包含用户 ID、组织 ID 或其他便于组织信息的标签。

这种结构支持对记忆进行层级化组织。随后可以通过内容过滤器支持跨命名空间搜索。

InMemoryStore

ts
import { InMemoryStore } from "@langchain/langgraph";

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

// InMemoryStore 将数据保存到内存字典中。在生产环境中请使用由数据库支持的 store。
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",
});

PostgreSQL

ts
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const embed = (texts: string[]): number[][] => {
  return texts.map(() => [1.0, 2.0]);
};

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI, {
  index: { embed, dims: 2 },
});
await store.setup();

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",
});

const item = await store.get(namespace, "a-memory");
const items = await store.search(namespace, {
  filter: { "my-key": "my-value" },
  query: "language preferences",
});

有关 memory store 的更多信息,请参阅持久化(Persistence)指南。

在工具中读取长期记忆 ​

InMemoryStore

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

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

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

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

const agent = createAgent({
  model: "google:gemini-3.6-flash",
  tools: [getUserInfo],
  contextSchema,
  // 将 store 传递给智能体 - 使智能体在运行工具时能够访问 store
  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);

/**
 * Outputs:
 * User Information:
 * - **Name:** John Smith
 * - **Language:** English
 */
ts
import * as z from "zod";
import { createAgent, tool, type ToolRuntime } from "langchain";
import { InMemoryStore } from "@langchain/langgraph";

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

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

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

const agent = createAgent({
  model: "openai:gpt-5.5",
  tools: [getUserInfo],
  contextSchema,
  // 将 store 传递给智能体 - 使智能体在运行工具时能够访问 store
  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);

/**
 * Outputs:
 * User Information:
 * - **Name:** John Smith
 * - **Language:** English
 */
ts
import * as z from "zod";
import { createAgent, tool, type ToolRuntime } from "langchain";
import { InMemoryStore } from "@langchain/langgraph";

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

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

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

const agent = createAgent({
  model: "anthropic:claude-sonnet-5",
  tools: [getUserInfo],
  contextSchema,
  // 将 store 传递给智能体 - 使智能体在运行工具时能够访问 store
  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);

/**
 * Outputs:
 * User Information:
 * - **Name:** John Smith
 * - **Language:** English
 */
ts
import * as z from "zod";
import { createAgent, tool, type ToolRuntime } from "langchain";
import { InMemoryStore } from "@langchain/langgraph";

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

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

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

const agent = createAgent({
  model: "openrouter:z-ai/glm-5.2",
  tools: [getUserInfo],
  contextSchema,
  // 将 store 传递给智能体 - 使智能体在运行工具时能够访问 store
  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);

/**
 * Outputs:
 * User Information:
 * - **Name:** John Smith
 * - **Language:** English
 */
ts
import * as z from "zod";
import { createAgent, tool, type ToolRuntime } from "langchain";
import { InMemoryStore } from "@langchain/langgraph";

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

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

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

const agent = createAgent({
  model: "fireworks:accounts/fireworks/models/glm-5p2",
  tools: [getUserInfo],
  contextSchema,
  // 将 store 传递给智能体 - 使智能体在运行工具时能够访问 store
  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);

/**
 * Outputs:
 * User Information:
 * - **Name:** John Smith
 * - **Language:** English
 */
ts
import * as z from "zod";
import { createAgent, tool, type ToolRuntime } from "langchain";
import { InMemoryStore } from "@langchain/langgraph";

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

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

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

const agent = createAgent({
  model: "baseten:zai-org/GLM-5.2",
  tools: [getUserInfo],
  contextSchema,
  // 将 store 传递给智能体 - 使智能体在运行工具时能够访问 store
  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);

/**
 * Outputs:
 * User Information:
 * - **Name:** John Smith
 * - **Language:** English
 */
ts
import * as z from "zod";
import { createAgent, tool, type ToolRuntime } from "langchain";
import { InMemoryStore } from "@langchain/langgraph";

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

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

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

const agent = createAgent({
  model: "ollama:north-mini-code-1.0",
  tools: [getUserInfo],
  contextSchema,
  // 将 store 传递给智能体 - 使智能体在运行工具时能够访问 store
  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);

/**
 * Outputs:
 * User Information:
 * - **Name:** John Smith
 * - **Language:** English
 */

查看示例 Trace

打开该示例的公开 LangSmith 运行记录。

PostgreSQL

ts
import * as z from "zod";
import { createAgent, tool, type ToolRuntime } from "langchain";
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI);
await store.setup();

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

await store.put(["users"], "user_123", {
  name: "John Smith",
  language: "English",
});

const getUserInfo = tool(
  async (_, runtime: ToolRuntime<unknown, z.infer<typeof contextSchema>>) => {
    const userId = runtime.context.userId;
    if (!userId) throw new Error("userId is required");
    const userInfo = await runtime.store.get(["users"], userId);
    return userInfo?.value ? JSON.stringify(userInfo.value) : "Unknown user";
  },
  {
    name: "getUserInfo",
    description: "Look up user info by userId from the store.",
    schema: z.object({}),
  },
);

const agent = createAgent({
  model: "google:gemini-3.6-flash",
  tools: [getUserInfo],
  contextSchema,
  store,
});

await agent.invoke(
  { messages: [{ role: "user", content: "look up user information" }] },
  { context: { userId: "user_123" } },
);
ts
import * as z from "zod";
import { createAgent, tool, type ToolRuntime } from "langchain";
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI);
await store.setup();

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

await store.put(["users"], "user_123", {
  name: "John Smith",
  language: "English",
});

const getUserInfo = tool(
  async (_, runtime: ToolRuntime<unknown, z.infer<typeof contextSchema>>) => {
    const userId = runtime.context.userId;
    if (!userId) throw new Error("userId is required");
    const userInfo = await runtime.store.get(["users"], userId);
    return userInfo?.value ? JSON.stringify(userInfo.value) : "Unknown user";
  },
  {
    name: "getUserInfo",
    description: "Look up user info by userId from the store.",
    schema: z.object({}),
  },
);

const agent = createAgent({
  model: "openai:gpt-5.5",
  tools: [getUserInfo],
  contextSchema,
  store,
});

await agent.invoke(
  { messages: [{ role: "user", content: "look up user information" }] },
  { context: { userId: "user_123" } },
);
ts
import * as z from "zod";
import { createAgent, tool, type ToolRuntime } from "langchain";
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI);
await store.setup();

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

await store.put(["users"], "user_123", {
  name: "John Smith",
  language: "English",
});

const getUserInfo = tool(
  async (_, runtime: ToolRuntime<unknown, z.infer<typeof contextSchema>>) => {
    const userId = runtime.context.userId;
    if (!userId) throw new Error("userId is required");
    const userInfo = await runtime.store.get(["users"], userId);
    return userInfo?.value ? JSON.stringify(userInfo.value) : "Unknown user";
  },
  {
    name: "getUserInfo",
    description: "Look up user info by userId from the store.",
    schema: z.object({}),
  },
);

const agent = createAgent({
  model: "anthropic:claude-sonnet-5",
  tools: [getUserInfo],
  contextSchema,
  store,
});

await agent.invoke(
  { messages: [{ role: "user", content: "look up user information" }] },
  { context: { userId: "user_123" } },
);
ts
import * as z from "zod";
import { createAgent, tool, type ToolRuntime } from "langchain";
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI);
await store.setup();

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

await store.put(["users"], "user_123", {
  name: "John Smith",
  language: "English",
});

const getUserInfo = tool(
  async (_, runtime: ToolRuntime<unknown, z.infer<typeof contextSchema>>) => {
    const userId = runtime.context.userId;
    if (!userId) throw new Error("userId is required");
    const userInfo = await runtime.store.get(["users"], userId);
    return userInfo?.value ? JSON.stringify(userInfo.value) : "Unknown user";
  },
  {
    name: "getUserInfo",
    description: "Look up user info by userId from the store.",
    schema: z.object({}),
  },
);

const agent = createAgent({
  model: "openrouter:z-ai/glm-5.2",
  tools: [getUserInfo],
  contextSchema,
  store,
});

await agent.invoke(
  { messages: [{ role: "user", content: "look up user information" }] },
  { context: { userId: "user_123" } },
);
ts
import * as z from "zod";
import { createAgent, tool, type ToolRuntime } from "langchain";
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI);
await store.setup();

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

await store.put(["users"], "user_123", {
  name: "John Smith",
  language: "English",
});

const getUserInfo = tool(
  async (_, runtime: ToolRuntime<unknown, z.infer<typeof contextSchema>>) => {
    const userId = runtime.context.userId;
    if (!userId) throw new Error("userId is required");
    const userInfo = await runtime.store.get(["users"], userId);
    return userInfo?.value ? JSON.stringify(userInfo.value) : "Unknown user";
  },
  {
    name: "getUserInfo",
    description: "Look up user info by userId from the store.",
    schema: z.object({}),
  },
);

const agent = createAgent({
  model: "fireworks:accounts/fireworks/models/glm-5p2",
  tools: [getUserInfo],
  contextSchema,
  store,
});

await agent.invoke(
  { messages: [{ role: "user", content: "look up user information" }] },
  { context: { userId: "user_123" } },
);
ts
import * as z from "zod";
import { createAgent, tool, type ToolRuntime } from "langchain";
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI);
await store.setup();

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

await store.put(["users"], "user_123", {
  name: "John Smith",
  language: "English",
});

const getUserInfo = tool(
  async (_, runtime: ToolRuntime<unknown, z.infer<typeof contextSchema>>) => {
    const userId = runtime.context.userId;
    if (!userId) throw new Error("userId is required");
    const userInfo = await runtime.store.get(["users"], userId);
    return userInfo?.value ? JSON.stringify(userInfo.value) : "Unknown user";
  },
  {
    name: "getUserInfo",
    description: "Look up user info by userId from the store.",
    schema: z.object({}),
  },
);

const agent = createAgent({
  model: "baseten:zai-org/GLM-5.2",
  tools: [getUserInfo],
  contextSchema,
  store,
});

await agent.invoke(
  { messages: [{ role: "user", content: "look up user information" }] },
  { context: { userId: "user_123" } },
);
ts
import * as z from "zod";
import { createAgent, tool, type ToolRuntime } from "langchain";
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI);
await store.setup();

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

await store.put(["users"], "user_123", {
  name: "John Smith",
  language: "English",
});

const getUserInfo = tool(
  async (_, runtime: ToolRuntime<unknown, z.infer<typeof contextSchema>>) => {
    const userId = runtime.context.userId;
    if (!userId) throw new Error("userId is required");
    const userInfo = await runtime.store.get(["users"], userId);
    return userInfo?.value ? JSON.stringify(userInfo.value) : "Unknown user";
  },
  {
    name: "getUserInfo",
    description: "Look up user info by userId from the store.",
    schema: z.object({}),
  },
);

const agent = createAgent({
  model: "ollama:north-mini-code-1.0",
  tools: [getUserInfo],
  contextSchema,
  store,
});

await agent.invoke(
  { messages: [{ role: "user", content: "look up user information" }] },
  { context: { userId: "user_123" } },
);

查看示例 Trace

打开该示例的公开 LangSmith 运行记录。

在工具中写入长期记忆 (Write long-term memory from tools) ​

InMemoryStore

ts
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");
    }
    // 将数据存储到 store 中(命名空间 namespace,键 key,数据 data)
    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:gemini-3.6-flash",
  tools: [saveUserInfo],
  contextSchema,
  store,
});

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

// 你可以直接访问 store 来获取该值
const result = await store.get(["users"], "user_123");
console.log(result?.value); // 输出: { name: "John Smith" }
ts
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");
    }
    // 将数据存储到 store 中(命名空间 namespace,键 key,数据 data)
    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: "openai:gpt-5.5",
  tools: [saveUserInfo],
  contextSchema,
  store,
});

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

// 你可以直接访问 store 来获取该值
const result = await store.get(["users"], "user_123");
console.log(result?.value); // 输出: { name: "John Smith" }
ts
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");
    }
    // 将数据存储到 store 中(命名空间 namespace,键 key,数据 data)
    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: "anthropic:claude-sonnet-5",
  tools: [saveUserInfo],
  contextSchema,
  store,
});

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

// 你可以直接访问 store 来获取该值
const result = await store.get(["users"], "user_123");
console.log(result?.value); // 输出: { name: "John Smith" }
ts
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");
    }
    // 将数据存储到 store 中(命名空间 namespace,键 key,数据 data)
    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: "openrouter:z-ai/glm-5.2",
  tools: [saveUserInfo],
  contextSchema,
  store,
});

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

// 你可以直接访问 store 来获取该值
const result = await store.get(["users"], "user_123");
console.log(result?.value); // 输出: { name: "John Smith" }
ts
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");
    }
    // 将数据存储到 store 中(命名空间 namespace,键 key,数据 data)
    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: "fireworks:accounts/fireworks/models/glm-5p2",
  tools: [saveUserInfo],
  contextSchema,
  store,
});

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

// 你可以直接访问 store 来获取该值
const result = await store.get(["users"], "user_123");
console.log(result?.value); // 输出: { name: "John Smith" }
ts
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");
    }
    // 将数据存储到 store 中(命名空间 namespace,键 key,数据 data)
    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: "baseten:zai-org/GLM-5.2",
  tools: [saveUserInfo],
  contextSchema,
  store,
});

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

// 你可以直接访问 store 来获取该值
const result = await store.get(["users"], "user_123");
console.log(result?.value); // 输出: { name: "John Smith" }
ts
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");
    }
    // 将数据存储到 store 中(命名空间 namespace,键 key,数据 data)
    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: "ollama:north-mini-code-1.0",
  tools: [saveUserInfo],
  contextSchema,
  store,
});

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

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

查看示例追踪 (View example trace)

打开该示例的公开 LangSmith 运行记录。

PostgreSQL

ts
import * as z from "zod";
import { tool, createAgent, type ToolRuntime } from "langchain";
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI);
await store.setup();

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

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:gemini-3.6-flash",
  tools: [saveUserInfo],
  contextSchema,
  store,
});

await agent.invoke(
  { messages: [{ role: "user", content: "My name is John Smith" }] },
  { context: { userId: "user_123" } },
);

const result = await store.get(["users"], "user_123");
console.log(result?.value);
ts
import * as z from "zod";
import { tool, createAgent, type ToolRuntime } from "langchain";
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI);
await store.setup();

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

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: "openai:gpt-5.5",
  tools: [saveUserInfo],
  contextSchema,
  store,
});

await agent.invoke(
  { messages: [{ role: "user", content: "My name is John Smith" }] },
  { context: { userId: "user_123" } },
);

const result = await store.get(["users"], "user_123");
console.log(result?.value);
ts
import * as z from "zod";
import { tool, createAgent, type ToolRuntime } from "langchain";
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI);
await store.setup();

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

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: "anthropic:claude-sonnet-5",
  tools: [saveUserInfo],
  contextSchema,
  store,
});

await agent.invoke(
  { messages: [{ role: "user", content: "My name is John Smith" }] },
  { context: { userId: "user_123" } },
);

const result = await store.get(["users"], "user_123");
console.log(result?.value);
ts
import * as z from "zod";
import { tool, createAgent, type ToolRuntime } from "langchain";
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI);
await store.setup();

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

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: "openrouter:z-ai/glm-5.2",
  tools: [saveUserInfo],
  contextSchema,
  store,
});

await agent.invoke(
  { messages: [{ role: "user", content: "My name is John Smith" }] },
  { context: { userId: "user_123" } },
);

const result = await store.get(["users"], "user_123");
console.log(result?.value);
ts
import * as z from "zod";
import { tool, createAgent, type ToolRuntime } from "langchain";
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI);
await store.setup();

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

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: "fireworks:accounts/fireworks/models/glm-5p2",
  tools: [saveUserInfo],
  contextSchema,
  store,
});

await agent.invoke(
  { messages: [{ role: "user", content: "My name is John Smith" }] },
  { context: { userId: "user_123" } },
);

const result = await store.get(["users"], "user_123");
console.log(result?.value);
ts
import * as z from "zod";
import { tool, createAgent, type ToolRuntime } from "langchain";
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI);
await store.setup();

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

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: "baseten:zai-org/GLM-5.2",
  tools: [saveUserInfo],
  contextSchema,
  store,
});

await agent.invoke(
  { messages: [{ role: "user", content: "My name is John Smith" }] },
  { context: { userId: "user_123" } },
);

const result = await store.get(["users"], "user_123");
console.log(result?.value);
ts
import * as z from "zod";
import { tool, createAgent, type ToolRuntime } from "langchain";
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres/store";

const DB_URI =
  process.env.POSTGRES_URI ??
  "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable";
const store = PostgresStore.fromConnString(DB_URI);
await store.setup();

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

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: "ollama:north-mini-code-1.0",
  tools: [saveUserInfo],
  contextSchema,
  store,
});

await agent.invoke(
  { messages: [{ role: "user", content: "My name is John Smith" }] },
  { context: { userId: "user_123" } },
);

const result = await store.get(["users"], "user_123");
console.log(result?.value);

查看示例追踪 (View example trace)

打开该示例的公开 LangSmith 运行记录。