Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs 菜单
Docs 主页
/ /

使用MongoDB Atlas将长期记忆添加到 LangGraph.js 代理

您可以将MongoDB与 LangGraph.js 集成,以便除了从 MongoDB LangGraph 检查点获得的短期记忆之外,还为代理添加长期记忆。

本页以以下教程中的概念为基础:

使用此页面可学习;了解如何:

  • 在 LangGraph 中了解短期记忆与长期记忆的对比。

  • 为 LangGraph.js 配置MongoDB支持的长期内存存储。

  • 跨线程和会话保留和检索用户特定的数据。

  • 将长期记忆与MongoDB Vector Search 和 Voyage AI嵌入与 AutoEmbeddings 相结合,实现语义召回。

注意

此页面上的示例使用 TypeScript 风格的语法。您可以通过删除类型注解来将其调整为适用于纯JavaScript 。

LangGraph 提供两种互补的内存机制:

使用 检查指针 在请求之间保留单个线程(对话)的状态。在MongoDB集成中,这是由MongoDB LangGraph 检查点MongoDBSaver () 处理的。这样就可以为给定的对话启用时间旅行、人工在环查看和容错等功能。

使用 Store 抽象来跨线程(而不仅仅是在单个会话中)持久保存数据。非常适合存储应在会话之间和跨代理之间保存的数据。

借助适用于 LangGraph.js 的MongoDB Store,您可以:

  • 以MongoDB作为后端,在JavaScript /TypeScript 中实现 BaseStore 接口。

  • 使用 LangGraph 中的标准 Store API (getputdeletesearch)。

  • JSON文档存储在分层命名空间下(示例, [userId, "memories"])。

  • 在MongoDB Vector Search 和 Voyage AI嵌入 AutoEmbeddings 的支持下,对存储的数据执行语义搜索和元数据筛选。

在开始之前,请确保您具备以下内容:

您应该熟悉并最好已经完成:

安装构建AI助手教程中使用的核心依赖项,以及 LangGraph.js 的MongoDB Store 模块。

npm init -y
# Core LangChain / LangGraph / MongoDB dependencies
npm i --legacy-peer-deps \
langchain \
@langchain/langgraph \
@langchain/mongodb \
@langchain/community \
@langchain/langgraph-checkpoint-mongodb \
dotenv \
express \
mongodb \
zod

@langchain/langgraph-checkpoint-mongodb包包括检查指针和用于长期记忆的MongoDB存储。

LangGraphBaseStore getputdeletesearch存储为分层命名空间下的JSON文档实现带有 、 、 和 等操作的 接口。

重复使用现有 LangGraph.js代理服务器上的MongoDB客户端配置。

// mongodb-client.ts
import { MongoClient } from "mongodb";
import "dotenv/config";
export const client = new MongoClient(process.env.MONGODB_URI as string);
export async function connectClient() {
await client.connect();
await client.db("admin").command({ ping: 1 });
console.log("Pinged your deployment. You successfully connected to MongoDB!");
}

创建一个模块,导出长期记忆配置的 MongoDBStore

// long-term-store.ts
import type { MongoClient } from "mongodb";
import { MongoDBStore } from "@langchain/langgraph-checkpoint-mongodb";
const DB_NAME = "hr_database";
const COLLECTION_NAME = "long_term_memory";
export function createMongoDBStore(client: MongoClient) {
const store = new MongoDBStore({
client,
dbName: DB_NAME,
collectionName: COLLECTION_NAME,
});
return store;
}

该存储可跨线程和会话持久保存数据,并由 [userId, "memories"][userId, "preferences"] 等分层命名空间进行键控。

当您对有关用户或域的稳定事实进行建模时,长期记忆效果最佳。

常见模式包括:

  • 用户配置文件 — 角色、资历、团队、位置。持久偏好(示例,语气、语言、产品层级)。

  • 限制和政策 — 过敏、合规限制、预算上限。

  • 交互历史摘要 — 过去会话的高级摘要。应该继续推进的决策(示例,“与自我管理相比,用户更喜欢使用MongoDB Atlas ”)。

您可以将它们存储为简单的JSON文档,也可以存储为带有用于语义搜索的嵌入内容的文档。

MongoDB Store API支持以下操作:

  • put —存储或更新值。

  • get — 按命名空间和键检索值。

  • delete —删除一个值。

  • search — 通过向量相似度和/或元数据筛选器检索值。

确切的 TypeScript 类型可能有所不同,但以下代码演示了 LangGraph.js 中的典型使用模式:

// memory-api.ts
import type { MongoDBStore } from "@langchain/langgraph-checkpoint-mongodb";
type MemoryValue = {
type: "profile" | "preference" | "fact";
data: Record<string, unknown>;
updatedAt: string;
};
export async function putUserMemory(
store: MongoDBStore,
userId: string,
key: string,
value: MemoryValue
) {
await store.put(
[userId, "memories"],
key,
value
);
}
export async function getUserMemories(
store: MongoDBStore,
userId: string,
key: string
) {
const result = await store.get(
[userId, "memories"],
key
);
return result;
}

本节假设您已经拥有类似于使用 LangGraph.js 和MongoDB Atlas构建AI助手中描述的代理工作流程,包括:

  • 带有 messages字段的 GraphState 注解。

  • 一个工具节点,它使用来自 Voyage AI的嵌入调用MongoDB Vector Search。

  • 聊天模型节点,用于决定是调用工具还是直接响应。

  • 短期记忆的 MongoDBSaver 检查指针。

更新 callAgent 函数以接受 store 和MongoDB客户端端:

// agent-with-long-term-memory.ts
import { ChatOpenAI } from "@langchain/openai";
import {
AIMessage,
BaseMessage,
HumanMessage,
} from "@langchain/core/messages";
import {
ChatPromptTemplate,
MessagesPlaceholder,
} from "@langchain/core/prompts";
import { StateGraph, Annotation } from "@langchain/langgraph";
import { tool } from "@langchain/core/tools";
import { ToolNode } from "@langchain/langgraph/prebuilt";
import { MongoDBSaver } from "@langchain/langgraph-checkpoint-mongodb";
import type { MongoClient } from "mongodb";
import type { MongoDBStore } from "@langchain/langgraph-checkpoint-mongodb";
import { putUserMemory, getUserMemories } from "./memory-api";
export async function callAgent(
client: MongoClient,
store: MongoDBStore,
query: string,
threadId: string,
userId: string,
) {
const dbName = "hr_database";
const db = client.db(dbName);
const collection = db.collection("employees");
// 1. Retrieve long-term memories for the user
const existingMemories = await getUserMemories(store, userId, "last_response");
// 2. Define graph state
const GraphState = Annotation.Root({
messages: Annotation<BaseMessage[]>({
reducer: (x, y) => x.concat(y),
}),
userId: Annotation<string>(),
memories: Annotation<unknown | null>(),
});
// 3. Define tools (for example, MongoDB Vector Search retriever)
const employeeLookupTool = tool(/* ...reuse from Build an AI Agent tutorial... */);
const tools = [employeeLookupTool];
const toolNode = new ToolNode<typeof GraphState.State>(tools);
// 4. Configure the chat model
const model = new ChatOpenAI({
model: "gpt-5.4-mini",
}).bindTools(tools);
// 5. Define the model node
async function callModel(state: typeof GraphState.State) {
const prompt = ChatPromptTemplate.fromMessages([
"system",
`You are a helpful HR chatbot agent.
Use the provided tools and long-term memories to answer questions.
Long-term memories (if any) are in the "memories" field.`,
new MessagesPlaceholder("messages"),
]);
const formatted = await prompt.formatMessages({
messages: state.messages,
});
const result = await model.invoke(formatted);
return { messages: [result] };
}
// 6. Define routing logic
function shouldContinue(state: typeof GraphState.State) {
const messages = state.messages;
const lastMessage = messages[messages.length - 1] as AIMessage;
if (lastMessage.tool_calls?.length) {
return "tools";
}
return "__end__";
}
// 7. Build the workflow
const workflow = new StateGraph(GraphState)
.addNode("agent", callModel)
.addNode("tools", toolNode)
.addEdge("__start__", "agent")
.addConditionalEdges("agent", shouldContinue)
.addEdge("tools", "agent");
// 8. Configure short-term memory (checkpointer)
const checkpointer = new MongoDBSaver({ client, dbName });
const app = workflow.compile({
checkpointer,
store,
});
// 9. Invoke the graph with both short-term and long-term memory
const finalState = await app.invoke(
{
messages: [new HumanMessage(query)],
userId,
memories: existingMemories,
},
{
recursionLimit: 15,
configurable: { thread_id: threadId },
},
);
const last = finalState.messages[finalState.messages.length - 1];
const content = last.content;
// 10. Optionally, update long-term memory with new facts
await putUserMemory(store, userId, "last_response", {
type: "fact",
data: { content },
updatedAt: new Date().toISOString(),
});
return content;
}

此模式允许您:

  • 在每次交互开始时读取长期记忆。

  • 将这些内存注入到状态中(示例,作为 memories 或注入到系统提示符中)。

  • 在每次交互后根据代理学内容更新长期记忆。

要使长期记忆可按含义搜索,您可以:

  1. 将每个记忆存储为文档,其中包括:

    • 文本摘要或描述。

    • 结构化元数据(示例userIdtypetags)。

    • 用于语义搜索的嵌入向量。

  2. 在内存集合的 embedding字段上配置MongoDB Vector Search索引。

  3. 在插入每个内存文档之前,使用 Voyage AI嵌入或 Voyage AutoEmbeddings(通过Atlas Embedding 和 Reranking API)为每个内存文档生成嵌入。

  4. MongoDBStore 使用内置的search 方法,该方法会对内存集合调用 $vectorSearch,并可以选择与 userIdtype 等元数据筛选器结合使用。

以下代码演示了如何使用 MongoDBStore 上内置的search 方法,通过语义相似度和元数据筛选器查找记忆:

// semantic-memory.ts
import type { MongoDBStore } from "@langchain/langgraph-checkpoint-mongodb";
export async function searchUserMemories(
store: MongoDBStore,
userId: string,
queryText: string,
limit = 5,
) {
const results = await store.search(
[userId, "memories"],
{
query: queryText,
filter: { type: "fact" },
limit,
},
);
return results;
}

search 方法接受命名空间前缀和带有以下字段的选项对象:

  • query — 用于语义搜索的文本字符串。该存储使用MongoDB Vector Search 来查找在语义上与查询相似的记忆。

  • filter — 用于缩小结果范围的元数据过滤对象(示例{ type: "fact" })。

  • limit - 要返回的最大结果数(默认:10)。

  • offset - 分页时跳过的结果数(默认:0)。

注意

借助 Voyage AutoEmbeddings,您可以卸载嵌入生成工作分流给Atlas Embedding 和 Reranking API ,并使用MongoDB Vector Search 作为存储后端。 LangGraph.js 长期记忆存储旨在利用这种体验,以便您可以将自动嵌入生成与 LangGraph 存储和向量搜索相结合,形成统一的长期记忆层。

使用以下指南为应用程序的每个部分选择正确的内存机制:

机制
何时使用
详情

短期记忆(检查点)

用于仅在对话中重要的每线程上下文。

非常适合用于分步推理、工具调用结果和中间状态。在Python和JavaScript集成中均由 MongoDBSaver 支持。

长期记忆(存储)

用于应持续存在一段时间的跨线程信息。

非常适合用户配置文件、策略和约束、长期事实和语义召回。由 LangGraph.js 中 BaseStore 的MongoDB存储实施提供支持。

在许多实际应用程序中,您将:

  • 利用短期记忆保持当前对话的连贯性。

  • 使用长期记忆来记住用户和过去对话中的重要事实。

  • 将MongoDB Vector Search 和 Voyage AI嵌入与 AutoEmbeddings 结合使用,在生成响应时按语义搜索内存。

MongoDB 还提供以下开发者资源:

提示

后退

构建AI助手