今天我们抓到的 GitHub Trending 日榜上,第三位是 mksglu/context-mode,页面上显示当日新增 485 星。按 GitHub API 在同一时段读回来的数字:26,878★、1,926 个 fork、173 个未关 issue,建仓写着 2026 年 2 月 23 日,许可一栏是 Elastic License 2.0;npm 上的包名就叫 context-mode,最新版本 1.0.169,发布于 6 月 29 日。

它要解决的不是“模型不够聪明”,而是一个更土的问题:你的上下文窗口被工具输出的原始数据吃光了。

一句话定位:它不帮模型记东西,它少给模型喂东西

  • 它的位置:插在工具调用和上下文窗口之间。一条命令、一次网页抓取、一份日志,先进沙箱,原始内容不进对话。
  • 它回给你的:结论。stdout 的那几行、被检索命中的那几段,而不是 56KB 的整页快照。
  • 它不做的:不替你决定模型该怎么写答案。仓库 README 专门写了一节,说自己只搬数据、不管文风,行文长短与格式还是你(或你的 AGENTS.md)说了算。它和那种“给 Agent 加一句少啰嗦”的技能文件不是一回事。

官方基准表给了几个具体数字:一次 Playwright 快照 56.2KB 压到 299 字节,20 条 GitHub issue 58.9KB 压到 1.1KB,500 行访问日志 45.1KB 压到 155 字节,一份 500 行的分析 CSV 85.5KB 压到 222 字节。按它的说法,一轮完整会话下来 315KB 的原始输出会变成 5.4KB,会话寿命从“半小时就没”变成“三小时还有余”。

问题陈述:上下文到底是怎么被吃光的

  • 输入侧堆原始数据。README 举的例子:一次 Playwright 快照 56KB,二十条 GitHub issue 59KB,一份访问日志 45KB。它的说法是,一轮长会话三十分钟后四成上下文就没了。
  • 压缩之后状态丢失。窗口满了,客户端压掉旧消息,接着模型忘了在改哪个文件、哪些任务在做、你上一条要求是什么。这是所有用编码 Agent 的人都撞过的那堵墙。
  • 输出侧的废话。同一份文档把“输出 token 浪费在客套话与冗长解释上”列为第四个要解决的问题——不过它选择不干预这一条,理由见上。

功能一:11 个工具,把“读进来”换成“算出来”

这是最该记住的一段。它一共注册 11 个 MCP 工具,六个干活、五个管自己:

工具干什么官方给的节省数字
ctx_execute在沙箱里跑代码,只有 stdout 进上下文56KB → 299B
ctx_execute_file处理文件,原始内容不出沙箱45KB → 155B
ctx_batch_execute一次调用跑多条命令加多组查询986KB → 62KB
ctx_index把 markdown 按标题切块入 FTS560KB → 40B
ctx_search一次多组查询检索已索引内容按需取片段
ctx_fetch_and_index抓网页、转 markdown、切块入库60KB → 40B
ctx_stats ctx_doctor ctx_upgrade ctx_purge ctx_insight省了多少、装得对不对、升级、清库、开仪表盘—

背后的思想它叫“用代码思考”:要数 50 个文件各有多少行,不要把 50 个文件读进上下文,而是让模型写一段脚本来数,只打印结果。官方给的对比是一段脚本替掉十次工具调用。支持的运行时按 README 是 12 种(JavaScript、TypeScript、Python、Shell、Ruby、Go、Rust、PHP、Perl、R、Elixir、C#),检测到 Bun 时 JS/TS 会更快;gh、aws、kubectl、docker 这类已登录的命令行工具通过环境变量透传凭据,不把凭据写进对话。

功能二:知识库不是向量库,是 SQLite FTS5

  • 底层:用 SQLite 的 FTS5 全文索引,默认落在 ~/.context-mode/content/ 下,按项目分库;检索靠 BM25 打分,标题与二级标题在打分里权重 5 倍。它没有用向量检索那一套。
  • 双路召回:一路 Porter 词干——“caching” 能命中 cached、caches;一路 trigram 子串——“useEff” 能命中 useEffect。两路排名用 Reciprocal Rank Fusion 合并,多词查询再走一遍邻近度重排,词靠得近的段落排前面,输错字先用编辑距离纠正。
  • 缓存与清理:同一个 URL 在 TTL 窗口(默认 24 小时,可按调用传参覆盖)内二次抓取直接跳过,只回一条约 0.3KB 的缓存提示;超过 14 天的内容库在启动时自动清掉。

功能三:压缩之后还接得上

会话里的每一次文件修改、git 操作、任务推进、报错、你的决定,都会被写进项目专属的 SQLite。窗口压缩之后(或者你用 --continue、--resume 回来),它不是把这些整块灌回上下文,而是先入 FTS5,再按需要检索出相关的那几条,模型从你最后一句要求接着往下干。有个细节值得留意:不带 --continue 时,上个会话的数据会被立即删除——新会话就是一张干净的白纸,这也是它的隐私口径之一。

功能四:路由靠 hooks 硬拦,不靠“劝模型配合”

  • 两套机制两条命:hooks 能在工具真的跑起来之前拦下、改写参数、把命令重定向进沙箱;指令文件(CLAUDE.md、AGENTS.md 那一类)只能劝。官方自己给了两组数字——有 hooks 约省 98%,只有指令文件约省 60%,并直接写明:只要漏一次不听话的 curl 或截图,一轮攒下的节省就被抹平。
  • 覆盖面:能力矩阵列了 18 个客户端——Claude Code、Qwen Code、Gemini CLI、VS Code 与 JetBrains 的 Copilot、GitHub Copilot CLI、Cursor、OpenCode、KiloCode、OpenClaw、Codex CLI、Kimi Code、Antigravity 与它的命令行、Kiro、Zed、Pi、OMP;README 正文另一处写的却是 17 个。
  • 但矩阵要横着看:一列一列看过去,SessionStart、PreCompact、能不能拦工具,格子里填的是“是 / 插件 / 空 / 有界”。Antigravity 与 Zed 那两列写得明白——不支持 hooks,只能手工拷一份指令文件,等于落回那 60%。

怎么用起来

  • Claude Code 最省事:先确认版本在 1.0.33 以上,然后两句——/plugin marketplace add mksglu/context-mode、/plugin install context-mode@context-mode,重启或 /reload-plugins,再用 /context-mode:ctx-doctor 验一遍,全绿才算真装上。插件会一次挂上六个 hook 与全部 11 个工具。
  • 只想先试试:claude mcp add context-mode -- npx -y context-mode,一行接上 11 个工具;代价是没有自动路由,得靠模型自己想起来用它。
  • 其他客户端:npm install -g context-mode 之后写配置。以 Cursor 为例要三样东西——.cursor/mcp.json 指向 context-mode 命令,.cursor/hooks.json 挂 preToolUse、postToolUse、stop 三个 hook,再把仓库里的 context-mode.mdc 拷进 .cursor/rules/(因为 Cursor 目前不给 sessionStart hook,路由说明只能靠规则文件带进去)。
  • 不开 AI 也能用:终端里直接 context-mode index <路径> --source project:my-app 把代码库入库,再 context-mode search “登录中间件” --source project:my-app 检索。

我们实际跑了一下

这台服务器只有 1.6GB 内存,Node 26.7.0。我们在 /tmp/lab-context-mode 里装了一遍(刻意加 --ignore-scripts 跳过原生模块编译),做完四件事:

  • 装:141 个依赖包,8 秒装完,占 52MB。
  • 自检:context-mode doctor 报 FTS5/SQLite 通过、MCP server 初始化通过、六个 hook 脚本全部就位。这里撞到一个真情况:它在 Node 26 上本来就打算绕开 better-sqlite3——仓库源码注释写着,Node 26 从 V8 里移除了 info.This(),导致 better-sqlite3 12.9.0 原生编译失败,所以它优先改用 Node 自带的 node:sqlite。我们跳过原生编译,FTS5 检查照样通过。
  • 索引与检索:一个 6 小节的测试文件进去变成 7 个分块,库里能看到 chunks 与 chunks_trigram 两张索引表,中文查询能命中对应小节。
  • MCP 真调用:用一段最小 MCP 客户端握手,11 个工具名全部列了出来;调 ctx_execute 跑一段“先生成 2,000 行访问日志再统计”的脚本——沙箱内部处理了 104,586 字节,约 102KB,回到我这边的响应只有 530 字节,内容只有一行摘要 lines=2000 errors=0 totalBytes=104586。这是全文我最看重的一个数字:原始数据确实没进对话。

顺手记一个坑:索引时 project 默认取被索引的那个目录,搜索时默认取当前工作目录。我在 A 目录索引、在 B 目录搜索,第一次直接得到 No matches,加 --project 指到同一处才出结果——命令行使用者容易在这儿愣一下。测完进程已停、目录已删,内存回到安装前水平。

四条硬门槛

① 许可证不是 OSI 意义上的开源。 LICENSE 文件是 Elastic License 2.0(ELv2),署名 Copyright 2026 Mert Koseoglu。能读、能改、能分发,但不能拿它做托管服务卖给别人,也不能删掉许可声明。项目在 README 里解释了这个选择:用 MIT 的话,别人可以把代码包成闭源 SaaS 去卖。

② “67 万用户”这个数字要看口径。 仓库顶部的徽章写着 671.8k+ users,它读的是仓库里的 stats.json,由 CI 每天刷新。我们对着 npm 官方下载接口读回来的是:累计 629,371 次下载(2026-02-20 起)、最近一个月 102,090 次、最近一周 24,651 次。下载量不是人数,CI、镜像、反复重装都会重复计入。同一排的 “Used across teams at Microsoft / Google / Meta” 品牌徽章,链接全是 #,没有可核对的出处,当宣传语看就行。

③ 6 月 24 日之后没有实质代码提交。 这是这次核对里最意外的发现:提交接口显示,从 6 月 25 日到今天,这个仓库有 206 条提交,消息全部是 ci: update install stats——每天几条,只是把下载统计刷进徽章。最后一次实打实的代码提交停在 6 月 24 日的落地页动效。再叠上 173 个未关 issue,你要按“出问题可能没人在修”来估风险。1.0.169 是个能跑完的完整版本,不等于不能用,但这是决策时必须知道的一件事。

④ 两处口径差一。 README 正文说覆盖 17 个客户端,自己的能力矩阵列了 18 列;说沙箱支持 12 种语言运行时,我们机器上 doctor 报的却是 5/11(45%)。实际能跑几种,取决于你本机装了哪些运行时——它不会替你把 Python、Go、Rust 补上。

和同类比,它买的是哪一段

做法谁在干活省的是哪一段代价
客户端自带的自动压缩与 /compact客户端压缩对话历史免费,但压完容易丢工作状态
“少说废话”的提示词或技能文件模型输出侧免费,管不住输入侧的原始数据
各类浏览器、抓取、搜索 MCP各自工具不省,反而往上下文里灌原始数据每个都要单独接
云端上下文或可观测平台平台方省,但数据要过云按席位订阅
mksglu/context-mode本地沙箱子进程加本地 SQLite输入侧原始数据,以及压缩后的状态回填免费,但要 Node ≥ 22.5,许可证是 ELv2

它和本站拆过的几条线在同一张地图上:OpenShell 管的是 Agent 能碰什么(内核级沙箱),这里管的是 Agent 往回带什么(原始数据不出沙箱);Hindsight 给 Agent 装的是长期记忆,这里的会话续跑只解决“压缩之后别失忆”;再往前,CLI-Anything 和 REA 都是“把能力接进 Agent 的循环”这一类活,只是拼图位置不同。

我的判断:谁该上、谁再等等、谁别碰

该上的:① 天天用 Claude Code、Codex CLI、Gemini CLI 写代码,一到下午就被压缩和失忆折腾的人;② 常让 Agent 读日志、抓网页、翻 issue 的人——这几类工具的原始输出最肥,省下来的最直观;③ 在意数据不出本机的人:无遥测、无账号,索引与事件都落在自己硬盘上,还能用 ctx_purge 一键清空。

再等等的:① 只用网页版聊天、不接 MCP 的人,这套东西没有落点;② 工作流里没有大量原始输出的轻度用户,装上去只是多一层配置和一次诊断;③ 需要长期维护保障的团队——先把第三条硬门槛看完再定。

别碰的:① 想拿它做托管服务卖的人,许可证不允许;② Node 还停在 22.5 以下的人,先升级;③ 指望它替模型改文风的人——项目自己写明了不干这事。

顺带一提:让 Agent 少灌数据之后,屏幕前的活反而更长——如果一天十几个小时钉在椅子上,这篇人体工学椅怎么选按体型与预算分了档。

本文由拾光札记编辑部整理,勘误请联系我们