ctxtrim 通过本地规则裁剪日志、测试输出和文件内容,并可选用兼容 OpenAI 接口的模型进一步摘要。工具提供 CLI 与 MCP 服务,还能将决策和发现保存为精简会话记录,要求 Node.js 20 及以上。
项目仓库:👉 github.com/bayuh85/ctxtrim(MIT 许可证,Node.js 20+)
Claude Code、Cursor 和 Cline 这样的 coding Agent 用起来很顺手,直到 context window 被各种无用信息塞满。跑一次测试,输出几百行;服务器日志反复打印同一条启动消息;Agent 为了检查一个字段,用 cat 读完整个大 JSON 文件。这些内容都会进入上下文,每一轮都被重新读取,还会挤掉真正重要的信息,比如你二十分钟前做出的决定。
常见的解决办法都靠手动处理:| tail -50、grep ERROR,或者叮嘱 Agent「别把整个文件都读进来」。这些办法能管用,但总有失效的时候。
ctxtrim 能压缩 coding Agent 需要读取的内容:
Press:通过机械规则裁剪大型日志、测试输出和文件内容,无需联网,也不需要 key。
Gloss(可选):如果裁剪后的结果仍然很大,就用一个低成本的 OpenAI-compatible 模型生成摘要,默认模型是 zai/glm-5.3。
Session notes:把决策和发现记入精简的会话记录,而不是任由对话记录不断膨胀。
它同时提供命令行工具和 MCP server,两者提供相同的操作。
需要 Node.js 20 或更高版本。
git clone https://github.com/bayuh85/ctxtrim.git
cd ctxtrim
npm install
npm run build
机械裁剪完全不需要 key。如果想使用模型摘要,设置一个 key:
cp .env.example .env
# CTXTRIM_API_KEY=your-key
现在,把一段嘈杂的输出通过管道传给它:
export CTXTRIM_API_KEY=your-key
# optional; these are already the defaults
export CTXTRIM_BASE_URL=https://atmorouter.dev/v1
export CTXTRIM_MODEL=zai/glm-5.3
npm test 2>&1 | node dist/cli.js shrink --kind test --session demo
node dist/cli.js note add --session demo --tag decision "Retry refresh with jitter."
node dist/cli.js recall --session demo
精简结果写入 stdout,方便继续通过管道处理;一行处理回执则写入 stderr。README 中的示例是:对一份包含三条连接错误和一条警告的 300 行日志执行 press,会得到下面的回执:
ctxtrim · log · press · 12578 → 1299 bytes · kept 10%
精简结果会折叠重复的启动日志(ready ×3),保留错误、警告以及开头和结尾。中间没有重要信息的部分,则用一行省略提示代替。
回执会告诉你实际走了哪条处理路径:
passthrough:输入本来就很小。press:机械裁剪。gloss:模型摘要。cache:复用了相同文本和模型对应的 gloss 缓存。先执行 npm run build 完成构建,再将客户端指向 node /absolute/path/to/ctxtrim/dist/cli.js serve。
项目中的 .mcp.json(或你的用户配置):
{
"mcpServers": {
"ctxtrim": {
"command": "node",
"args": ["/absolute/path/to/ctxtrim/dist/cli.js", "serve"],
"env": {
"CTXTRIM_API_KEY": "your-key",
"CTXTRIM_BASE_URL": "https://atmorouter.dev/v1",
"CTXTRIM_MODEL": "zai/glm-5.3"
}
}
}
}
claude mcp add ctxtrim --env CTXTRIM_API_KEY=your-key -- node /absolute/path/to/ctxtrim/dist/cli.js serve
将同样的 mcpServers.ctxtrim 配置块放入项目的 .cursor/mcp.json,或者通过 Cursor Settings → MCP 添加。
在 Cline 的 MCP 设置文件中添加相同的配置:
~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json%APPDATA%\Code\User\globalStorage\saoudrizwan.claude-dev\settings\cline_mcp_settings.json(VS Code Insiders 和其他衍生版本使用各自的 User/globalStorage 目录。)文件保存后,Cline 就会读取配置。
重启 MCP 客户端后,可以养成这样的使用习惯:让 Agent 对体积较大的工具输出调用 shrink,并在长任务开始时调用 recall。你可以把这些要求写进 CLAUDE.md、Cursor rules 或 Cline custom instructions。
Detect(识别)。auto 会把输入分类为日志、测试输出、文件内容(源代码或 JSON),或者普通文本。可以通过 --kind 手动指定类型。
Press(裁剪)。重复行会被折叠。日志保留错误、警告以及开头和结尾。测试输出保留失败信息、附近的堆栈帧和结果摘要。源代码保留由 import 和声明组成的大纲。JSON 会变成一段简短的结构描述。如果结果仍然过大,就按字符数上限截断。
Gloss(摘要)。如果 press 的结果仍然很大,并且设置了 CTXTRIM_API_KEY,ctxtrim 就会把 press 的结果,而非原始大段文本,发送到 POST {CTXTRIM_BASE_URL}/chat/completions,要求模型生成一份不超过 CTXTRIM_TARGET_CHARS 的纯文本摘要。如果返回的 gloss 为空,或者比 press 的结果还长,就会被丢弃。结果缓存在 CTXTRIM_HOME 下。
有几个行为需要了解:
--offline 绝不会调用模型。--gloss 要求提供 key;缺少 key 时,会以状态码 2 退出。--gloss。这样拆分的思路很简单:机械裁剪免费,而且结果确定;低成本模型只会看到已经裁剪过的文本,因此生成摘要的成本,远低于让主力 coding 模型直接读取原始输出。
笔记按会话分别以 JSON 格式存储在 $CTXTRIM_HOME/sessions/ 下(CTXTRIM_HOME 默认为 ~/.ctxtrim)。每条笔记只占精简的一行,可以附加 decision、blocker 或文件名主干等标签。当当前笔记超出 CTXTRIM_NOTE_BUDGET 时,最早的记录会被汇总成摘要,让会话记录始终足够小,方便粘贴回 prompt。
recall 会打印压缩统计数据,包括输入字节数、输出字节数和保留比例,以及汇总摘要和当前笔记。注意,压缩后的精简内容本身不会被复制进会话记录。如果想让 Agent 记住某个结论,需要专门写一条笔记。
所有配置都通过环境变量设置。主要的调节项:
import { loadConfig, shrink, Ledger } from "ctxtrim";
const result = await shrink(logText, { env: process.env, kind: "log" });
const ledger = new Ledger(loadConfig().home);
await ledger.add("feature-auth", "Refresh flake is a clock skew, not a bad signature.");
这个思路受到 mksglu 的 context-mode 启发。ctxtrim 是一个独立项目,与 context-mode 没有关联。如果你也在探索这个方向,不妨看看 context-mode。
默认情况下,ctxtrim 使用 zai/glm-5.3,将 gloss 请求发送到 AtmoRouter。AtmoRouter 是一个兼容 OpenAI 和 Anthropic 的网关,按 token 计费,支持通过 QRIS 和 USDC 付款,并以较低成本提供前沿模型的访问服务。这正好契合「让摘要步骤的成本低于 coding 模型」的思路。
不过,你并不一定要用它。ctxtrim 只依赖带有 messages、model、temperature 和 max_tokens 的 POST /chat/completions,所以任何 OpenAI-compatible provider 都可以使用:
export CTXTRIM_BASE_URL=https://your-provider.example/v1
export CTXTRIM_API_KEY=your-key
export CTXTRIM_MODEL=your-cheap-model
即使完全不设置 key,你仍然可以使用机械裁剪,而且不会发起任何网络请求。
如果你的 Agent 总被测试输出和日志淹没,可以试试:
尤其欢迎对 press 启发式规则的反馈。如果它处理某种日志或测试格式的效果不好,提交一个附带样本的 issue,就是最有帮助的反馈。
如需采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。