给 AI Agent 做“上下文减法”:基于副作用边界的运行时路由设计Context Budgeting for AI Agents: Side-Effect-Driven Runtime Routing

• 约 2 分钟 2 min read

在长期使用 AI 编程助手或知识库 Agent 的过程中,很容易陷入一个“规则膨胀”的怪圈:每当 Agent 犯了一次错,我们就在系统提示词(如 AGENTS.md 或 CLAUDE.md)里补一条新规矩。几个月下来,光规则文档就攒了二十多份——从文件命名、标签词表、图片管理、格式校验到写入审批,加起来好几万字。

这时候尴尬的局面就出现了:

  • 如果每次对话启动都把所有协议一股脑塞进 Context Window,不仅首字延迟高、Token 消耗大,更严重的是注意力稀释(Lost in the Middle)——当你只是想问一个简单的概念时,模型脑子里却塞满了十几条它根本用不上的“文件写入审批与图片哈希校验规则”。
  • 反过来,如果完全靠模型自己去目录里乱翻协议,它又常常在真正需要修改文件时漏读关键的安全约束。

为了解决这个矛盾,我在知识库里做了一层很轻量的架构拆分:把启动入口压缩到极简,用一层基于“副作用边界(Side-Effect Boundary)”的 Runtime Router 来按需挂载协议与工具。

核心思路:按“副作用风险”而不是按“话题关键词”路由

很多早期设计喜欢按领域关键词路由,但实际上决定 Agent 需要遵守多少规矩的,不是它在聊数学还是聊编程,而是这次操作会不会对外部世界产生不可逆的副作用。

按照副作用从零到高的光谱,所有任务可以被干净地收敛为几个显式路由(task_type):

路由类型本质动作读写属性必须加载的最小协议集审批边界
query检索并解释既有笔记纯只读仅加载检索协议零审批,直接返回证据路径
rag-query语义混合检索与查重纯只读检索协议 + RAG 降级协议零审批,显式报告索引状态
audit扫描断链、格式与元数据异常纯只读仅加载审计清单零审批,只出报告不自动改文件
inbox-process分析原始输入,提出归档提案只读分析 + 提案分类协议 + Schema停在提案阶段,等待人工确认
note-write创建或实质修改正式笔记持久化写入写入协议 + 样式规范 + 门禁必须确认精确路径与内容后才放行
asset生成或替换技术插图与附件二进制/SVG 写入资产协议 + 图表生命周期协议规格审批与成品审批双阶段分离

这样一来,当你只是让 Agent 查一个知识点(query)或做一次体检(audit)时,它的上下文里根本不会加载任何关于“如何写文件、如何打标签、如何跑写入门禁”的长篇大论;只有当意图真正切换到 note-write 时,才增量加载写入协议。

七条最小读取原则(Minimal Reading Policy)

为了让上下文预算可控,运行时遵循一套简单的加载纪律:

  1. 入口只做路标:启动文件(AGENTS.md)只保留百余行的核心红线与路由表指针,绝不复制具体协议的正文。
  2. 只读优先:只要不涉及磁盘文件改动,一律走最轻量的只读路径。
  3. 条件触发(Conditional Loading):像标签词表、网页剪藏规范、图表视觉 Profile 这类细则,只有当任务真正触及对应动作时才按需拉入。
  4. 作用域叠加(Scope Overlay):局部目录的特殊规则(比如专门针对备考题库的排版要求)只在目标路径命中该目录时才叠加生效,不污染全局。
  5. 切换时只读差集:如果一次对话前半段在查资料(query),后半段决定把结论存成笔记(note-write),中途只补充加载两者的协议差集(Delta),不重复读取已加载的文档。
  6. 先读摘要,按需展开正文:检索时优先读取 Frontmatter 里的 200 字 summary 和元数据,只有强相关候选才打开完整 Markdown 正文。
  7. 未知意图绝不退回“全量加载”:如果意图不明确,直接停下来向人确认,而不是为了保险把整个规则目录全读一遍。

导航与授权解耦:Router 只指路,不赋权

在实现上,路由查询被做成了确定性的 CLI 工具(pnpm run agent:route -- --task-type note-write --json),返回结构化的协议清单、可用工具、前置条件与退出判据:

{
  "schema_version": 1,
  "task_type": "note-write",
  "required_protocols": [
    "80_System/INBOX_PROCESS.md",
    "80_System/SCHEMA.md",
    "80_System/CLAUDE_WRITE_PROTOCOL.md"
  ],
  "read_write": "mixed",
  "approval": {
    "required": true,
    "stages": ["proposal", "batch-registration", "preflight", "seal"]
  }
}

这里有一条至关重要的安全不变量:Router 的输出只是“导航地图”,绝对不是“写入许可证”。

所有会修改文件的路由都受同一个单向状态机约束:

read-only (只读分析)
  → proposal-required (输出完整修改提案)
  → final-approved (人类明确批准路径与内容)
  → registered (登记批准批次与写前文件哈希)
  → preflight-passed (写前校验通过)
  → written (执行落盘)
  → sealed (严格审计通过并封存写后哈希)

任何一步缺少前置状态,工具层都会直接阻断(Fail-Closed)。把“上下文按需减法”和“确定性状态机门禁”结合起来后,日常对话既保持了极低的 Token 开销和响应速度,又在真正动刀改文件时守住了 100% 的可追溯与可回滚边界。

Anyone who uses coding or knowledge-base AI agents over a long period eventually runs into protocol bloat: every time the agent makes a mistake, we add another rule to AGENTS.md or CLAUDE.md. After a few months, the system directory has accumulated over twenty protocol files—covering naming conventions, tag taxonomies, figure registries, markdown linting, and write approvals—totalling tens of thousands of words.

This creates a painful tradeoff:

  • If you preload every protocol into the context window at the start of every session, you pay high time-to-first-token and token costs, while suffering severe attention dilution (Lost in the Middle)—when you just want to ask a quick conceptual question, the model’s working memory is cluttered with rules about SVG SHA256 hashes and batch write gates.
  • Conversely, if you leave the agent to browse protocol files ad hoc, it frequently misses critical safety invariants right when it’s about to modify files on disk.

To resolve this tension, I introduced a lightweight architectural split: shrink the entry prompt down to a minimal signpost, and use a side-effect-driven Runtime Router to mount protocols and tools strictly on demand.

Core Idea: Route by Side-Effect Boundary, Not by Topic Keywords

Early agent routers often classify tasks by domain keywords (math vs. networking vs. frontend). In practice, what determines which rules an agent must load is not the subject matter, but whether the operation can cause irreversible side effects on disk.

Ordered along a spectrum from zero side effects to persistent state mutation, every task maps cleanly to an explicit task_type:

Route (task_type)Core ActionRead/Write ModeMinimum Required ProtocolsApproval Boundary
queryRetrieve and explain existing notesStrictly read-onlyQuery protocol onlyZero approval; return evidence paths directly
rag-queryHybrid semantic retrieval & deduplicationStrictly read-onlyQuery + RAG degradation protocolsZero approval; explicitly report index health
auditScan for broken links, schema, or style driftStrictly read-onlyAudit checklist onlyZero approval; emit report without auto-fixing
inbox-processAnalyze raw inputs and propose filingRead + ProposalClassification protocol + SchemaHalts at proposal stage; awaits human confirmation
note-writeCreate or materially update structured notesPersistent writeWrite protocol + Style rules + Batch gateRequires explicit path & content approval before write
assetGenerate or replace technical figures/assetsBinary/SVG writeAsset protocol + Figure lifecycle protocolTwo-stage approval (specification + final visual verification)

When you simply ask the agent to look up a concept (query) or run a health check (audit), zero lines of file-writing, tagging, or batch-gating instructions ever enter its context window. Write protocols are loaded incrementally only when the task transitions to note-write.

Seven Minimal Reading Principles

To keep the context budget tight and predictable, the runtime enforces seven loading rules:

  1. Entry point as signpost only: AGENTS.md stays under ~150 lines of core invariants and routing pointers, never duplicating full protocol bodies.
  2. Read-only by default: Any task that does not mutate disk state takes the lightest read-only route.
  3. Conditional loading: Specialized rules—like the controlled tag vocabulary, web clipping provenance, or figure visual profiles—are pulled in only when the task actually touches those actions.
  4. Scoped overlays: Directory-specific rules (such as exam-prep formatting rules) apply only when the target path falls inside that scope, never polluting global tasks.
  5. Delta-only loading on route upgrades: If a session starts as a read-only query and later upgrades to note-write, the agent loads only the set difference (delta) of required protocols without re-reading already loaded files.
  6. Summaries before full bodies: Retrieval reads the 200-character frontmatter summary and metadata first, opening full Markdown bodies only for top candidates.
  7. Never fall back to “load everything” on ambiguity: If user intent is unclear, pause and ask one clarifying question rather than dumping the entire system folder into context.

Decoupling Navigation from Authorization

Under the hood, routing is exposed as a deterministic CLI command (pnpm run agent:route -- --task-type note-write --json) that returns the exact protocol list, allowed tools, preconditions, and exit criteria:

{
  "schema_version": 1,
  "task_type": "note-write",
  "required_protocols": [
    "80_System/INBOX_PROCESS.md",
    "80_System/SCHEMA.md",
    "80_System/CLAUDE_WRITE_PROTOCOL.md"
  ],
  "read_write": "mixed",
  "approval": {
    "required": true,
    "stages": ["proposal", "batch-registration", "preflight", "seal"]
  }
}

A critical security invariant governs this design: Router output is a navigation map, never a write permit.

Every write-capable route is enforced by a one-way approval state machine:

read-only (analysis)
  → proposal-required (emit full path & content proposal)
  → final-approved (explicit human approval of exact paths)
  → registered (record batch & pre-write hashes)
  → preflight-passed (pre-write validation clean)
  → written (files written to disk)
  → sealed (strict post-write audit passed & output hashes sealed)

If any prerequisite state is missing, the tooling fails closed. Combining context budgeting via side-effect routing with a deterministic approval state machine keeps everyday queries fast and cheap while guaranteeing 100% traceability and rollback safety whenever files are touched.