【AI智能体】Langchain 上下文记忆使用实战操作详解

本文系统讲解LangChain中上下文记忆的实现机制与治理策略,涵盖短期记忆(基于InMemorySaver和PostgreSQL Checkpointer)与长期记忆的分层设计,重点解析消息裁剪、删除及摘要三种上下文管理技术,包括其原理、API调用方式与生产级代码实现,帮助开发者解决大模型无状态导致的多轮对话记忆难题。

目录

一、前言

二、Langchain 上下文记忆介绍

2.1 什么是上下文记忆

2.2 为什么需要上下文记忆

2.3 如何解决记忆问题

2.3.1 上下文工程

2.3.2 上下文类型及相关的API

2.4 记忆分类

2.5 记忆管理

三、短期记忆

3.1 基于内存的持久化器

3.2 内存记忆的工作原理

3.3 基于外部存储介质的持久化器

3.3.1 安装PostgreSQL

3.3.2 具体代码实现

3.3.3 查看持久化数据

四、记忆治理策略(上下文管理)

4.1 消息裁剪

4.1.1 案例代码

4.2 消息删除

4.2.1 案例代码

4.2.2 RemoveMessage干了什么

4.3 消息摘要

4.3.1 案例代码

4.3.2 关于摘要的常见问题

五、写在最后


一、前言

在与大模型对话过程中,上下文管理是一件非常重要的事情,因为会话窗口所能承载的上下文长度是有限的,在使用Langchain做大模型应用开发时,上下文记忆与管理就成了必须考虑的内容,本篇将深入探讨如何在使用Langchain做上下文的记忆管理。

二、Langchain 上下文记忆介绍

2.1 什么是上下文记忆

LangChain 的“上下记忆管理”本质上是在解决一个核心矛盾:LLM 本身是无状态的,但多轮对话和复杂任务又需要它“记住”之前的信息。为此,LangChain 提供了一套分层的记忆体系,将“记忆”拆解为短期会话状态和长期持久化知识,并配以相应的上下文压缩策略来应对窗口限制。

2.2 为什么需要上下文记忆

记忆是一种记住之前互动信息的系统。随着Agent处理涉及大量用户交互的复杂任务,记忆变得至关重要!大多数的大模型应用程序都会有一个会话接口 ,允许我们进行 多轮的对话 ,并有一定的上下文记忆能力。

但实际上,大模型本身是“无状态”的, 不会记忆 任何上下文的。即每次调用 agent.invoke() 都是全新的开始,不记得之前的对话。

我们希望的智能体应该是右图的情况:

下面是一个具体的与大模型交互的案例,通过这个案例的输出可以发现,默认情况下大模型是没有记忆的

import os

from dotenv import load_dotenv

load_dotenv(override=True)

OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY")
OPENROUTER_API_BASE = os.getenv("OPENROUTER_API_BASE")

# 以init_chat_model为例
from langchain_openrouter import ChatOpenRouter

model = ChatOpenRouter(
    model="deepseek/deepseek-v4-flash",
    api_key=OPENROUTER_API_KEY,
    base_url=OPENROUTER_API_BASE,
)

from langchain.agents import create_agent
from langchain_core.messages import HumanMessage, AIMessage

messages1 = [
    HumanMessage("你好,我叫小明"),
    AIMessage("很高兴认识你,小明"),
    HumanMessage("你用一句话介绍下你自己"),
]

agent = create_agent(
    model=model,
    tools=[],
)

response1 = agent.invoke({"messages": messages1})

for msg in response1["messages"]:
    msg.pretty_print()

运行结果如下

2.3 如何解决记忆问题

解决大模型的记忆问题,目前主要有下面几种解决方案。

2.3.1 上下文工程

实现记忆功能,就需要额外的模块 去保存我们和模型对话的上下文信息,然后在下一次请求时,把历史信息都输入给模型,让模型输出结果。

  • 在 LangChain 中, 记忆(Memory) 就是专门负责“ 存储历史交互信息 ”的组件,核心作用是「 保存上下文 」和「 提供上下文 」,让LLM在每次响应时,都能“看到”之前的对话内容。

  • 上下文工程(Context Engineering) 负责 “合理组织”这些记忆和任务信息 ,让LLM的响应更连贯、更贴合需求。这也是Agent能实现 复杂多轮交互 的核心基础。

可以通过下面这张图类比理解

下面这张图与大模型的对话示例形象展示了上下文工程的使用过程

2.3.2 上下文类型及相关的API

LangChain的上下文工程是基于Agent讨论的,而上下文工程是构建在LangGraph之上的。

LangGraph 提供了三种管理上下文的方法,这些方法结合了可变性和生命周期维度:

上下文类型

描述

可变性

生命周期

访问方法

动态运行时上下文

在单次运行中会演变的可变数据

动态

单次运行

LangGraph

state对象

动态跨会话上下文

在对话间共享的持久数据。比如用户偏好、 历史洞察、知识条目

动态

跨对话

LangGraph

store对象

静态运行时上下文

在启动时传入的用户元数据、工具、数据库 连接

静态

单次运行

LangGraph

context对象

2.4 记忆分类

官方文档说明:Memory overview - Docs by LangChain

记忆分为短期记忆和长期记忆,对应不同的使用场景:

  • 短期记忆(Short-term memory、会话级记忆、thread-scoped memory):作用范围是单个对话线程(Thread)内,一旦开启新对话(更换 thread_id ),记忆即消失。

  • 长期记忆(Long-term memory,跨会话级记忆 ):在会话间存储用户特定或应用级数据, 并在 会话线程间共享 。它可以随时在任何线程中被调用。记忆的范围是任意自定义命名空间,而不仅仅是单一线程 ID。

2.5 记忆管理

在LangChain v0.x版本中,通过专用的xxxMemory类管理记忆。

在LangChain v1.x版本中,Agent是构建在LangGraph图结构之上的,通过上文提到的state和store构建记忆系统。使用更简单、功能更统一。

  • state:短期记忆对象,以 会话 为单位组织,包含当前会话的所有消息记录以及自定义信息。

  • store:长期记忆对象, 跨会话持久化 的数据,通常需要结合向量数据库或外部存储实现。

三、短期记忆

LangChain1.x 的短期记忆是三者的组合:

State(会话内部状态) + Checkpointer(持久化机制) + Thread ID(会话作用域)

  • State :默认存储历史消息列表messages ,通过State 管理历史消息

  • Checkpointer :负责将State 作为检查点持久化保存,检查点是某个时刻的State 快照

  • Thread ID :用于唯一标识State ,LangChain运行时会按照 thread_id 读写State快照

就像玩 RPG 游戏时的“自动存档”:你不需要手动保存,系统在关键节点自动记录,下次进入游

戏随时可以从上次的存档点继续。

3.1 基于内存的持久化器

在下面的案例中,如果没有使用会话的持久化存储,通过输出结果可以看到,第二轮对话的时候是不知道第一轮对话的内容

import os

from dotenv import load_dotenv

load_dotenv(override=True)

OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY")
OPENROUTER_API_BASE = os.getenv("OPENROUTER_API_BASE")

# 以init_chat_model为例
from langchain_openrouter import ChatOpenRouter

model = ChatOpenRouter(
    model="deepseek/deepseek-v4-flash",
    api_key=OPENROUTER_API_KEY,
    base_url=OPENROUTER_API_BASE,
)

from langchain.agents import create_agent
from langchain.messages import HumanMessage

agent = create_agent(
    model=model,
    tools=[],
)

print("\n第一轮对话:")
response1 = agent.invoke({
    "messages": [HumanMessage("我叫张三")]
})
print(f"Agent: {response1['messages'][-1].content}")

print("\n第二轮对话:")
response2 = agent.invoke({
    "messages": [HumanMessage("我叫什么?")]
})
print(f"Agent: {response2['messages'][-1].content}")

运行结果如下:

只需要在create_agent 中添加checkpointer 即可实现记忆功能,此处我们使用InMemorySaver 这个内存记忆来存储会话,改造后的代码如下:

  • 你只需传入 checkpointer 和 config,Agent 就能自然具备连续对话能力。

import os

from dotenv import load_dotenv

load_dotenv(override=True)

OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY")
OPENROUTER_API_BASE = os.getenv("OPENROUTER_API_BASE")

# 以init_chat_model为例
from langchain_openrouter import ChatOpenRouter

model = ChatOpenRouter(
    model="deepseek/deepseek-v4-flash",
    api_key=OPENROUTER_API_KEY,
    base_url=OPENROUTER_API_BASE,
)

from langchain.agents import create_agent
from langchain.messages import HumanMessage

from langgraph.checkpoint.memory import InMemorySaver

checkpointer = InMemorySaver()

# 1. 创建 Agent 时添加 checkpointer
agent = create_agent(
    model=model,
    tools=[],
    checkpointer=checkpointer  # 添加内存管理
)

# 2. 调用时指定 thread_id
config = {
    "configurable": {
        "thread_id": "1"
    }
}

print("\n第一轮对话:")
response1 = agent.invoke({
    "messages": [HumanMessage("我叫张三")]
    },
    config=config  # 传入 config
)
print(f"Agent: {response1['messages'][-1].content}")

print("\n第二轮对话:")
response2 = agent.invoke({
    "messages": [HumanMessage("我叫什么?")]
},
    config=config  # 传入 config
)
print(f"Agent: {response2['messages'][-1].content}")

再次运行时,可以看到记忆已经生效了

注意:thread_id 隔离不同会话空间,在上面的案例中,两次不同的会话使用了同一个thread_id

在下面的案例中,第三次会话,使用另一个thread_id ,看一下效果如何

import os

from dotenv import load_dotenv

load_dotenv(override=True)

OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY")
OPENROUTER_API_BASE = os.getenv("OPENROUTER_API_BASE")

# 以init_chat_model为例
from langchain_openrouter import ChatOpenRouter

model = ChatOpenRouter(
    model="deepseek/deepseek-v4-flash",
    api_key=OPENROUTER_API_KEY,
    base_url=OPENROUTER_API_BASE,
)

from langchain.agents import create_agent
from langchain.messages import HumanMessage

from langgraph.checkpoint.memory import InMemorySaver

checkpointer = InMemorySaver()

# 1. 创建 Agent 时添加 checkpointer
agent = create_agent(
    model=model,
    tools=[],
    checkpointer=checkpointer  # 添加内存管理
)

# 2. 调用时指定 thread_id
config = {
    "configurable": {
        "thread_id": "1"
    }
}

print("\n第一轮对话:")
response1 = agent.invoke({
    "messages": [HumanMessage("我叫张三")]
    },
    config=config  # 传入 config
)
print(f"Agent: {response1['messages'][-1].content}")

print("\n第二轮对话:")
response2 = agent.invoke({
    "messages": [HumanMessage("我叫什么?")]
},
    config=config  # 传入 config
)
print(f"Agent: {response2['messages'][-1].content}")

config2 = {
    "configurable": {
        "thread_id": "2"
    }
}
print("\n第三轮对话:")
response3 = agent.invoke({
    "messages": [HumanMessage("刚刚问了什么问题?")]
},
    config=config2  # 传入 config
)
print(f"Agent: {response3['messages'][-1].content}")

通过输出可以看到,由于第三个会话的thread_id 变了,所以大模型在回答的时候获取不到前两次的信息,即不共享内存会话信息

3.2 内存记忆的工作原理

使用内存做会话记忆时,内存中保存了什么信息呢?主要信息如下:

agent.invoke({"messages": [{"role": "user", "content": "你好"}]}, config) 
# InMemorySaver 保存: 
# { 
#     "thread_id": "xxx", 
#     "messages": [ 
#     HumanMessage("你好"), 
#     AIMessage("你好!有什么可以帮助你的吗?") 
#     ] 
# } 
agent.invoke({"messages": [{"role": "user", "content": "天气"}]}, config) 
# InMemorySaver 更新: 
# { 
#     "thread_id": "xxx", 
#     "messages": [ 
#     HumanMessage("你好"), 
#     AIMessage("你好!有什么可以帮助你的吗?"), 
#     HumanMessage("天气"), 
#     AIMessage("...") 
#     ] 
# }

在多轮对话中,每次会自动追加到历史会话中去

# 你只需要传新消息 
agent.invoke( 
    {"messages": [{"role": "user", "content": "新问题"}]}, 
    config 
)

此时,checkpointer 自动做下面的事情:

  • 读取之前的历史

  • 追加新消息

  • 调用模型(传入完整历史)

  • 保存新的历史

说明:

  • checkpointer 会自动管理历史

3.3 基于外部存储介质的持久化器

如果将 状态检查点(checkpointer) 保存在内存, 进程结束 则状态丢失,生产环境不可接受。因此,生产环境要用持久化的外部存储介质,如PostgreSQL。LangGraph提供的checkpointer后端列表如下:

Persistence - Docs by LangChain

此处选择PostgreSQL作为持久化器。

3.3.1 安装PostgreSQL

找一台服务器,或者虚拟机,最快的方式是使用docker 快速搭建一个服务,我这里直接让AI给我快速搭建

3.3.2 具体代码实现

在此之前,先准备好PostgreSQL环境,此处在云服务器的Ubuntu系统安装PostgreSQL。大家需要根据自己云服务器位置,更改URL中的IP即可。

postgresql://用户名:密码@IP地址:5432/langchain_db? 
sslmode=disable
  • 上述URL中的用户名、密码、IP地址,需要根据自己的情况替换。

  • 要在LangChain中对接PostgreSQL,还需要额外的依赖,比如:

pip install langgraph-checkpoint-postgres

下面看完整的代码

from langchain.chat_models import init_chat_model
from dotenv import load_dotenv
import os

from dotenv import load_dotenv

load_dotenv(override=True)

OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY")
OPENROUTER_API_BASE = os.getenv("OPENROUTER_API_BASE")

# 以init_chat_model为例
from langchain_openrouter import ChatOpenRouter

model = ChatOpenRouter(
    model="deepseek/deepseek-v4-flash",
    api_key=OPENROUTER_API_KEY,
    base_url=OPENROUTER_API_BASE,
)

from langchain.agents import create_agent
from langchain.messages import HumanMessage
from langgraph.checkpoint.postgres import PostgresSaver

DB_URL = "postgresql://你的账号:你的密码@服务器IP地址:5432/langchain_db?sslmode=disable"

with PostgresSaver.from_conn_string(DB_URL) as checkpointer:
    # 初始化PostgreSQL数据库
    checkpointer.setup()

    agent = create_agent(
        model=model,
        checkpointer=checkpointer
    )

    config = {"configurable": {"thread_id": "1"}}

    response1 = agent.invoke(
        {"messages": [HumanMessage("你好,我是老王")]},
        config=config
    )

    print("=" * 30, "-> 第一次调用 <-", "=" * 30)
    for msg in response1["messages"]:
        msg.pretty_print()

    response2 = agent.invoke(
        {"messages": [HumanMessage("你好,我是谁?")]},
        config=config
    )
    print("=" * 30, "-> 第二次调用 <-", "=" * 30)
    for msg in response2["messages"]:
        msg.pretty_print()

运行一下看到下面的效果,通过输出日志可以看到,每一次的聊天会话信息被存储了,下一次的对话中就可以读取到历史的对话,从而看起来就有记忆功能

代码说明:

setup() 用于初始化PostgreSQL数据库,首次运行会创建必要的表,重复执行不会重新建表,底层逻辑是 Create IF Not Exists 

3.3.3 查看持久化数据

查看PostgreSQL数据库,可以通过命令行或图形化工具查看

PostgreSQL的存储结构是 Database -> Schema -> Table

  • Database :数据库

  • Schema :分区

  • Table :表

通过 \dt 命令可以看到有哪些数据表,这四张表都是 setup() 函数初始化时创建的

  • checkpoints :这是主表,存每个 thread 在某个时刻的 checkpoint 快照。

  • checkpoint_blobs :这张表专门存不适合直接内联进 checkpoints.checkpoint 的较复杂channel 值。

  • checkpoint_writes :这张表存的是中间写入 / pending writes,不是最终完整 checkpoint。

  • checkpoint_migrations :这张表不是业务数据表,而是迁移版本表。

总结:

  • InMemorySaver()将状态持久化到内存, 进程结束或重建Saver() 则历史状态丢失

  • 基于外部存储介质(如PostgreSQL)的持久化器,其存储的状态不会随进程终止而丢失,只要不显式删除历史状态 ,即可通过 thread_id 加载历史状态。

四、记忆治理策略(上下文管理)

随着对话的进行,历史消息不断累积, state会持续增长 ,为模型带来挑战:

  • LLM的 上下文窗口是有限的 ,完整历史可能无法装入LLM的上下文窗口,导致上下文丢失或错误。

  • 容“分散注意力” 。即便模型的上下文窗口够大,多数LLM在长上下文场景仍然表现不佳。模型会被陈旧或离题的内

  • 同时,会带来 高昂的token花费 。

此时需要对上下文进行管理:对历史记录进行压缩、清理、重组等。下面针对常用的治理策略做介绍。

4.1 消息裁剪

调用模型之前裁剪上下文,目标是控制token用量,通常 保留系统初始消息和最近若干消息 ,或 按token数保留末尾内容 。

  • 适合成本敏感、对旧上下文依赖不强的场景

4.1.1 案例代码

如下代码中,使用@before_model装饰器定义一个方法,对消息进行裁剪

from dotenv import load_dotenv
import os

# 从.env文件中加载环境变量
load_dotenv(override=True)

OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY")
OPENROUTER_API_BASE = os.getenv("OPENROUTER_API_BASE")

# 以init_chat_model为例
from langchain_openrouter import ChatOpenRouter

model = ChatOpenRouter(
    model="deepseek/deepseek-v4-flash",
    api_key=OPENROUTER_API_KEY,
    base_url=OPENROUTER_API_BASE,
)

from langchain_core.messages import HumanMessage
from langchain.messages import RemoveMessage
from langgraph.graph.message import REMOVE_ALL_MESSAGES
from langgraph.checkpoint.memory import InMemorySaver
from langchain.agents import create_agent, AgentState
from langchain.agents.middleware import before_model
from langgraph.runtime import Runtime
from langchain_core.runnables import RunnableConfig
from typing import Any

@before_model
def trim_messages(state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
    messages = state["messages"]

    if len(messages) <= 3:
        return None

    first_msg = messages[0]
    recent_messages = messages[-3:] if len(messages) % 2 == 0 else messages[-4:]
    new_messages = [first_msg] + recent_messages

    return {
        "messages": [
            RemoveMessage(id=REMOVE_ALL_MESSAGES),
            *new_messages
        ]
    }

agent = create_agent(
    model=model,
    middleware=[trim_messages],
    checkpointer=InMemorySaver(),
)

config: RunnableConfig = {"configurable": {"thread_id": "1"}}

agent.invoke({"messages": [HumanMessage("你好,我是老王")]}, config)
agent.invoke({"messages": [HumanMessage("从现在起,你叫小王")]}, config)
agent.invoke({"messages": [HumanMessage("今天天气不错")]}, config)
final_response = agent.invoke({"messages": [HumanMessage("告诉我,你是谁?我是谁?")]}, config)

for msg in final_response["messages"]:
    msg.pretty_print()

运行之后效果如下

代码说明:

假设有 5 条消息: [H1, A1, H2, A2, H3] (当前总数 5,奇数)。执行 messages[-4:] 取出 [A1, H2, A2, H3] 。加上第一条 H1 ,最终大模型看到的是 [H1, A1,H2, A2, H3] (相当于没剪掉什么)。

4.2 消息删除

消息裁剪强调“在 模型调用前裁剪 消息列表,控制模型可以看到的上下文范围”,而消息删除强调 模型调用完成后将某些消息从消息列表中移除 ,永久更改状态。

  • 适合明确要遗忘、清理、重置某些历史。

4.2.1 案例代码

在下面的代码中,设置最大消息数为3,即超过3条的时候将会触发删除

import os

from dotenv import load_dotenv

# 从.env文件中加载环境变量
load_dotenv(override=True)

OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY")
OPENROUTER_API_BASE = os.getenv("OPENROUTER_API_BASE")

# 以init_chat_model为例
from langchain_openrouter import ChatOpenRouter

model = ChatOpenRouter(
    model="deepseek/deepseek-v4-flash",
    api_key=OPENROUTER_API_KEY,
    base_url=OPENROUTER_API_BASE,
)

from langchain.messages import RemoveMessage
from langchain.agents import create_agent, AgentState
from langchain.agents.middleware import after_model
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.runtime import Runtime
from langchain_core.runnables import RunnableConfig


@after_model
def delete_old_messages(state: AgentState, runtime: Runtime) -> dict | None:
    messages = state["messages"]
    # 保持最近的 5 条消息
    if len(messages) > 3:
        # 框架中通常使用 RemoveMessage 来标记删除,并返回更新状态。
        to_delete = len(messages) - 3
        return {"messages": [RemoveMessage(id=m.id) for m in
                             messages[:to_delete]]}
    return None

agent = create_agent(
    model=model,
    middleware=[delete_old_messages],
    checkpointer=InMemorySaver(),
)

config: RunnableConfig = {"configurable": {"thread_id": "1"}}

agent.invoke({"messages": "你好,我是老王"}, config)
agent.invoke({"messages": "从现在起,你叫小王"}, config)
agent.invoke({"messages": "今天天气不错"}, config)
final_response = agent.invoke({"messages": "告诉我,你是谁?我是谁?"}, config)

for msg in final_response["messages"]:
    msg.pretty_print()

完整输出结果如下

显然,模型调用后消息列表规模超过阈值触发了消息裁剪。

说明:

只要消息总数超过 3 条,就计算超出几条( to_delete ),然后精准地删掉最老的那几条,使剩下的消息总数永远保持在 3 条。

4.2.2 RemoveMessage干了什么

当你在中间件里返回 [RemoveMessage(id=m.id)] 时,你实际上是向框架发送了一个 删除指令 。

框架的底层处理逻辑如下:

[历史消息池 (内存中持续存在)] 
    ├── Message(id="1", content="你好,我是老王") 
    ├── Message(id="2", content="...") 
    └── RemoveMessage(id="1") <-- 这是一个新追加进去的“墓碑”标记

具体解释如下:

  • 追加“墓碑”标记:框架收到 RemoveMessage(id="1") 后,并不会去内存的数组里把 id="1" 的对象删掉,而是把这个 RemoveMessage 作为一条新记录追加到当前线程的状态历史中。这个RemoveMessage 就像是一个“墓碑”。

  • 运行时过滤合并(Reducer):当下一次你再次调用 agent.invoke 或者大模型要去读取上下文时,框架的内置合并器(Reducer)会把“原始消息”和“墓碑标记”放在一起进行计算:

原始消息 (id: 1) + 墓碑标记 (id: 1) = ∅(对外隐藏)

它在丢给大模型之前,会自动把被标记删除的消息过滤掉。

4.3 消息摘要

把早期历史压缩成摘要,再替换原始消息,可以结合下图进行理解

消息裁剪和删除都会导致上下文缺失,影响回答质量和用户体验。和它们相比,摘要是更适合长会话的折中方案:保语义,不保原文。官方推荐内置 SummarizationMiddleware 。

4.3.1 案例代码

参考下面的完整代码

from langchain.chat_models import init_chat_model
from dotenv import load_dotenv
import os

from dotenv import load_dotenv

# 从.env文件中加载环境变量
load_dotenv(override=True)

OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY")
OPENROUTER_API_BASE = os.getenv("OPENROUTER_API_BASE")

# 以init_chat_model为例
from langchain_openrouter import ChatOpenRouter

model_out = ChatOpenRouter(
    model="deepseek/deepseek-v4-flash",
    api_key=OPENROUTER_API_KEY,
    base_url=OPENROUTER_API_BASE,
)

model_in = ChatOpenRouter(
    model="deepseek/deepseek-v4-pro",
    api_key=OPENROUTER_API_KEY,
    base_url=OPENROUTER_API_BASE,
)

from langchain.agents.middleware import SummarizationMiddleware
from langchain.agents import create_agent
from langgraph.checkpoint.memory import InMemorySaver

# 创建带摘要中间件的 Agent
agent = create_agent(
    model=model_out,
    tools=[],
    checkpointer=InMemorySaver(),
    middleware=[
        SummarizationMiddleware(
            model=model_in,
            trigger=[
                ("tokens", 100),  # 超过 100 tokens 就摘要
            ],
            keep=("messages", 2),
            summary_prompt="对历史消息摘要,消息列表如下\n{messages}",
        )
    ]
)
config = {"configurable": {"thread_id": "1"}}

print("\n进行多轮对话...")
conversations = [
    "我叫张三,是工程师。这里是一段非常长非常长的废话..." * 20,  # 强制撑爆 100 tokens
    "请总结一下我的信息"
]

for msg in conversations:
    response = agent.invoke(
        {"messages": [{"role": "user", "content": msg}]},
        config=config
    )
    
    for msg in response["messages"]:
        msg.pretty_print()
    print("*" * 50)

4.3.2 关于摘要的常见问题

下面列举了关于摘要应用中的几个常见问题

1、摘要会丢失信息吗?

会有一些细节丢失,但是:

  • 重要信息会保留(姓名、关键事实)

  • 最近的消息完整保留

  • 对于大部分场景足够

2、摘要成本高吗?

  • 摘要只在超过阈值时触发

  • 可以使用便宜的模型(如 gpt-4o-mini)

  • 相比传输全部历史,通常更便宜

3、设置最大token数触发摘要的标准是啥?

# 模型上下文窗口 4k → 设置 3000 
# 模型上下文窗口 8k → 设置 6000 
# 模型上下文窗口 16k → 设置 12000 
# 留一些余量给工具调用和系统提示

4、摘要触发的频率要关注吗?

要关注,根据监控摘要触发频率,调整阈值。

  • 如果频繁触发 → 提高阈值

  • 如果从不触发 → 降低阈值

五、写在最后

本文通过较大的篇幅详细介绍了Langchain 上下文记忆管理相关的技术,有兴趣的同学可以基于此继续深入研究,本篇到此结束,感谢观看。

评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逆风飞翔的小叔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值