Codemode 的核心想法,是让模型自己写一小段程序来调工具。
Pi 的做法很具体。模型负责决定怎么查、怎么处理,写一段 JavaScript 丢进 QuickJS 的 WebAssembly 沙箱里跑。程序去干循环、并行、筛选、计算这些体力活,最后只把结果交回模型。跑的时候,await tools.someTool(...) 是真的在调用已经接入 Pi 的工具,不是模型在脑子里模拟。
真正值钱的变化藏在数据流里。以前工具之间传来传去的中间数据,全都要过一遍模型的上下文。现在它们可以先留在程序里处理完。
我拿那个例子算了一遍账。给定一百条 issue,要挑出被评论追得最猛的那五条,附上标题和链接。老办法,模型先要整个列表,再逐条要评论,每收一次数据就得重新想一次。
用 Codemode 就换了个人干活。模型先写好查询程序,调 tools.listIssues 拿到那 100 条。接着在循环里逐条拉评论,用 tools.listComments({ issueId }) 补上。
每轮把 issue.title、issue.url 连同 comments.length 一起 ranked.push 进数组。收齐以后按 b.commentCount 对 a.commentCount 降序,截出前五。
100 条照样查了,模型却只看见排好序的前 5 条。Pi 的文档写得明白:工具调用的原始返回不会自己溜进模型上下文,会进来的只有脚本最终吐出的那点东西。
省下的就是这次数。服务请求一次不少,模型参与的中间步骤却大幅缩水。我之前一直愁上下文被工具返回值灌满,这个思路等于把过滤这一步外包给了程序。
它和 MCP 的关系也顺了。MCP 负责把外部工具接进来,通信、发现、认证都归它管。Codemode 干的是另一头,把这些现成工具串成一段可执行的流程,顺序和中间数据都由程序自己拿捏。两边各管一摊,互不越界。
Codemode 也不认死 MCP。Pi 自带的工具直接就能用,Jev 这类分类模型也能在程序里随手调。
工具清单也不是写死的。想接谁,就去 settings.json 里登记 defaultTools。走 OAuth 授权的第三方服务能挂,跑在 Node.js 环境里的扩展同样能挂。接上了,模型随手就能调。
有一个前提容易被忽略。各个工具吐回来的得是规整的结构,拼接才顺利。要是一团乱文本,程序没法稳定地排序和筛选,这套就废了一半。
我打算先拿手头一个"跨文件找重复逻辑"的任务试。它天然要并行读多个文件、抽字段、比对,正好是程序该干而模型不该干的活。跑通了再谈推广。













