跳到正文
Agent 工程实践Context Engineering
返回课程/Agent 工程实践
第 7 / 15 章 约 8 分钟

Context Engineering

组织有效上下文,控制长度并保留任务状态。

这个模块在 Agent 里的位置

Context 是模型的短期工作记忆。它决定:

  • 模型看到什么。
  • 哪些信息被保留为引用。
  • 上下文什么时候增长过快。
  • 压缩后保留什么。
  • 任务如何继续,而不是从头重做。

工程上,Context 的目标不是“塞得越多越好”,而是让模型在有限注意力里看到正确的信息。

先记住几个概念

概念含义为什么重要
Working context当前 turn 可见消息模型实际看到的内容
Context budgettoken、图片、工具输出的上限控制成本和质量
Refs稳定 ID 引用让证据可校验、可精查
Compaction把旧历史压缩成摘要防止上下文无限增长
Resume prompt压缩后的继续指令避免重做已完成步骤
Checkpoint可恢复的上下文快照支持断点续跑和审计

从一个真实问题开始:上下文越长,结果反而越差

一个 Agent 要完成:

分析 30 天、50 万实体,输出 Top 10 风险实体和证据引用。

前 5 轮执行正常:

  1. 查询 30 天聚合。
  2. 锁定 Top 10。
  3. 补查 3 个证据窗口。

第 6 轮开始,模型突然问:

我需要重新查询 30 天聚合。

排查发现:

  1. 工具返回了 20 个原始事件窗口。
  2. 上下文超过 128k。
  3. 系统触发 compaction。
  4. 压缩摘要只保留了“已分析风险”,没有保留“已完成聚合查询”。
  5. 模型看不到已完成步骤,于是重新查。

这不是模型“忘性大”,而是 compaction summary 的契约不完整。

上下文膨胀的连锁反应

工具返回过大
  -> 上下文增长
  -> token 成本上升
  -> 关键约束被稀释
  -> 触发 compaction
  -> 摘要丢任务状态
  -> 模型重复查询
  -> 成本继续上升

上下文过长还会带来一个更隐蔽的问题:注意力被稀释。

例如任务要求“每个结论必须引用 evidenceWindowId”,但如果上下文里混入了:

  • 50 万行原始数据
  • 20 个无关工具输出
  • 3 张无关截图
  • 旧错误结论

模型很容易把关键约束淹没在噪声里。

工具结果应该先瘦身,再进入上下文

错误做法:

{
    "events": [
        { "id": 1, "payload": { "...": "raw" } },
        { "id": 2, "payload": { "...": "raw" } }
    ]
}

正确做法:

{
    "summary": {
        "topRiskEntityCount": 10,
        "timeRange": "30d"
    },
    "refs": [
        {
            "entityId": "entity-9182",
            "evidenceWindowIds": ["win-1001", "win-1002"]
        }
    ],
    "coverage": {
        "complete": true
    }
}

给模型的应该是:

  1. 结论。
  2. 稳定引用。
  3. 数据覆盖状态。
  4. 未解决问题。

不是原始世界。

Context budget 不只管 token

一个常见的错误是只看 token。实际上还应该管:

维度控制方式原因
Token真实 usage + 上下文窗口策略成本和窗口限制
Tool calls最大调用次数控制多轮增长
Output bytes单次工具输出上限控制单次膨胀
Imagesimage block 数量和字节数多模态请求容易失败
History blocks保留最新关键块避免旧噪声持续影响

示例预算:

{
    "contextBudget": {
        "maxTokens": 128000,
        "maxToolCalls": 20,
        "maxOutputBytes": 131072,
        "maxImageBlocks": 8
    }
}

真实 token 用量来自 LLM Gateway,不由工具自行估算。

Compaction summary 必须保留什么

Compaction 不是简单“删历史”。它至少要保留:

  1. 当前任务目标。
  2. 已完成步骤。
  3. 重要引用。
  4. 未完成问题。
  5. 用户最新约束。
  6. 失败和重试状态。

一个可用的 summary 结构:

{
    "taskGoal": "输出 Top 10 风险实体",
    "completed": ["已查询 30 天聚合", "已锁定 Top 10 实体"],
    "keyRefs": ["win-1001", "win-1002", "win-1003"],
    "constraints": ["每个结论必须引用证据窗口", "缺数据写入 unresolvedQuestions"],
    "pending": ["补查 3 个实体的证据窗口"]
}

对应恢复提示:

从中断处继续当前任务,不要重做已经完成的查询。

这句话的价值在于:

  • 明确任务是继续,不是重开。
  • 保留已完成步骤。
  • 保留关键引用。
  • 保留用户约束。

图片和多模态要单独预算

如果任务包含截图、图表或 OCR 结果,不能简单按文本 token 处理。

常见问题:

  1. 图片数量超过 provider 限制。
  2. 单张图片过大。
  3. 历史图片累计过多。
  4. 旧图片没有被裁剪。

工程做法:

  • 工具先返回 imageId。
  • 模型需要看图时再读取。
  • 每轮限制 image block 数量。
  • 上下文里只保留最新关键图。
  • 旧图替换成引用文本。

示例:

{
    "images": [
        {
            "imageId": "image-1001",
            "reason": "风险峰值窗口"
        }
    ],
    "budget": {
        "loadedImageCount": 4,
        "maxImageBlocks": 8
    }
}

Checkpoint 设计

大上下文不应直接存数据库 JSONB 字段。更稳的做法是:

  • 数据库存元数据和指针。
  • 对象存储存 checkpoint 文件。
  • checkpoint immutable。
  • 恢复时校验 generation。
create table agent_context_checkpoints (
  id bigint primary key,
  run_id bigint not null,
  generation bigint not null,
  checkpoint_type text not null,
  object_key text not null,
  token_count int not null,
  created_at timestamptz not null
);

create index agent_context_checkpoint_idx
  on agent_context_checkpoints (run_id, generation, created_at desc);

设计要点:

  1. checkpoint 不可覆盖。
  2. 旧 worker 只能追加,不能覆盖新结果。
  3. token count 用于监控,不用于权威计费。
  4. 恢复时按 generation 校验。

上下文包示例

{
    "runId": "run-9f27",
    "contextBudget": {
        "maxTokens": 128000,
        "usedTokens": 63400,
        "imageBlocks": 4
    },
    "taskState": {
        "goal": "输出 Top 10 风险实体",
        "completedSteps": ["已查询 30 天聚合", "已锁定 Top 10 实体"],
        "pendingSteps": ["补查 3 个实体的证据窗口"]
    },
    "evidenceRefs": [
        {
            "windowId": "win-1001",
            "reason": "风险峰值"
        }
    ]
}

这份数据能明确回答:

  • 任务目标是什么。
  • 已经做到哪里。
  • 还剩什么。
  • 关键引用在哪里。
  • 预算用了多少。

常见工程错误

错误实际后果正确做法
原始数据进上下文注意力稀释、成本暴涨summary + refs
压缩只保留结论任务状态丢失保留 goal / completed / pending
图片无预算请求失败或成本暴涨image block budget
观测日志进上下文无关噪声增加观测和上下文分离
checkpoint 可覆盖旧 worker 覆盖新状态immutable + generation
只看 token 不看工具输出单次返回仍可失控bytes / rows / images

上线前检查

  1. 上下文有 token 和多模态预算。
  2. 工具输出先瘦身。
  3. 引用 ID 稳定。
  4. compaction summary 保留任务状态。
  5. 恢复提示明确“继续,不重做”。
  6. checkpoint 有版本和 generation。