《智能体设计模式》第 2 章思考题解答(上下文工程)
来源:bojieli.github.io/ai-agent-book · 第 2 章 整理日期:2026-08-12
本章核心素材:实验 2-3(滑动窗口导致重复工具调用);KV Cache 前缀机制;Qwen3 Chat Template 思维链保留;DeepSeek R1/V4 策略反转;上下文感知压缩(148K→2000 字符);Agent 状态栏;提示工程消融(结构混乱致成功率 -30%);“上下文学习本质上是检索而非推理”;Skills 渐进式披露。
题 1(★★★):既不丢信息、又控长度、还不破坏 KV Cache 前缀的历史管理策略
冲突本质: 滑动窗口每轮都从中间删消息 → 每轮都破坏前缀(第一个被删 token 之后的 KV 全部失效),还丢信息;完整保留不破坏缓存但长度爆炸。突破口:**追加不破坏缓存,修改和删除才破坏。**设计四件套:
- 稳定前缀 + 只追加轨迹:系统提示词、工具定义固定在序列最前端且逐字节不变;对话轨迹只在尾部追加,绝不修改或删除中段。追加天然缓存友好。
- 控制"进入"而非"删除":长度控制的重点从裁剪历史,前移到限制每轮新增内容——工具结果截断/摘要化、大产物写入外部文件只在上下文留"引用 + 摘要"(指针 + digest)。这直接针对实验 2-3 的病因,且不动历史。
- 尾部状态块(状态栏):每轮在末尾注入紧凑的结构化状态(任务清单、已完成步骤、关键事实、工具计数)。末尾区域本来就每轮变化,放在那里零缓存代价,却能让模型不必回读旧轮次就知道"做过什么"——实验 2-3 的重复源于"忘了做过",而不是"原文没了"。
- 低频、有损可控的压实(compaction):长度逼近预算时才做一次压实,把旧轮次改写为结构化摘要(必须保留:决策、事实、失败过的尝试——失败教训是防重复的核心)。压实造成一次缓存失效,但每 K 轮一次,摊还后远低于滑动窗口的每轮一次;压实后的摘要成为新的稳定前缀,供后续 K 轮复用。压实时机选在子任务边界而非固定窗口。
辅助手段:子 Agent 分治——长探索放进全新小上下文,只回传结论,从源头避免单条轨迹过长。
题 2(★★):Qwen3 思维链保留机制的改造 + R1/V4 策略对比
问题: Qwen3 Chat Template 只以"真实用户消息"为思考重置点。ReAct 循环里上百轮工具调用之间没有真实用户消息,思考只增不减,上下文被推理过程淹没。
改造思路——把重置点从"用户消息"改为"决策粒度":
- 思考蒸馏为决策记录:后续轮次真正需要的是"决定了什么、为什么"。超过 K 轮的旧 think 块压缩成一行决策摘要(选择 + 依据 + 被否决的备选),只在尾部保留最近 N 轮的原始思考(尾部是缓存增量区,不伤前缀)。
- 预算制保留:给 reasoning 总量设 token 预算,超预算按"最旧先压缩"处理,与题 1 的压实机制共用基础设施。
- 模板参数化:重置点可配置(
keep_thinking = last_n / budget / summary),让框架按任务长度选择策略。
R1(剥离全部历史思考)vs V4(强制回传全部 reasoning_content):
| R1:剥离 | V4:全量回传 | |
|---|---|---|
| 利 | 省 token、上下文干净;避免模型读到训练时没见过的输入格式(分布外) | 长程规划、早期假设、死胡同教训全部保留;多轮推理连贯,不重复踩坑 |
| 弊 | 丢失长程计划,跨轮"失忆",反复犯同样的错 | token 成本巨大(叠加第 1 章的二次方增长问题);注意力稀释;依赖超大上下文窗口 |
反转说明了什么: 上下文处理策略不是普适定律,而是与模型训练配方耦合的工程选择。R1 时代模型没有经过"把自己历史 reasoning 作为上下文"的训练,喂进去是分布外噪声,剥离是对的;V4 时代模型在 agentic 强化学习中就是带着多轮 reasoning 上下文训练的,全量回传变成分布内输入,收益反超成本。同时需求侧也变了:Agent 场景(上百轮循环)让"长程连贯"的价值压过"省 token"。呼应第 1 章题 10的规律:原则(保留决策相关信息)不变,手段随模型能力反转。
题 3(★★):148K → 2000 字符的极端压缩,不可逆信息损失怎么办?
风险确实存在,且有三重:
- 意图锁定:压缩是"上下文感知"的——按当前查询意图蒸馏。任务方向一旦转变,当初被判定为冗余而丢弃的细节可能正是新方向需要的,而原文已不在上下文里;
- 压缩器自身出错:做摘要的 LLM 可能幻觉、改写或遗漏关键事实(数字、人名、职位、引用原文);
- 不可验证:极端压缩后无法回溯核对,错误会静默污染下游所有推理。
解法——把压缩从"销毁"变成"视图":
- 原文外置 + 引用保留:原始 148K 存入文件/向量库,上下文里的摘要携带指针(chunk 编号、来源链接)。压缩只是当前视角的投影,需要时可重新取回或按新意图重新压缩——把"不可逆"变回"可逆"的根本手段;
- 事实性内容逐字保留:数字、日期、人名、ID、URL 等"记录型事实"禁止改写,只允许删减背景性文字;
- 压缩带出处与时间戳:标注"本摘要于何时、针对何种意图生成",让后续阶段知道适用边界;
- 抽检/校验通道:对摘要中的关键断言保留可回查原文的机制(引用 span),高风险场景用独立校验步骤比对;
- 多分辨率留存:不只留极限版,保留中间档(如 20K 版),缓冲信息断层。
题 4(★★):状态栏自身有 bug(元信息可靠性)如何缓解?
核心原则:状态栏必须是"推导出来的",而不是"记出来的"。
- 单一事实源:工具计数器等状态直接从框架的真实调用日志计算得出,绝不通过解析模型消息或模型自报来维护。派生,不复制,就不存在两边不一致;
- 可再推导 + 定期对账:每个字段都能用一条确定性函数从日志重算;框架周期性跑一致性断言,发现不一致就重算覆盖,而不是信任旧值;
- 标注可信级别:区分"系统核验的事实"(tool calls: 7, verified)与"模型侧估计"(进度约 60%),让模型知道哪些可以直接用于决策;
- 只写隔离:状态栏只能由 harness 写入,模型无权修改,防止误差被自我强化;
- 关键决策不唯状态栏:涉及不可逆操作时,要求 Agent 向环境本身求证(重新列目录,而不是相信"已创建 3 个文件"的计数);
- 把状态栏当生产代码:单元测试、不变量检查、线上漂移监控——状态栏出错是普通 bug,按普通 bug 的流程修。
一句话:状态栏的价值在于显式化,可靠性来自"从事实计算,而非从记忆誊写"。
题 5(★★):多人维护下,如何防止系统提示词"熵增"?
提示词熵增的本质是公地悲剧 + 缺少回归测试。对策是把提示词当代码治理:
- 提示词即代码:进版本库,改动走 PR + 评审,有 style guide(章节顺序、优先级标记、标题层级——消融实验证明这些结构本身值 30% 的成功率);
- 固定骨架 + 分区所有权:固定章节构成(身份、全局规则、工具策略、领域规则…),每章有 owner,改动只允许发生在对应章节内;
- 自动化 lint:脚本/LLM 检查器扫描重复规则、互相矛盾的指令、层级破坏、超长膨胀,作为 CI 的第一道门;
- 回归评测门禁(最关键):维护任务评测集,每次提示词变更必须跑评测,成功率回退超过阈值就阻断合并——把消融实验结论变成持续执行的护栏;
- 模块化组装 + 静态核心稳定:提示词拆成可独立演进的模块,运行时拼装;静态核心稳定还能保护 KV Cache 前缀(呼应题 9);
- 定期熵审计:每个季度重构一次,删除"死去缘由"的规则(每条规则入库时记录它因何而加)。
题 6(★★★):“上下文学习本质上是检索而非推理”,如何突破?
本章论断:模型擅长在上下文里定位已有信息,但不擅长在单次前向传播里对海量内容做统计、归纳、聚合(上下文窗口是"只有一半功能的检索引擎")。“把更多信息塞进上下文"的边际收益递减甚至为负(注意力稀释)。突破方向是把工作从"被动上下文"挪到"主动计算与检索”:
- 注入结论,而非原料:聚合、计数、排序、去重交给代码/SQL/脚本在上下文之外完成,模型只接收蒸馏后的高密度结论 + 样本证据;
- 把推理改造成检索编排:模型通过工具循环做分析——不是读 10 万行日志,而是发出 grep/查询/统计的工具调用,每步只把小而准的结果拿进上下文。推理被分解成多次"精准检索 + 小步判断";
- 信息塑形:确需进上下文的,按检索友好方式组织——标题、编号、一行一事实、关键字段前置(同样解释了题 5 中结构为何值 30%);
- 分治:多个子 Agent 各持一份小而聚焦的上下文独立处理,汇总结论;
- 外置记忆 + 按需检索(RAG/Skills):不预载全部知识,需要时检索进来——渐进式披露正是此思路的产品化;
- 保留出处以便核验:蒸馏结论附引用,使"检索来的事实"可回溯。
辩证视角:该论断描述的是当前模型的行为边界。长上下文注意力改进、记忆架构、长程 agentic 训练都可能移动这条边界——但工程上不能赌模型进步,应按"检索为主、推理为辅"设计,与"原则穿越周期、手段随模型演进"一致。
题 7(★★★):Skills 渐进式披露的"元认知"问题:模型不知道自己不知道什么
关键转换:把"召回"(模型主动想起该加载什么)降级为"识别"(给模型看清单让它认),再对识别本身做工程兜底。
- 目录常驻,描述为触发而写:技能名称 + 一行"何时使用"的描述(触发场景、症状、关键词)常驻上下文,token 成本很小。模型不需要凭空想起某个技能,只需在清单里认出匹配项——识别远比回忆容易;
- 语义路由兜底:不完全依赖模型自觉——harness 用当前任务描述对技能目录做向量检索/关键词匹配,把 top-k 候选技能的描述主动注入,替模型完成"不知道自己不知道"的那一步;
- 失败驱动触发:Agent 连续失败、反复重试或命中特定错误模式时,harness 钩子自动检索并建议相关技能——用行为信号代替内省;
- 阶段式预注入:在已知决策点按任务阶段加载(要写代码了→注入 TDD/调试技能),由框架判断时机而非模型;
- 显式入口:用户可直接点名调用(slash command),覆盖模型判断失误的场景;
- 闭环改进:记录"本应加载却未加载"的案例,反哺技能描述质量——技能描述本身就是触发器。
题 8(★★):动态读取 SKILL 指令后,模型能否遵从?不同模型有何区别?
能否遵从取决于三件事:
- 指令跟随能力:技能内容以"文件读取结果/工具返回"身份进入上下文,模型必须把它当作有约束力的指令而非待处理数据。前沿模型遵从度高;弱模型容易漂移、部分执行、或把指令当资料引用而不照做;
- 位置与竞争:技能指令出现在对话中段,要和系统提示词、用户消息竞争注意力。缓解:技能末尾放强制检查清单、harness 在下一轮复述关键约束、把最硬的规则提升到系统提示层;
- 可执行性设计:技能内容越短、越命令式、越结构化(编号步骤 + 完成判据),遵从率越高;长篇叙述性文档的遵从率显著下降。
模型间的区别:
- 部分模型/框架(如 Claude Code 的 Skills)对技能加载有专门训练与特权注入位置,加载即高优先级指令,遵从是内建行为;
- 没有该机制的模型,技能只是普通文本,遵从完全依赖通用指令跟随能力,随模型规模与训练分布波动很大;
- 上下文短的模型加载大技能后注意力稀释更严重;
- 实践上必须按模型做遵从性评测,并把安全关键约束放在 harness 层用代码强制(护栏),而不是指望模型读到技能后一定照做。
镜像风险:遵从性是把双刃剑——动态加载的内容若被污染(提示注入),模型同样会"遵从"。技能来源必须可信,动态注入的内容要过护栏。
题 9(★★★):工具多且频繁变动的生产系统,如何布局上下文最大化缓存命中?
原理: KV Cache 复用最长公共前缀;工具定义位于系统提示之后的前缀区,工具列表内容或顺序的任何变化,都会使变化点之后的缓存全部作废。设计目标:让前缀尽可能长、尽可能稳,把变动赶到序列后部。
- 稳定度分层排序:序列布局 = 系统提示(永不变)→ 核心工具集(极少变)→ 会话级工具集(会话内不变)→ 动态内容(时间戳、用户信息)一律后置到尾部。越稳定越靠前;
- 固定排序,禁止动态重排:工具按固定键(名称/ID 字典序)排序。想做相关性排序时不动列表物理顺序,改用软排序——在尾部追加一条"本轮推荐工具"消息;
- 追加式注册:会话中途新增工具只追加到列表末尾(前缀仍命中);移除或重排会截断缓存,推迟到会话边界执行;
- 超集策略 / 配置分桶:(a) 定义稳定的工具超集,逻辑上不可用的工具在列表保留、由服务端拒绝调用,用少量 token 换满缓存;(b) 收敛到少数标准"工具配置档",请求按配置档哈希路由到同一缓存实例(前缀感知调度),同档请求互相加热缓存;
- 动态信息逐出前缀:时间戳、用户名、环境状态等高频变化字段绝不放进系统提示,统一注入尾部;
- 变更灰度与度量:工具描述改版灰度发布、新旧并行预热缓存;持续监控每请求的缓存命中率/缓存读取 token,配置变更引发回退即告警——把缓存命中率当作和延迟、成本同级的一级指标。
附:全题结论速览
| # | 问题 | 核心结论 |
|---|---|---|
| 1 | 历史管理三难 | 稳定前缀+只追加;控制"进入"而非"删除";尾部状态块零缓存代价防重复;低频压实摊还缓存失效 |
| 2 | 思维链保留 | 重置点从"用户消息"改为"决策粒度",旧思考蒸馏为决策摘要;R1/V4 反转说明上下文策略与训练配方耦合,非普适定律 |
| 3 | 极端压缩损失 | 风险=意图锁定+压缩器出错+不可验证;解法=原文外置、压缩只是视图、记录型事实逐字保留、可回查 |
| 4 | 状态栏可靠性 | 从事实计算而非记忆誊写:单一事实源、定期对账、可信级别标注、只写隔离、关键决策向环境求证 |
| 5 | 提示词熵增 | 提示词即代码:PR 评审、骨架+分区所有权、lint、回归评测门禁、模块化组装、定期熵审计 |
| 6 | 检索而非推理 | 注入结论不注入原料、推理改造为检索编排、信息塑形、子 Agent 分治、外置记忆按需检索 |
| 7 | Skills 元认知 | 召回降级为识别:目录常驻+触发式描述、语义路由兜底、失败驱动、阶段式预注入、闭环改进描述 |
| 8 | 技能指令遵从 | 取决于指令跟随能力、位置竞争、内容可执行性;有专门训练的框架遵从内建;安全约束靠 harness 强制 |
| 9 | 工具多变的缓存布局 | 稳定度分层、固定排序+软排序、追加式注册、超集/配置分桶+哈希路由、动态信息后置、命中率一级监控 |