在整个行业里,智能体式编程(agentic coding)从“新鲜又激动人心”快速变成了“必备能力”;随着底层模型持续进步,无人值守的编码智能体也从可能性走向现实。
Minions 是 Stripe 自研的编码智能体:完全无人值守,并以“一次成型(one-shot)”完成任务为目标。在 Stripe,每周合并的一千多个 PR 都是由 minion 全程产出;虽然最终仍会经过人工 review,但其中不包含任何人类手写的代码。
我们的开发者当然仍然可以和 Claude、Cursor 之类的智能体一起做规划与协作;但在一个最稀缺资源往往是「开发者注意力」的世界里,无人值守的智能体让任务并行化成为可能。
一次典型的 minion 运行,从一条 Slack 消息开始,以一个通过 CI、可供人工 review 的 pull request 结束,中间不需要任何交互。我们经常看到工程师同时启动多个 minion 并行推进,以便并行完成许多不同的任务。尤其在 on-call 轮值期间,这对于高效解决大量零碎的小问题非常有帮助。
在这篇系列文章的第一部分,我们会展示工程师如何使用 minions,以及它们能做什么;第二部分我们会深入到实现细节与底层机制,讲讲我们是如何构建它们的。
为什么要自己造?
从零“氛围编程(vibe coding)”做一个原型,和向 Stripe 的代码库贡献代码,本质上是两件完全不同的事。
Stripe 的代码库横跨少数几个大型仓库,总体规模达数亿行代码。我们的后端主要使用 Ruby(不是 Rails),并配合 Sorbet 类型系统——这套栈并不常见。同时,我们的代码大量依赖 Stripe 自研的内部库;这些库对 LLM 来说天然是陌生的。
风险也很高:这些代码在生产环境里承载着每年超过 1 万亿美元的支付交易量。与此同时,Stripe 在现实世界里还与金融机构存在复杂依赖,并且必须遵守大量监管、合规义务——我们的代码必须正确地兑现这些约束。
当一个系统的约束相对较少时,LLM 智能体非常擅长从零构建软件;但要在像 Stripe 这样规模、复杂度与成熟度都极高的代码库上迭代,本来就难得多。人类要做出有效改动,都必须先建立非常复杂的心智模型;要让智能体在有限的上下文窗口内形成正确直觉、并使用正确工具,同样充满挑战。
多年来,Stripe 在开发者效率的基础设施上持续投入,以支持我们在开发生命周期各阶段的独特约束——包括源码管理、环境、代码生成、CI 等等。因此,我们的 minion harness 会与这些工具链紧密集成。Minions 使用与 Stripe 工程师同样的开发者工具,让他们能在这种规模下有效工作:对人类好用的工具,对 LLM 也同样好用。
使用 minion 是什么体验?
Minions 有多种入口,我们尽可能让它们在 Stripe 工程师日常所在的地方“用起来顺手”。我们提供了 CLI 和 Web 界面来发起 minion,但最常见的方式还是从 Slack 启动:在讨论某个改动的 thread 里 @ 我们的 Slack app,就能直接启动一个 minion;它还可以把整个 thread 以及其中的链接都作为上下文读取。
如果你是做内部工具的工程师,你可能会用类似这样的消息启动一个 minion:

一条 Slack 消息触发一次 minion 运行
Minions 也可以在 Stripe 的其他内部应用里被调用。我们的内部文档平台、feature flag 平台、内部工单 UI 都与 minions 集成。举例来说,当 CI 系统检测到 flaky tests 时,我们会创建自动化工单,提示用户用一个 minion 来修复问题。

一个 flaky test 工单,带有启动 minion 来修复它的按钮
在 minion 工作期间或事后,工程师可以在 Web UI 里查看 minion 做出的决策与执行过的动作。

用于管理 minion 运行的 Web 界面示例
当任务完成后,minion 会创建分支、推送到 CI,并按照 Stripe 的 PR 模板准备好一个 pull request。如果代码看起来没问题,工程师就会打开 PR 并请求另一位 Stripe 工程师 review;如果不理想,工程师也可以给 minion 更多指令,它会在完成后把更新后的代码再推到该分支上。
工程师也可以在 minion 完成后对结果进行手工迭代。我们的北极星目标是“PR 完全由智能体产出、没有任何人类代码”;但即便 minion 的结果并不完全正确,它通常仍然是工程师集中火力继续完善的一个非常好的起点。
Minions 是怎么工作的?
一个 minion 的流程包含许多阶段;在本系列第二部分中,我们会提供更多关于它们如何工作的细节。很多细节是 Stripe 特有的,但我们也认为其中有一些经验值得推广。先给你一个“按时间顺序的速览”,吊吊胃口。
一次 minion 运行从一个隔离的开发者环境(我们称为 “devbox”)开始——这和 Stripe 工程师日常写代码使用的机器类型一致。Devbox 会被预热,因此我们可以在 10 秒内启动一个,且里面已预加载 Stripe 的代码与服务。它们与生产资源与互联网隔离,所以我们可以在不经过人工权限审核的情况下在 devbox 上运行 minions。这也提供了并行化能力,而不必承受像 git worktrees 这类方案在 Stripe 规模下难以扩展的开销。
核心的 agent loop 运行在 Block 的编码智能体 goose 的一个 fork 上。goose 是最早被广泛使用的编码智能体之一,我们很早就 fork 了它。我们以偏“强观点”的方式定制了编排流程,让智能体循环与确定性代码交错运行——例如 git 操作、lint、测试等等——这样 minion 运行既能利用智能体的创造力,又能保证它一定会完成 Stripe 强制要求的步骤(比如 lint)。
总体来说,minions 会读取与人类工具(例如 Cursor、Claude Code)相同的“编码智能体规则文件”,并兼容多种规则文件格式。但对 Stripe 来说,写很多无条件规则并不现实,所以我们几乎所有的 agent rules 都是基于子目录条件性生效的。
Minions 连接到 MCP(Model Context Protocol),它为可联网的 LLM 函数调用提供了一种通用语言。它们通过 MCP 获取上下文,例如内部文档、工单细节、构建状态、通过 Sourcegraph 搜索获得的代码情报等等。事实上,在 minion 运行开始之前,我们甚至会对看起来“可能相关”的链接确定性地运行一遍相关 MCP 工具,以便更好地“注水”上下文。
由于 MCP 是 Stripe 内所有智能体(不只是 minions)的通用语言,我们还构建了一个内部的中心化 MCP 服务器:Toolshed。它托管了超过 400 个 MCP 工具,覆盖 Stripe 使用的内部系统与各类 SaaS 平台。Minions 与其他智能体可以连接到这些工具的可配置但经过筛选的子集。
Minions 的目标是“一次成型”完成任务;但如果没做到,给智能体反馈就非常关键。我们通过多层自动化测试让 minions 能持续迭代。第一道防线是一个本地可执行程序,它会用启发式方法在每次 git push 时选择并自动运行部分 lint;这一步少于 5 秒。
在思考开发者效率时,我们追求“把反馈尽量左移(shift feedback left)”。这意味着:无论是人类还是智能体,只要某个 lint 步骤会在 CI 里失败,最好就能在 IDE 或 git push 时立刻被强制并呈现给工程师。
如果本地测试没有发现问题,CI 会在每次 push 时选择性地运行 Stripe 的测试体系——我们有超过 300 万个测试。很多测试的失败都有自动修复(autofix),我们会自动应用;如果某个失败没有 autofix,就把它交回给 minion 去尝试修复。
由于 CI 运行会消耗 tokens、算力与时间,我们最多只允许两轮 CI。如果第一次 push 后测试失败,我们会提示 minion 修复失败用例并进行第二次 push;之后就结束。这里需要在速度与完整性之间做权衡:让 LLM 反复跑完整 CI 循环的边际收益会迅速下降。我们的经验是:“通常一次,最多两次 CI——并且只有在我们已经本地修完一切能修的问题之后再跑”,在两者之间取得了不错的平衡。
总之,minions 被赋予了和人类工程师同样的工具、以及足够的上下文,使它们能写出符合 Stripe 最佳实践的代码;工程师也可以、并且确实会把它们自然地融入到日常工作职责之中。
接下来呢?
Minions 已经重新定义了 Stripe 的编码体验。行业仍在探索智能体式编程的未来会是什么样子,但我们确信,“无人值守的代码智能体”这一使用场景会长期成为智能体最令人兴奋的应用之一。
在第二部分里,我们会更深入地讲解 minions 的实现细节:https://stripe.dev/blog/minions-stripes-one-shot-end-to-end-coding-agents-part-2
如果你有兴趣和 minions 一起工作,或者直接参与 minions 的开发:我们正在招聘。