内存¶
LangGraph 支持两种内存类型,这对于构建会话式代理至关重要
本指南演示了如何在 LangGraph 中将这两种内存类型与代理结合使用。如需深入了解内存概念,请参阅 LangGraph 内存文档。
短期记忆¶
短期记忆使代理能够跟踪多轮对话。要使用它,您必须
- 在创建代理时提供一个
checkpointer
。checkpointer
能够实现代理状态的持久化。 - 在运行代理时在配置中提供一个
thread_id
。thread_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
);
MemorySaver
是一个将代理状态存储在内存中的检查点。在生产环境中,您通常会使用数据库或其他持久化存储。请查阅检查点文档以获取更多选项。如果您使用 LangGraph Platform 进行部署,平台将为您提供一个生产就绪的检查点。checkpointer
被传递给代理。这使得代理能够在其调用之间持久化其状态。请注意,- 配置中提供了一个唯一的
thread_id
。此 ID 用于标识会话。该值由用户控制,可以是任何字符串。 - 代理将使用相同的
thread_id
继续对话。这将使代理能够推断用户正在具体询问纽约的天气。
当代理使用相同的 thread_id
第二次被调用时,第一次对话的原始消息历史会自动包含在内,从而使代理能够推断用户正在具体询问纽约的天气。
LangGraph Platform 提供生产就绪的检查点
如果您使用LangGraph Platform,在部署过程中,您的检查点将自动配置为使用生产就绪的数据库。
长期记忆¶
使用长期记忆来存储跨对话的用户特定或应用程序特定数据。这对于聊天机器人等应用程序非常有用,您可以记住用户偏好或其他信息。
要使用长期记忆,您需要
- 配置存储以在调用之间持久化数据。
- 使用
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" } }
);
InMemoryStore
是一个将数据存储在内存中的存储。在生产环境中,您通常会使用数据库或其他持久化存储。请查阅文档以获取更多选项。如果您使用 LangGraph Platform 进行部署,平台将为您提供一个生产就绪的存储。- 对于本示例,我们使用
put
方法向存储写入一些示例数据。请参阅 BaseStore.put API 参考以获取更多详细信息。 - 第一个参数是命名空间。这用于将相关数据分组。在本例中,我们使用
users
命名空间来分组用户数据。 - 命名空间中的键。此示例使用用户 ID 作为键。
- 我们希望为给定用户存储的数据。
- 您可以通过
config.store
从您的节点、工具和提示中的任何位置访问存储。它包含在创建代理时传递给代理的存储。 get
方法用于从存储中检索数据。第一个参数是命名空间,第二个参数是键。这将返回一个StoreValue
对象,其中包含值和有关值的元数据。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
InMemoryStore
是一个将数据存储在内存中的存储。在生产环境中,您通常会使用数据库或其他持久化存储。请查阅存储文档以获取更多选项。如果您使用 LangGraph Platform 进行部署,平台将为您提供一个生产就绪的存储。UserInfo
类是一个定义用户信息结构的接口。我们将在下面使用 zod 对象指定相同的 schema,以便 LLM 根据 schema 格式化响应。saveUserInfo
是一个允许代理更新用户信息的工具。这对于用户想要更新其个人资料信息的聊天应用程序可能很有用。- 您可以通过
config.store
从您的节点、工具和提示中的任何位置访问存储。它包含在创建代理时传递给代理的存储。 put
方法用于将数据存储在存储中。第一个参数是命名空间,第二个参数是键。这将把用户信息存储在存储中。userId
在配置中传递。这用于识别正在更新其信息的用户。