大多数“AI 帮你修问题”的演示都只是一次会话:跑个 CLI,它改文件,你看 diff。我想要的是另一种东西:一个常驻服务,守在仓库旁边,自动接手打了 bug、docs 或 chore 标签的 issue,然后开一个 pull request——而且能一直挂着跑,不用盯着大模型的账单。
这就是 fly-swe,基于 mini-swe-agent 构建。下面说说它的整体结构,以及在一个真实 TypeScript monorepo 上跑下来的成本。
一台机器、一对进程、一个 SQLite 文件
整个系统就是一个 FastAPI webhook 接收器加一个 worker,由 honcho 一起跑在一台 shared-cpu-1x 的 Fly Machine 上,挂 1 GB 卷。Webhook 会做校验(HMAC、时序安全比较,密钥为空时直接拒绝),按 delivery ID 去重,再写入卷上 WAL 模式的 SQLite 队列。worker 轮询这个队列。
没有 Postgres,没有 Redis,没有消息中间件。如果 Machine 在任务执行中途重启,孤儿恢复机制会把任务重新捡起来:不丢任务,也不会重复执行。基础设施成本大约每月 $6。
大模型永远不碰 git
这是我最在意的一条不变式。编码 Agent 只负责改文件,改完留在工作区里。然后它发出完成信号,之后的一切都归执行框架管:git add、commit、push 和 PR。Agent 的 shell 拿到的是一个不带 token 的 remote,没有 push 凭据,没有 gh,环境变量白名单里也没有任何密钥。
还有个附带好处:当目标仓库的 AGENTS.md 写着“commit 并开 PR”时,Agent 会照着它处理代码风格和测试,但不会去碰 git,所以不会出岔子。
三道预算,写死在代码里
-
max_iterations:Agent 步数的硬上限 -
max_cost_per_task_usd:每个任务 -
max_daily_cost_usd:每个仓库每天
cost_tracking: strict 更进一步:某一步如果算不出价格,就不执行。
一次运行触到上限时,不会直接终止。它会把未完成的工作强制推送到 WIP 分支,下一次触发时从那里继续,同时附上此前已尝试内容的摘要。这份摘要不消耗任何 LLM token。
“我如何测试”以 harness 实际看到的结果为准,而非模型的自述
Agent 的循环结束后,harness 会在同一环境中重新运行 Agent 声称用过的测试命令。PR 里的“我如何测试”复选框反映的就是这次运行的结果。Agent 无法运行的内容(比如需要数据库、而沙箱里没有的测试套件)会单独列出,标注为 Agent 的报告,且永远不会勾选。
如果验证失败,harness 会在 issue 上说明情况并自动重试。下面 10 个 issue 中有 3 个出现过这种情况。
来自真实仓库的数据
在一个包含 SDK 和文档站的 TypeScript monorepo 上,使用 GLM-5.3 连续处理 10 个 issue(bug 和文档):
- 每个 issue 的费用中位数:约 $0.31;最差 $1.85(225 次迭代,两次验证重试)
- 典型运行:约 80 次迭代
- 10 个 PR 全部在合并前经过人工审查。fly-swe 从不自行合并。
目前还做不到的事
执行没有沙箱隔离:Agent 的命令作为子进程运行在同一容器中,靠环境变量白名单和缺少凭据来缓解风险(SECURITY.md)。按任务隔离的沙箱是路线图上的下一项,临时的 Fly Machines / Sprites 是明显的候选方案。
目前只支持 GitHub,但它位于一个带一致性测试套件的 provider 插件之后。GitLab 或 Gitea 会是不错的第一个贡献方向。
约 10 分钟完成部署: 快速开始 · AGPL-3.0
