跳到内容

内存

LangGraph 支持两种内存类型,这对于构建会话式代理至关重要

  • 短期记忆:通过在会话中维护消息历史来跟踪正在进行的对话。
  • 长期记忆:跨会话存储用户特定或应用程序级别的数据。

本指南演示了如何在 LangGraph 中将这两种内存类型与代理结合使用。如需深入了解内存概念,请参阅 LangGraph 内存文档

image

短期记忆长期记忆都需要持久化存储,以在 LLM 交互中保持连续性。在生产环境中,此数据通常存储在数据库中。

术语

在 LangGraph 中

  • 短期记忆也称为线程级内存
  • 长期记忆也称为跨线程内存

一个线程表示由相同 thread_id 分组的一系列相关运行。

短期记忆

短期记忆使代理能够跟踪多轮对话。要使用它,您必须

  1. 在创建代理时提供一个 checkpointercheckpointer 能够实现代理状态的持久化
  2. 在运行代理时在配置中提供一个 thread_idthread_id 是会话的唯一标识符。
import { MemorySaver } from "@langchain/langgraph-checkpoint";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { initChatModel } from "langchain/chat_models/universal";
import { tool } from "@langchain/core/tools";
import { z } from "zod";

const checkpointer = new MemorySaver();  // (1)!

const getWeather = tool(
  async (input: { city: string }) => {
    return `It's always sunny in ${input.city}!`;
  },
  {
    name: "getWeather",
    schema: z.object({
      city: z.string().describe("The city to get the weather for"),
    }),
    description: "Get weather for a given city.",
  }
);

const llm = await initChatModel("anthropic:claude-3-7-sonnet-latest");
const agent = createReactAgent({
  llm,
  tools: [getWeather],
  checkpointer  // (2)!
});

// Run the agent
const config = { configurable: { thread_id: "1" } };  // (3)!
const sfResponse = await agent.invoke(
  { messages: [ { role: "user", content: "what is the weather in sf" } ] },
  config  // (4)!
);
const nyResponse = await agent.invoke(
  { messages: [ { role: "user", content: "what about new york?" } ] },
  config
);
  1. MemorySaver 是一个将代理状态存储在内存中的检查点。在生产环境中,您通常会使用数据库或其他持久化存储。请查阅检查点文档以获取更多选项。如果您使用 LangGraph Platform 进行部署,平台将为您提供一个生产就绪的检查点。
  2. checkpointer 被传递给代理。这使得代理能够在其调用之间持久化其状态。请注意,
  3. 配置中提供了一个唯一的 thread_id。此 ID 用于标识会话。该值由用户控制,可以是任何字符串。
  4. 代理将使用相同的 thread_id 继续对话。这将使代理能够推断用户正在具体询问纽约的天气

当代理使用相同的 thread_id 第二次被调用时,第一次对话的原始消息历史会自动包含在内,从而使代理能够推断用户正在具体询问纽约的天气

LangGraph Platform 提供生产就绪的检查点

如果您使用LangGraph Platform,在部署过程中,您的检查点将自动配置为使用生产就绪的数据库。

长期记忆

使用长期记忆来存储跨对话的用户特定或应用程序特定数据。这对于聊天机器人等应用程序非常有用,您可以记住用户偏好或其他信息。

要使用长期记忆,您需要

  1. 配置存储以在调用之间持久化数据。
  2. 使用 config.store 从工具或提示中访问存储。

读取

代理可用于查找用户信息的工具
import { initChatModel } from "langchain/chat_models/universal";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
// highlight-next-line
import { InMemoryStore } from "@langchain/langgraph-checkpoint";
// highlight-next-line
import { getStore } from "@langchain/langgraph";
import { LangGraphRunnableConfig } from "@langchain/langgraph";
import { tool } from "@langchain/core/tools";
import { z } from "zod";

const store = new InMemoryStore(); // (1)!

await store.put(  // (2)!
  ["users"],  // (3)!
  "user_123",  // (4)!
  {
    name: "John Smith",
    language: "English",
  } // (5)!
);

// Look up user info tool
const getUserInfo = tool(
  async (input: Record<string, any>, config: LangGraphRunnableConfig): Promise<string> => {
    // Same as that provided to `createReactAgent`
    const store = config.store; // (6)!
    if (!store) {
      throw new Error("store is required when compiling the graph");
    }

    const userId = config.configurable?.userId;
    if (!userId) {
      throw new Error("userId is required in the config");
    }

    const userInfo = await store.get(["users"], userId); // (7)!
    return userInfo ? JSON.stringify(userInfo.value) : "Unknown user";
  },
  {
    name: "get_user_info",
    description: "Look up user info.",
    schema: z.object({}),
  }
);

const llm = await initChatModel("anthropic:claude-3-7-sonnet-latest");
const agent = createReactAgent({
  llm,
  tools: [getUserInfo],
  store, // (8)!
});

// Run the agent
const response = await agent.invoke(
  { messages: [ { role: "user", content: "look up user information" } ] },
  { configurable: { userId: "user_123" } }
);
  1. InMemoryStore 是一个将数据存储在内存中的存储。在生产环境中,您通常会使用数据库或其他持久化存储。请查阅文档以获取更多选项。如果您使用 LangGraph Platform 进行部署,平台将为您提供一个生产就绪的存储。
  2. 对于本示例,我们使用 put 方法向存储写入一些示例数据。请参阅 BaseStore.put API 参考以获取更多详细信息。
  3. 第一个参数是命名空间。这用于将相关数据分组。在本例中,我们使用users命名空间来分组用户数据。
  4. 命名空间中的键。此示例使用用户 ID 作为键。
  5. 我们希望为给定用户存储的数据。
  6. 您可以通过 config.store 从您的节点、工具和提示中的任何位置访问存储。它包含在创建代理时传递给代理的存储。
  7. get方法用于从存储中检索数据。第一个参数是命名空间,第二个参数是键。这将返回一个StoreValue对象,其中包含值和有关值的元数据。
  8. store 被传递给代理。这使得代理在运行工具时能够访问存储。

写入

更新用户信息的工具示例
import { initChatModel } from "langchain/chat_models/universal";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { InMemoryStore } from "@langchain/langgraph-checkpoint";
import { getStore } from "@langchain/langgraph";
import { LangGraphRunnableConfig } from "@langchain/langgraph";
import { tool } from "@langchain/core/tools";
import { z } from "zod";

const store = new InMemoryStore(); // (1)!

interface UserInfo { // (2)!
  name: string;
}

// Save user info tool
const saveUserInfo = tool(  // (3)!
  async (input: UserInfo, config: LangGraphRunnableConfig): Promise<string> => {
    // Same as that provided to `createReactAgent`
    // highlight-next-line
    const store = config.store; // (4)!
    if (!store) {
      throw new Error("store is required when compiling the graph");
    }

    const userId = config.configurable?.userId;
    if (!userId) {
      throw new Error("userId is required in the config");
    }

    await store.put(["users"], userId, input); // (5)!
    return "Successfully saved user info.";
  },
  {
    name: "save_user_info",
    description: "Save user info.",
    schema: z.object({
      name: z.string(),
    }),
  }
);

const llm = await initChatModel("anthropic:claude-3-7-sonnet-latest");
const agent = createReactAgent({
  llm,
  tools: [saveUserInfo],
  // highlight-next-line
  store,
});

// Run the agent
await agent.invoke(
  { messages: [ { role: "user", content: "My name is John Smith" } ] },
  { configurable: { userId: "user_123" } } // (6)!
);

// You can access the store directly to get the value
const userInfo = await store.get(["users"], "user_123")
userInfo.value
  1. InMemoryStore 是一个将数据存储在内存中的存储。在生产环境中,您通常会使用数据库或其他持久化存储。请查阅存储文档以获取更多选项。如果您使用 LangGraph Platform 进行部署,平台将为您提供一个生产就绪的存储。
  2. UserInfo 类是一个定义用户信息结构的接口。我们将在下面使用 zod 对象指定相同的 schema,以便 LLM 根据 schema 格式化响应。
  3. saveUserInfo 是一个允许代理更新用户信息的工具。这对于用户想要更新其个人资料信息的聊天应用程序可能很有用。
  4. 您可以通过 config.store 从您的节点、工具和提示中的任何位置访问存储。它包含在创建代理时传递给代理的存储。
  5. put方法用于将数据存储在存储中。第一个参数是命名空间,第二个参数是键。这将把用户信息存储在存储中。
  6. userId 在配置中传递。这用于识别正在更新其信息的用户。

更多资源