AI Pulse
📡 X 信号

为开源模型优化的代码读取工具每月节省数十亿token

Command Code是专为开源模型打造的编码平台,团队优化了其他编码代理普遍忽略的细节。本次v1版本中,开发者从头重构了`read_file`读取工具,每月可节省数十亿token。

为了打造最优的文件读取工具,团队将其与Claude Code、opencode、cline等其他9种常见编码代理工具逐一进行了能力对标测试。其中大多数工具都是开源的,Claude Code未开源,测试通过向其在线工具输入手工制作的文件后观察返回结果完成。

在任意编码代理会话中,每次编辑都始于读取操作,每次搜索结果都会触发读取,每个规划步骤都会打开3个文件。平均每个会话会产生数百次读取,Command Code全平台每月的读取总次数约为5000万次。

现有工具普遍存在很多浪费token的问题:读取文件后一无所获又重复读取,直接将5MB大小的锁文件全部读入上下文,读取压缩打包文件后无用内容会一直占用上下文窗口。

粗略计算后可得:每次读取会产生500个无用token,乘以每月5000万次读取,再乘以这些无用token始终留在上下文里,每月总共会产生250亿个无用token。文件读取工具就像编译器,将文件系统内容转换为模型上下文,每一个决策都会影响token预算,而每月的使用次数高达数千万次。编码代理使用成本高,主要原因就是构建上下文的读取环节产生了大量浪费。

Claude Code的读取工具靠消耗更多token实现功能:每次调用消耗更多token,出错后会多轮重试,依赖足够聪明的模型从噪音中提取有效信号。Command Code的读取工具为适配开源模型,需要靠减少token消耗实现功能,因此优化了大量细节。

如果让Claude Code读取一个3000行的文件,它会把全部3000行都传给模型;如果读取包含一条3900字符压缩行的文件,它会把整行完整传出,不设行数、字节、单行长任何上限。开发者测试了两次,才确认这个结果。

大多数团队在开发第一周就写完了读取工具,按偏移量截取返回字符串即可,这是第一个写好的工具,也是最后一个会去优化的工具。Command Code的读取工具最终拆分为数十个模块,包含98个测试,是v1版本中投入产出比最高的工作。简单实现和工程化实现的工具都能运行,但前者会悄悄占用五分之一的上下文窗口存放模型永远用不到的字节,偶尔还会和写入工具陷入冲突。

开发中总结出14项值得分享的优化经验:
第一,需要设置三重上限而非一重上限,应对代码库中各种异常文件:8万行的锁文件、单长行的压缩包、不断增长的日志文件。具体为:普通大文件限制最多2000行,日志文件限制总大小128KB,压缩包文件限制单行最多2000字符。缺少任意一重上限,都会出现吃掉全部上下文、模型一无所获还产生全额token成本的问题。

第二,工具返回沉默是成本最高的失败。模糊的无结果回答会让模型无法区分是空文件还是工具故障,因此会重新读取、扩大窗口、尝试其他路径,白白消耗数轮对话。所有终止场景都需要明确给出恢复提示:空文件标注“为空”,读到文件末尾标注“请缩小范围重试”,达到字节上限标注“继续读取偏移量为1847”等等。继续读取的偏移量会提前计算好,避免模型花费推理token做算术还容易出错;所有提示都不加错误前缀,不让模型把事实信息当作需要道歉的错误。

第三,最难发现的bug出现在工具间的关联关系,输入校验无法捕捉这类问题。读取工具会把模型看过的文件内容、修改时间、是否为部分读取记录在台账中;写入工具发现仅读取了部分内容时,会拒绝覆盖文件,避免破坏模型没见过的部分。但如果和单行长限制结合,就会形成死循环:读取触发截断→台账标记为部分读取→写入被拒绝→模型重新读取→去重后返回内容未变→再次触发截断,bug出现在三个有状态工具的关联关系中,只有观察线上流量才能发现。

第四,过期命中会引发严重问题的缓存,应当在使用时自动过期。重新读取未修改文件的同一窗口完全是浪费,因此只有修改时间、文件大小、读取范围都完全匹配时,才返回简短的引用桩。如果之前的结果已经被对话压缩清理,引用桩就会失效,因此去重命中会自动清除旧记录,最坏情况仅浪费一轮对话,不会陷入无限循环。这种设计是复杂度和风险之间足够好的折中,也是 benchmarks 中表现最好的方案。

第五,文件名对模型来说充满陷阱,模型无法发现其中的问题。macOS的截图文件名会在AM/PM前加入窄无间断空格,文件名使用NFD分解编码,访达重命名会把单引号改成弯引号,肉眼看不出区别,但实际字节完全不同,模型照着屏幕输入后永远找不到文件,还会白白消耗一整个会话的token。因此读取失败前,工具会自动重试7种常见的候选拼写,修复编码和符号问题,之后再找不到才会基于编辑距离给出建议,这些修复比压缩token的技巧省下更多token。

第六,分块读取边界容易出错。分块流式读取可以避免加载整个大文件,但如果刚好在分块边界触发行数限制,无法判断文件是否还有剩余内容,此时猜测对错各半,猜错就会浪费一轮对话。正确的做法是把判断推迟到下一个分块,不确定就先不给出结论。

第七,图片可以正常附加,工具会将4K截图从最高画质开始逐级降低JPEG画质,直到满足大小要求,不会直接附加失败。工具会通过魔数检测文件格式,不依赖后缀名,避免错误文件进入API。非视觉模型也可以通过专用VISION工具使用图片能力。

第八,缩小后的图片会标注缩放比例。如果原尺寸3024×1964的图片缩小到1092×709附加,会明确告诉模型点击坐标需要乘以2.77,否则模型计算出的坐标一定会出错。

第九,Jupyter笔记本会被渲染为规范文档,原始的JSON文件会拆分出带标记的单元格,图表转为图片附加,超过10000字符的单元格输出仅提供提取提示,避免大体积数据占据读取预算,模型仍然可以正常推理,不用花费多余token。

第十,特殊格式仅返回一行关键信息:SVG直接返回XML文本,二进制文件仅返回MIME类型,PDF提供文本提取提示,不同格式按需加载解析工具,模型不用读取全部内容就能推理,用户不用支付多余token。

第十一,行号和`cat -n`输出保持一致,全部使用1索引,每行都带行号前缀,模型、编辑器、堆栈追踪对行号的定义完全统一,偏移量计算和编辑目标都依赖这个统一规则。

第十二,自动修复输入错误不直接拒绝,会自动转换常见的参数别名,比如把filePath转换为file_path,数字字符串转换为数值,错误格式的输入直接拒绝,不会静默转换,错误的读取范围比报错更糟糕。

第十三,部分危险路径永远禁止读取,/dev/zero、/dev/urandom、标准输入、进程文件描述符这类路径,会在执行IO前直接按名称拒绝,读取这类路径会导致工具挂起,相当于自己埋下了拒绝服务漏洞。

第十四,细节卫生只有出问题时才会被注意到,需要自动去掉字节顺序标记,统一把CRLF换行转换为LF换行,截断字节时会用二分查找找到完整的UTF-8编码点,不会拆分字符,去重缓存也保留了环境变量开关,所有缓存都该有应急关闭选项。

对标10款工具后可以发现,前两项优化已经基本普及,八成工具都设置了行数上限和字节上限,属于公开常识。但后续优化几乎没有工具覆盖:10款工具里仅1款做了分块边界延迟判断、仅1款处理了文件名编码问题、仅1款屏蔽了危险设备文件、仅1款把文件结束提示放在错误之外,这些优化都不会在演示中展示,只会在长时间会话里产生消耗,只有上线出问题后团队才会动手修复。

大多数开发者只会在项目初期随便选一个基础框架,之后再也不会调整,默认大牌模型厂商出的框架就是最好的,这个思路并不正确。Claude Code作为现有产品,已经实现了台账、笔记本处理、视觉能力、空文件提示,但没有做任何上限限制、偏移提示、流式读取、失败建议,它的团队还没遇到必须优化的压力,而且本身模型足够宽容,可以承受这些浪费。

Command Code因为要运行开源模型,浪费的轮次当天就会体现在评估分数中,所以必须做这些优化。约束本身是好事,它会推动开发者工程化出正确的解决方案,而不是寄希望于模型自己解决问题。

Command Code现在已经可以试用,不久后会完全开源,开发者计划分享更多Command Code框架工程化的深度内容。

查看 X 原帖

订阅 AI Pulse

每天 08:00 · 12:30 · 18:30 · 23:50 更新