教你跑通一个全自动 Coding Agent 的 MVP
——大模型规划,小模型干活
我最近想验证一个反直觉的猜想:
在多智能体(agent)编排中,非思考型小模型有时候比思考型大模型更省钱。
为了验证这件事,我搭了一个最小可运行原型(MVP),项目名叫 hero-coding。我用同一个测试框架(harness)跑了三组模型:ChatGPT 5.4、Ling-2.6-flash、Ling-2.5-1T。
跑出来的数据让我推翻了自己一开始的判断——并不是单纯“小模型赢”,而是“用对地方才赢”。
下面我把整个过程拆开讲,尽量让你读完就能明白这个模式怎么跑、怎么配,以及哪些环节最值得投入精力。
一、什么是全自动 coding agent
一句话解释:
你把一个用户需求(user story)丢进 inbox/ 目录,半小时后回来看 git log,就能检查任务是否完成。
整体流程
inbox/us-001.md ← 用户需求(markdown + frontmatter)
│
▼
Dispatcher ──── 监听 inbox/,启动子进程
│
▼
Worker ──── pi-coding-agent --mode json
│ 原子化执行,每改一个东西就 git commit
▼
Judge ──── 读 git log + 全部 diff,给出结构化判定
│
┌───┴───┐
PASS FAIL
│ │
▼ ▼
done/ 把失败原因追加到 story,再起一轮 worker
三个核心组件全是 stateless 一次性进程:
-
Worker 一次只活一遍,跑完退出; -
Judge 一次只活一遍,给完结论退出; -
所有状态靠 git + 文件系统持久化。
这种设计正好对应“长任务由短任务串成”的工作流形态。
Worker 这一块我直接用了现成的 pi-coding-agent(Mario 在他的 README 里也提到:Pi 故意不做 sub-agent 和 plan mode,留给你自己扩展)。
我做的扩展就是用约 400 行 TypeScript 把它包成一个有 inbox 的自动小助手。
这个比例说明了一个重点:
搭一个能真正跑起来的 coding agent 工厂,不需要重写一个 coding agent,把现成的 harness 拼好就行。
二、什么是 user story
一个最小可执行的任务单位。我用 markdown + frontmatter 来写:
---
id: us-001
title: Add timezone parameter to formatDate
priority: normal
max_retries: 3
---
## Goal
给 formatDate 加可选 timezone 参数,默认 UTC。
## Acceptance Criteria
- [ ] 函数签名加 timezone?: string
- [ ] 不传时和现在 byte-identical
- [ ] 传 Asia/Tokyo 时按该 tz 格式化
- [ ] 在 tests/utils.test.ts 加 3 个测试
- [ ] npm test 全绿
## Out of Scope
- 不改其他函数
- 不动 locale 设置
写好后丢进 inbox/,Dispatcher 自动接管。
你会发现,Out of Scope 比 Goal 更值钱——非思考小模型容易自由发挥,这一节是给它的“紧箍咒”。输入越清楚,结果越好。
三、跑了什么、用什么跑的
我准备了一个故意带 bug 的 mini TypeScript 项目,包含三个 utility 函数:
-
formatDate(date)—— 不支持 timezone(待加) -
parseRange(1-5)—— 应该返回[1,2,3,4,5],但有 off-by-one 返回[1,2,3,4] -
formatNumber(-1234)—— 应该返回-1,234,但代码 bug 返回--1,234
三个 user story 对应三种典型工作量:
三组模型对照:
-
ChatGPT 5.4(思考模型)—— 通过本地反代走真实账号 -
Ling-2.6-flash(非思考小模型)—— 蚂蚁百灵 OpenAI 兼容 API -
Ling-2.5-1T(非思考大模型)—— 同上
Worker 和 Judge 通过 ~/.pi/agent/models.json 配置不同 provider,全部走 OpenAI 兼容协议,改 model 字段就能切换。
四、跑出来的数据
我把原始统计整理成表格:
从这些数据可以得出几个明确的结论。
1. 明确 bug 修复:Ling-flash 比 ChatGPT 快 31%
us-002 同一个任务:
-
Ling-flash 用时 90 秒 -
ChatGPT 用时 131 秒
Ling-flash 调了 52 次 tool(比 ChatGPT 的 14 次多得多),但每次极快。这种高频小任务场景就是 Ling-flash 的舒适区:编辑器补全、快速改写、报错修复。
2. 加功能任务:Ling-1T 用 ChatGPT 的 11% token、63% 时间
us-001 同一个任务:
-
Ling-1T 1 轮 130 秒,13K token 就过了 -
ChatGPT 用了 2 轮 205 秒,120K token
差距接近 10 倍 token 量级。
原因在于 ChatGPT 5.4 思考更多,每次响应都隐式 reasoning,prompt 也被反复带入 context。Ling-1T 的思考强度更克制,token 主要花在理解和输出上。
3. 加输入校验:Ling-1T 快 33%,token 少 40%
us-003 同一个任务(给 parseRange 加边界校验 + 友好错误信息 + 测试):
-
Ling-1T 1 轮 58 秒,7 tools,5K token -
ChatGPT 1 轮 86 秒,8 tools,13K token
两个都通过,但 Ling-1T 用时和 token 都更少。三组对照里 Ling 全部胜出,胜幅 30–36%。这是同一个 harness、同一个 user story、同一个 Judge 跑出来的数据,仓库里的 runs/*.json 全部公开。
五、总结
我一开始全部用 Ling-2.6-flash 当 worker,结果 us-001 死循环了:
worker → bash: echo All criteria met.
worker → bash: echo All criteria met.
worker → bash: echo All criteria met.
...(直到 80 tool 上限触发)
后来我调整策略:
-
Ling-2.6-1T 负责理解、规划、拆解 -
Flash 负责快速执行、快速补全和快速修补
非思考小模型一点规划能力也没有,只能是 Ling-2.6-1T 来做设计任务。把 us-001 的 worker 换成 Ling-1T 之后,1 轮就过了。
实测结论:
-
Ling-2.6-flash 在高频小任务上确实更快(us-002 比 ChatGPT 快 31%) -
Ling-2.5-1T 做规划和理解类任务能省到夸张的 token(us-001 比 ChatGPT 省 89%) -
小模型跑 agent 必须配 harness,否则容易死循环或漏 commit -
Ling 1T 作为大脑 + flash 作为手的分工是有效的
如果你已经有真实 harness,换成 Ling-2.6 系列并按上述分工使用,token 会下降一个数量级,速度反而提升。
仓库在评论区,自取。跑起来你会看到 Worker 实时滚动每个工具调用——这一段我特别推荐你亲自跑一次,比读这篇文章更有价值。
六、harness 工程的简单且有效的实践
这次开发 Coding Agent 一共翻车五次,全是非思考小模型的典型坑。虽然看似简单的一个小小编程任务,但只有真跑过才知道需要怎么样的 harness 去做兜底,才能让小模型顺利完成任务。
Claude 写的护栏代码加起来不到 50 行。
循环检测(worker.ts,约 10 行)
const recent: string[] = [];
if (sig) {
recent.push(sig);
if (recent.length > 6) recent.shift();
if (recent.filter(s => s === sig).length >= 4) {
child.kill(SIGKILL); // 同一 sig 在 6 次窗口内出现 4 次 = 循环
}
}
Auto-rescue commit(dispatcher.ts,约 10 行)
async function autoRescueCommit(repo: string, round: number) {
const status = await git([status, --porcelain], repo);
if (!status.trim()) return false;
await git([add, -A], repo);
await git([commit, -m, `chore(rescue): ${round}`], repo);
console.log( ↳ auto-rescue: committed pending changes left by worker);
return true;
}
特别值得说的是:Ling-1T 在 us-003 上把代码全改对了,但忘了 commit。如果没有 dispatcher 这一层兜底,Judge 看 git log 会说没 commit 直接 FAIL,整个 round 白跑。dispatcher 自动 commit 之后 Judge 立刻 PASS。
七、写在最后
这篇文章一直躺在想法库里,趁 Ling 模型发布,就顺便验证了自己的猜想。
-
Ling-2.6-flash 在它擅长的高频小任务上确实更快(us-002 比 ChatGPT 快 31%)。如果你在搭 IM 助手、编辑器补全、批量改写、code review 标注这类高频低延迟工作流,flash 是好选择。 -
Ling-2.5-1T 做规划和理解类任务能省到夸张的 token(us-001 比 ChatGPT 省 89%)。1M 上下文的优势在 multi-agent 场景里特别突出——可以把整个仓库 + 所有 git history 一次喂进去,而且很便宜。 -
小模型跑 agent 必须配 harness。这不是 Ling 的问题,是非思考模型本身的特性。我用约 400 行就把 harness 写出来了,放进去跑就很安逸。 -
Ling 1T 作为大脑 + flash 作为手的分工是有效的。
如果你让我给一个最简单的建议:
在你已经有真实 harness 的场景下,换成 Ling-2.6 系列,按上面说的分工使用——你的 token 会下降一个数量级,速度反而上去。

