LangChain / Advanced usage / Long-term memory

英文原文链接:https://docs.langchain.com/oss/python/langchain/long-term-memory

高级用法

长期记忆

复制页面

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

长期记忆基于 LangGraph 存储(stores)构建,这些存储将数据保存为按命名空间(namespace)和键(key)组织的 JSON 文档。

用法

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

InMemoryStore

python 复制代码
from langchain.agents import create_agent
from langchain_core.runnables import Runnable
from langgraph.store.memory import InMemoryStore

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

agent: Runnable = create_agent(
    "claude-sonnet-4-6",
    tools=[],
    store=store,
)

PostgreSQL

pip

bash 复制代码
pip install -U langgraph-checkpoint-postgres "psycopg[binary]"

默认情况下,langgraph-checkpoint-postgres 会安装不包含额外依赖的 psycopg(Psycopg 3)。上面的安装命令添加了 psycopg[binary],这对于大多数用户来说是推荐的。对于其他选项,请参阅 Psycopg 安装文档

python 复制代码
from langchain.agents import create_agent
from langchain_core.runnables import Runnable
from langgraph.store.postgres import PostgresStore  # type: ignore[import-not-found]

DB_URI = "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable"

with PostgresStore.from_conn_string(DB_URI) as store:
    store.setup()
    agent: Runnable = create_agent(
        "claude-sonnet-4-6",
        tools=[],
        store=store,
    )

然后,工具可以使用 runtime.store 参数从存储中读取和写入数据。有关示例,请参阅 从工具中读取长期记忆从工具中写入长期记忆

有关记忆类型(语义记忆、情景记忆、程序性记忆)和编写记忆策略的更深入探讨,请参阅 记忆概念指南

记忆存储

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

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

这种结构支持记忆的分层组织。然后,可以通过内容过滤器实现跨命名空间的搜索。

InMemoryStore

python 复制代码
from collections.abc import Sequence

from langgraph.store.base import IndexConfig
from langgraph.store.memory import InMemoryStore


def embed(texts: Sequence[str]) -> list[list[float]]:
    # 替换为实际的嵌入函数或 LangChain 嵌入对象
    return [[1.0, 2.0] for _ in texts]


# InMemoryStore 将数据保存到内存字典中。在生产环境中请使用数据库支持的存储。
store = InMemoryStore(index=IndexConfig(embed=embed, dims=2))
user_id = "my-user"
application_context = "chitchat"
namespace = (user_id, application_context)
store.put(
    namespace,
    "a-memory",
    {
        "rules": [
            "用户喜欢简短、直接的语言",
            "用户只说英语和Python",
        ],
        "my-key": "my-value",
    },
)
# 通过ID获取"记忆"
item = store.get(namespace, "a-memory")
# 在此命名空间内搜索"记忆",基于内容等价性进行过滤,并按向量相似度排序
items = store.search(
    namespace, filter={"my-key": "my-value"}, query="语言偏好"
)

PostgreSQL

python 复制代码
from collections.abc import Sequence

from langgraph.store.base import IndexConfig
from langgraph.store.postgres import PostgresStore  # type: ignore[import-not-found]


def embed(texts: Sequence[str]) -> list[list[float]]:
    # Replace with an actual embedding function or LangChain embeddings object
    return [[1.0, 2.0] for _ in texts]


DB_URI = "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable"

with PostgresStore.from_conn_string(
    DB_URI,
    index=IndexConfig(embed=embed, dims=2),  # type: ignore[arg-type]
) as store:
    store.setup()
    user_id = "my-user"
    application_context = "chitchat"
    namespace = (user_id, application_context)
    store.put(
        namespace,
        "a-memory",
        {
            "rules": [
                "User likes short, direct language",
                "User only speaks English & python",
            ],
            "my-key": "my-value",
        },
    )
    item = store.get(namespace, "a-memory")
    items = store.search(
        namespace, filter={"my-key": "my-value"}, query="language preferences"
    )

有关记忆存储的更多信息,请参阅 持久化指南

从工具中读取长期记忆

InMemoryStore

Google OpenAI Anthropic OpenRouter Fireworks Baseten Ollama

python 复制代码
from dataclasses import dataclass

from langchain.agents import create_agent
from langchain.tools import ToolRuntime, tool
from langchain_core.runnables import Runnable
from langgraph.store.memory import InMemoryStore


@dataclass
class Context:
    user_id: str


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

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


@tool
def get_user_info(runtime: ToolRuntime[Context]) -> str:
    """查找用户信息。"""
    # 访问存储 - 与提供给 `create_agent` 的存储相同
    assert runtime.store is not None
    user_id = runtime.context.user_id
    # 从存储中检索数据 - 返回包含值和元数据的 StoreValue 对象
    user_info = runtime.store.get(("users",), user_id)
    return str(user_info.value) if user_info else "Unknown user"


agent: Runnable = create_agent(
    model="google_genai:gemini-3.6-flash",
    tools=[get_user_info],
    # 将存储传递给智能体 - 使智能体在运行工具时能够访问存储
    store=store,
    context_schema=Context,
)

# 运行智能体
agent.invoke(
    {"messages": [{"role": "user", "content": "查找用户信息"}]},
    context=Context(user_id="user_123"),
)

PostgreSQL

python 复制代码
from dataclasses import dataclass

from langchain.agents import create_agent
from langchain.tools import ToolRuntime, tool
from langchain_core.runnables import Runnable
from langgraph.store.postgres import PostgresStore  # type: ignore[import-not-found]


@dataclass
class Context:
    user_id: str


DB_URI = "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable"

with PostgresStore.from_conn_string(DB_URI) as store:
    store.setup()
    store.put(("users",), "user_123", {"name": "John Smith", "language": "English"})

    @tool
    def get_user_info(runtime: ToolRuntime[Context]) -> str:
        """Look up user info."""
        assert runtime.store is not None
        user_info = runtime.store.get(("users",), runtime.context.user_id)
        return str(user_info.value) if user_info else "Unknown user"

    agent: Runnable = create_agent(
        "claude-sonnet-4-6",
        tools=[get_user_info],
        store=store,
        context_schema=Context,
    )

    result = agent.invoke(
        {"messages": [{"role": "user", "content": "look up user information"}]},
        context=Context(user_id="user_123"),
    )

从工具中写入长期记忆

InMemoryStore

Google OpenAI Anthropic OpenRouter Fireworks Baseten Ollama

python 复制代码
from dataclasses import dataclass

from langchain.agents import create_agent
from langchain.tools import ToolRuntime, tool
from langchain_core.runnables import Runnable
from langgraph.store.memory import InMemoryStore
from typing_extensions import TypedDict

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


@dataclass
class Context:
    user_id: str


# TypedDict 为 LLM 定义了用户信息的结构
class UserInfo(TypedDict):
    name: str


# 允许智能体更新用户信息的工具(对于聊天应用程序很有用)
@tool
def save_user_info(user_info: UserInfo, runtime: ToolRuntime[Context]) -> str:
    """保存用户信息。"""
    # 访问存储 - 与提供给 `create_agent` 的存储相同
    assert runtime.store is not None
    store = runtime.store
    user_id = runtime.context.user_id
    # 将数据存储到存储中(命名空间、键、数据)
    store.put(("users",), user_id, dict(user_info))
    return "成功保存用户信息。"


agent: Runnable = create_agent(
    model="google_genai:gemini-3.6-flash",
    tools=[save_user_info],
    store=store,
    context_schema=Context,
)

# 运行智能体
agent.invoke(
    {"messages": [{"role": "user", "content": "我的名字是 John Smith"}]},
    # 在上下文中传递 user_id,以标识要更新谁的信息
    context=Context(user_id="user_123"),
)

# 您可以直接访问存储以获取值
item = store.get(("users",), "user_123")

PostgreSQL

python 复制代码
from dataclasses import dataclass

from langchain.agents import create_agent
from langchain.tools import ToolRuntime, tool
from langchain_core.runnables import Runnable
from langgraph.store.postgres import PostgresStore  # type: ignore[import-not-found]
from typing_extensions import TypedDict


@dataclass
class Context:
    user_id: str


class UserInfo(TypedDict):
    name: str


@tool
def save_user_info(user_info: UserInfo, runtime: ToolRuntime[Context]) -> str:
    """Save user info."""
    assert runtime.store is not None
    runtime.store.put(("users",), runtime.context.user_id, dict(user_info))
    return "Successfully saved user info."


DB_URI = "postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable"

with PostgresStore.from_conn_string(DB_URI) as store:
    store.setup()
    agent: Runnable = create_agent(
        "claude-sonnet-4-6",
        tools=[save_user_info],
        store=store,
        context_schema=Context,
    )

    agent.invoke(
        {"messages": [{"role": "user", "content": "My name is John Smith"}]},
        context=Context(user_id="user_123"),
    )
相关推荐
JaydenAI4 小时前
[基于OpenEvals的自动化评估-12]Agent执行轨迹评估[无LLM参与]
ai·langchain·agent·evaluation·openevals
北斗落凡尘7 小时前
LangGraph 入门实战(3)
python·langchain
lzjava20247 小时前
LangChain集成MCP
langchain
前端 贾公子8 小时前
LangChain 实战:让 LLM 拥有记忆与结构化输出能力
langchain
chaors13 小时前
DeepResearchSystem 0x08:KB 知识记忆
langchain·agent·ai编程
北斗落凡尘18 小时前
LangGraph 入门实战(2)
python·langchain
北斗落凡尘1 天前
如何使用LangGraph(1)
python·langchain
JaydenAI1 天前
[基于OpenEvals的自动化评估-11]针对Agent对话的评估[下篇]
ai·langchain·agent·evaluation·openevals
小白的后端世界1 天前
LangChain 模型初始化参数详解:从基础配置到企业级实践
java·人工智能·langchain