当 AI 编码代理在 30 分钟内处理 20 个 GitHub Issues 时,59 KB 的原始数据会直接注入上下文窗口;一个 Playwright 页面快照消耗 56 KB;500 条访问日志占 用 45 KB。上下文窗口在短时间内被原始工具输出淹没,代理被迫执行上下文压缩(compaction),导致正在编辑的文件、进行中的任务、上一次用户需求全部被遗忘。这是当前 AI 编码代理面临的系统性挑战,而 context-mode 项目提供了完整的工程化解决方案。
问题本质:上下文泄漏的四维冲击
AI 编码代理的工具调用本质上是一个数据泵 —— 每次 Read、Bash、WebFetch 调用都将原始输出无差别地塞入上下文。GitHub 仓库研究场景中,一个子任务的 5 次工具调用即可产生 986 KB 的原始输出;即便是看似轻量的日志分析,500 条请求记录也能轻松达到 45 KB。这些数字背后是一个残酷的现实:上下文窗口的 40% 在 30 分钟内被原始数据消耗,代理不得不压缩对话以释放空间,而压缩即意味着记忆丢失。
context-mode 识别出四个相互叠加的问题维度。数据注入问题是最直接的 —— 原始工具输出未经任何处理直接进入上下文。记忆断裂问题紧随其后 —— 当压缩发生时,模型忘记文件编辑状态、任务进度和用户最新指令。计算浪费问题则更隐蔽 —— 模型被当作数据处理器来使用,逐文件读取并逐行分析,而不是编写脚本让代码自己完成计算。输出膨胀问题则从另一个方向侵蚀上下文 —— 模型输出的礼貌用语、填充词和冗长解释同样消耗珍贵 token。这四个维度相互强化,形成了一个快速恶化的负向循环。
沙箱隔离:98% 上下文缩减的实现机制
context-mode 的核心创新是将所有产生大体积输出的工具调用重定向到沙箱环境,而非直接进入对话上下文。每个 ctx_execute 调用会 spawn 一个独立的子进程,该进程拥有独立的内存空间,运行用户编写的脚本,捕获 stdout,而原始数据 —— 日志文件、API 响应、Playwright 快照、文件内容 —— 从未离开沙箱。只有脚本的标准输出会被注入上下文,通常只有几百字节。
这个设计的关键参数如下:沙箱进程与主进程严格隔离,脚本无法访问彼此内存或状态;标准输出截获策略确保只有 console.log() 或等效输出进入上下文;输出过滤在超过 5 KB 且提供 intent 参数时触发,此时工具会将完整输出索引到知识库,只返回与意图匹配的相关片段。这些参数共同构成了 98% 上下文缩减的技术基础。
实际测试数据有力支撑了这一设计:Playwright 快照从 56.2 KB 降至 299 B(99% 缩减);20 个 GitHub Issues 从 58.9 KB 降至 1.1 KB(98% 缩减);500 条访问日志从 45.1 KB 降至 155 B(100% 缩减);500 行 Analytics CSV 从 85.5 KB 降至 222 B(100% 缩减)。一个完整会话的累计效果更为惊人:315 KB 原始输出被压缩至 5.4 KB,会话持续时间从约 30 分钟延长至约 3 小时。
沙箱支持 11 种语言运行时:JavaScript、TypeScript、Python、Shell、Ruby、Go、Rust、PHP、Perl、Elixir 和 Bun。Bun 环境会被自动检测并启用 bun:sqlite 获得 3-5 倍的 JS/TS 执行加速。认证 CLI(如 gh、aws、gcloud、kubectl、docker)通过凭据传递机制继承环境变量和配置路径,无需额外授权即可在沙箱内使用。
知识库架构:SQLite FTS5 与 BM25 搜索
当输出数据量超过 5 KB 且用户提供了 intent 参数时,context-mode 不会返回完整输出,而是将内容索引到基于 SQLite FTS5 的知识库中。索引过程对 markdown 内容按标题分块,代码块保持完整,随后存储到 FTS5 虚拟表。搜索时使用 BM25 排名算法 —— 一种基于词频、逆文档频率和文档长度归一化的概率相关性评分模型 —— 返回与查询意图最相关的片段,而非全文或近似结果。
FTS5 配置包含多项优化。Porter 词干提取在索引时应用,使 "running"、"runs"、"ran" 匹配同一词干 "run"。三 gram 子串匹配作为补充策略,使 "useEff" 能找到 "useEffect",使 "authenticat" 能找到 "authentication"。两种策略并行执行,通过 ** 倒数排名融合(RRF)** 合并结果 —— 在两种策略中排名都高的文档会获得更高综合排名。
标题加权是另一个关键参数:标题和标题行的 BM25 权重设为 5 倍,确保导航性查询能精确定位。智能片段提取替代简单截断 —— 搜索结果围绕匹配词项展开窗口,返回实际相关内容而非前 N 个字符。多查询邻近度重排序进一步提升质量:查询词项在内容中相邻出现的文档会获得排名提升。
内容缓存机制确保效率:索引内容在 ~/.context-mode/content/ 的每项目 SQLite 数据库中持久化。24 小时 TTL 缓存避免重复拉取 ——24 小时内对同一 URL 的再次调用返回 0.3 KB 的缓存提示而非 48 KB 的完整响应。超过 14 天的内容在启动时自动清理。force: true 参数可绕过缓存强制重新获取。
会话连续性:五钩子的状态恢复机制
上下文压缩是不可避免的 —— 当窗口满了,代理必须丢弃旧消息。context-mode 的会话连续性设计确保压缩后模型能无缝恢复工作状态,而非请求用户重复已提供的上下文。
这一机制依赖五个钩子的协同工作。PostToolUse 在每次工具调用后捕获事件 —— 文件读写编辑、Git 操作、任务创建与完成、错误与错误解决对、发现的限制等 23 类事件被结构化提取并持久化到 SQLite。UserPromptSubmit 捕获用户决策和修正 ——"使用 X 替代"、"不要做 Y" 这类偏好被记录为后续决策依据。PreCompact 在压缩发生前触发,读取所有会话事件并构建优先级分层的 XML 快照,预算上限为 2 KB—— 关键状态(活跃文件、任务、规则、决策)始终保留,低优先级事件(意图、MCP 工具计数)可能被丢弃。SessionStart 在压缩后或使用 --continue、--resume 恢复会话时触发,从 session_resume 表检索快照,将其写入结构化事件文件并自动索引到 FTS5,构建包含 15 个类别的会话指南,最后将 <session_knowledge> 指令注入上下文,模型即可从上一次用户提示继续工作。
快照内容覆盖完整的会话状态:用户最后请求、任务列表(带完成状态)、计划进出与审批、关键决策、修改的文件、未解决的错误、约束条件、阻塞项、Git 操作、项目规则路径、MCP 工具使用计数、子代理任务摘要、拒绝的方法、外部引用、环境变量和会话意图分类。
十四平台兼容性:钩子与路由的差异化实现
context-mode 支持 14 个 AI 编码平台,但各平台的钩子能力差异显著。设计哲学是:有钩子用钩子(程序化路由,~98% 节省),无钩子用指令文件(~60% 节省)。
Claude Code、Qwen Code、VS Code Copilot、JetBrains Copilot 和 Gemini CLI 提供完整的五个钩子支持。OpenCode 和 KiloCode 使用 TypeScript 插件架构 —— 通过 tool.execute.before/after、experimental.session.compacting 和 experimental.chat.system.transform 钩子实现完整功能,其中后者作为 SessionStart 的替代方案注入路由块和会话快照。OpenClaw 以原生网关插件形式运行,直接通过 api.on() 和 api.registerHook() 注册钩子。Pi Coding Agent 作为扩展实现全部四个事件钩子。
Cursor 的情况值得关注:其 preToolUse 和 postToolUse 钩子正常工作,但 sessionStart 被其验证器拒绝,因此会话压缩后的状态恢复暂不可用。Codex CLI 的 PreToolUse 当前仅支持 permissionDecision: "deny" 规则,输入重写仍依赖上游的 updatedInput 支持。
三个平台完全没有钩子支持:Antigravity、Kiro 和 Zed。它们依赖手动复制路由指令文件(AGENTS.md 或 GEMINI.md)到项目根目录,模型通过提示词获得路由指导,合规率约为 60%。
工具集:六沙箱工具与五元工具
context-mode 提供 11 个 MCP 工具,分为两组。六沙箱工具直接执行代码或操作文件:ctx_batch_execute 在单次调用中运行多条命令或执行多查询搜索,支持 1-8 的并发参数,典型场景下 986 KB 原始数据压缩至 62 KB;ctx_execute 在沙箱中运行 11 种语言的代码,仅 stdout 进入上下文,56 KB 原始输出压缩至 299 B;ctx_execute_file 在沙箱中处理文件,原始内容从不离开,45 KB 日志压缩至 155 B;ctx_index 将 markdown 内容分块并索引到 FTS5,60 KB 文档压缩至 40 B;ctx_search 使用多查询在索引内容中搜索,返回智能片段而非全文;ctx_fetch_and_index 抓取 URL、转换 HTML 为 markdown、分块并索引,24 小时 TTL 缓存避免重复网络请求。
五元工具提供诊断和运维能力:ctx_stats 报告上下文节省详情、分项工具消耗和会话统计;ctx_doctor 诊断运行时、钩子、FTS5 和版本问题;ctx_upgrade 从 GitHub 拉取最新版本、重建并重新配置钩子;ctx_purge 永久删除知识库中的所有索引内容;ctx_insight 打开本地 Web UI,提供 90 个指标、37 种洞察模式和 4 个复合评分。
安全性:权限扩展与网络硬化
context-mode 将 Claude Code 的权限规则扩展到 MCP 沙箱。如果用户在设置中配置了 deny: ["Bash(sudo \*)", "Bash(rm -rf /\*)", "Read(.env)"],这些规则同样在 ctx_execute、ctx_execute_file 和 ctx_batch_execute 中生效。规则格式为 Tool(匹配模式),* 表示任意内容,deny 优先于 allow,项目级规则覆盖全局规则。
网络拉取实行硬化策略:仅允许 http: 和 https: 协议;云元数据端点 169.254.169.254 所属的 169.254.0.0/16 网段被硬阻断(DNS 劫持防御);多播和保留地址(224.0.0.0/4、0.0.0.0/8、IPv6 对应网段)被阻断;环回地址和 RFC1918 私有地址(127.x、10.x、172.16-31.x、192.168.x)默认放行以支持本地开发。通过设置 CTX_FETCH_STRICT=1 可额外阻断环回和私有地址,适合共享服务或 CI 环境。
MCP 工具的 tool_input 在持久化前会进行脱敏处理 —— 包含 authorization、token、secret、password、api_key、cookie、signature、private_key 的字段被替换为 [REDACTED],确保凭据不会存入会话数据库。
落地参数:工程实践的关键阈值
在生产环境中部署 context-mode 时,以下参数值得关注。
沙箱输出过滤阈值设为 5 KB—— 超过此大小的输出在提供 intent 时触发知识库索引,返回意图相关的智能片段。BM25 搜索的默认返回数量为每个查询 2 个结果,调用次数达到第 4-8 次时降为 1 个结果并附带警告,第 9 次起重定向到 ctx_batch_execute。FTS5 词干化和三 gram 策略始终并行执行并通过 RRF 融合结果,不存在级联回退。标题权重固定为 5 倍。
缓存策略遵循 24 小时 TTL 和 14 天清理周期。对于需要会话连续性的场景,确保平台支持 PreCompact 和 SessionStart 钩子 ——Claude Code、VS Code Copilot、JetBrains Copilot、OpenCode 和 KiloCode 提供完整支持,Cursor、Codex CLI 和 Zed 的部分功能可能受限。
权限配置建议在项目级 .claude/settings.json 中定义 deny 规则,覆盖危险命令和敏感文件读取。生产环境可考虑设置 CTX_FETCH_STRICT=1 阻断所有非公网地址。
数据来源
本文技术细节基于 context-mode GitHub 仓库(https://github.com/mksglu/context-mode)的完整文档。