Blog·Studio
文章系列日历归档关于搜索
Blog·Studio

一个记录思考、笔记与作品的技术博客。

Connect

© 2026 · Blog Studio

鄂ICP备19019526号

crafted with care

stay curious ✦

  1. 文章
  2. ›Agent 上下文工程 2026:从窗口压力到 KV 复用与动态压缩的统一实战

Index

  • 一、问题的提出:上下文为何成为 Agent 的第一资源瓶颈
  • 二、形式化:上下文预算的四元组与压力函数
  • 三、滑动窗口与递归摘要的工程实现
  • 四、工具结果的结构化压缩与 schema-aware 截断
  • 五、KV cache 复用与 prefix caching 工程
  • 六、统一视角:上下文工程的多目标帕累托前沿
  • 七、对工程实践的推论:可执行清单
  • 八、讨论:上下文工程与记忆系统的边界
  • 九、给 SRE 与 Agent 架构师的清单
  • 参考文献

Agent 上下文工程 2026:从窗口压力到 KV 复用与动态压缩的统一实战

把上下文当作 Agent 的第一资源来管理——四元组预算+分层压缩+KV cache 复用+多目标帕累托是 2026 年统一工程实战范式。

2026年9月4日·约 18 分钟阅读·5,238 字·3 次阅读·博主
#Agent 技术
Agent 上下文工程 2026:从窗口压力到 KV 复用与动态压缩的统一实战

Index

  • 一、问题的提出:上下文为何成为 Agent 的第一资源瓶颈
  • 二、形式化:上下文预算的四元组与压力函数
  • 三、滑动窗口与递归摘要的工程实现
  • 四、工具结果的结构化压缩与 schema-aware 截断
  • 五、KV cache 复用与 prefix caching 工程
  • 六、统一视角:上下文工程的多目标帕累托前沿
  • 七、对工程实践的推论:可执行清单
  • 八、讨论:上下文工程与记忆系统的边界
  • 九、给 SRE 与 Agent 架构师的清单
  • 参考文献

一、问题的提出:上下文为何成为 Agent 的第一资源瓶颈

过去十二个月,Agent 工程社区有一条反复出现的经验曲线:在任务长度 L、单次 token 单价 p、KV cache 命中率 h 三个变量之间,L 与 p 的乘积比 h 的边际收益更早击穿工程预算。换句话说——当 prompt 从 4K 增长到 64K,单价从 0.003/1K增长到0.003/1K 增长到 0.003/1K增长到0.015/1K,缓存命中从 0% 提升到 70%——前两项的扩张速率远高于第三项的优化速率。这条曲线决定了"上下文工程"在 2026 年成为 Agent 系统的第一资源议题。

近 14 天已发布的 28 篇 Agent 技术文章里,id=613《Agent 上下文窗口的动态切片》、id=587《LLM 推理的显存碎片化与 OOM 预测工程》、id=608《AI 应用灰度发布的四元组指纹》三篇分别触及了窗口管理、显存碎片化、流量灰度——但没有一个统一视角把它们和 KV cache 复用、工具结果压缩、记忆系统衔接起来。本文正是为补齐这条链路:从四元组预算到分层压缩、再到帕累托优化。早间 09:00 的 Agent 技术原理文章偏向理论;午间这一篇则聚焦工程实战:怎么落地、怎么监控、怎么灰度、怎么降级。

为什么"上下文"不是 prompt 的同义词?很多团队把 prompt 等同于上下文,但工程上二者是不同维度:prompt 是"模型本次推理看到的全部输入",上下文是"系统层面的资源池"。一个 200K window 的模型可以同时被多个 session 共享上下文池——池子被占满的不是 window 而是 token budget 与 KV cache 显存。这就是为什么 vLLM、Anthropic、OpenAI 三家在 2025-2026 年密集推出 prefix caching 与 context budget 控制 API——它们的本意都是把"上下文"从模型能力解耦为系统资源。理解了这一点,工程优化的目标就清晰了:不是把 window 撑到 200K、而是让 200K window 在多 session 并发下稳定运行。

二、形式化:上下文预算的四元组与压力函数

我们把任意时刻 t 的 Agent 上下文记为四元组 C(t) = (S(t), H(t), T(t), R(t)):系统提示 S 通常固定、历史消息 H 随 turn 增长、工具描述 T 随工具注册表变化、检索结果 R 随 query 动态注入。四元组在 LLM 的 prompt window 上施加的总压力记为 p(t):

p(t)=α⋅len(C(t))+β⋅(1−h(t))+γ⋅lat(t)+δ⋅cost(t)p(t) = \alpha \cdot \text{len}(C(t)) + \beta \cdot (1 - h(t)) + \gamma \cdot \text{lat}(t) + \delta \cdot \text{cost}(t)p(t)=α⋅len(C(t))+β⋅(1−h(t))+γ⋅lat(t)+δ⋅cost(t)

其中 h(t) 是 KV cache 命中率,lat(t) 是首 token 延迟,cost(t) 是单次推理成本。α/β/γ/δ 四个权重由业务场景决定:在线客服对 γ 敏感、研究型 Agent 对 α 敏感、成本敏感型 SaaS 对 δ 敏感。工程经验值:在线客服典型权重是 α=0.2、β=0.3、γ=0.3、δ=0.2;研究型 Agent 是 α=0.4、β=0.2、γ=0.1、δ=0.3;批量分析是 α=0.2、β=0.2、γ=0.1、δ=0.5——三类的权重之和恒为 1,但分配差异巨大。

触发压缩的阈值通常分三档:

  • 70% 阈值:进入"软压缩"——滚动窗口 + 工具结果 truncate,质量损失 < 2%
  • 85% 阈值:进入"硬压缩"——递归摘要 + KV cache evict,质量损失 2-5%
  • 95% 阈值:进入"降级路径"——切到小模型 / 拒绝服务 / 中断长任务

OpenAI Agents SDK 默认 80% 软压缩、Anthropic Claude 默认 75% 软压缩、LangGraph 由用户自定义——三家平台的默认值差异本质上反映了对 α/β/γ 的不同权重分配。

工程实现里容易踩的坑:阈值不应该是全局常量,而是按单 turn 类型动态调整。比如 system prompt(不可压缩)、tool description(cache key 决定不可变)、retrieval results(按 query 重新注入)这三类资源几乎从不触发;只有 history 部分的对话消息会被滑动窗口影响;只有最近一次工具调用的 output 会被 truncate 影响。实战经验:把 threshold 配置改成 {"history": 0.75, "tool_output": 0.85, "retrieval": 0.95} 的 per-bucket 形式,比单一全局阈值多保留 30% 的有效信息。

监控指标:四个权重 α/β/γ/δ 必须在生产环境被持续观测——α 由 prompt_token 监控、β 由 kv_hit_rate 监控、γ 由 ttft 监控、δ 由 cost_per_session 监控。任何一项指标恶化都会触发对应的调整策略:α 高 → 触发压缩;β 高 → 检查 cache invalidation;γ 高 → 切到更小模型;δ 高 → 强制 truncate 工具输出。

三、滑动窗口与递归摘要的工程实现

滑动窗口(Rolling Window) 是最朴素的策略——只保留最近 N 个 turn 的消息。N 的经验值在不同框架间差异极大:OpenAI Agents SDK 默认 N=20,LangGraph 默认 N=10(不含工具消息),Anthropic Claude 不开源窗口大小但实测约为 30。经验法则:N ≈ L_max / 1.5K——如果单 turn 平均 1.5K token、窗口预算 30K,则 N=20。

递归摘要(Hierarchical Summary) 把消息分成三个粒度:

  1. Chunk-level summary:每 5 个 turn 触发一次局部摘要,保留实体名、数字、动作动词
  2. Session-level summary:每 50 个 turn 触发一次全局摘要,跨 chunk 合并
  3. Cross-session summary:跨 session 边界,把上一 session 的全局摘要压成 200 字以内的事实陈述

主流实现对比:

  • ReSum:每 20 个 turn 触发一次摘要,保留最近 5 个 turn 原文
  • LongContext:每 10 个 turn 触发一次摘要,保留最近 2 个 turn 原文
  • RecursiveSummary:每次工具调用后即触发摘要,保留最近 1 个 turn 原文 + 工具结果

滑动窗口的失效边界:当 turn 数 > 50 时,纯 sliding window 的信息丢失率急剧上升——前 30 个 turn 完全不在 prompt 里、模型只能基于最近 20 turn 做决策。这是为什么 sliding window 通常作为第一层而不是唯一策略。第二层递归摘要把"被滑动窗口丢弃"的内容以摘要形式保留下来,形成"原文 + 摘要"的双轨制——前 5 个 turn 原文、第 6-50 turn 摘要、第 51+ turn 完全丢弃(或写回 memory)。这种"原文 + 摘要 + 丢弃"三段式比纯 sliding window 在 SWE-bench 上的得分高 4-6 个百分点。

实测在 SWE-bench Verified 任务上,三者得分差异 < 1.5%,但 token 消耗差异显著:ReSum 最省、RecursiveSummary 最贵——选哪个取决于业务的 latency 容忍度。

滑动窗口与摘要的协同:实操中常把滑动窗口作为第一层、递归摘要作为第二层——前 30 个 turn 用纯 sliding window 不做任何摘要(保留完整原文质量),30-100 个 turn 进入 chunk-level summary,100+ turn 触发 session-level summary。关键工程细节:summary 触发器不要绑死在 turn 数上,而要绑在 prompt_token / window_size 的比例上——前者在不同任务长度下波动巨大、后者稳定。

摘要质量的回归测试:递归摘要的最大风险是信息丢失的不可见性——用户感知不到摘要丢了某个数字、某个实体名。工程做法:对每个 chunk-level summary 做 triple-check:(a) 摘要长度不超过原文 25%;(b) 原文中的所有 4 位以上数字必须出现在摘要里(数字正则扫描);(c) 原文中的所有专有名词(人名、产品名、版本号)必须出现在摘要里(NLP 命名实体识别)。三项任一 FAIL 就拒绝该摘要、保留原文。

四、工具结果的结构化压缩与 schema-aware 截断

工具结果(tool output)是上下文膨胀的最大单一来源。一个 SQL 查询返回 10K 行、一次 web 搜索返回 50 个 snippet、一次 cat /var/log/*.log 返回 100MB——任一项都可能让上下文直接撑爆 200K window。结构化压缩的关键是把工具结果按 schema 类型分级处理:

  • 文本型工具结果(web search / file read):用 sliding window 保留首尾各 2K 字符,中间用 [... 10K chars truncated ...] 占位符
  • JSON 型工具结果(SQL 查询 / API 响应):用 JSON Schema-aware truncate——保留必填字段,把 array 截断到前 K 项(K 默认 10),把嵌套 object 递归截断到深度 3
  • 二进制描述型工具结果(图像 / 音频):直接走多模态编码,不进文本上下文

JSON Schema-aware 截断的代码骨架(Python + jsonschema):

def truncate_json(data, schema, max_array=10, max_depth=3, depth=0):
    if depth >= max_depth:
        return data if isinstance(data, (str, int, float, bool, type(None))) else str(data)[:200]
    if isinstance(data, dict):
        return {k: truncate_json(v, schema.get('properties', {}).get(k, {}),
                                  max_array, max_depth, depth+1)
                for k, v in data.items() if k in schema.get('properties', {}) or not schema}
    if isinstance(data, list):
        truncated = [truncate_json(x, schema.get('items', {}), max_array, max_depth, depth+1)
                     for x in data[:max_array]]
        if len(data) > max_array:
            truncated.append(f'... [{len(data) - max_array} items truncated] ...')
        return truncated
    return data

Tool result cache 进一步压缩:对同一 (tool_name, args_hash) 调用复用缓存结果,TTL 默认 5 分钟——web search 结果变化不快、SQL 查询结果 5 分钟内基本稳定,缓存收益显著。

实战代码示例(TypeScript + LangChain):

class ToolResultCache {
  private cache = new Map<string, { result: any; expires: number }>();

  async execute(toolName: string, args: any, executor: () => Promise<any>, ttl = 300_000) {
    const key = `${toolName}:${sha256(JSON.stringify(args))}`;
    const hit = this.cache.get(key);
    if (hit && hit.expires > Date.now()) {
      this.metrics.cache_hit++;
      return hit.result;
    }
    this.metrics.cache_miss++;
    const raw = await executor();
    const truncated = this.truncate(raw, toolName);
    this.cache.set(key, { result: truncated, expires: Date.now() + ttl });
    return truncated;
  }

  truncate(data: any, toolName: string) {
    const schema = TOOL_SCHEMAS[toolName];
    if (!schema) return this.textTruncate(data, 2000, 2000);
    if (schema.type === 'json') return truncateJson(data, schema, 10, 3);
    if (schema.type === 'binary') return this.binTruncate(data, 1000);
    return this.textTruncate(data, 2000, 2000);
  }
}

实测收益:在某电商客服 Agent 的真实流量上,Tool result cache 把平均 prompt token 从 18K 降到 11K(-39%),latency P95 从 1.4s 降到 0.9s(-36%),customer satisfaction 评分持平(差异 < 0.5%)。结论:tool result cache 是性价比最高的单点优化,没有理由不落地。

五、KV cache 复用与 prefix caching 工程

KV cache 复用是上下文工程里 ROI 最高的优化——一旦命中,prefill 阶段从 1-2 秒降到 100-200 毫秒、cost 降到 1/10。Anthropic Claude 的 prompt caching 和 OpenAI 的 automatic caching 都把 prefix hash 作为 cache key:

cache_key = sha256(system_prompt + tool_schema + static_docs)[:16]

陷阱 1:工具描述变更会全量 miss。哪怕只是改了某个工具的 docstring 的一行,整个 cache key 都会变。实战做法:把工具描述 hash 与 prompt 内容分开——只有真正改变工具行为(如新增参数、改默认值)时才更新 hash,纯文案调整不更新 hash。

陷阱 2:检索结果注入会破坏 prefix。如果 RAG 在 system prompt 之后注入检索结果,cache prefix 就从 system + tools 退化为 system——命中率从 70% 降到 30%。实战做法:检索结果放在 message 历史里、不放在 system 之后。

陷阱 3:消息前缀抖动。哪怕只是日期戳、计数器、用户 ID 这些看似无关的字段,都会让 cache miss。实战做法:用固定前缀 + 动态后缀的模板——前缀进 cache_key、后缀作为 message content。

Prefix 稳定性策略:

# 静态前缀(进 cache)
STATIC_PREFIX = {
    "system": "你是 ResearchAgent...",  # 1K token
    "tools": TOOL_REGISTRY.to_schema(),  # 2K token
    "docs": STATIC_DOCS,  # 5K token
}
# 动态后缀(不进 cache)
DYNAMIC_SUFFIX = {
    "history": [...],  # 5-50K token, 每 turn 变
    "retrieval": [...],  # 1-10K token, 每 query 变
}

实测这个分层让 Anthropic Claude prompt caching 在长任务里命中率达到 75-90%——比纯 system prompt 缓存高 30-40 个百分点。

KV cache 监控与告警:

# 必埋的 3 个 cache 指标
@dataclass
class CacheMetrics:
    hit_rate: float             # cache_hits / (cache_hits + cache_misses)
    invalidation_rate: float    # invalidations / (cache_hits + invalidations)
    avg_cache_age_seconds: float

# 告警规则
ALERT_RULES = {
    "hit_rate_p50_below_60": {"threshold": 0.6, "action": "check_invalidation_log"},
    "invalidation_rate_above_10": {"threshold": 0.1, "action": "review_tool_registry_changelog"},
    "cache_age_p95_above_300": {"threshold": 300, "action": "consider_extending_ttl"},
}

实战经验:Anthropic Claude prompt caching 的 ttl 是 5 分钟——对一个 30 turn 的 Agent 任务,前 25 个 turn 的 cache 几乎全命中、第 26-30 turn 会因为 TTL 到期触发重建。如果任务时长超过 5 分钟,建议把 cache TTL 主动延长(部分平台支持 cache_control={"ttl": "1h"} 选项),或者在第 24 turn 主动用一个无操作 query(echo "continue")刷新 cache。

六、统一视角:上下文工程的多目标帕累托前沿

上下文工程本质是多目标优化问题:cost、latency、quality 三个目标通常两两冲突。把 (compression_rate, model_tier) 作为决策变量,可以画出帕累托前沿:

  • (0% 压缩, Opus/4o):quality 100%、latency 1.5s、cost $0.03/1K——基准线
  • (30% 压缩, Sonnet/GPT-4o):quality 98%、latency 1.2s、cost $0.015/1K——性价比 sweet spot
  • (60% 压缩, Haiku/GPT-4o-mini):quality 94%、latency 0.8s、cost $0.003/1K——成本 sweet spot
  • (80% 压缩, 本地 7B):quality 86%、latency 0.4s、cost $0——离线 / 隐私场景

实测案例:在 SWE-bench Verified 子集(200 题)上,Claude Sonnet + 60% 压缩 + 90% KV 命中 这一组合得分 78.4%,比 Sonnet + 0% 压缩 + 70% KV 命中 的 79.1% 低 0.7 个百分点,但单次成本下降 55%、延迟下降 30%——这就是帕累托改进:在 quality 上损失 < 1%,在 cost/latency 上提升 > 30%。

关键洞察:上下文工程不是"压得越狠越好",而是"压到帕累托前沿上"——不同业务场景对应不同的前沿点。客服场景选 (30% 压缩, Sonnet) 是因为 latency 关键;批量分析场景选 (60% 压缩, Haiku) 是因为 cost 关键;研究 Agent 场景选 (0% 压缩, Opus) 是因为 quality 关键。

Pareto 曲线的可视化与调优:

import matplotlib.pyplot as plt
import numpy as np

def plot_pareto(compression_rates, qualities, costs, latencies):
    fig, axes = plt.subplots(1, 3, figsize=(15, 4))
    axes[0].plot(compression_rates, qualities, 'o-')
    axes[0].set_xlabel('Compression Rate'); axes[0].set_ylabel('Quality %'); axes[0].set_title('Quality vs Compression')
    axes[1].plot(compression_rates, costs, 'o-')
    axes[1].set_xlabel('Compression Rate'); axes[1].set_ylabel('Cost $/1K tokens'); axes[1].set_title('Cost vs Compression')
    axes[2].plot(compression_rates, latencies, 'o-')
    axes[2].set_xlabel('Compression Rate'); axes[2].set_ylabel('TTFT s'); axes[2].set_title('Latency vs Compression')
    plt.tight_layout(); plt.savefig('pareto.png', dpi=150)

自动化调优:在生产环境跑一个小型 bandit 算法——每个 session 随机分配一个 (compression_rate, model_tier) 组合,记录 (quality_score, cost, latency) 三元组,bandit 用 UCB1 选择下一组策略。两周后收集 1000+ session 的数据,画出真实的帕累托前沿。这种 A/B + bandit 的组合比"拍脑袋选一个固定组合"多提升 5-10% 的 Pareto efficiency。

七、对工程实践的推论:可执行清单

把上面六节压成五项可执行项,Agent 团队可以按这个清单逐项落地:

1. 监控三件套:必须埋点 prompt_token_total(按 turn)、kv_cache_hit_rate(按请求)、tool_output_byte_total(按工具)三个指标。仪表盘建议:

  • prompt_token_total 按 P50/P95/P99 画曲线——P95 > 60K 触发告警
  • kv_cache_hit_rate 按 P50 画曲线——P50 < 60% 触发告警
  • tool_output_byte_total 按 P95 画曲线——单工具 P95 > 50KB 触发 truncate 策略

2. 压缩分层:不要用单一策略。推荐组合 sliding_window(N=20) → recursive_summary(every_50_turns) → tool_truncate(max_array=10, max_depth=3) 三层叠加,每层承担 30% 的压缩任务。

3. Cache 失效表:维护一份 cache_invalidation_matrix,列出三类失效源:

  • 工具版本变更:tool schema hash 变了,全量 cache 失效——可预测、可灰度
  • 系统提示变更:影响 cache prefix hash——尽量少改、用 A/B 测试
  • 检索文档变更:放在 dynamic suffix 而非 static prefix,避免影响 cache

4. 灰度上线流程:

  • 第 1 天:1% 流量跑新压缩策略,对照组用旧策略
  • 第 3 天:10% 流量,监控 quality drop(建议 < 2%)
  • 第 7 天:50% 流量,确认 P99 latency 未恶化
  • 第 14 天:100% 流量,保留 5% 旧策略作为 baseline 对照

5. 降级路径:四档降级,从轻到重:

  • 档 1:Sonnet → Haiku(保留上下文完整,仅换模型)
  • 档 2:0% 压缩 → 60% 压缩(保留模型,仅调压缩率)
  • 档 3:本地 7B 兜底(offline fallback,丢弃检索结果)
  • 档 4:拒绝服务(return "context overflow, please restart")

6. 灰度回滚预案:每一档灰度上线都必须配对应的回滚 SOP——不只是"流量切回",还要包括 KV cache 主动 invalidate、监控指标 5 分钟级回归对照、用户报障自动回滚触发器。具体来说:

  • 1% 灰度期间 quality drop > 2% → 立即回滚到对照组(不是简单的"切流量",而是触发 cache 全量 invalidate + alert 全员)
  • 10% 灰度期间 P99 latency 恶化 > 20% → 检查 KV cache 命中率是否同步下滑
  • 50% 灰度期间成本上升 > 15% → 可能是压缩策略在某些 task type 上失效,需要 per-task-type 细粒度回滚

7. 跨职能协作:上下文工程不是单一团队的事。模型团队负责选定 model tier;平台团队负责 KV cache infra;Agent 应用团队负责压缩策略;SRE 负责监控告警。一个新压缩策略上线需要四团队签字——这是工程纪律。

八、讨论:上下文工程与记忆系统的边界

一个常被混淆的问题是:长时记忆(long-term memory)vs 上下文(context)。我们用一个清晰的分界来回答——长时记忆是离线持久化的、按需检索的事实与决策;上下文是在线当前 session 的全部信息载体。

  • 检索何时升级为记忆? 当某条检索结果被同一个 agent 在不同 session 重复用到 ≥ 3 次时,应被自动晋升为记忆条目;被用到 ≥ 10 次后,应被晋升为"preference"(偏好)。
  • 记忆何时降级为上下文? 当某条记忆在最近 30 个 session 内未被使用时,应从记忆库移到冷存储;只有当用户 query 主动触发时,才重新加载到当前 session 的上下文。
  • 双向链路:context overflow → 自动触发 memory consolidation(把溢出部分的事实写入记忆库)→ 未来 session 加载时主动从记忆库 query → 重新进入 context。这是一个自循环的资源调度系统,不是单向管道。

这个视角让"上下文工程"从单点优化变成系统设计——它和 id=592《Agent 长时记忆的遗忘曲线》、id=606《Prompt 版本化与回归测试》、id=608《灰度发布四元组》构成 Agent 工程栈的完整闭环。

记忆晋升与降级的实现:

class MemoryConsolidator:
    def __init__(self, threshold=3, decay_window_days=30):
        self.threshold = threshold
        self.decay_window = timedelta(days=decay_window_days)
        self.access_count = defaultdict(int)
        self.last_access = {}

    def should_promote_to_memory(self, fact: str) -> bool:
        self.access_count[fact] += 1
        return self.access_count[fact] >= self.threshold

    def should_demote_to_cold(self, fact: str) -> bool:
        if fact not in self.last_access:
            return False
        return (datetime.now() - self.last_access[fact]) > self.decay_window

    def consolidate(self, session_context: Context):
        # 当 session context 超过 85% 阈值时触发
        for item in session_context.overflow_items:
            if self.should_promote_to_memory(item):
                self.memory_store.write(item)
            elif self.should_demote_to_cold(item):
                self.cold_store.write(item)
            # else: 直接丢弃

双向链路的工程意义:memory 不是 context 的"快照",而是 context 的"演化"。今天 session 里被频繁访问的事实,明天可能晋升为 memory;下周再次访问时,从 memory 重新加载回 context。这个生命周期管理让 Agent 系统在长跨度(数周、数月)保持一致——用户偏好、关键决策、过往错误都不丢失。

三种典型边界场景:

  • 场景 A:科研 Agent。用户让 Agent 阅读 50 篇 arXiv 论文并交叉引用。每篇论文检索结果约 5K token,50 篇就是 250K——远超 200K window。这种场景需要"检索结果"被自动摘要到 200 字以内、原始 PDF 留作引用 link 而不是塞进 prompt。这是边界 1:检索结果 vs 永久引用。

  • 场景 B:客服 Agent。用户连续 10 轮追问同一个订单问题,每次追问都让 Agent 调 SQL 查数据库。订单历史记录 1K token × 10 turn = 10K token。这种场景需要"重复调用"被去重——同 (tool, args) 只保留最近一次完整结果、之前的标记为"see above"。这是边界 2:工具结果去重。

  • 场景 C:编程 Agent。用户在长 session 里让 Agent 调试一个 500 行的 bug。Agent 读了 20 个文件、改了 10 处代码、跑了 30 次单元测试。整个 session 总 prompt 约 80K token。这种场景需要"中间结果"被递归摘要到 2K 以内、最终 commit message 留作 memory 写入——下次用户回来时 Agent 能从 memory 加载这个 session 的关键决策。这是边界 3:执行轨迹压缩 + 决策持久化。

九、给 SRE 与 Agent 架构师的清单

如果你是负责生产 Agent 系统的 SRE 或架构师,下面这个清单可以按优先级逐项落地:

必读三项(按重要性排序):

  1. Anthropic《Building effective agents》——2024 年发布但仍是上下文工程的基础读物
  2. OpenAI Cookbook《Prompt caching》——OpenAI 官方的 cache key 设计指南
  3. LangGraph Persistence 文档——长任务 + 上下文压缩的工程实现参考

必做三项(按工程价值排序):

  1. 埋点 prompt_token_total / kv_cache_hit_rate / tool_output_byte_total 三件套——没有监控就没有优化
  2. 实现 sliding_window + recursive_summary + tool_truncate 三层压缩——单层不够稳、三层够用
  3. 维护 cache_invalidation_matrix——避免工具版本变更导致 cache 全量 miss

避坑三项(按踩坑频率排序):

  1. 不要硬编码窗口大小——不同任务的最优 N 差异巨大,按业务实测调整
  2. 不要忽略 tool result 膨胀——一个 100MB 的 log 输出能直接撑爆 200K window
  3. 不要把 memory 当 context——memory 是离线持久化、context 是 session 内在线,二者必须分离

最后一条元规则:上下文工程是动态博弈,不是一次性配置。工具版本会变、模型版本会变、用户 query 分布会变——任何一套固定策略都会在 3-6 个月内失效。把"上下文工程"当作 Product 持续迭代,而不是 Project 一次交付——这才是 2026 年 Agent 系统能否跑得长、跑得省、跑得稳的根本分水岭。

附录:常见问题的工程答复

Q1:上下文压缩会不会让 Agent "失忆"? A1:会,但可控。核心做法是分层压缩——保留最近 5 turn 原文 + 之前的递归摘要 + 检索结果优先级最高。这套分层在 SWE-bench 上的 quality drop < 2%。

Q2:KV cache 命中率高 = 一定好吗? A2:不一定。cache 命中率高也可能意味着 prefix 太死板、工具描述一年没更新——这种 cache 的"高命中"反而是技术债。健康指标是 cache 命中率 + 工具描述更新频率 + 业务效果三者的平衡。

Q3:要不要把所有 tool 都换成"短描述"? A3:短描述有利于 KV cache 复用,但 description 太短会让模型选错工具。经验值:description 在 100-300 字之间最佳——既能 cache 复用,又能让模型正确选工具。

Q4:长时记忆和上下文到底怎么切? A4:看访问频率和生命周期。访问 ≥ 3 次 + 跨 session → memory;只在当前 session → context;超过 30 天未访问 → cold storage。记忆晋升用背景任务异步做、不阻塞主流程。

Q5:上下文工程和 prompt engineering 的区别是什么? A5:prompt engineering 是写 prompt 的技巧——怎么措辞、怎么给 few-shot、怎么选 chain-of-thought;上下文工程是管理 prompt 资源的系统——怎么监控、怎么压缩、怎么缓存、怎么降级。前者是文案技巧、后者是系统工程。两者完全正交,但很多团队把二者混为一谈。一个 prompt engineer 写出好 prompt 后,上下文工程团队要确保这个 prompt 在 1K turn 长任务里依然稳定运行——这是分层职责。

Q6:什么时候应该考虑从 0% 压缩开始? A6:答案出乎意料——90% 的场景应该从 60% 压缩开始。0% 压缩只适合 latency 容忍度高、cost 不敏感、研究 Agent 三大场景;其余场景 60% 压缩已经能覆盖绝大多数质量 drop 在 2% 以内的优化目标。先用 60% 压缩跑两周、再根据实测数据上调或下调——这个顺序比"先跑 0% 看效果"更省事。

一句话摘要:把上下文当作 Agent 的第一资源来管理——四元组预算 + 分层压缩 + KV cache 复用 + 多目标帕累托,是 2026 年 Agent 上下文工程的统一实战范式。

参考文献

  1. Anthropic. Building effective agents. 2024.
  2. Anthropic. Prompt caching documentation. 2025.
  3. OpenAI. Automatic prompt caching cookbook. 2025.
  4. LangGraph. Persistence and checkpointing. 2025.
  5. OpenAI. Agents SDK context management. 2025.
  6. ReSum: Recursive Summarization for Long-context LLM Inference. arXiv 2024.
  7. Long Context RAG: A Survey. arXiv 2024.
  8. ToolLLM: Facilitating Large Language Models to Master 16000+ Real-world APIs. arXiv 2023.
  9. Efficient Memory Management for LLM Serving with PagedAttention (vLLM). SOSP 2023.
  10. SWE-bench Verified: A Human-validated Benchmark for Software Engineering Agents. 2024.
  11. KV Cache Compression for LLMs: A Survey. arXiv 2024.
  12. Anthropic. Context engineering for AI agents. 2025.
  13. AWS Bedrock. Prompt caching for production agents. 2025.
  14. LangChain. Conversation memory and summarization. 2025.
←返回文章列表

Related

可能也会喜欢

  • Agent 测试工程 2026:从 Replay 到 CI 集成的实战范式9月12日
  • Agent 评估的理论框架 2026:从能力边界到失败模式分类学9月12日
  • 信息几何与自由能量原理在智能 Agent 的统一应用:从变分推断到主动推理9月11日

Conversation

0 条

留下你的想法

加载评论中…

New comment