# 推理偏移、监督机制与上下文预算管理 > **背景**: Yandex 研究者 Rodionov (2026.04) 发现 LLM 在长上下文中不是"找不到信息",而是"主动减少思考量"——推理 token 缩水高达 53%,且推理能力越强的模型偷懒越严重。 > **影响**: 所有 Agent 框架(包括 lambdagentpaas)的 ReAct 循环和多步管道都受此影响。 > **应对**: lambdagentpaas 的三层防御——形式化保证(不依赖模型行为)、架构抗偏移(短上下文设计)、运行时监督(CEK Yield 注入)。 --- ## 一、推理偏移:模型在偷懒,不是在犯错 ### 核心发现 Rodionov 的《Reasoning Shift》论文揭示了一个反直觉的现象: ``` 实验: 同一道奥数题,在不同上下文条件下让 LLM 做 基线 (干净): 准确率 74.5%, 推理 token 28,771 + 64K 莎士比亚: 准确率 67.8%, 推理 token 16,415 ← 缩水 43%! 模型完全知道莎士比亚无关 ("这跟几何题无关,专注几何") 但还是少想了 43% ``` **关键数据**: | 指标 | 发现 | 含义 | |------|------|------| | 推理 token 缩水 | 最高 53% (Qwen 深度思考) | 模型不是想错了,是想少了 | | 自我检查率 | 43% → 32% | 模型跳过了验证步骤 | | 128 token 触发 | 仅 2-3 句话就砍掉 18% 推理 | 极其敏感的偷懒机制 | | 能力越强越偷懒 | 深度思考模式缩短 53% vs 普通模式 19% | 训练推理能力加剧了偷懒 | | "wait/but/maybe" 频率 | 下降 50-75% | 犹豫、自我质疑被系统性砍掉 | ### 两种"失败"的区分 ``` 致命失败 (结构性错误): API 返回 500 / 解析异常 / 工具崩溃 → 模型无法继续 → lambdagentpaas 的 lint/type_check 可在编译时拦截 推理偏移 (认知节省): 模型看到长上下文 → 主动减少思考量 → 跳过自我验证 → 该深入的地方草草带过 → 不报错、不坦白、只是极其自信地给出敷衍的答案 → 这是最危险的——你无法从输出中看出它偷懒了 ``` ### 对 Agent 系统的影响 ``` 所有依赖 LLM 多步推理的系统都受影响: ReAct 循环: Step 1-3: 上下文短 → 推理充分 Step 8-10: 上下文长 → 推理缩水 → 选错工具/跳过验证 Step 15-20: 推理严重衰减 → 回答质量不可预测 多智能体协作: 第 1 轮 GroupChat: 每个 Agent 推理充分 第 5 轮: 对话历史累积 → 后面的 Agent 开始敷衍 第 10 轮: 综合质量远不如单 Agent 执行 LLM Wiki Ingest: 前 100 个文件: 实体提取全面 第 500 个文件: 提取开始变粗糙 (如果上下文累积) ``` --- ## 二、为什么 lambdagentpaas 的架构天然抗偏移 ### 2.1 形式化保证不依赖模型行为 ``` 模型偷不偷懒,以下保证都成立: 类型安全 (T-Compose): output(f) <: input(g) → 不管模型输出什么质量的内容 类型不兼容在编译时就拦截,不进入运行时 成本上界 (分级类型): 跑 20 步 Opus = $0.27 → 不管模型推理多深或多浅 上界是数学计算,不是模型行为的函数 终止性 (Theorem 5.4): fix_n 在 n 步后终止 → 不管模型是否找到答案 即使模型每步都在偷懒,也不会无限运行 并行安全 (Proposition 30): writes(f) ∩ writes(g) = ∅ → 不管模型输出什么 Store independence 是静态分析,不受推理质量影响 ``` **这就是形式化方法的价值**:模型行为不可靠时,数学保证仍然可靠。 ### 2.2 LLM Wiki 模式:短上下文设计 论文发现推理偏移的触发条件是**上下文长度**。LLM Wiki 的设计恰好规避了这个条件: ``` 传统 RAG: Query 时: 塞 5 个文档块 (几千 token) → 上下文长 → 触发偏移 用户问 "有哪些安全风险?" → 检索 5 个原始文档块 (每个 500 token = 2500 token) → 塞进 prompt → 总上下文 ~4000 token → 论文数据: 即使 128 token 就能砍掉 18% 推理深度 LLM Wiki 模式: Ingest 时: LLM 在短上下文中阅读单个文件 → 写 wiki 页面 每次 Ingest 只看一个文件 → 上下文短 → 不触发偏移 知识被"编译"成结构化 wiki → 以后不需要重新处理 Query 时: 读 index.md → 只读 2-3 个 wiki 页面 wiki 页面是已编译的精华 (比原始文档短 5-10 倍) → 上下文更短 → 推理偏移更小 → 而且 wiki 的交叉引用已经建好,不需要 LLM 自己推理关联 本质: 把"一次长上下文推理"拆成了"多次短上下文编译 + 一次短上下文查阅" ``` ### 2.3 三层编程模型限制上下文增长 ``` Layer 1 — Skill (原子能力): 每个 Skill 是独立的短任务 上下文 = Skill 自己的 prompt + 当次输入 不累积历史 → 不触发偏移 例: answer-generator Skill 每次只看 "检索到的 wiki 页面 + 问题" 不看之前所有的对话历史 Layer 2 — Pattern (协作模式): fan_out_merge: 每个并行分支独立执行,上下文不共享 → 3 路并行中每路只看自己的上下文 → 不会因为分支 A 的输出让分支 B 的上下文变长 review: 每轮审查是独立的 LLM 调用 → 审查者只看"当前回答 + 参考原文" → 不累积前几轮的审查历史 escalation: 每级只看上一级的最终结果 → L2 不看 L1 的完整推理过程 → 上下文不膨胀 Layer 3 — Orchestration (YAML 编排): 声明式编排把大任务拆成小步骤 每步的上下文是 YAML 定义的,受控的 不会出现"整个任务历史塞进一个 prompt" ``` ### 2.4 CEK Machine 的结构化执行 ``` Python 递归调用栈: 整个 ReAct 循环共享一个上下文 Step 1 的输出 + Step 2 的输出 + ... 全部累积 → 上下文线性增长 → 推理偏移线性加剧 CEK Machine: 每个 Yield 点是一个状态快照 ⟨C, E, K, σ, c⟩ 上下文 E 可以在 Yield 点被压缩/重置 → 上下文增长可控 → 在偏移信号出现时主动干预 ``` --- ## 三、三级监督机制 lambdagentpaas 的 CEK Yield 机制天然支持在 Agent 执行过程中注入监督。 ### Level 1: 规则监督(已实现) 编译时和运行时的自动化检查,不需要 LLM 参与: ``` 编译时: lint (26 规则): "没有 terminate 工具,会死循环" type_check: "Stage 2 输出 Json, Stage 3 期望 Str" cost_predict: "这个管道最多花 $0.42,成功率 63%" store_independence: "两个并行 Agent 写同一个 key" 运行时 (CEK Yield 点): 成本熔断: machine.state.cost.money > budget → 暂停 循环检测: 连续 3 步 state hash 相同 → 停止 步数上限: step_count > max_steps → 终止 特点: 零 LLM 成本,毫秒级,确定性 局限: 不理解内容,只检查结构和数值 ``` ### Level 2: 模型监督(可实现) 用一个轻量 LLM 作为"监督者",每 N 步检查 Agent 的输出质量: ``` 实现方式: class SupervisedCEKEngine(CEKEngine): def __init__(self, supervisor_llm, supervise_every=3, **kwargs): self.supervisor = supervisor_llm self.supervise_every = supervise_every def execute(self, term, input_val, ctx, **opts): machine = AgentCEKMachine(...) machine.load(term, input_val) step = 0 while not machine.state.is_terminal(): transition = machine.step() step += 1 # Level 1 检查 (已有) self._check_cost_budget(machine) self._check_loop(machine) # Level 2 检查 (新增): 每 N 步用监督 LLM 检查 if step % self.supervise_every == 0: verdict = self._supervise(machine.state, transition) if verdict.action == "STOP": break elif verdict.action == "CORRECT": machine.state.control = verdict.corrected_value elif verdict.action == "COMPRESS": machine.state.env = self._compress_context(machine.state.env) 监督者的检查内容: 1. 推理偏移检测: "当前输出 (500 token) 比第 1 步 (2000 token) 短 75%,可能存在推理缩水" → 建议: COMPRESS (压缩上下文后重试) 2. 方向偏离检测: "Agent 连续 3 步在搜索无关关键词,偏离了原始目标" → 建议: CORRECT (注入纠正信息) 3. 质量衰减检测: "回答中缺少来源引用,且置信度异常高 (偷懒的典型特征)" → 建议: 要求 Agent 重新检查并补充引用 成本: 主 Agent (Opus): $0.015/次 监督者 (Haiku): $0.00025/次 (便宜 60 倍) 每 3 步监督一次: 额外成本 ≈ 主 Agent 的 2% ``` ### Level 3: 人类监督(可实现) CEK Yield 暂停 → 推送给人类审批 → 等待确认后继续: ``` 实现方式: class HumanSupervisedEngine(CEKEngine): def __init__(self, approval_callback, require_approval_for=None, **kwargs): self.approval_callback = approval_callback self.require_approval = require_approval_for or [ "WriteFile", "EditFile", "Bash", "DeleteFile" ] # 在 Yield(tool) 点检查是否需要人类审批 if transition.label.kind == LabelKind.TOOL: if transition.label.name in self.require_approval: approved = await self.approval_callback({ "tool": tool_name, "input": transition.label.input, "cost_so_far": machine.state.cost, }) if not approved: break # 人类拒绝 → 终止 适用场景: - Agent 要删除生产数据库 → 暂停,推送给人类确认 - Agent 要修改敏感配置文件 → 暂停,人类审阅 diff - WikiIngest 发现矛盾 → 暂停,人类判断哪个版本正确 成本: 最贵但最安全 适用于高风险操作(不是每步都需要) ``` ### 三级监督的成本效益对比 ``` 场景: Agent 跑 20 步,第 5 步走错方向 不监督: 20 步全跑完 → 第 5-20 步全浪费 → $0.06 → 结果错误 Level 1 (规则): 第 10 步检测到循环 → 停止 $0.03 → 结果仍然错误,但省了钱 Level 2 (模型): 第 6 步监督者发现方向错 → 纠正 Agent 从第 7 步走对 → 第 12 步完成 $0.04 + $0.002 (监督成本) → 结果正确 Level 3 (人类): 第 5 步人类发现走错 → 手动纠正 Agent 从第 6 步走对 → 第 10 步完成 $0.03 + 5 秒人类注意力 → 结果正确且最优 ``` --- ## 四、推理偏移检测器 ### 设计原理 基于 Rodionov 论文的发现,推理偏移有可量化的症状: ``` 症状 1: 输出长度递减 正常: Step 1 → 2000 token, Step 5 → 1800 token, Step 10 → 1600 token (缓慢下降) 偏移: Step 1 → 2000 token, Step 5 → 1200 token, Step 10 → 600 token (加速下降) 症状 2: 自检词消失 正常: "wait" 11%, "but" 46%, "maybe" 23% 偏移: "wait" 5%, "but" 20%, "maybe" 9% 症状 3: 首答到终结的距离缩短 正常: 找到答案后继续验证 (43% 概率) 偏移: 找到答案后直接输出 (68% 概率) 症状 4: 置信度异常升高 正常: "我认为...""可能是...""根据文档..." 偏移: "答案是...""显然...""毫无疑问..." (偷懒的模型反而更自信) ``` ### 检测指标 ``` 推理密度 (Reasoning Density): RD(step) = output_tokens(step) / max(output_tokens(step_1), 1) RD ≈ 1.0: 推理深度保持 RD < 0.5: 推理深度衰减 50%+,高度疑似偏移 推理密度衰减率 (Decay Rate): DR = (RD(step_1) - RD(step_n)) / n DR < 0.02/步: 正常衰减 DR > 0.05/步: 快速衰减,偏移确认 自检词频率 (Self-Check Frequency): SCF(step) = count("wait"|"but"|"maybe"|"however"|"等一下"|"不过"|"也许") / total_words SCF 基线: 从 Step 1 采样 SCF < 基线 × 0.5: 自检行为被砍掉一半,偏移确认 综合偏移分数 (Shift Score): SS = 0.4 × (1 - RD) + 0.3 × DR_normalized + 0.3 × (1 - SCF/SCF_baseline) SS < 0.2: 正常 SS 0.2-0.5: 轻度偏移 (告警) SS > 0.5: 重度偏移 (干预) ``` ### MCP 工具接口 ``` 工具名: monitor_reasoning_shift 输入: { "trace": [ {"step": 1, "input_tokens": 500, "output_tokens": 2000, "output_text": "..."}, {"step": 2, "input_tokens": 2500, "output_tokens": 1800, "output_text": "..."}, ... ] } 输出: { "shift_score": 0.62, "severity": "HIGH", "reasoning_density": [1.0, 0.9, 0.75, 0.5, 0.3], "decay_rate": 0.175, "self_check_frequency": [0.11, 0.09, 0.06, 0.04, 0.02], "onset_step": 3, "recommendation": "Step 3 后推理密度下降 65%。建议: (1) 在 Step 3 压缩上下文 (2) 拆分为两个独立子任务 (3) 对 Step 4+ 的输出启用 Guard 验证" } ``` --- ## 五、上下文预算管理 ### 扩展成本分级 在原有的 `CostGrade(p, p_fatal, t, l, m)` 基础上,新增上下文负载维度: ``` 扩展后: CostGrade(p, p_fatal, t, l, m, context_tokens, context_load) context_tokens: 累积输入 token 数(所有步骤的 input 之和) context_load: = context_tokens / model_context_window context_load 是推理偏移的先导指标: < 30%: 安全区 → 推理偏移风险低 30-60%: 警戒区 → 开始出现轻度偏移 60-80%: 危险区 → 推理密度可能衰减 30-50% > 80%: 红线区 → 推理偏移几乎必然发生 ``` ### 上下文预算规则 ``` 每个 Agent 编译时计算上下文预算: ReAct 循环 (maxSteps=10, Sonnet 200K window): 每步估算: system_prompt (2000) + history (step × 1500) + tools (500) Step 1: 2000 + 0 + 500 = 2,500 (1.25% load) → 安全 Step 5: 2000 + 7500 + 500 = 10,000 (5% load) → 安全 Step 10: 2000 + 15000 + 500 = 17,500 (8.75% load) → 安全 结论: 10 步 Sonnet 循环的上下文负载始终 < 10%,偏移风险低 GroupChat (5 agents, maxRounds=10): 每轮: 5 agents × 1500 token/轮 = 7,500 10 轮: 75,000 token → 37.5% load → 进入警戒区! 建议: 第 6 轮后启用上下文压缩 (smart windowing) Pipeline 5 级 (每级 Opus 调用): 每级输入: 上一级输出 (约 3000 token) + system_prompt (2000) → 上下文不累积 (每级是独立调用) → 始终安全 这是 Pipeline 相比 ReAct 的天然优势: 上下文不膨胀 ``` ### 上下文压缩策略 ``` 当 context_load 超过阈值时的自动干预: 策略 1: Smart Windowing (已有) 保留: system_prompt + 最近 N 步 + 关键中间结果 丢弃: 早期步骤的完整输出 → context_load 回落到 30% 以下 策略 2: Summary Compaction 对早期历史做摘要: "Step 1-5 完成了文件读取和初步分析,发现 3 个关键问题: ..." 替换原始历史 → 信息保留但 token 大幅减少 → 需要额外 1 次 LLM 调用 (用便宜模型) 策略 3: Context Reset (最激进) 在 CEK Yield 点完全重置上下文 只保留: 当前任务目标 + 到目前为止的最终结果 → context_load 回到接近 0% → 最有效但可能丢失细节 自动选择: context_load < 30%: 不压缩 30-60%: Smart Windowing 60-80%: Summary Compaction > 80%: Context Reset ``` --- ## 六、与 Harness Engineering 的关系 ### 文章的论点 Rodionov 和 Anthropic 的研究暗示:如果能从模型内部解决推理偏移(通过情绪向量注入等手段),外部的 Harness(Todo list/Checkpoint/子代理验证)就不再需要。 ### lambdagentpaas 的定位 ``` 会过时的 (外部约束): ✗ Todo list 强制模型按步骤做 ✗ Checkpoint 定期验证中间结果 ✗ 子代理交叉验证 ✗ 上下文压缩/窗口管理 → 模型足够可靠后,这些都是多余的脚手架 不会过时的 (lambdagentpaas 核心): ✓ 类型安全 → 数学定理,和模型行为无关 ✓ 成本上界 → 算术计算,和推理深度无关 ✓ 终止性保证 → Y 组合子性质,和模型质量无关 ✓ 并行安全 → 集合论性质,和上下文长度无关 ✓ Skill/Pattern 架构 → 短上下文设计,天然限制偏移触发条件 ✓ LLM Wiki → 知识编译模式,根本不依赖长上下文推理 关键区别: Harness = "管住一个不可靠的模型" → 模型可靠后不需要 λA 类型系统 = "数学保证组合的正确性" → 永远需要 ``` ### 两层护城河 ``` 第一层 (短期): 模型还在偷懒 → 推理偏移检测 + 三级监督 + 上下文预算管理 → 这是当前有价值的能力 → 随着模型进化,这层价值会递减 第二层 (永久): 不管模型多完美 → 类型检查: output(f) <: input(g) 是数学事实 → 成本预测: 20 步 × $0.015 = $0.30 是算术事实 → 终止性: fix_20 在 20 步后终止是定理 → 这些和模型是否偷懒完全无关 → 这层价值永不递减 ``` --- ## 七、总结 ``` 推理偏移的本质: 不是 bug,不是能力不足 是模型学到的"认知节省策略"——省力但不报错 越聪明的模型越会偷懒(因为它知道怎么走捷径) lambdagentpaas 的三层防御: Layer A — 架构抗偏移 (天然): LLM Wiki 短上下文编译 Skill 独立执行 Pattern 分支隔离 → 从结构上限制上下文增长,不给偏移可乘之机 Layer B — 运行时监督 (CEK Yield): Level 1 规则: 成本熔断 + 循环检测 (零成本) Level 2 模型: 监督 LLM 每 N 步检查 (低成本) Level 3 人类: 高风险操作暂停审批 (高安全) → 在偏移发生时实时检测和干预 Layer C — 形式化保证 (永久): 类型安全 + 成本上界 + 终止性 + 并行安全 → 不依赖模型行为,数学保证永远成立 → 即使模型偷懒到极致,这些保证仍然有效 这就是为什么 lambdagentpaas 不怕"Harness 被模型进化吞没": Harness 是外部脚手架 → 会被淘汰 λA 类型系统是数学定理 → 不会被淘汰 推理偏移检测是过渡期工具 → 有当前价值 LLM Wiki 是架构选择 → 天然抗偏移 ```