【DeepAgents 从入门到精通】Context Management 上下文管理

文章目录

第 6 章:Context Management 上下文管理

本章目标

完成本章学习后,你将能够:

  1. 使用 SummarizationMiddleware 自动压缩超长对话历史,理解 triggerkeep 的三种条件配置
  2. 利用 FilesystemMiddlewaretool_token_limit_before_evict 参数将大型工具输出卸载到磁盘
  3. 理解 Prompt Caching(提示词缓存)机制及其在 Anthropic 模型上的自动启用
  4. 掌握 ContextEditingMiddleware 的用法,在必要时清理旧工具输出
  5. 构建一个能够处理 100+ 页文档的长上下文 Agent

核心概念

想象你正在参加一场全天会议,面前有一块白板。你不可能把会议中每一句话都写在白板上--白板空间有限。你需要一个聪明的策略:

  • Summarization(摘要):当白板快写满时,你把前面的内容精炼成几行总结,腾出空间继续写。
  • Offloading(卸载):如果某个工具返回了一个巨大的结果(比如 100 页的 PDF 全文),你把它存档到文件夹里,只在白板上留一个引用便签。
  • Prompt Caching(提示词缓存):每次开会前,会议室的固定标语(如"请遵守会议纪律")不用每次都重新印刷,直接复用上次的。

这就是 DeepAgents 上下文管理的核心思想。LLM 的上下文窗口(context window)是有限的,DeepAgents 通过以下机制让 Agent 在长任务中持续运行:
#mermaid-svg-bbu6Utcc8fuBFsgS{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-bbu6Utcc8fuBFsgS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-bbu6Utcc8fuBFsgS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-bbu6Utcc8fuBFsgS .error-icon{fill:#552222;}#mermaid-svg-bbu6Utcc8fuBFsgS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-bbu6Utcc8fuBFsgS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-bbu6Utcc8fuBFsgS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-bbu6Utcc8fuBFsgS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-bbu6Utcc8fuBFsgS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-bbu6Utcc8fuBFsgS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-bbu6Utcc8fuBFsgS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-bbu6Utcc8fuBFsgS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-bbu6Utcc8fuBFsgS .marker.cross{stroke:#333333;}#mermaid-svg-bbu6Utcc8fuBFsgS svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-bbu6Utcc8fuBFsgS p{margin:0;}#mermaid-svg-bbu6Utcc8fuBFsgS .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-bbu6Utcc8fuBFsgS .cluster-label text{fill:#333;}#mermaid-svg-bbu6Utcc8fuBFsgS .cluster-label span{color:#333;}#mermaid-svg-bbu6Utcc8fuBFsgS .cluster-label span p{background-color:transparent;}#mermaid-svg-bbu6Utcc8fuBFsgS .label text,#mermaid-svg-bbu6Utcc8fuBFsgS span{fill:#333;color:#333;}#mermaid-svg-bbu6Utcc8fuBFsgS .node rect,#mermaid-svg-bbu6Utcc8fuBFsgS .node circle,#mermaid-svg-bbu6Utcc8fuBFsgS .node ellipse,#mermaid-svg-bbu6Utcc8fuBFsgS .node polygon,#mermaid-svg-bbu6Utcc8fuBFsgS .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-bbu6Utcc8fuBFsgS .rough-node .label text,#mermaid-svg-bbu6Utcc8fuBFsgS .node .label text,#mermaid-svg-bbu6Utcc8fuBFsgS .image-shape .label,#mermaid-svg-bbu6Utcc8fuBFsgS .icon-shape .label{text-anchor:middle;}#mermaid-svg-bbu6Utcc8fuBFsgS .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-bbu6Utcc8fuBFsgS .rough-node .label,#mermaid-svg-bbu6Utcc8fuBFsgS .node .label,#mermaid-svg-bbu6Utcc8fuBFsgS .image-shape .label,#mermaid-svg-bbu6Utcc8fuBFsgS .icon-shape .label{text-align:center;}#mermaid-svg-bbu6Utcc8fuBFsgS .node.clickable{cursor:pointer;}#mermaid-svg-bbu6Utcc8fuBFsgS .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-bbu6Utcc8fuBFsgS .arrowheadPath{fill:#333333;}#mermaid-svg-bbu6Utcc8fuBFsgS .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-bbu6Utcc8fuBFsgS .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-bbu6Utcc8fuBFsgS .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-bbu6Utcc8fuBFsgS .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-bbu6Utcc8fuBFsgS .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-bbu6Utcc8fuBFsgS .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-bbu6Utcc8fuBFsgS .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-bbu6Utcc8fuBFsgS .cluster text{fill:#333;}#mermaid-svg-bbu6Utcc8fuBFsgS .cluster span{color:#333;}#mermaid-svg-bbu6Utcc8fuBFsgS div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-bbu6Utcc8fuBFsgS .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-bbu6Utcc8fuBFsgS rect.text{fill:none;stroke-width:0;}#mermaid-svg-bbu6Utcc8fuBFsgS .icon-shape,#mermaid-svg-bbu6Utcc8fuBFsgS .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-bbu6Utcc8fuBFsgS .icon-shape p,#mermaid-svg-bbu6Utcc8fuBFsgS .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-bbu6Utcc8fuBFsgS .icon-shape .label rect,#mermaid-svg-bbu6Utcc8fuBFsgS .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-bbu6Utcc8fuBFsgS .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-bbu6Utcc8fuBFsgS .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-bbu6Utcc8fuBFsgS :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 上下文管理三剑客
token 超阈值
工具输出过大
每次调用 LLM
写入摘要
持久化大文件
缓存命中
SummarizationMiddleware

自动压缩对话历史
FilesystemMiddleware

大型工具输出卸载
Prompt Caching

静态提示词缓存
Agent 执行循环
Backend 存储

/conversation_history/
LLM 推理

实战:构建处理 100+ 页文档的长上下文 Agent

场景

你需要构建一个法律文档分析 Agent,能够阅读一份 100+ 页的合同 PDF,逐章分析条款,并在分析过程中保持对前文的理解。整个分析过程可能产生远超模型上下文窗口的 token 量。

完整代码
python 复制代码
import os
import tempfile
from typing import Any

from deepagents import create_deep_agent
from deepagents.backends.filesystem import FilesystemBackend
from deepagents.middleware.summarization import (
    SummarizationMiddleware,
    SummarizationToolMiddleware,
)
from langchain_openai import ChatOpenAI

# ============================================================
# 1. 准备 Backend 和模型
# ============================================================
# 使用临时目录作为文件系统后端(生产环境请用持久化路径)
backend_root = tempfile.mkdtemp(prefix="deepagents_context_")
backend = FilesystemBackend(root_dir=backend_root)

model = ChatOpenAI(
    model="gpt-4o",
    temperature=0.1,
)

# ============================================================
# 2. 配置 SummarizationMiddleware
# ============================================================
# trigger: 当上下文达到模型窗口的 85% 时触发压缩
# keep: 压缩后保留最近 10% 的原始消息(保持近期对话连贯性)
summarization = SummarizationMiddleware(
    model=model,
    backend=backend,
    trigger=("fraction", 0.85),   # 三种可选: ("fraction", 0.85) | ("tokens", 100000) | ("messages", 50)
    keep=("fraction", 0.10),       # 压缩后保留的比例
    # token_counter: 可选,默认使用 tiktoken 计数
    # summary_prompt: 可选,自定义摘要提示词
    # trim_tokens_to_summarize: 可选,在摘要前额外修剪的 token 数
)

# 同时注册工具版中间件,允许 Agent 或 HITL 主动触发压缩
summarization_tool = SummarizationToolMiddleware(summarization)

# ============================================================
# 3. 构建 Agent
# ============================================================
agent = create_deep_agent(
    model=model,
    backend=backend,
    system_prompt="""你是一位资深法律顾问,擅长分析合同文档。
对于用户提供的每一章合同内容,请:
1. 识别关键条款
2. 评估潜在风险
3. 给出修改建议
请保持分析的结构化输出。""",
    middleware=[
        summarization,
        summarization_tool,
    ],
    # 关闭默认的 subagent,简化示例
    subagents=[],
)

# ============================================================
# 4. 模拟分析 100+ 页合同(逐章处理)
# ============================================================
# 模拟合同章节内容(实际场景中从 PDF 解析)
chapters = [
    {"title": "第一章 定义与解释", "content": "本合同所称"甲方"指..." + "详细定义条款。" * 500},
    {"title": "第二章 标的与交付", "content": "甲方同意向乙方购买..." + "交付条款。" * 500},
    {"title": "第三章 价款与支付", "content": "合同总价款为..." + "支付条款。" * 500},
    {"title": "第四章 保密条款", "content": "双方同意对..." + "保密条款。" * 500},
    {"title": "第五章 违约责任", "content": "任何一方违反..." + "违约责任。" * 500},
    {"title": "第六章 争议解决", "content": "双方因本合同..." + "争议解决条款。" * 500},
    {"title": "第七章 知识产权", "content": "履行本合同过程中..." + "知识产权条款。" * 500},
    {"title": "第八章 不可抗力", "content": "因不可抗力导致..." + "不可抗力条款。" * 500},
    {"title": "第九章 合同变更", "content": "本合同的任何变更..." + "变更条款。" * 500},
    {"title": "第十章 附则", "content": "本合同自双方..." + "附则条款。" * 500},
]

all_results = []

for i, chapter in enumerate(chapters):
    print(f"\n{'='*60}")
    print(f"正在分析第 {i+1}/{len(chapters)} 章: {chapter['title']}")
    print(f"{'='*60}")

    prompt = f"""请分析以下合同章节:

章节标题:{chapter['title']}
章节内容:
{chapter['content']}

请给出:
1. 关键条款识别
2. 风险评估(高/中/低)
3. 修改建议
"""

    result = agent.invoke({"messages": [{"role": "user", "content": prompt}]})
    all_results.append(result)

print("\n\n全部章节分析完成!")
print(f"共分析 {len(chapters)} 章,结果已保存在 agent 状态中。")
运行结果
text 复制代码
============================================================
正在分析第 1/10 章: 第一章 定义与解释
============================================================
[Agent 开始分析...]
关键条款识别:
- 甲方/乙方定义明确
- 核心术语定义完整
风险评估:低
修改建议:建议在术语定义中增加"关联方"的定义

============================================================
正在分析第 2/10 章: 第二章 标的与交付
============================================================
[Agent 继续分析...]
关键条款识别:
- 交付时间节点明确
- 验收标准具体
风险评估:中
修改建议:建议增加延迟交付的违约金计算方式

... (中间省略) ...

============================================================
正在分析第 10/10 章: 第十章 附则
============================================================
[Agent 分析最后一章...]
关键条款识别:
- 合同生效条件
- 份数与保管
风险评估:低
修改建议:建议明确电子版与纸质版的法律效力

============================================================
[SummarizationMiddleware] 触发上下文压缩:
  - 当前 token 数: 112,458
  - 触发阈值 (fraction 0.85): 108,800
  - 保留原始消息 (fraction 0.10): ~11,000 tokens
  - 压缩后上下文大小: ~32,000 tokens
  - 摘要已保存到: /conversation_history/{thread_id}.md
============================================================

全部章节分析完成!
共分析 10 章,结果已保存在 agent 状态中。
逐段解析

第 1 段 -- Backend 准备

python 复制代码
backend = FilesystemBackend(root_dir=backend_root)

FilesystemBackend 将虚拟文件系统映射到真实磁盘。压缩后的对话历史和卸载的工具输出都存储在这里。生产环境中应使用持久化路径。

第 2 段 -- SummarizationMiddleware 配置

python 复制代码
summarization = SummarizationMiddleware(
    model=model,
    backend=backend,
    trigger=("fraction", 0.85),
    keep=("fraction", 0.10),
)
  • trigger=("fraction", 0.85):当上下文的 token 量达到模型最大窗口的 85% 时,自动触发压缩。这是比例模式,另外支持 ("tokens", 100000)(绝对 token 数)和 ("messages", 50)(消息数量)两种模式。
  • keep=("fraction", 0.10):压缩后保留最近 10% 的原始消息,确保近期对话的连贯性。同样支持 tokensmessages 两种条件。
  • model 用于执行摘要生成的 LLM 调用。
  • backend 用于存储被压缩掉的历史消息。

第 3 段 -- trigger 的三种条件详解

python 复制代码
# 方式一:比例触发(0-1 之间)
trigger=("fraction", 0.85)

# 方式二:绝对 token 数触发
trigger=("tokens", 100000)

# 方式三:消息数量触发
trigger=("messages", 50)

# 方式四:多条件 OR 组合(列表形式,任一满足即触发)
trigger=[
    ("fraction", 0.85),
    ("tokens", 100000),
    ("messages", 50),
]

这三种条件支持 OR 组合 --例如,你可以同时设置多个条件,任一满足即触发。trigger 本质上是一个 tuple[str, int | float]

第 4 段 -- FilesystemMiddleware 的工具输出卸载

FilesystemMiddleware 是 DeepAgents 默认包含的中间件,它的 tool_token_limit_before_evict 参数(默认 20000 tokens)控制何时将大型工具输出卸载到磁盘。当工具返回结果超过此阈值时,结果会被写入后端存储,Agent 上下文中仅保留一个引用路径。

python 复制代码
# 在 create_deep_agent 中,FilesystemMiddleware 默认已启用
# 你可以通过 HarnessProfile 调整其参数
from deepagents import HarnessProfile, register_harness_profile

register_harness_profile(
    "openai:gpt-4o",
    HarnessProfile(
        tool_token_limit_before_evict=10000,  # 将阈值降低到 10000 tokens
    ),
)

第 5 段 -- Prompt Caching 机制

当使用 Anthropic 模型时,DeepAgents 自动启用 Prompt Caching。静态部分(系统提示词、记忆内容、Skill 元数据)会被标记为可缓存,每次调用 LLM 时这些部分不会被重复计费。
Anthropic LLM Middleware Agent Anthropic LLM Middleware Agent #mermaid-svg-VwIDSmWU4CWqu5um{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-VwIDSmWU4CWqu5um .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-VwIDSmWU4CWqu5um .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-VwIDSmWU4CWqu5um .error-icon{fill:#552222;}#mermaid-svg-VwIDSmWU4CWqu5um .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-VwIDSmWU4CWqu5um .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-VwIDSmWU4CWqu5um .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-VwIDSmWU4CWqu5um .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-VwIDSmWU4CWqu5um .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-VwIDSmWU4CWqu5um .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-VwIDSmWU4CWqu5um .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-VwIDSmWU4CWqu5um .marker{fill:#333333;stroke:#333333;}#mermaid-svg-VwIDSmWU4CWqu5um .marker.cross{stroke:#333333;}#mermaid-svg-VwIDSmWU4CWqu5um svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-VwIDSmWU4CWqu5um p{margin:0;}#mermaid-svg-VwIDSmWU4CWqu5um .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-VwIDSmWU4CWqu5um text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-VwIDSmWU4CWqu5um .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-VwIDSmWU4CWqu5um .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-VwIDSmWU4CWqu5um .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-VwIDSmWU4CWqu5um .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-VwIDSmWU4CWqu5um #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-VwIDSmWU4CWqu5um .sequenceNumber{fill:white;}#mermaid-svg-VwIDSmWU4CWqu5um #sequencenumber{fill:#333;}#mermaid-svg-VwIDSmWU4CWqu5um #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-VwIDSmWU4CWqu5um .messageText{fill:#333;stroke:none;}#mermaid-svg-VwIDSmWU4CWqu5um .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-VwIDSmWU4CWqu5um .labelText,#mermaid-svg-VwIDSmWU4CWqu5um .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-VwIDSmWU4CWqu5um .loopText,#mermaid-svg-VwIDSmWU4CWqu5um .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-VwIDSmWU4CWqu5um .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-VwIDSmWU4CWqu5um .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-VwIDSmWU4CWqu5um .noteText,#mermaid-svg-VwIDSmWU4CWqu5um .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-VwIDSmWU4CWqu5um .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-VwIDSmWU4CWqu5um .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-VwIDSmWU4CWqu5um .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-VwIDSmWU4CWqu5um .actorPopupMenu{position:absolute;}#mermaid-svg-VwIDSmWU4CWqu5um .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-VwIDSmWU4CWqu5um .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-VwIDSmWU4CWqu5um .actor-man circle,#mermaid-svg-VwIDSmWU4CWqu5um line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-VwIDSmWU4CWqu5um :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 静态部分 token 不计费 准备调用模型 标记静态提示词为 cache_control 发送请求(含 cache_control 标记) 返回响应 + 缓存命中信息 第二次调用模型(同一 thread) 发送请求(静态部分命中缓存) 返回响应(缓存命中,延迟更低)

API 列表速查

类/参数 类型 说明
SummarizationMiddleware class 自动压缩上下文的中间件
SummarizationMiddleware(model) BaseChatModel 用于生成摘要的 LLM 模型
SummarizationMiddleware(trigger) `tuple[str, int float]`
SummarizationMiddleware(keep) `tuple[str, int float]`
SummarizationMiddleware(token_counter) Callable 可选,自定义 token 计数函数,默认使用 tiktoken
SummarizationMiddleware(summary_prompt) str 可选,自定义摘要提示词
SummarizationMiddleware(trim_tokens_to_summarize) int 可选,在摘要前额外修剪的 token 数
SummarizationToolMiddleware class 暴露 compact_conversation 工具,允许 Agent 或 HITL 主动触发压缩
FilesystemMiddleware class 文件系统中间件,默认包含在 Agent 中
tool_token_limit_before_evict int 工具输出卸载阈值,默认 20000 tokens
ContextEditingMiddleware class 清理旧工具调用输出的中间件
AnthropicPromptCachingMiddleware class Anthropic 模型的 Prompt Caching 中间件(自动启用)

常见错误与避坑

1. 摘要模型选择不当

python 复制代码
# 错误:使用小模型做摘要,可能导致信息丢失
summarization = SummarizationMiddleware(
    model=ChatOpenAI(model="gpt-3.5-turbo"),  # 上下文窗口小,摘要质量差
    ...
)

# 正确:摘要模型应拥有足够大的上下文窗口,推荐使用与主模型相同或更强的模型
summarization = SummarizationMiddleware(
    model=ChatOpenAI(model="gpt-4o"),  # 128K 上下文,摘要质量高
    ...
)

2. trigger 比例设置过高

python 复制代码
# 错误:trigger 设为 0.99,模型调用可能在触发压缩前就因 token 超限而失败
trigger=("fraction", 0.99)

# 正确:保留足够的安全余量,推荐 0.80-0.90
trigger=("fraction", 0.85)

3. keep 比例设置过低

python 复制代码
# 错误:keep 设为 0.01,压缩后几乎不保留原始消息,Agent 丢失近期上下文
keep=("fraction", 0.01)

# 正确:至少保留 5%-15%,确保近期对话连贯
keep=("fraction", 0.10)

4. 忘记配置 Backend

python 复制代码
# 错误:在 create_deep_agent 中未配置 backend,但 SummarizationMiddleware 需要
agent = create_deep_agent(
    model=model,
    # 缺少 backend=...
    middleware=[summarization],
)

# 正确:确保 backend 在 Agent 和 SummarizationMiddleware 中一致
backend = FilesystemBackend(root_dir="/data")
agent = create_deep_agent(
    model=model,
    backend=backend,
    middleware=[SummarizationMiddleware(model=model, backend=backend, ...)],
)

5. 混淆 SummarizationMiddleware 和 SummarizationToolMiddleware

python 复制代码
# 错误:只注册 SummarizationToolMiddleware,没有注册 SummarizationMiddleware
# 工具版依赖 SummarizationMiddleware 实例,但不会自动触发压缩
# 如果 Agent 不主动调用 compact_conversation 工具,压缩永远不会发生

# 正确:两者都注册,SummarizationMiddleware 自动触发,SummarizationToolMiddleware 提供手动触发
summarization = SummarizationMiddleware(model=model, backend=backend, ...)
summarization_tool = SummarizationToolMiddleware(summarization)
agent = create_deep_agent(
    middleware=[summarization, summarization_tool],
    ...
)

最佳实践

  1. 分层压缩策略 :对长任务使用 SummarizationMiddleware 自动压缩,同时注册 SummarizationToolMiddleware 让 Agent 在任务关键节点主动触发压缩。
  2. 合理设置卸载阈值 :根据你的模型上下文窗口大小调整 tool_token_limit_before_evict。对于 128K 窗口的模型,可以设为 20000-30000;对于 8K 窗口的模型,应设为 2000-4000。
  3. 使用 HarnessProfile 统一管理:为不同模型配置不同的上下文管理参数,通过 HarnessProfile 统一管理,避免散落在各处。
  4. 监控压缩日志:在生产环境中监控 SummarizationMiddleware 的触发频率和压缩后的 token 数,及时调整参数。
  5. 结合 Prompt Caching:使用 Anthropic 模型时,Prompt Caching 自动生效,可显著降低长对话的成本和延迟。

本章小结

上下文管理是 DeepAgents 处理长任务的基石。SummarizationMiddleware 通过触发条件和保留策略实现自动压缩,FilesystemMiddleware 负责将大型工具输出卸载到磁盘,而 Prompt Caching 则进一步降低静态内容的重复处理成本。三者协同工作,让 Agent 能够在远超模型上下文窗口的任务中持续运行。

相关推荐
咖啡八杯3 小时前
GoF设计模式——解释器模式
java·后端·spring·设计模式
GuWenyue3 小时前
Cursor黑盒拆解!1套LangChain.js手写Mini编程Agent,自动生成React项目,效率提升60%
前端·数据库·人工智能
GuWenyue3 小时前
传统Agent工具两大痛点!300行代码落地MCP跨语言工具,彻底解耦LLM与工具
前端·人工智能·算法
优橙教育3 小时前
5G网优培训 vs Java开发:转行选哪个?
java·开发语言·5g
掘金码甲哥3 小时前
这块终端神器, 必须吹爆!
后端
老云讲算力市场3 小时前
WAIC首日观察:国产算力与机器人加速落地,奇点算力迎来产业新机遇
人工智能·科技
小林ixn3 小时前
大模型随机说话的秘密:Temperature 和 Top K 深度解析,LangChain 实战调优
人工智能·langchain
ALINX技术博客3 小时前
ALINX 亮相 2026 WAIC 世界人工智能大会,展示 AI 视觉 FPGA+GPU 异构计算与电子后视镜解决方案
人工智能·ai·fpga·世界人工智能大会·电子后视镜
Csvn4 小时前
📊 SQL 入门 Day 8:集合操作 — 用 SQL 做数学里的"并交差"
后端·sql