context-mode 强制路由规则解析:在 Kiro 上守护 AI 编码 Agent 的上下文窗口
2026/9/13 19:22:24 网站建设 项目流程

context-mode 强制路由规则解析:在 Kiro 上守护 AI 编码 Agent 的上下文窗口

【免费下载链接】context-modeContext window optimization for AI coding agents. Sandboxes tool output (98% reduction), persists session memory, and enforces routing across 17 platforms via MCP + hooks.项目地址: https://gitcode.com/GitHub_Trending/cl/context-mode

导读

configs/kiro/KIRO.md是 context-mode 为 Kiro 平台(IDE/CLI)准备的强制路由规则文件,它规定了 Agent 在 Kiro 上必须遵循的工具调用纪律:未加路由的原始命令可能一次性向上下文窗口倾倒约 56 KB 数据,而本规则把"分析"从"读取"中剥离出来,用沙箱工具只把最终答案送进上下文。读完本文,你将掌握 KIRO.md 的完整规则体系(Think in Code、BLOCKED/REDIRECTED 清单、五级工具选择层级、并发批处理与记忆检索约定),并理解它在仓库中对应的适配器与 Hook 实现原理,可直接把该文件部署到~/.kiro/steering/中获得确定性注入。

为什么 Kiro 需要强制路由规则

AI 编码 Agent 的上下文窗口是有限资源。每一次工具调用的原始输出——命令回显、HTTP 响应体、搜索结果、文件全文——都会完整进入对话记忆,并在会话剩余时间里持续占用推理容量。在 Kiro 上,一次未路由的命令输出可以膨胀到约56 KB,多次累积就会让窗口迅速被噪声填满,模型在关键决策点反而"看不清"真正重要的内容。

KIRO.md 的定位正是解决这个问题的强制纪律文件(MANDATORY routing rules)。它通过与 context-mode 的 MCP 工具集配合,把「分析数据」的职责从 Agent 的上下文窗口转移到沙箱进程:原始字节留在沙箱里,只有console.log()的派生结果进入对话。

从源码看,这个文件的部署方式由适配器直接支持:src/adapters/kiro/index.tsgetInstructionFiles()返回["KIRO.md"]getRoutingInstructions()则从仓库configs/kiro/KIRO.md读取该文件全文作为默认路由指令;KiroAdapter的注释明确说明,用户可以把该文件复制到.kiro/steering/以选择确定性注入(deterministic injection)。

Think in Code:强制分析纪律

KIRO.md 开篇第一条硬性规则:

凡是分析/计数/过滤/比较/搜索/解析/转换数据,必须写代码:通过@context-mode/ctx_execute(language, code)完成,只用console.log()输出答案。不要直接把原始数据读进上下文。

核心思想是"PROGRAM the analysis, not COMPUTE it"——用程序做分析,而不是把数据读进来"人工计算"。规范要求:

  • 使用纯 JavaScript,仅限 Node.js 内置模块(fspathchild_process);
  • 必须try/catch,正确处理null/undefined
  • 一条脚本可以替代十次工具调用。

这一规则在运行时被注入到每次会话的指令块中。hooks/routing-block.mjscreateRoutingBlock()生成的<priority_instructions>中写有同样表述:"Every byte a tool returns enters your conversation memory and costs reasoning capacity for the rest of the session",并把 Think-in-Code 定义为最高优先级指令。在 Kiro 上,工具名的命名空间由 hooks/core/tool-naming.mjs 统一管理,Kiro 的 MCP 工具以@context-mode/<tool>形式呈现(见TOOL_PREFIXES["kiro"]),这也是整个 KIRO.md 中所有@context-mode/ctx_*工具名的来源。

BLOCKED:被拦截、禁止重试的操作

KIRO.md 明确列出了一类"不要尝试,重试也无用"的操作,它们会被 PreToolUse Hook 直接拦截:

操作替代方案
Shellcurl/wget@context-mode/ctx_fetch_and_index(url, source)@context-mode/ctx_execute(language: "javascript", code: "const r = await fetch(...)")
内联 HTTP(fetch('httprequests.get(requests.post(http.get(http.request(@context-mode/ctx_execute(language, code)——只有 stdout 进入上下文
直接 Web 抓取@context-mode/ctx_fetch_and_index(url, source)后接@context-mode/ctx_search(queries)

这些拦截不是文档纸面声明,而是路由层的真实行为。在 hooks/core/routing.mjs 中可以看到实现细节:检测先剥离引号内内容以避免误报(如gh issue edit --body "text with curl in it",Issue #63),再匹配(^|\s|&&|\||\;)(curl|wget)\s模式;对 curl/wget 采取"允许静默文件下载、拦截 stdout 洪泛"策略(Issue #166)——只有非静默(缺少-s/--silent-q/--quiet)的 stdout 输出才会被重定向,被拦时返回的引导消息会明确建议改用ctx_executectx_fetch_and_index,并注明二者都具备完整网络访问能力,遇到瞬时 DNS 错误(EAI_AGAINETIMEDOUTENETUNREACH)可重试同一次调用。

拦截语义在 Kiro 上通过退出码落地:pretooluse.mjsdeny分支向 stderr 写入原因并以退出码 2 结束(block),allow则以退出码 0 放行,stdout 内容注入 Agent 上下文。

REDIRECTED:被引导进入沙箱的操作

第二类操作不会直接报错,但会被重定向到沙箱工具,取决于 Agent 的使用意图:

Shell(输出 >20 行)——Shell 仅保留给:gitmkdirrmmvcdlsnpm installpip install。其余场景应使用@context-mode/ctx_batch_execute(commands, queries)@context-mode/ctx_execute(language: "javascript", code: "...");只有当代码确实匹配宿主 shell 时才用language: "shell"。路由块中的<when_not_to_use>给出了精确判据:意图处理输出(过滤/计数/解析/聚合)→ 用批处理或沙箱执行;意图观察固定短输出(clean tree 上的git statuswhoamipwd)或变更状态(git、mkdir、rm、mv、导航)→ 继续用 Shell。

fs_read / read(用于分析)——读取是为了编辑→ fs_read 正确;读取是为了分析/探索/总结→ 用@context-mode/ctx_execute_file(path, language, code)。原因很实际:编辑工具需要在上下文里匹配精确字节,而分析只需要结论。routing-block.mjscreateReadGuidance()把这句话做成了一条在读取工具被调用时注入的轻量提示(<context_guidance><tip>)。

grep / search(结果过大)——用@context-mode/ctx_execute(language: "javascript", code: "...")在沙箱里做可移植的过滤与计数。createGrepGuidance()提示:当要计数、过滤或聚合匹配结果(而非抽查一条)时,把搜索放进沙箱执行,原始匹配列表留在沙箱,只有派生答案进入上下文;language: "shell"仅在代码匹配宿主 shell 时使用(Windows 用 PowerShell,Unix 用 POSIX shell)。

五级工具选择层级

KIRO.md 给出了一套优先级明确的工具选择流程,对应注入指令块中的<tool_selection_hierarchy>

  1. MEMORY(记忆)@context-mode/ctx_search(sort: "timeline")—— 恢复会话后,先查历史上下文,再决定是否询问用户;
  2. GATHER(收集)@context-mode/ctx_batch_execute(commands, queries)—— 一次并行运行所有命令、自动建立索引并返回搜索结果,一次调用替代 30+ 次;每个命令形如{label: "header", command: "..."},label 会成为 FTS5 分块标题,描述性 label 能改善后续检索质量;
  3. FOLLOW-UP(追问)@context-mode/ctx_search(queries: ["q1", "q2", ...])—— 把所有问题放进数组一次调用(默认相关性模式),排名流水线按查询逐个执行,往返开销只付一次;
  4. PROCESSING(处理)@context-mode/ctx_execute(language, code)@context-mode/ctx_execute_file(path, language, code)—— 沙箱内执行,只有 stdout 进入上下文;
  5. WEB(网络)@context-mode/ctx_fetch_and_index(url, source)后接@context-mode/ctx_search(queries)—— 原始 HTML 永远不进入上下文;
  6. INDEX(索引)@context-mode/ctx_index(content, source)—— 把内容存入 FTS5 供后续检索。

这六步(文档编号 0–5)构成了完整的"先查记忆 → 批量收集 → 批量追问 → 沙箱处理 → 网络检索 → 主动建索引"闭环,几乎覆盖了 Agent 在真实开发会话中的全部数据消费路径。

并行 I/O 批处理与并发度控制

多 URL 抓取或多 API 调用场景下,KIRO.md 要求始终携带concurrency: N(1–8)

  • @context-mode/ctx_batch_execute(commands: [3+ network commands], concurrency: 5)—— 适用于 gh、curl、dig、docker inspect、多区域云查询;
  • @context-mode/ctx_fetch_and_index(requests: [{url, source}, ...], concurrency: 5)—— 多 URL 批量抓取。

并发度的选择原则非常具体:

  • I/O 密集型(网络调用、API 查询)→ 用4–8
  • CPU 密集型(npm test、build、lint)或共享状态的命令(端口、锁文件、同一仓库写入)→ 保持1
  • GitHub API 速率限制gh调用并发上限为4

这一规则的价值在于把"批处理工具"从"能用"提升到"用得对":并行度太低浪费往返,太高则踩 API 限流或造成端口/锁冲突。

输出规范与会话连续性

输出(Output):产物(代码、配置、PRD 等)必须写入文件,绝不内联输出;返回时只给"文件路径 + 一行描述"。同时为search(source: "label")提供描述性 source 标签,让后续检索能按来源过滤。这正是路由块中<artifact_policy>的表述:Write artifacts to files. Return only: file path + 1-line description

会话连续性(Session Continuity):技能、角色与决策在整个会话期间持续有效,不能随对话增长而丢弃。不过路由块的<session_continuity>对这一点做了更精细的限定:早前捕获的技能/角色/决策是记忆辅助而非常设命令,用户的最新消息始终优先,如果捕获的指令与当前请求冲突,以用户为准——"过去的措辞不约束你"。

Memory:先搜索,再提问

会话历史是持久化且可检索的。恢复会话后,KIRO.md 要求先搜索再问用户

需求命令
我们之前决定了什么?@context-mode/ctx_search(queries: ["decision"], source: "decision", sort: "timeline")
存在哪些约束?@context-mode/ctx_search(queries: ["constraint"], source: "constraint")

明确禁止问"我们之前在做什么?"——先搜。若搜索返回 0 条结果,才按全新会话处理。这个机制在运行时由agentspawn.mjs落地:当事件源为compactresume时,Hook 会加载 SessionDB、读取该会话的持久化事件,写入事件文件并追加buildSessionDirective(source, eventMeta, toolNamer)生成的会话恢复指令;startup时会清理过期会话(cleanupOldSessions(7))并建立新的 session 记录。

ctx 命令表

KIRO.md 内嵌了一套可直接对用户使用的命令表,全部通过 MCP 工具实现:

命令行为
ctx stats调用statsMCP 工具,原样显示完整输出
ctx doctor调用doctorMCP 工具,执行返回的 shell 命令,以清单形式展示
ctx upgrade调用upgradeMCP 工具,执行返回的 shell 命令,以清单形式展示
ctx purge调用purgeMCP 工具并传confirm: true,清空知识库前给出警告

特别约定:执行/clear/compact之后,知识库与会话统计被保留;如需全新开始,使用ctx purge。路由块中的<ctx_commands>还补充了命令变体与行为细节(如ctx-stats/ctx-stats、context savings 问题均触发 stats),并规定/clear/compact后应告知用户"context-mode knowledge base preserved. Usectx purgeto start fresh"。

仓库中的实现:适配器、Hook 与配置文件

适配器与平台能力

Kiro 的支持由 src/adapters/kiro/index.ts 中的KiroAdapter实现,其关键平台事实:

  • Hook 范式json-stdio,Hook 注册在 Agent 配置文件~/.kiro/agents/<name>.jsonhooks键下;
  • 配置~/.kiro/settings/mcp.json(JSON 格式),MCP 通过其中的mcpServers完整支持;
  • Hook 退出码0=allow2=block
  • 能力边界canModifyArgs: false——Kiro CLI 只用退出码,无法修改工具输入,因此路由的modify分支在pretooluse.mjs中会把更新后的命令拆出提示文本写入 stderr 并以退出码 2 拒绝("deny with redirect message");
  • 会话目录~/.kiro/context-mode/sessions/
  • 路由文件KIRO.md

测试 tests/adapters/kiro.test.ts 验证了这些契约:agentSpawn被映射为 SessionStart(supports sessionStart via agentSpawn)、parsePreToolUseInput解析execute_bash工具名、generateHookConfig生成的 matcher 同时包含execute_bash@context-mode/ctx_executeHOOK_SCRIPTSagentSpawn映射到agentspawn.mjs

Hook 类型与匹配器

src/adapters/kiro/hooks.ts 定义了四种 Hook 类型:preToolUsepostToolUseagentSpawnuserPromptSubmit,分别映射到hooks/kiro/下的pretooluse.mjsposttooluse.mjsagentspawn.mjsuserpromptsubmit.mjs

PreToolUse 的匹配器数组(PRE_TOOL_USE_MATCHERS)包括:execute_bashfs_read@context-mode/ctx_execute@context-mode/ctx_execute_file@context-mode/ctx_batch_execute,以及一个特殊的外部 MCP 路由匹配器@(?!context-mode/)。这个负向前瞻模式针对 Issue #529:Kiro 的 MCP 工具在线路上形如@<server>/<tool>,该模式会对任何非 context-mode 前缀的外部 MCP 工具(如 slack / telegram / gdrive / notion 类)触发 PreToolUse——否则这些服务器返回的大体积负载(频道历史、文件内容、搜索结果)会绕过路由提示、在 PostToolUse 阶段"为时已晚"地涌入上下文窗口。routing.mjsisExternalMcpTool也相应扩展识别@<server>/前缀形状。

示例配置文件

仓库提供了可直接对照的完整配置:

  • configs/kiro/agent.json:Agent 配置文件示例,preToolUse使用管道符合并的匹配器(含外部 MCP 负向前瞻),postToolUse*全匹配,命令为context-mode hook kiro pretooluse/posttooluse
  • configs/kiro/mcp.json:MCP 注册示例,把context-mode服务器指向command: "context-mode"

各 Hook 脚本职责

  • agentspawn.mjs:Kiro 的agentSpawn等价于 Claude Code 的 SessionStart,在 Agent 加载时触发一次,负责注入路由块(createRoutingBlock,其中工具名经由createToolNamer("kiro")生成@context-mode/ctx_*形式)以及恢复/压缩场景下的会话恢复指令;输出形状为{ hookSpecificOutput: { hookEventName: "agentSpawn", additionalContext } }
  • pretooluse.mjs:调用routePreToolUse(tool, toolInput, projectDir, "kiro", sessionId)得到决策,按deny(退出码 2 + stderr 原因)、modify(Kiro 无法改输入 → 拆出提示文本后以退出码 2 拒绝)、context(stdout 注入附加上下文,退出码 0)、ask(Kiro 无 ask 概念 → 直接放行)分发;
  • posttooluse.mjs:非阻塞的会话事件捕获,注释明确要求必须在 20ms 内完成——不联网、不调 LLM,只做 SQLite 写入;extractEvents从工具名/输入/响应中抽取事件后经attributeAndInsertEvents落库;
  • userpromptsubmit.mjs:捕获用户提示用于连续性,自动跳过<task-notification><system-reminder><context_guidance><tool-result>等系统消息,其余提示作为user_prompt事件入库并做项目归属解析。

安装与使用前提

要将这套规则投入 Kiro 环境,前提是完成 context-mode 在 Kiro 上的安装与注册(配置示例见上文两个文件):

  1. 将 context-mode 注册到 Kiro 的 MCP 配置(~/.kiro/settings/mcp.jsonmcpServers,命令为context-mode),使@context-mode/ctx_*工具可用;
  2. ~/.kiro/agents/<name>.jsonhooks下配置preToolUsepostToolUseagentSpawnuserPromptSubmitagentSpawnpreToolUse为必需项,postToolUseuserPromptSubmit为可选项,见hooks.tsREQUIRED_HOOKS/OPTIONAL_HOOKS);
  3. 可选:把本文件复制到.kiro/steering/启用确定性注入;Hook 未配置时,KiroAdapter.validateHooks()会给出context-mode upgrade的修复提示,checkPluginRegistration()则检查 MCP 注册状态。

完成上述部署后,Kiro 上的 Agent 将在每次启动时收到路由指令块,遵循本文所述的强制规则:原始输出留在沙箱,只有派生答案进入上下文窗口。

【免费下载链接】context-modeContext window optimization for AI coding agents. Sandboxes tool output (98% reduction), persists session memory, and enforces routing across 17 platforms via MCP + hooks.项目地址: https://gitcode.com/GitHub_Trending/cl/context-mode

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询