Agent 上下文工程:四种主流框架的处理策略对比(LangChain、AgentScope、Claude Agent SDK、OpenAI Agents SDK)

魏远标 Lv7

提问

Agent 在上下文工程中达到一定量的时候,要怎么处理?在 LangChain、AgentScope、Claude Agent SDK、OpenAI Agents SDK 上分别说下。

参考答案

一句话:四大策略组合拳——滑动窗口 + 摘要压缩 + 主动遗忘 + 检索增强。每个框架实现方式不同,但核心思路一致:让 LLM 永远只看最相关的信息


一、为什么需要上下文管理

LLM 有上下文窗口限制(8K / 32K / 128K / 200K),超过就报错或截断。

但多轮 Agent 场景会很快爆掉

1
2
3
4
5
10 轮对话 × 每轮 2K token = 20K
+ 5 个工具调用 × 1K 返回 = 5K
+ RAG top-5 文档 × 500 = 2.5K
+ system prompt 1K
= 28.5K ← 已接近 GPT-4o-mini 32K 上限

症状

  • 第 15 轮后 429: context_length_exceeded
  • 每次调用成本涨到 $0.05+
  • 模型越来越慢(注意力 O(n²))

二、四大策略总览

策略 原理 适用
滑动窗口 只保留最近 N 轮 短对话、低频引用老信息
摘要压缩 用 LLM 把老历史压缩成短摘要 长对话、需保留关键信息
主动遗忘 设置 TTL,定期清理不重要记忆 长期 agent、有”过期”概念
检索增强 把历史写进向量库,需要时检索相关 超长会话、跨会话记忆

实战最佳:四种组合用:

  • 最近 5-10 轮:完整保留(保证指代消解)
  • 更早的:用 LLM 摘要成 200 字
  • 关键事实:提取后存向量库
  • 过期信息:TTL 清理

三、LangChain:最完整生态

3.1 5 种 Memory 模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from langchain.memory import (
ConversationBufferMemory,
ConversationBufferWindowMemory,
ConversationSummaryMemory,
ConversationSummaryBufferMemory,
ConversationTokenBufferMemory,
)
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4o-mini")

# 1. 完整缓冲(最简单,无压缩)
memory = ConversationBufferMemory(memory_key="history", return_messages=True)

# 2. 滑动窗口(只保留最近 k 轮)
memory = ConversationBufferWindowMemory(k=10)

# 3. 摘要压缩(用 LLM 压缩老历史)
memory = ConversationSummaryMemory(llm=llm)

# 4. 混合:最近完整 + 更早摘要(⭐ 生产推荐)
memory = ConversationSummaryBufferMemory(
llm=llm,
max_token_limit=4000,
return_messages=True
)

# 5. 按 token 限额
memory = ConversationTokenBufferMemory(llm=llm, max_token_limit=3000)

3.2 自定义压缩策略

1
2
3
4
5
6
7
8
9
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMChainExtractor

# 检索后用 LLM 重新提炼内容
compressor = LLMChainExtractor.from_llm(llm)
compression_retriever = ContextualCompressionRetriever(
base_compressor=compressor,
base_retriever=vectorstore.as_retriever()
)

3.3 Token 计数 + 主动截断

1
2
3
4
5
6
7
8
from langchain.memory.token_buffer import ConversationTokenBufferMemory

# 精确控制 token 数(用 tiktoken 计算)
memory = ConversationTokenBufferMemory(
llm=llm,
max_token_limit=4000, # 超出自动截断
return_messages=True
)

LangChain 优势:生态最全,几乎所有需求都有现成组件。


四、AgentScope:阿里达摩院的中文场景之王

4.1 核心抽象:Msg + Pipeline

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import agentscope
from agentscope.agents import ReActAgent

agent_a = ReActAgent(
name="researcher",
sys_prompt="你是研究员",
model_config={"model": "qwen-max"},
tools=[search_tool]
)

agent_b = ReActAgent(
name="writer",
sys_prompt="你是写作员",
model_config={"model": "qwen-max"},
tools=[]
)

# Msg 是消息载体(强类型)
msg = agentscope.Msg("user", "写一篇 RAG 文章")

# Pipeline 自动管对话历史
pipeline = agentscope.Pipeline([agent_a, agent_b])
result = pipeline(msg)

4.2 长对话处理(关键!)

AgentScope 内置了 自动 token 截断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
agent = ReActAgent(
name="qa_bot",
sys_prompt="...",
model_config={
"model": "qwen-max",
# ⭐ 关键:自动管理 token
"token_limit": 6000, # 超出自动截断老消息
"truncation_strategy": "summarize", # 用摘要压缩
},
long_term_memory={
"type": "vector", # 用向量库存长期记忆
"path": "/path/to/memory.db"
}
)

4.3 手动控制(更细)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 获取对话历史
history = agent.memory.get_memory()

# 手动截断
agent.memory.truncate(n=10) # 只保留最近 10 条

# 摘要压缩
agent.memory.summarize(llm=qwen_llm)

# 持久化
agent.memory.save("/path/to/memory.json")

# 清空
agent.memory.clear()

AgentScope 优势中文场景深度优化(qwen-max 默认),配置即用。


五、Claude Agent SDK:Skills 即 Markdown

5.1 核心抽象:Markdown Skill

1
2
3
4
5
6
7
8
9
10
11
12
<!-- skills/context-aware/SKILL.md -->

# Context Aware Skill

触发条件:用户问题包含"它/那个/之前/刚才"

工作流程:
1. 读取 chat_history.json(最近 10 轮)
2. 如果新问题含代词,调用 LLM 改写:
"把含糊的问题改写为独立完整问题"
3. 把改写后的问题 + 最近 3 轮历史一起传给主 LLM
4. 输出 JSON:{rewritten_question, relevant_history}
1
2
3
4
5
6
7
8
9
# 加载并使用
async for msg in query(
prompt=user_question,
options=ClaudeAgentOptions(
skill_paths=["./skills"], # 扫描 SKILL.md
model="claude-sonnet-4-5"
)
):
print(msg)

5.2 CLAUDE.md 项目记忆

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- CLAUDE.md(项目根目录) -->

# Project Memory

## 项目信息
- 这是 javai.tech 个人技术博客
- 用户:Sherwin.Wei,13年 Java + AI 经验
- 技术栈:Hexo + 七牛云 + frp 隧道

## 长期事实
- 用户偏好用英文名 Sherwin.Wei
- 服务器:阿里云 ECS 8.148.150.180
- frp 服务端:飞牛 OS + 0.66 客户端

Agent 启动时自动加载 CLAUDE.md,相当于项目级长期记忆。

5.3 长对话的 MCP 配置

1
2
3
4
5
6
7
8
9
10
# claude_desktop_config.json
{
"mcpServers": {
"memory": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-memory"],
"env": {"MEMORY_FILE": "/Users/sherwin/claude-memory.json"}
}
}
}

Claude SDK 优势Skill = Markdown 让非程序员也能配置记忆策略。


六、OpenAI Agents SDK:Handoffs + Guardrails

6.1 Sessions(内置会话管理)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from agents import Agent, Runner, SQLiteSession

agent = Agent(
name="assistant",
instructions="你是有记忆的助手",
model="gpt-4o-mini"
)

# 用 SQLite 持久化会话历史
session = SQLiteSession(session_id="user_123", db_path="sessions.db")

# 多轮对话(自动从 SQLite 加载历史)
result1 = await Runner.run(agent, "Python 怎么读文件?", session=session)
result2 = await Runner.run(agent, "它能读多大?", session=session)
result3 = await Runner.run(agent, "给我个例子", session=session)

6.2 内置 Tokens 管理

1
2
3
4
5
6
7
8
9
10
11
12
agent = Agent(
name="assistant",
instructions="...",
model="gpt-4o-mini",
model_settings=ModelSettings(
# ⭐ OpenAI SDK 自动管理上下文
max_tokens=4096, # 单次输出上限
truncation="auto", # 自动截断
),
# Hook 系统(OpenAI SDK 的核心特性)
hooks=MyContextHook(), # 自定义上下文处理
)

6.3 自定义 Hook:上下文窗口管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from agents import RunHooks

class ContextManager(RunHooks):
async def on_llm_start(self, context, agent):
"""LLM 调用前触发"""
messages = context.messages
token_count = count_tokens(messages)

if token_count > 100000:
# 触发压缩
context.messages = compress(messages)

elif token_count > 50000:
# 滑动窗口:只保留最近 20 条
context.messages = messages[-20:]

OpenAI SDK 优势Handoffs + Hooks + Tracing 三件套。


七、四种框架横向对比

维度 LangChain AgentScope Claude Agent SDK OpenAI Agents SDK
核心抽象 Chain / Runnable Msg / Pipeline Skill (Markdown) Agent / Hook
短期记忆 ConversationBufferMemory Memory 内置 chat_history.json Session
长期记忆 VectorStoreRetrieverMemory long_term_memory CLAUDE.md + MCP SQLite / 自定义
滑动窗口 BufferWindow(k=10) truncate(n=10) 需自己写 context.messages[-N:]
摘要压缩 SummaryMemory summarize(llm) 需自己写 需自己写
混合(推荐) SummaryBufferMemory truncate + summarize 需自己组合 Hook 自己组合
持久化 RedisChatMessageHistory memory.save() 自动(CLAUDE.md) SQLiteSession
生态 ⭐⭐⭐⭐⭐ ⭐⭐⭐(中文场景⭐⭐⭐⭐) ⭐⭐⭐ ⭐⭐⭐⭐
学习曲线 低(Markdown)
配置即用 需自己组装 内置压缩/截断 Skill 即可 内置 Session

八、生产级通用策略(不论哪个框架)

8.1 黄金三层

1
2
3
4
5
6
7
8
9
10
11
第 1 层:滑动窗口(最近 5-10 轮)
└─ 保证指代消解 + 当前话题连贯
└─ 实现:保留最新 N 条

第 2 层:摘要压缩(10 轮之外的)
└─ 用便宜模型(gpt-4o-mini / qwen-turbo)压缩成 200 字
└─ 实现:每 5 轮触发一次

第 3 层:检索增强(关键事实存向量库)
└─ "用户是 Java 工程师"、"3 周前问过 Redis"
└─ 实现:每次对话开始时 top-3 检索

8.2 Token 预算公式

1
2
3
4
5
6
7
总预算 = system_prompt(500) + 当前问题(200) + 短期记忆(2000) + RAG结果(1500) + 输出预留(1000)
≈ 5200 token

模型选择:
< 4K → gpt-4o-mini / qwen-turbo
4-16K → gpt-4o / qwen-max / claude-sonnet
> 16K → gpt-4o-128k / claude-sonnet-200k

8.3 实战配置建议

1
2
3
4
5
6
7
8
9
10
11
12
13
agent_config:
short_term_window: 10 # 滑动窗口 10 轮
summary_threshold: 10 # 超过 10 轮触发摘要
summary_max_tokens: 300 # 摘要最多 300 字
long_term_top_k: 3 # 检索 top-3 长期记忆
tool_result_max_tokens: 1500 # 工具结果截断到 1500 token

# 成本控制
cheap_llm: gpt-4o-mini # 摘要用便宜模型
main_llm: gpt-4o # 主对话用好模型

# 性能监控
alert_threshold: 30000 # token 超 30K 报警

九、面试怎么答

面试官问「上下文管理」时,这样答:

「Agent 的上下文管理有四大策略

  1. 滑动窗口保留最近 N 轮(保证指代消解)
  2. 摘要压缩把老历史压成短摘要(控制 token)
  3. 主动遗忘给记忆设 TTL
  4. 检索增强把关键事实存向量库

不同框架实现方式不同:

  • LangChain:5 种 Memory 类,生态最全
  • AgentScope:内置 token_limit 自动管理,中文场景最优
  • Claude Agent SDK:用 SKILL.md 配置,CLAUDE.md 做长期记忆
  • OpenAI Agents SDK:内置 SQLiteSession + Hooks 系统

生产实践:三层组合——滑动窗口(最近 10 轮)+ 摘要压缩(10 轮外)+ 长期记忆向量库(关键事实)。

核心心法:让 LLM 永远只看最相关的信息,不管历史多长。」


十、踩坑清单

怎么避
上下文太长导致 API 报错 滑动窗口 + 摘要 + token_limit 强制
成本暴涨 用便宜模型做摘要(gpt-4o-mini 比 gpt-4o 便宜 30x)
指代消解失败 Query Rewriting + 历史 3 轮一起喂
跨会话记忆泄露 session_id 严格隔离 + 用户 ID 过滤
摘要本身太长 递归摘要(摘要的摘要再摘要)
重要信息被截掉 关键事实额外提取存向量库,不依赖压缩
LLM 自己要求压缩导致丢关键信息 用 Hook 强制压缩,不让 LLM 决定
长期记忆查询慢 用 Redis 缓存 top-K 结果

相关阅读


最后更新:2026-09-04