如何为 context-mode 编写符合 ADR-0002 风格契约的 ctx_* 工具描述?
2026/9/13 6:07:41 网站建设 项目流程

如何为 context-mode 编写符合 ADR-0002 风格契约的 ctx_* 工具描述?

【免费下载链接】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

context-mode 通过server.registerTool()在 src/server.ts 中注册 11 个ctx_*MCP 工具,每个工具的description字段都会被 Claude、GPT、Gemini、Llama 等各类宿主 LLM 在工具选择时读取。项目用 docs/adr/0002-tool-description-style.md(下称 ADR-0002)锁定了这些描述必须遵循的结构与用词规则,并由 tests/core/server.test.ts 中名为tool description style contract (#683 ADR-0002)的静态契约测试在每次提交时逐条校验。

这篇文章面向要在本仓库新增ctx_*工具或重写某个现有工具描述的开发者:任务是产出一段能直接通过契约测试的描述文本。规则来源只有两处——ADR-0002 的 Decision 与 Canonical structure 章节,以及契约测试的断言本身;两者冲突时,测试是最终裁判(ADR 中也明确“this section is the source of truth”,测试在每个 commit 上强制每条规则)。

描述写在哪个位置,测试如何扫描它

所有工具描述都在src/server.tsserver.registerTool()调用块内,形如:

server.registerTool( "ctx_execute", { title: "...", description: `...`, // 本文要写的部分 inputSchema: ... }, ... )

契约测试的提取逻辑(见 tests/core/server.test.ts)决定了两个硬性格式约束:

  • 工具名必须是"ctx_xxx"形式的独立一行(正则^\s*"(ctx_[a-z_]+)"\s*,\s*$),紧跟在server.registerTool(之后;
  • 描述是description:键下的字符串字面量(模板字符串或+拼接的字符串均可以),扫描到下一个同缩进的inputSchema:/outputSchema:/annotations:行结束。

也就是说,工具名、description:起始行、inputSchema:结束行的排版不能偏离现有 11 个工具的写法,否则测试的提取器直接找不到这个工具(sanity 断言要求至少提取到 11 个ctx_*工具)。

规范结构:WHEN / WHEN NOT / RETURNS / EXAMPLE

除豁免工具外,每个描述必须按以下模板组织(模板来自 ADR-0002 的 Decision 章节):

<1 行标题,≤ 120 字符,祈使句+正面表述> WHEN: - <正面触发条件,逐条列出> WHEN NOT: - <与兄弟工具的正面区分,逐条列出> RETURNS: <agent 调用后看到什么,1-3 行> EXAMPLE: <一个带真实参数的规范调用>

各条规则(对应 ADR-0002 §Canonical structure,测试逐一断言):

  1. 章节顺序固定为WHEN -> WHEN NOT -> RETURNS -> EXAMPLE:正面选择线索必须排在负向区分之前。WHEN NOT:在工具没有兄弟工具歧义时可以省略,其余章节全部必选(测试对WHEN:RETURNS:EXAMPLE:做存在性断言)。
  2. 列表符号只能用 markdown 的-1.1-*一律被拒,原因是这些形式在不同 LLM 家族的 tokenizer 下表现不一致,且契约要求每条 bullet 独立成立、不隐含序号顺序。
  3. 章节头必须是大写 + 冒号、顶格写在行首(测试用^([A-Z][A-Z _]+):提取,任何不在规范集合与豁免集合内的大写章节头都会报错,错误信息会提示“把 CONCURRENCY、TIPS 之类的操作性子指导折进 WHEN:/RETURNS: 的正文里”)。
  4. 每个章节头下的 bullet 用两空格缩进。测试不强制缩进数(LLM 对 2 与 4 空格都容忍),但src/server.ts中所有已发布描述统一用两空格,新描述应保持一致。
  5. 章节之间空一行
  6. 一个工具一个EXAMPLE:。确有双输入形态的工具(ADR 举的例子是ctx_purge的 per-session 与 per-project)允许写两行相邻的EXAMPLE:,但不能与其他章节交错。
  7. RETURNS:头必须独占一行,正文换行缩进在下方。这是测试单独锁定的一条:RETURNS: 只返回你的打印输出这类行内写法会失败,必须写成RETURNS:\n <正文>。注意EXAMPLE:保持行内形式是有意为之的不对称(ADR 模板第 59 行即为EXAMPLE: <one canonical call>)。

一个真实例子是 src/server.ts 中ctx_search的描述(节选,正文省略):

Search a unified knowledge base with a multi-strategy ranking pipeline. ... WHEN: - You want to recall something that exists in storage (...) instead of re-reading raw sources - You have multiple related questions about the same body of knowledge — batch every question into one call - You want to scope the query to one labelled source (pass `source` — partial match is fine) WHEN NOT: - The data you want to query has never been stored in the knowledge base ... RETURNS: Per-query ranked sections with window-extracted snippets. ... EXAMPLE: ctx_search(queries: ["root cause", "proposed fix"], source: "issue-#683")

新写描述时,可以直接对照这一块的排版:标题行、空行、大写章节头、两空格 bullet、RETURNS:头独占一行。

禁用词与保留字

ADR-0002 的 Forbidden tokens 表与测试的FORBIDDEN规则列表一致,描述中不得出现:

禁用词原因(ADR 原文口径)替代写法
MANDATORY:(作开头)开发者政策口吻,不是选择线索角色定义 +WHEN:章节
BLOCKED保留给 ADR-0003 的 CASE B(真实安全/策略限制),见 docs/adr/0003-routing-deny-reasons.md工具描述里本就没有安全限制可表达,删掉即可
PREFER X OVER Y(测试正则精确匹配PREFER THIS OVER把选择框定成取舍用正面WHEN:表述
Do NOT read/use/pull/call肯定句优于否定句(rubric #2)改写为WHEN:/WHEN NOT:条款
Never use禁止式语气改写为WHEN NOT:条款
SESSION STATE子句skill/role 持久化属于 hooks/routing-block.mjs 的职责移到 routing-block 层
/emoji bullet在 Llama/Gemini 家族中分词不一致,且构成负样本泄漏用 prose,如USE concurrency 4-8 for ...

另有一条用词规则:RFC 2119 的 MUST/SHOULD/MAY 层级只允许用于“调用后的义务”(post-call obligations),绝不用于工具选择线索。ADR 给的正例是ctx_upgrade:“you MUST run the returned shell command and display the output as a checklist”——这是对 agent 的调用后契约,不是选择提示。选择线索一律用WHEN:/WHEN NOT:表达。

长度方面:描述 SHOULD ≤ 1,000 字符,硬上限 1,500。

豁免与 carve-out:哪些工具不受某条规则约束

测试代码里的两个集合界定了豁免范围,写描述前先确认你的工具属于哪一档:

  • ctx_statsctx_doctorctx_insight:设计上就是一行最小描述(诊断/GUI 能力,不是路由目标),豁免WHEN:结构要求。
  • ctx_upgrade:豁免WHEN:要求,但允许MUST(post-call obligation 规则)。
  • ctx_purge:不豁免任何规则,但有 allow-list 的额外章节头DESTRUCTIVESCOPESCONTRACT(对应测试中的ALLOWED_EXTRA_SECTIONS,见 tests/core/server.test.ts)。依据是审计 Probe 4 的实证:对这个工具,重表述框架反而保住小模型的参数保真度(Haiku 上 5/5 vs 3/5)。这里的DESTRUCTIVE是准确的用户侧信号,与 rubric 禁止的跨 LLM 偏差式负面框架是两回事。它仍然必须满足完整的WHEN / WHEN NOT / RETURNS / EXAMPLE结构,carve-out 章节只是共存。
  • 遗留别名WHEN TO USE::被接受为过渡形式(ctx_index现在就用它),但新工具必须用WHEN:——测试正则同时匹配两种写法,而 ADR 明确要求新工具用WHEN:

如果你的新需求落在这些豁免之外(比如想要一个新的章节头或一个新的豁免),ADR 明确规定:贡献者不能自创章节名,必须开一个新 ADR 来修订本 ADR,契约测试在 allow-list 更新前会失败,这正是设计意图(“locked to make future PRs ungameable”)。

操作步骤:新增一个 ctx_* 工具描述

  1. src/server.ts按现有registerTool块的排版新增你的工具:server.registerTool(一行,下一行"ctx_your_tool",,再下一个对象里写description:,描述块结束于同缩进的inputSchema:行。
  2. 按规范模板写描述:
    • 标题一行,≤ 120 字符,祈使句、正面表述;
    • WHEN:下列正面触发条件,-符号、两空格缩进;
    • 与兄弟工具有歧义时加WHEN NOT:(没有则省略);
    • RETURNS:头独占一行,正文换行两空格缩进,写清 agent 调用后拿回什么;
    • 行内EXAMPLE: ctx_your_tool(...)一个规范调用;
    • 章节之间空一行;全文 ≤ 1,000 字符(硬上限 1,500)。
  3. 自查禁用词:过一遍上表七个禁用项,确认没有MANDATORY:BLOCKEDPREFER ... OVERDo NOT ...Never useSESSION STATE/MUST只出现在 post-call 义务句里。
  4. 在 PR 描述中引用 ADR-0002——这是 ADR Consequences 章节对新工具的要求。

运行契约测试并解读失败信息

契约测试是纯静态扫描,不做 LLM 调用,因此反馈很快。仓库的pretest脚本会先执行完整构建(npm run build),只想快速校验描述风格时用文件级运行更省时间:

npx vitest run tests/core/server.test.ts -t "tool description style contract"

(完整回归用npm test,即vitest run。)

测试按工具名生成describe(tool.name)分组,每个失败信息都自带定位与整改方向,例如:

  • 禁用词命中:ctx_xxx description (src/server.ts:行号) contains forbidden token 'MANDATORY:' (rule: MANDATORY: opener). <该规则的整改说明>——行号直接指向你该改的位置;
  • 缺章节:ctx_xxx (src/server.ts:行号) missing mandatory section 'WHEN:' per ADR-0002 canonical structure
  • 顺序错误:section 'WHEN NOT:' appears before a sibling that should follow it,并附上四个章节的实际位置值;
  • 非规范大写章节:uses off-spec UPPERCASE sections [TIPS] ... Fold operational sub-guidance ... into WHEN: / RETURNS: prose
  • bullet 违规:bullet uniformity violation: numeric-dot bullet (e.g. '1.') at description-line N

全部通过即说明你的描述满足 ADR-0002;测试同时校验hooks/routing-block.mjshooks/core/routing.mjs两个提示词面,如果你动了这两个文件,同样的禁用词规则(另加<forbidden_actions>NEVERFORBIDDEN- NO X for Y四条)也会在同一个 describe 块中执行。

边界与限制

  • 结构被锁定:想偏离规范结构(新章节头、新豁免)的唯一正路是开新 ADR 修订 ADR-0002 并同步更新测试的 allow-list,测试会先失败、ADR 合并后放行。
  • “训练者语气”的文本(如THINK IN CODEMANDATORY routing rules)不属于工具描述层,按 ADR 的分工应放在 hooks/routing-block.mjs(system-prompt 注入)和CLAUDE.md中。
  • 重写现有工具描述时注意审计结论:风格不能一刀切,ctx_purge的重表述若丢了DESTRUCTIVE/SCOPES/CONTRACT信号会回归 Haiku 上的参数保真度(Probe 4 数据),这类 carve-out 以测试里的 allow-list 为准。

【免费下载链接】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),仅供参考

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

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

立即咨询