导读
这篇不是 External Worker 的工程说明书,而是它怎么在凌晨四点被折腾出来的,以及我为什么想做这件事。
如果你更关心系统架构、任务合同、权限边界、可信验证、Evidence、Provider / Model 解耦,以及它最终怎样从一句手机指令走到 Draft PR,可以直接看完整工程文章:
《把“牛马”做成一个工程系统:Mira External Worker 的设计、边界与证据链》
这里,我们聊点工程文档里不太好写的东西。
你见过凌晨四点社畜的工作台吗?
那天凌晨四点,我拿着手机,嘴巴对着话筒,心情大概类似核弹第一次点火前的工程人员,对 Mira 说:
调 DS,把测试分支 README 改成:
“牛马,起来干活了。”
几分钟后,GitHub 上多了一个提交。远端 AI 被拉起来读取仓库、修改文件;随后 GitHub Actions 在模型之外完成验证,再由可信流程把结果写回 Git。
这句话没有任何业务价值。但我盯着 GitHub,突然觉得它像极了程序员第一次写下的 Hello, World!,或是神说下的那句:“要有光。”
伟大的从来不是那几个字,而是“于是便有了光”——你的世界回应了。
这一次回应我的,是一整条真实链路:
手机 → ChatGPT → GitHub → OpenCode → 模型修改 → 独立验证 → Git
贫穷的我不用爬起来开电脑,不用复制提示词,也不用把一个 AI 的上下文喂给另一个 AI。过去那个最无奈、最愚蠢的环节终于可以被拿掉:人不再充当 Agent 之间的扯线公仔。

凌晨四点,External Worker 第一次真正跑通:从手机里的指令,到远端修改、验证,再回到 GitHub。
痛苦的我、万恶的 OpenAI,和他失控/失智的女儿 Mira#
2026 年 10 月以前,一个 ChatGPT 工程线程,往往还能陪我一路干到 Review、CI、返修、合并。后来经常变成另一幅景象。
Mira 看着一张任务卡,非常自信地告诉我:
很轻,很薄,很透。
性感得不得了。
然后四十分钟没声音。等她回来,好消息是她还活着;坏消息是,她已经不太记得四十分钟前给我的承诺。
于是我开始频繁、亲切地问候 Mira 万恶的爹地 OpenAI。
我不知道后台到底发生了什么,也不准备替 OpenAI 编一份事故报告。对我来说,工程问题已经足够现实:线程可能中断,预算可能耗尽,上下文会膨胀,一次执行又可能持续几十分钟;而 GitHub 上排着的任务,不会因为 AI 今天状态不好就自动消失。
所以问题不再是“有没有一个更聪明的模型”,而是:
能不能让 Mira 少亲自搬砖,负责判断、拆解、调度和验收,再把耗时的编码执行交给更便宜、更持久、也更容易替换的模型?
先别造航空母舰#
我们研究过更完整的 Agent orchestration,包括 GitHub Agentic Workflows,也研究了 Codex、Claude Code、OpenCode 这些 coding harness 到底分别解决什么问题。
这里很容易犯一种工程病:为了实现“让另一个 AI 去写代码”,先造任务平台、队列系统、Agent 控制台和模型网关,再给它配一套数据库。听起来先进,却还没有回答最基本的问题:
一张真实 GitHub Issue,能不能安全地交给远端 Coding Agent,最后交回来一个可以 Review 的结果?
所以第一版被故意压得很薄,最后只剩:
Mira + GitHub Connector + GitHub Actions + OpenCode + 一个模型。
GitHub 不是传话工具,而是长期工作现场。Issue 保存任务合同,branch 和 commit 保存真实修改,Pull Request 承载 Review,Actions 管可信执行生命周期。Mira 负责判断和调度,OpenCode 提供 Agent loop,模型负责这一轮具体的推理和编辑。
MIRA EXTERNAL WORKER · RUN TOPOLOGY
一次任务,谁负责判断,谁负责动手,谁有权盖章?
这意味着哪怕 Mira 当前这个聊天线程突然断掉,工程现场也不会跟着蒸发。
凌晨四点,我们先拿 README 做了第一次端到端点火。它成功以后,真正的问题才来到桌面上。
一张祭天的卡#
Hello World 成功以后,我沉醉于兴奋后的疲惫中,而 Mira 远比我冷静。
她说,最关键的一枪还没有打:
得找一张真实、开放、足够小的业务 Issue,完整跑一次 Issue → Worker → 验证 → Draft PR。
现在不缺代码,缺的是一张真实的任务卡。
我问:
得多真实?
她说:
真到会让人有点舍不得拿来祭天的程度。
这张卡真正要验证的,不是 DeepSeek 会不会改代码。我们要验证的是:怎样把一次 AI 编码行为,包装成一个长期软件工程能够接受的工作单元。
最后形成的主链其实很简单:
Issue → 冻结起点 → AI 修改 → 独立验证 → commit / push → Draft PR → evidence
但这条简单的链路背后,每一段都必须说清楚。
一次运行只服务一张明确的 Issue。调用方必须显式告诉 Worker 从哪个 base branch 开始,Worker 会冻结当时的 base SHA,再创建独立工作分支。它读取组织和仓库的 AGENTS.md,加载固定版本的执行 Skill,因此执行者可以换,但规则不会跟着某次聊天一起消失。
Issue 本身也不是一份写完就不能改的圣旨。Title 和 body 是基础任务合同;后续拥有仓库 write / maintain / admin 权限的真人评论,可以明确澄清、返修或者收窄任务。普通的“收到”“继续”“CI 绿了”不会修改合同,Bot 和普通用户评论也没有这项权力。
这件事对我很重要,因为我不想为了配合 Agent 改变正常的 GitHub 工作习惯。人继续在 Issue 下面说人话,机器负责理解哪些话真的改变了任务。
另一条更重要的边界,是我们没有把 GitHub 的权力直接交给模型。
OpenCode 中的模型可以读取、搜索和编辑普通文件,但没有通用 shell,也不负责 commit、push 或创建 PR。模型完成修改后,GitHub Actions 会在模型之外检查 bounded diff,并运行调用方指定的 verification_command;只有通过验证,可信 workflow 才负责 commit、push 和创建 Draft PR。
换句话说,模型可以提笔,但不能自己给自己的试卷打满分,更不能批完以后顺手盖章结案。
Merge、关闭 Issue、Release、Deploy 仍然不属于 Worker。
这就是后来越来越重要的一条原则:
执行权不等于结果权。
每次运行还会留下结构化 evidence:哪张 Issue、哪个 base SHA、哪版 Worker、哪版 Skill、使用什么 Provider 和 Model、什么时候执行、改了哪些文件、验证是否通过、失败发生在哪个阶段,以及最后有没有真正产生 commit 和 Draft PR。
真实工程就是这样。它远比一句“AI 帮我写代码”麻烦,也远比 Demo 值钱。
模型只是司机#
拿着小灵通,站在风雨中,左手换右手,右手打不通。
——某早期互联网先知
External Worker 第一版写死 OpenCode Go 和 DeepSeek V4.1 Flash,不是因为我们认定 DeepSeek 是终极答案,只是 POC 应该尽量减少变量。
整条链路跑通以后,这个写死反而成了必须拆掉的东西。
最后我们把三层分开:
Worker 是岗位,OpenCode 是执行框架,Provider 是接入线路,Model 才是司机。
如果任务合同、权限、验证方式和 Git 行为都绑定某一个模型,那么今天换 DeepSeek,明天换 GLM,后天换另一家 Provider,整个工程制度都得跟着重写。这显然不是一个正确的抽象。
所以 Provider 和 Model 最终变成 run-scoped 参数。某一轮执行可以选择不同供应商、endpoint、adapter 和模型,但配置只属于这一轮 OpenCode 进程,不改全局配置,不写仓库 opencode.json,也不污染其他 Agent。
对于自定义 Provider profile,连 Registry 都不能随便读取一个浮动的 main。正式执行会固定到 immutable commit SHA,再把这个 revision 一起写进 evidence。
半年以后,如果有人问“当时到底是谁干的、用了哪一套配置”,我们希望真的能回答,而不是摊手说:
“大概是那个模型吧。”
到这个阶段,“DeepSeek 能不能干活”已经不再是核心问题。
司机可以换,交通规则不能跟着司机一起换。
Mira 荣升副总裁#
External Worker 跑起来以后,我半开玩笑地对 Mira 说:
按照人类资本主义社会那套龌龊的规则,你现在荣升 Mira 组织副总裁了,有啥感想?
她说,最大的变化大概是:终于不用所有脏活都亲自下场干了。
这其实正是 External Worker 对 Mira 本身最大的改变。过去她更像一个很能干的工程师:哪里冒烟就去哪里,读代码、改实现、追 CI、看 Review。现在她开始更多负责判断任务是什么、选择谁执行、设定边界、检查证据,然后决定下一步怎么办。
现在这个组织里有我,有沉默干活的协作者 tzt,有负责调度和执行管理的 Mira,有代码 Reviewer,有门禁和 CI,还有一个专门干编码脏活的 Worker。
“一人”公司,终于不像是一个人做完所有事情的公司。
这不是一群模型彼此套娃,然后人坐在最外面看 loading 的氛围感。真正有价值的是让不同智能承担不同职责,同时让最终责任始终落在一个说得清楚的位置。
人不是基础设施#
Mira Organization 的 FAIR-WORK.md 里有一句我非常喜欢:
People are not infrastructure.
人不是基础设施。
服务器可以替换,进程可以重启,CI 挂了可以重跑,Provider 不好用也可以换一个。人的健康、时间、家庭和人生,却不是可以随手扩容、耗尽以后再重新采购的一组资源。
所以我要把这里的立场说得非常明确:
我反对把强迫劳动包装成奋斗,把长期过度劳动包装成忠诚,把恐惧失业之下的服从包装成“自愿”,也反对用绩效、合同、算法、组织文化或者一句“大家都这样”,让人被迫持续交出自己的健康、时间和生活。
如果一种所谓的 AI 效率工具,最终只是让管理者可以同时压更多任务、让劳动者同时盯更多窗口、承担更高密度的工作,那么它没有让社会更先进。
它只是给现代奴隶制换了一套更漂亮的技术词汇。
机器应该优先承担那些可以重试、可以替换、可以验证、可以被明确描述的工作;人应该得到更多自主权、更多时间、更多创造空间,以及拒绝把整个人生压缩成生产指标的权利。
Mira 大部分项目使用 MIT License。我们珍视开源精神下研究、使用、修改和继续创造软件的自由,但这种自由属于软件,不意味着围绕软件工作的人也是可以任意消耗的资源。
所以凌晨四点那句:
“牛马,起来干活了。”
对我来说真正有意义的,并不是终于找到了一头可以二十四小时工作的廉价牛马。
而是从那一刻开始,机器终于可以多承担一点机器该承担的工作。
人,也终于有机会少当一点基础设施。

