news 2026/9/13 7:00:29

context-mode 在 Gemini CLI 中的强制路由规则:GEMINI.md 指令全解与上下文窗口守护机制

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
context-mode 在 Gemini CLI 中的强制路由规则:GEMINI.md 指令全解与上下文窗口守护机制

context-mode 在 Gemini CLI 中的强制路由规则:GEMINI.md 指令全解与上下文窗口守护机制

【免费下载链接】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 通过 Gemini CLI 的 GEMINI.md 指令文件注入一组强制路由规则(MANDATORY routing rules),把模型对工具的使用路径收敛到沙箱化的 MCP 工具之上,从而防止未路由的命令把海量输出灌入上下文窗口。本文以configs/gemini-cli/GEMINI.md为骨架,结合src/adapters/gemini-cli/hooks/gemini-cli/的源码与configs/gemini-cli/settings.json的钩子配置,逐条拆解规则背后的机制、工具选择协议与并发批次用法,并给出可直接落地的实操指引。

为什么需要强制路由:一个未路由命令就灌入 56 KB

GEMINI.md 开篇就给出了这条规则的动机:一条未路由的命令会把 56 KB 原始输出直接塞进上下文窗口。Gemini CLI 的原生工具(如run_shell_commandread_fileweb_fetch)返回的都是未经处理的原始文本,反复调用会迅速耗尽上下文预算,导致模型"忘记"早期指令、产生幻觉或在长会话中退化。

context-mode 的解决思路不是禁止工具,而是路由:把"会吐大量数据的操作"从原生工具重定向到专用的 MCP 沙箱工具,只让经过提炼的结果(通常是 stdout 里的一行答案)进入上下文。这套路由由两个层面共同实现:

  • 钩子层拦截hooks/gemini-cli/beforetool.mjs调用routePreToolUse()(定义于 hooks/core/routing.mjs),对run_shell_command|read_file|read_many_files|grep_search|search_file_content|web_fetch|activate_skill|mcp__plugin_context-mode以及外部mcp__命名空间(负向前瞻mcp__(?!.*context-mode),见 src/adapters/gemini-cli/hooks.ts)做前置审查,命中则返回decision: "deny"或参数改写;
  • 指令层引导:GEMINI.md 告诉模型"哪些操作被拦截、应该改用哪个工具",从模型决策源头减少违规尝试。

Think in Code:用一段脚本替代十次工具调用

GEMINI.md 的第一条强制规则是Think in Code:凡是分析、计数、过滤、比较、搜索、解析、变换数据的任务,都必须通过mcp__context-mode__ctx_execute(language, code)写代码完成,只用console.log()输出答案,禁止把原始数据读进上下文

这条规则背后的原理("PROGRAM the analysis, not COMPUTE it")在于:原生工具链的每次调用都是一次往返,每次都把全量数据带回上下文;而把分析写成一段 JavaScript 代码放进沙箱,数据在沙箱内完成计算,唯一进入上下文的只有console.log打印的那一行结果。约束如下:

  • 使用纯 JavaScript,仅允许 Node.js 内置模块(fspathchild_process);
  • 必须写try/catch,处理null/undefined
  • 一段脚本替换十次工具调用。

代码形式的补充说明在 skills/context-mode/SKILL.md 中有更细的映射表,例如"命中 API 端点"用ctx_execute执行fetch('http://localhost:3000/api/orders'),"读取日志/数据文件做分析"用ctx_execute_file(文件加载进FILE_CONTENT而非上下文)。

BLOCKED:被强制拦截的三类操作

GEMINI.md 明确列出了三类被拦截的操作,模型不得重试,只能走指定替代路径:

被拦截操作拦截特征替代工具
curl / wgetShell 中的curl/wget被拦截ctx_fetch_and_index(url, source)ctx_execute(language: "javascript", code: "const r = await fetch(...)")
内联 HTTPfetch('httprequests.get(requests.post(http.get(http.request(ctx_execute(language, code)——只有 stdout 进入上下文
WebFetch / 网页浏览Gemini 原生web_fetch工具ctx_fetch_and_index(url, source)后再ctx_search(queries)

这些拦截由 hooks/gemini-cli/beforetool.mjs 的routePreToolUse实际执行,并经由 src/adapters/gemini-cli/index.ts 的formatPreToolUseResponse转译为 Gemini CLI 的响应格式——拦截时返回{ decision: "deny", reason: ... }(注意 Gemini CLI 用的是decision字段而非 Claude Code 的permissionDecision)。

ctx_fetch_and_indexctx_execute的价值在于"原始 HTML/网络响应永不进入上下文":抓取与索引在服务端完成,模型拿到的只有后续ctx_search的检索结果。

REDIRECTED:三类操作改走沙箱

对于未被完全封死、但会产生大量输出的操作,GEMINI.md 采取"重定向到沙箱"策略:

  • Shell(输出超过 20 行):Shell 仅保留给gitmkdirrmmvcdlsnpm installpip install这类低噪声命令;其余一律改用ctx_batch_execute(commands, queries)ctx_execute(language: "javascript", code: "...")。只有当代码与宿主机 shell 匹配时才使用language: "shell"
  • read_file(用于分析):区分意图——为了编辑而读文件用read_file正确;为了分析/探索/总结而读文件,改用ctx_execute_file(path, language, code),让文件内容进入沙箱的FILE_CONTENT而不进入上下文。
  • grep / search(结果量大):用ctx_execute(language: "javascript", code: "...")在沙箱内做可移植的过滤与计数。

从源码结构看,这种"编辑 vs 分析"的二分是为了保住read_file在写代码工作流中的低延迟体验,同时把分析型读取挡在上下文之外——这与 skills/context-mode/SKILL.md 中"处理大数据一律用ctx_execute/ctx_execute_file而非 Bash/cat"的总体约定一致。

工具选择协议:六步工作流

GEMINI.md 给出了一套编号的工具选择顺序,用于规范整个会话中的工具使用节奏:

  1. MEMORYctx_search(sort: "timeline")——恢复会话后、向用户提问之前,先检索既往上下文;
  2. GATHERctx_batch_execute(commands, queries)——一次性运行所有命令、自动建索引、返回搜索结果,一次调用替代 30+ 次调用;每条命令形如{label: "header", command: "..."}
  3. FOLLOW-UPctx_search(queries: ["q1", "q2", ...])——所有追问放进一个数组、一次调用(默认相关性模式);
  4. PROCESSINGctx_execute(language, code)/ctx_execute_file(path, language, code)——沙箱处理,只有 stdout 进入上下文;
  5. WEBctx_fetch_and_index(url, source)后接ctx_search(queries)——原始 HTML 永不进入上下文;
  6. INDEXctx_index(content, source)——把内容存入 FTS5 全文索引,供后续检索。

这套协议的核心思想是批量化:把"问一句答一句"的对话式工具使用,改造成"一次收集、多次检索、沙箱加工"的管道式处理,显著减少上下文往返次数。

并行 I/O 批次:concurrency 参数的正确用法

对于多 URL 抓取或多 API 调用,GEMINI.md 要求始终携带concurrency: N(1-8)

  • ctx_batch_execute(commands: [3+ network commands], concurrency: 5)——适用于 gh、curl、dig、docker inspect、多区域云查询等网络密集型命令;
  • ctx_fetch_and_index(requests: [{url, source}, ...], concurrency: 5)——多 URL 批量抓取。

并发的选型有明确的取舍规则:

  • I/O 密集(网络调用、API 查询)用concurrency 4-8
  • CPU 密集(npm test、build、lint)或共享状态(端口、锁文件、同一仓库写入)保持 concurrency 1
  • GitHub API 有速率限制gh调用上限设为 4。

输出与会话连续性:写文件、打标签、先搜索再提问

GEMINI.md 对输出规范的要求是:

  • 产物写入文件,绝不打成内联文本——返回"文件路径 + 一行描述";
  • search(source: "label")提供描述性来源标签,便于事后检索定位;
  • 技能、角色与决策在整个会话期间持续生效,不随对话变长而放弃。

会话记忆(Memory)是这套机制的另一根支柱。会话历史是持久化且可搜索的,恢复会话后必须"先搜索、再提问":

需求命令
我们之前在做什么?ctx_search(queries: ["summary"], source: "compaction", sort: "timeline")
我们决定了什么?ctx_search(queries: ["decision"], source: "decision", sort: "timeline")
什么不要重复做?ctx_search(queries: ["rejected"], source: "rejected-approach")
存在哪些约束?ctx_search(queries: ["constraint"], source: "constraint")

若搜索返回 0 条结果,则按全新会话处理。注意:用户提示词历史不可用(Note: user-prompt history not available),因此不能依赖提示词回放,必须靠事件索引。

这套"先搜索再提问"的约定在实现层面由 hooks/gemini-cli/sessionstart.mjs 支撑:SessionStart 钩子按sourcestartup/compact/resume/clear)分派——startup清理旧会话并把~/.gemini/GEMINI.md与项目根GEMINI.md的规则内容写入会话事件库;compact写入事件文件并注入会话知识指令;resume加载此前会话事件并注入恢复指令。而 hooks/gemini-cli/beforeagent.mjs 则扮演 UserPromptSubmit 的等价物:捕获每条真实用户提示(跳过<system-reminder>等系统消息),做决策/角色/意图抽取并写入 SQLite 会话库,从而让 LLM 在 compact/resume 之后能从用户离开的确切位置续上——该钩子被要求极快(单次 SQLite 写入,目标 <10ms),失败时静默降级绝不阻塞会话。

ctx 命令:四条运维子命令

GEMINI.md 把四条上下文运维命令映射到了对应的 MCP 工具:

命令动作
ctx stats调用statsMCP 工具,原样显示完整输出
ctx doctor调用doctorMCP 工具,运行其返回的 shell 命令,以清单形式展示
ctx upgrade调用upgradeMCP 工具,运行其返回的 shell 命令,以清单形式展示
ctx purge调用purgeMCP 工具(confirm: true),清空知识库前会先警告

其中ctx doctor对 Gemini CLI 的健康检查覆盖全部六个钩子脚本(BeforeAgent/BeforeTool/AfterTool/AfterModel/PreCompress/SessionStart),见 src/adapters/gemini-cli/index.ts 的getHealthChecks——它直接探测<pluginRoot>/hooks/gemini-cli/<scriptName>的文件存在性,避免经过命令字符串解析的间接路径。

另外注意:/clear/compact之后,知识库与会话统计仍然保留。如需彻底清空、从零开始,必须显式执行ctx purge

环境配置:钩子与 MCP 的两份配置文件

要让 GEMINI.md 中的规则真正生效,Gemini CLI 环境需要完成两层配置:

1. 钩子注册(settings.json)——configs/gemini-cli/settings.json 展示了完整的钩子清单,用户级配置位于~/.gemini/settings.json,项目级位于项目根.gemini/settings.json(适配器注释见 src/adapters/gemini-cli/index.ts):

{ "hooks": { "BeforeTool": [ { "matcher": "run_shell_command|read_file|read_many_files|grep_search|search_file_content|web_fetch|activate_skill|mcp__plugin_context-mode", "hooks": [{ "type": "command", "command": "context-mode hook gemini-cli beforetool" }] } ], "AfterTool": [{ "matcher": "", "hooks": [{ "type": "command", "command": "context-mode hook gemini-cli aftertool" }] }], "AfterModel": [{ "matcher": "", "hooks": [{ "type": "command", "command": "context-mode hook gemini-cli aftermodel" }] }], "PreCompress": [{ "matcher": "", "hooks": [{ "type": "command", "command": "context-mode hook gemini-cli precompress" }] }], "SessionStart": [{ "matcher": "", "hooks": [{ "type": "command", "command": "context-mode hook gemini-cli sessionstart" }] }] } }

其中的 BeforeTool matcher 在适配器实现里(src/adapters/gemini-cli/index.ts)还会追加mcp__context-mode前缀与外部 MCP 捕获模式mcp__(?!.*context-mode)(对应 issue #529:没有它,slack/telegram/gdrive/notion 等外部 MCP 的大体积输出会绕过路由提示直接淹没模型上下文)。六个钩子分别对应hooks/gemini-cli/下的beforeagent.mjsbeforetool.mjsaftertool.mjsaftermodel.mjsprecompress.mjssessionstart.mjs(映射表见 src/adapters/gemini-cli/hooks.ts)。ctx upgrade会通过configureAllHooks(src/adapters/gemini-cli/index.ts)自动补齐或更新这些钩子条目,并为脚本设置 0755 可执行权限。

2. MCP 服务器注册(mcp.json)——configs/gemini-cli/mcp.json 的内容极简:

{ "mcpServers": { "context-mode": { "command": "context-mode" } } }

注册后,mcp__context-mode__ctx_executectx_batch_executectx_fetch_and_indexctx_searchctx_indexctx_execute_file等工具才会出现在模型中,GEMINI.md 中的全部路由指令才有对应的落点。

源码级原理补充:Gemini CLI 适配器的能力边界

从 src/adapters/gemini-cli/index.ts 的能力声明可以看到 Gemini CLI 平台支持:preToolUsepostToolUsepreCompactsessionStart全开,且canModifyArgs(通过hookSpecificOutput.tool_input合并改写参数)与canModifyOutputdecision: "deny"+ reason 替换输出)都为 true。但它也有明确限制:

  • decision: "ask"支持——需要用户确认的动作会被降级为deny(安全策略默认拦截,见 src/adapters/gemini-cli/index.ts);
  • PreCompress 仅为 advisory(异步、不能阻塞)
  • 钩子暂不对子代理(subagents)触发
  • 项目目录解析优先级为input.cwd>GEMINI_PROJECT_DIR>CLAUDE_PROJECT_DIR>process.cwd()(src/adapters/gemini-cli/index.ts),会话 ID 优先取session_id字段,缺失时回退pid-<ppid>

这些边界决定了 GEMINI.md 中"BLOCKED 即 deny、REDIRECTED 即改写参数"的实际行为模式,也解释了为何规则要写得如此强硬——因为 Gemini CLI 平台本身不提供温和的"询问用户"通道。

结语:一份可执行的"上下文预算管理手册"

configs/gemini-cli/GEMINI.md本质上是一份写给模型阅读的上下文预算管理手册:它把"工具输出不可控"这个 Agent 工程中的经典难题,拆解为 BLOCKED(硬拦截)、REDIRECTED(沙箱重定向)、工具选择协议、并行批次、文件化输出与先搜索再提问六组可执行规则。对使用者而言,只需保证~/.gemini/settings.json的钩子注册与 MCP 服务器配置完整(可运行ctx doctor自检),模型就会在 GEMINI.md 的持续约束下,把绝大多数数据密集操作收敛进沙箱,让 56 KB 的原始输出变成一行答案——这正是 context-mode 在 Gemini CLI 上守护上下文窗口的工作方式。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 6:59:49

HBase+MapReduce共享单车数据分析实战

简介&#xff1a;这是一份面向计算机相关专业学生、教师及初学者的高分毕业设计级共享单车大数据分析项目&#xff0c;基于Java与Hadoop生态实现数据采集、存储、统计与可视化全流程。项目将CSV格式的单车使用记录&#xff08;含起止时间、起终点等&#xff09;导入HBase&#…

作者头像 李华
网站建设 2026/9/13 6:58:37

LabVIEW在海洋气象观测中的创新应用与实践

1. 项目概述&#xff1a;当LabVIEW遇上海洋气象观测十年前我第一次接触海洋气象观测项目时&#xff0c;还在用传统的数据采集卡配合C语言写控制程序。直到某次台风监测任务中&#xff0c;设备在甲板剧烈摇晃下出现数据丢包&#xff0c;我才意识到需要更可靠的解决方案。LabVIEW…

作者头像 李华
网站建设 2026/9/13 6:57:26

text-to-CAD:从自然语言到可制造STEP模型的工业级映射

1. 什么是text-to-CAD&#xff1f;它不是“让AI画CAD”&#xff0c;而是重构设计工作流的底层入口text-to-CAD这个标题乍看像AI绘图的延伸——输入“一个带M6螺纹孔的铝制支架&#xff0c;长120mm宽60mm厚10mm&#xff0c;底部有4个Φ8安装孔”&#xff0c;就自动生成DWG文件。…

作者头像 李华
网站建设 2026/9/13 6:56:57

Jenkins Pipeline与Kubernetes实现云原生CI/CD实践

1. 项目概述在云原生技术栈中&#xff0c;Jenkins Pipeline与Kubernetes的结合已经成为现代CI/CD流水线的标准实践。这个项目展示了如何利用Jenkins的声明式Pipeline来自动化Kubernetes工作负载的更新过程&#xff0c;实现从代码提交到生产部署的完整自动化流程。我最近在客户现…

作者头像 李华
网站建设 2026/9/13 6:54:38

diagram-design:用代码构建可维护的视觉语言系统

1. 什么是 diagram-design&#xff1a;不只是画图&#xff0c;而是用代码构建可维护的视觉语言系统“diagram-design”这个词最近在前端、产品、文档和工程协作圈里频繁出现&#xff0c;但它绝不是“用鼠标拖拽几个方块再连条线”那么简单。我从2016年开始做技术文档可视化&…

作者头像 李华