AI coding agent 上下文瘦身:caveman 本地代理压缩 token 实战 1. 项目缘起为什么我要折腾一个叫 caveman 的东西第一次看到caveman这个词是在一个 AI coding agent 的讨论串里。有人甩了一句“用 caveman 跑一遍token 直接砍半”底下跟了一堆“求链接”“npx 能装吗”。我当时的第一反应是又一个套壳工具毕竟这两年打着“省 token”“代理转发”旗号的轮子太多了十个里有八个是改个base_url就敢叫框架的。但真正让我动手去试的是那段时间我自己踩的一个坑。我在本地跑一个基于 AI coding agent 的自动化流程任务本身不复杂——读代码、改代码、跑测试、再根据报错回改。问题出在上下文膨胀上agent 每轮都要把整个文件树、历史对话、工具返回结果重新塞进 prompt跑到第五六轮的时候单次请求的 token 用量已经飙到两万多账单肉眼可见地往上跳。我试过手动裁剪上下文、试过把大文件拆成小块喂效果都不稳定改着改着 agent 就“失忆”了把之前改好的代码又改回去。caveman吸引我的点就在这——它的定位不是又一个 agent 框架而是夹在 agent 和模型之间的一层“瘦身层”。你可以把它理解成一个专门给 AI coding agent 做 token 节流的中间件agent 照常发请求caveman 在中间把冗余的上下文压掉、把重复的工具调用结果合并、把不必要的历史轮次丢掉然后再转发给模型。对 agent 来说它无感对账单来说它是真省钱。这篇文章我打算把 caveman 这套东西从里到外拆一遍。不是官方文档的复读而是我自己从零搭起来、跑通、踩坑、再调优的完整记录。适合谁看如果你正在用或者打算用 AI coding agent 做实际开发被 token 用量和响应延迟折磨过或者你单纯想搞明白“agent 和模型中间那层代理到底在干什么”那这篇应该对你有用。我会把配置、参数、排查思路都摊开讲尽量做到你照着抄就能跑起来。先说清楚一个前提caveman 这类工具的核心价值不在“魔法”而在“取舍”。它省 token 的本质是主动丢弃一部分上下文所以你必须理解它丢什么、留什么否则省下来的钱会以 agent 变傻为代价还回去。这个平衡点怎么找是全文的主线。2. 核心思路拆解caveman 到底在哪一层做文章2.1 先搞清楚 AI coding agent 的 token 都花在哪了要理解 caveman 的价值得先算清楚一笔账。一个典型的 AI coding agent 单轮请求prompt 里通常包含这么几块系统提示词system prompt定义 agent 的角色、可用工具、输出格式。这块一般几百到一两千 token相对固定。项目上下文文件树、关键文件内容、依赖清单。这块是大头一个中等项目轻松上万 token。对话历史之前每一轮的 user 输入、assistant 回复、工具调用记录。轮次越多越恐怖。工具返回结果读文件、跑命令、搜代码的原始输出。经常是又臭又长比如一个npm install的完整日志。当前任务指令这一轮真正要干的事往往只占几百 token。问题就出在这——真正决定这一轮输出的“有效信息”可能只占 5%剩下 95% 都是历史包袱。而且 agent 有个坏习惯它倾向于把所有历史原封不动带上因为“怕丢信息”。结果就是 token 用量随轮次线性甚至指数增长而模型注意力被大量无关内容稀释反而更容易出错。我实测过一个场景一个改 bug 的任务跑到第八轮时单次 prompt 达到 2.3 万 token其中工具返回结果占了 1.1 万对话历史占了 8000真正跟当前这轮相关的不到 2000。这就是 caveman 要解决的问题。2.2 caveman 的定位不是 agent是 agent 的“上下文管家”很多人第一次接触 caveman 会误以为它是个 agent 框架其实不是。它更像一个反向代理 上下文处理器部署在 agent 和模型 API 之间。数据流是这样的AI coding agent -- caveman压缩/裁剪/合并 -- 模型 API | v 本地缓存 / 规则引擎agent 完全不知道 caveman 的存在它以为自己还在直接跟模型说话。caveman 拿到请求后做几件事解析 prompt 结构把 system、history、tool results、current task 分开识别。按规则压缩对不同类型的块用不同策略——历史轮次做摘要或截断工具结果做去重和精简文件内容做按需加载。重组请求把压缩后的内容重新拼成一个合法的 prompt转发给模型。缓存复用对重复出现的上下文比如没变过的文件树做缓存避免每次都重新传。这个设计的巧妙之处在于“非侵入”。你不需要改 agent 的代码不需要换框架只要把 agent 的 API 端点指向 caveman 监听的本地端口就行。这也是为什么热词里会出现proxy、local proxy这些词——caveman 本质上就是一个本地代理。2.3 为什么用 npx 分发而不是传统安装热词里npx出现频率很高这不是偶然。caveman 这类工具选择用npx分发背后有几个现实考量零安装门槛npx caveman一行命令就能跑不用全局装、不用管 Node 版本冲突。对只想试一下的人极其友好。版本即用即取每次npx拉的都是最新版省去了“我装的版本对不对”的纠结。适合代理类工具代理工具通常生命周期短、配置简单没必要搞复杂的安装流程。但npx也有坑后面排查章节我会细讲尤其是npx playwright install失败那类问题本质上是网络和缓存目录的锅跟 caveman 本身没关系但会连带影响你的使用体验。2.4 方案选型为什么是“压缩”而不是“换更便宜的模型”有人会问省 token 为什么不直接换个便宜模型我的经验是这两件事解决的不是同一个问题。换便宜模型降的是单价但上下文膨胀导致的是“单次请求量爆炸”而且便宜模型在长上下文下的表现往往更差agent 更容易跑偏。caveman 的思路是先把请求本身瘦下来这样你既可以用好模型又不用为冗余内容付费。两者其实可以叠加——先 caveman 压缩再按任务难度选模型这是我认为最划算的组合。3. 核心细节解析caveman 的压缩策略与实操要点3.1 上下文分块识别它怎么知道哪块该压caveman 干活的第一步是“认路”。它需要从一段拼接好的 prompt 里识别出哪些是系统提示、哪些是历史、哪些是工具输出。常见做法是基于分隔符和角色标记来切分比如system:、user:、assistant:、tool:这些前缀以及代码块、JSON 结构等特征。这里有个实操要点你的 agent 输出格式越规范caveman 压得越准。如果你的 agent 把工具结果和自然语言回复混在一起、没有清晰分隔caveman 就可能误判把该留的压掉、把该压的留下。我踩过的第一个坑就是这个——早期我的 agent 把ls的输出直接拼在回复里没有用工具调用格式包裹结果 caveman 把它当成对话历史给截断了agent 下一轮就“看不见”文件列表反复重新ls反而更费 token。所以我的建议是先规范 agent 的输出结构再上 caveman。工具调用结果一定要用结构化的方式返回别图省事拼字符串。3.2 历史轮次压缩摘要、截断还是丢弃历史轮次是 token 大户caveman 对它的处理通常有三种策略我按激进程度排策略做法省 token 幅度风险保留最近 N 轮只留最近几轮完整历史中等早期关键决策丢失摘要压缩把旧轮次用模型总结成短句较高摘要本身要花 token且可能丢细节关键信息抽取只保留文件路径、变量名、结论最高实现复杂容易漏我自己的配置是“保留最近 3 轮完整 更早的做摘要”。为什么是 3 轮因为 AI coding agent 的决策通常有“局部性”——它当前这轮的动作八成跟最近两三轮的上下文强相关再往前的信息大多已经体现在代码里了。这个数字不是死的任务越复杂、跨文件改动越多就该留越多轮。我试过留 5 轮token 省得少但 agent 更稳也试过留 1 轮省是真省但 agent 经常把改好的又改回去。注意摘要压缩这一步如果也用同一个模型来做会产生额外请求。有些实现会用本地小模型或规则来做摘要成本更低但质量参差。选之前先确认你的 caveman 用的是哪种。3.3 工具结果去重与精简最容易被忽视的省钱点工具返回结果是很多人忽略的 token 黑洞。一个npm install的日志动辄几千行一个git diff可能几百行agent 其实只需要其中几行关键信息。caveman 对这块的处理通常是去重同一个文件被读了三次内容一样只保留一份。截断超长输出只留头尾中间用省略标记。结构化提取从日志里只抽错误行、从 diff 里只抽改动行。我实测下来光是把工具结果做去重和截断单次请求就能省 30% 到 40% 的 token。而且这部分压缩对 agent 的“伤害”最小因为冗余的日志本来就没用。这里的关键参数是“截断阈值”——留多少行、省略多少行。我的经验值是命令输出留头 20 行 尾 20 行diff 留全部改动行但去掉上下文行。这个值你可以根据自己项目调。3.4 文件内容的按需加载别一次性把整个项目塞进去很多 agent 一上来就把整个文件树和一堆文件内容塞进 prompt这是最浪费的做法。caveman 的思路是“按需”——只有当 agent 明确要读某个文件时才把它的内容加进去而且加之前先做一次“是否已经读过且没变”的判断。这里涉及一个缓存机制caveman 会记录每个文件的读取状态和哈希值如果文件没变过就不重复传内容只在 prompt 里放一个引用标记。这个机制对多轮任务特别有效因为大部分文件在整个任务过程中是不变的。实操上要注意缓存失效的判断要准。如果你的 agent 改了文件但 caveman 没检测到它就会用旧内容导致 agent 基于过时信息做决策。我建议开启文件监听或者每轮强制校验关键文件的哈希宁可多花一点点开销也别让缓存坑了你。4. 实操过程从零把 caveman 跑起来4.1 环境准备与依赖确认动手之前先把环境理清楚。caveman 走npx分发所以你需要一个能跑 Node 的环境。我的建议是 Node 18 以上因为很多现代工具链依赖较新的 API。node -v npm -v npx -v三个命令都能正常输出版本号说明基础环境没问题。如果npx报错多半是 npm 没装好或者 PATH 有问题先解决这个再往下走。接下来确认你的 AI coding agent 支持自定义 API 端点。这是 caveman 能生效的前提——如果 agent 把端点写死了你就没法把流量导到 caveman。大部分开源 agent 都支持通过环境变量或配置文件改base_url比如常见的OPENAI_BASE_URL、ANTHROPIC_BASE_URL这类。先在你的 agent 配置里找到这个入口。4.2 启动 caveman 并配置监听端口启动命令本身很简单npx caveman --port 8787 --upstream https://api.example.com这里几个参数解释一下--portcaveman 本地监听的端口agent 会把请求发到这里。--upstream真正的模型 API 地址caveman 压缩完转发到这里。启动后你会看到它打印监听日志。这时候先别急着接 agent用curl测一下通路curl -X POST http://localhost:8787/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer YOUR_KEY \ -d {model:your-model,messages:[{role:user,content:hi}]}能正常返回说明 caveman 的转发链路通了。如果返回 401检查你的 key 有没有正确透传如果返回 404多半是路径没对上注意 caveman 的端点路径要跟 agent 期望的一致。提示--upstream一定要填对。我见过有人把 upstream 填成 caveman 自己的地址结果请求打回自己死循环。启动后先看日志确认转发目标。4.3 把 agent 的流量导到 caveman这一步是让 caveman 真正干活的关键。以常见的环境变量方式为例export OPENAI_BASE_URLhttp://localhost:8787/v1 export OPENAI_API_KEYYOUR_KEY然后正常启动你的 agent。这时候 agent 的所有请求都会先到 caveman压缩后再转发。你可以在 caveman 的日志里看到每个请求的原始 token 数和压缩后 token 数这个对比非常直观。我第一次看到日志时的感受是原来我之前的请求里有那么多废话。一个原本 1.8 万 token 的请求压完剩 7000 多而且 agent 的行为没有明显变化。当然这是调好参数之后的结果一开始压太狠也翻过车后面讲。4.4 参数调优找到省 token 和 agent 稳定性的平衡点caveman 的压缩力度是可调的核心参数大概有这么几类参数作用我的推荐值调大/调小的影响保留历史轮数完整保留最近几轮3调大更稳但费 token工具输出截断行数头尾各留多少行20调小省 token 但可能丢错误信息文件缓存开关是否复用未变文件开关掉更准但费 token摘要触发阈值多少轮后开始摘要5调小省 token 但可能丢细节调参的方法论是先保守再逐步激进。一开始把所有参数设成“尽量不压”跑一个完整任务记录 token 用量和 agent 表现。然后每次只调一个参数观察变化。如果 agent 开始出现“重复劳动”“改回已改代码”“找不到文件”这类症状说明压过头了往回退一档。我自己的调优过程大概花了两个下午最终稳定在一套参数上token 用量比不压时降了约 55%agent 的任务成功率基本没掉。这个数字因项目而异但思路是通用的。5. 常见问题与排查技巧实录5.1 token 相关报错从“token 失效”到“token exchange failed”热词里一大堆 token 报错我挑几个 caveman 场景下真正会遇到的讲。token exchange failed类错误这类通常出现在 agent 做认证的时候跟 caveman 的压缩逻辑没关系而是认证链路出了问题。常见原因是 caveman 转发时把认证头弄丢了或者 upstream 地址配错导致认证请求打到了错误的地方。排查方法在 caveman 日志里看转发出去的请求头确认Authorization有没有正确带上。token 失效/access token could not be refreshed这是认证 token 过期。caveman 本身不管理认证 token它只做内容压缩。如果你用的是需要定期刷新的认证方式确保刷新逻辑在 agent 侧正常工作别指望 caveman 帮你刷。token 用量不降反升这种情况我遇到过原因是摘要压缩本身也消耗 token如果摘要触发太频繁、或者摘要用的模型太贵总账反而更高。解决办法是调大摘要触发阈值或者改用规则摘要。5.2 代理转发失败local proxy failed系列排查cc switch local proxy failed while handling codex endpoint /responses这类报错核心是“代理在处理某个端点时挂了”。排查顺序我总结成一张表现象可能原因排查动作404 not found端点路径不匹配对比 agent 请求路径和 caveman 转发路径401 unauthorized认证头丢失检查 caveman 是否透传 Authorization503 service unavailableupstream 不可达直接 curl upstream 测连通性400 bad request请求体被压坏关掉压缩看原始请求能否通过我的经验是先关压缩再排查。caveman 加一个“透传模式”不压缩只转发如果透传模式下正常、压缩模式下报错那问题就在压缩逻辑如果透传也报错那就是网络或认证问题跟 caveman 无关。5.3 npx 相关坑npx playwright install失败与缓存问题npx虽然方便但坑也不少。npx playwright install失败是高频问题本质是下载浏览器二进制时网络不通或缓存目录权限不对。虽然这跟 caveman 没直接关系但如果你在同一个环境里跑 agent 的测试流程就会连带受影响。解决办法通常是检查 npm 缓存目录权限npm config get cache确认目录可写。清理缓存重试npm cache clean --force。如果公司网络有限制配置 npm 镜像源。caveman 自己用npx启动时如果卡住多半也是首次下载包时网络慢耐心等一次之后有缓存就快了。5.4 agent 行为异常压过头了怎么救这是 caveman 使用中最需要警惕的问题。症状包括agent 反复读同一个文件因为它“忘了”已经读过。agent 把之前改好的代码又改回去。agent 说“我找不到某个文件”但文件明明在。这些几乎都是压缩过度的信号。救火方法是临时把压缩参数调回保守值让 agent 跑完当前任务然后再慢慢调。根本解法是理解你的任务对上下文的依赖程度——跨文件重构类任务需要更多历史单文件小改可以压得很狠。我的独家技巧给 caveman 加一个“关键信息白名单”把文件路径、函数名、变量名这类绝对不能丢的内容标记出来压缩时强制保留。这个白名单可以手动维护也可以从 agent 的工具调用里自动提取。加了白名单之后agent 的“失忆”症状明显减少。5.5 性能与延迟压缩会不会拖慢响应会但通常可接受。压缩本身是本地计算开销主要在字符串处理和可能的摘要请求上。我实测下来纯规则压缩增加延迟在几十毫秒级别基本无感如果开了模型摘要每次摘要会多一次请求延迟增加几百毫秒到一秒。对于交互式 agent这个延迟可以接受对于批量任务建议关掉模型摘要改用规则。如果发现延迟异常高先看是不是摘要触发太频繁再看是不是文件缓存失效导致重复处理。这两个是延迟大户。6. 我踩过的坑和几条实在建议折腾 caveman 这段时间最大的体会是省 token 这件事省的是冗余不是信息。很多人一上来就想把压缩开到最大结果 agent 变傻任务失败重跑总成本反而更高。正确的姿势是先保证 agent 能稳定完成任务再在这个基础上一点点抠冗余。第二条建议是把 caveman 的日志当回事。它记录的原始 token 和压缩后 token 对比是你调参的唯一依据。别凭感觉调看数据。我一开始凭感觉把历史轮数设成 1觉得“反正代码都在文件里”结果 agent 疯狂重复劳动日志一看压缩率是高但请求次数翻了三倍总 token 反而涨了。第三条是别把 caveman 当万能药。它解决的是上下文膨胀解决不了 agent 本身的逻辑问题。如果你的 agent 经常跑偏先去看看它的 prompt 和工具设计别指望 caveman 能救。工具是放大器不是修复器。最后分享一个我最近在用的扩展思路把 caveman 的压缩规则和项目的代码结构绑定。比如对node_modules、构建产物这类目录直接标记为“永不入上下文”对核心业务代码标记为“优先保留”。这样压缩策略就跟项目语义对齐了比一刀切的参数更聪明。这个思路还在打磨但初步效果不错agent 的稳定性又上了一个台阶。