模式矩阵 /模式白皮书/P1

P1 · Context Triage · 上下文分诊

字段
双轴坐标 感知 Perception × 路由 Route(选)
成本档 ②(一次轻量优先级判断,不额外起推理链)
课程对应 02-02
目录归属 全集 33 模式之一 · 感知模块 4 模式之一
一句话 候选信息总量超出 context 窗口预算时,决定谁先进、谁等门外、谁压根不预加载。

它解决什么问题

生产级 Agent 的常态不是信息不够,而是信息太多。一个中等 codebase 加三周 git 历史扔进去就是 180K token 起步,企业知识库更是远超任何窗口。当候选信息装不下,最朴素的截断(按文件名排序砍后半段)会留下过期材料、丢掉关键证据,Agent 看着"完整一套"给出错误结论。

上下文分诊把这件事工程化:把所有候选信息分成 P0/P1/P2/P3 四级,从高到低塞,塞到 token 预算耗尽。它管的是单次请求的窗口分配,目标不是"喂给 Agent 完整信息",而是"保证最关键的信息不被淹没"。这两个目标听起来接近,工程做出来差很多。

为什么坐标是「感知 × 路由」

核心机制

一次分诊把候选信息按优先级分层,再用 token 预算切一刀:

级别 典型内容 加载策略
P0 永远加载 system prompt、安全规则、当前任务、业务身份(tenant_id) 占预算 5-10%,超预算也进
P1 有空间就加载 当前文件、最近 tool 结果、错误堆栈 占预算 20-30%
P2 压缩后加载 历史对话、背景文档 压成摘要,占 10-20%
P3 只挂句柄 可访问但不预加载的资源 0 预算,通过工具按需拉

三个工程要点决定分诊的成败。第一,优先级判定的来源有两条路:人工分诊(如 Claude Code 的五级 CLAUDE.md hierarchy,开发者本人把安全规则放 P0、个人偏好放 P2)和算法分诊(如 Aider 的 RepoMap 用 tree-sitter 抽符号、按图算法打分)。第二,错误堆栈受特殊保护,永远不被分诊掉——它是 Agent 的反馈回路,丢了 Agent 会反复犯同一个错。第三,每次分诊决策必须落 trace,否则线上无法判断关键文件是被分诊扔了还是压根没发现。

适合的生产场景

容易出错的地方

关键指标

最小骨架

对候选信息按优先级排序(P0 > P1 > P2 > P3,错误堆栈额外加分):
    逐条塞入:
        P3            → 进句柄池,不预加载
        其余 + 未超预算 → 进 context,累加 token
        其余 + 超预算   → 丢弃(但错误堆栈强制保留)
返回 (进 context 的, 挂句柄的, 一条 TriageDecision)
TriageDecision 留下:时间戳 / 预算 / selected / deferred / dropped / tokens_used

工程落地三处必改:token 估算换成真 tokenizer(len // 4 对中文误差大);错误识别要按领域补关键词;TriageDecision 必须落到 ELK 或 Datadog,每天看 dropped_count 趋势。

企业落地一例

一家区域银行的贷款评审 Agent,标准消费贷(8 份文档)跑得很准。直到一笔商业贷款申请堆进 43 份文档,context 装不下,Agent 按文件名排序做了一刀朴素截断,砍掉的那摞里有 2024 年的抵押物估值报告,留下的那摞里有一份 2019 年早已过期的工商登记拍照件。Agent 看着剩下的"完整一套"给出"建议批准",两周后这笔贷款进入坏账。重写后改为四级分诊:抵押物估值、当前财报这类强证据进 P0/P1,历史登记件按时间衰减降级,并强制保护所有"异常/缺失"标记不被丢弃。问题的根因不是推理不够强,是没教 Agent 谁该先进门。

与其他模式的关系

一句话记住它

上下文分诊不是 prompt 调优,而是操作系统进程调度在 LLM 时代的回响——context window 是稀缺的 CPU 时间,分诊算法就是那个保证最重要的进程不被饿死的调度器。


本页属于 ADPS 33 模式白皮书。返回 模式矩阵与白皮书目录, 或查看配套 可运行代码目录