欢迎来到 Gas Town
Steve Yegge / 2026年1月1日
新年快乐,欢迎来到 Gas Town!
Gas Town 到底是什么?
Gas Town 是 2026 年对 IDE 的一次全新诠释。Gas Town 帮你处理同时运行大量 Claude Code 实例时的繁琐事务——东西容易丢、很难追踪谁在做什么,等等。Gas Town 帮你搞定这些杂活,让你专注于你的 Claude Code 们在做的事。
在这篇文章里,“Claude Code"的意思是"Claude Code 以及所有长得一模一样的竞品”,也就是 Codex、Gemini CLI、Amp、Amazon Q-developer CLI,balabala,因为它们本来就是这么回事——都是克隆品。整个行业就像一群令人尴尬的小孩踢足球,追着 Claude Code 2025 年 CLI 形态跑,而不是去构建下一代的东西。
我直接去构建下一代了。我先预测了它,早在三月份,在《初级开发者的复仇》那篇文章里。我预测会有人把 Claude Code 这些骆驼绑在一起套上战车,而这正是我用 Gas Town 做到的事。我已经把它们驯服到了你可以同时使用 20 到 30 个、持续高效运转的程度。
Gas Town 是有主见的——就像 Kubernetes 或者 Temporal,Gas Town 跟这两个都有几分相似,至少你把眼睛眯到快闭上的时候能看出来。我会在文末做跟 k8s 和 Temporal 的对比。它们之间的相似程度其实挺让人吃惊的,尽管底层机制完全不同。
但这个对比也是一个警告:Gas Town 很复杂。不是因为我想让它复杂,而是我不得不一直往里加组件,直到它成为一台能自我维持的机器。而它现在拥有的这些组件,看起来很像 Kubernetes 和 Temporal 交配生了一个非常丑的孩子。
但它能用!Gas Town 轻松解决了 MAKER 问题(20 层汉诺塔),用一个你可以从公式生成的百万步 wisp 就能搞定。昨晚我为了好玩跑了 10 层的,几分钟内就完成了,证明一千步完全不是问题(MAKER 论文说 LLM 在几百步后就会失败)。20 层的 wisp 大概需要 30 个小时。感谢收看我的 TED 演讲。
如果你能看完接下来的 23 页,这一切都会完全说得通。
Gas Town 不是秘密
在《初级开发者的复仇》之后,我整年到处旅行,大声地告诉所有人究竟需要构建什么——我是说所有人。我一点都不含蓄。我会宣布"编排器是下一个!“然后所有人都会缓缓点头,若有所思地皱眉,说"哦。”
我去找了 Temporal 和 Anthropic 等公司的高层,告诉他们应该构建一个 agent 编排器,说 Claude Code 只是一个积木块,接下来会是 AI 工作流和"agent 的 Kubernetes"的天下。我在多个活动上台演讲,描述我对编排器的愿景。我走遍各处,拜访了所有人。
"它会像 Kubernetes,但用于 agent,"我说。
"它必须有多层 agent 互相监督,"我说。
"它会有合并队列,"我说。
"它会编排工作流,"我说。
"它会有插件和质量门控,"我说。
我说了很多,持续了好几个月。但说真的,我们当时连让人用起 Claude Code 都费劲,更别说同时用 10 到 20 个了。
于是八月份我开始自己构建编排器,既然没人在乎。最终失败了,推倒重来做 v2,也失败了,但我们搞出了 Beads。然后是 v3(Python 版 Gas Town),撑了六七周。
Go 版 Gas Town 是我 2025 年完成的第四个完整可运行的编排器。我是怎么一路走到 Gas Town 的,这个故事很有意思,但留到下次再讲。不幸的是,光是讲清楚它怎么运作的最基本原理,这篇文章就已经够长了(25 页以上)。背景故事以后再说。
不过在讲 Gas Town 的运作之前,我需要先快速把你赶走。
警告 危险 注意
滚
你会死的
我来讲部分你不该用 Gas Town 的理由。我能想到更多,但这些够了。
首先,代码库不到三周大。从"打磨好的钻石"到"未加工原石"再到"我刚把它藏在屁股里走私了 400 英里",我要把 Gas Town 定性为"你大概还不该用它"。它需要消消毒。而且它是 100% vibe coded 的。我从没看过这些代码,也从不打算看,这或许让你有些顾虑。当然,我也从没看过 Beads,但它有 22.5 万行 Go 代码,每天有几万人在用。我十月份才创建它。如果这让你不舒服,现在就走。
其次,你真的、认真地还没准备好。让我们来聊聊 2024—2026 年程序员的进化,如图 2 所示:
图2:开发者 AI 进化的 8 个阶段
首先,找到你在图表上的位置。你在 AI 辅助编程之旅的哪个阶段?
- 阶段 1:零或接近零 AI:也许有代码补全,偶尔问问 ChatGPT
- 阶段 2:IDE 内的 coding agent,已开启权限。侧边栏里一个狭窄的 coding agent 请求你的许可才能运行工具。
- 阶段 3:IDE 内 agent,YOLO 模式:信任度提升。你关掉权限,agent 活动范围变宽。
- 阶段 4:IDE 内,宽范围 agent:你的 agent 逐渐占满屏幕。代码只剩 diff 视图。
- 阶段 5:命令行,单 agent,YOLO。diff 滚屏而过。你可能看也可能不看。
- 阶段 6:命令行,多 agent,YOLO。你经常同时使用 3 到 5 个并行实例。速度极快。
- 阶段 7:10 个以上 agent,手动管理。你开始触及手动管理的极限。
- 阶段 8:构建自己的编排器。你在前沿,自动化自己的工作流程。
如果你不至少是阶段 7,或者阶段 6 且非常勇敢,你将无法使用 Gas Town。你还没准备好。Gas Town 是一个由超级智能机器人黑猩猩运营的工业化编程工厂,当它们想发飙的时候,能在瞬间把你的东西搞得一团糟。它们会搞乱其他黑猩猩、工作站、客户。如果你不是经验丰富的黑猩猩驯服者,它们会扯掉你的脸。所以不行。如果你有任何一丝犹豫,你就不能用它。
在 Gas Town 里高效工作意味着你要投身于 vibe coding。工作变得流动,像一种无法计数的物质,你随意甩来甩去,就像在码头把闪亮的鱼铲进木桶。大多数工作会完成;有些工作会丢失。鱼从桶里掉出来。有些逃回了海里,有些被踩扁了。还会有更多鱼来。重点是吞吐量:以思维的速度创造和修正。
Gas Town 里的工作可以是混乱而粗糙的,这也是它得名的原因。有些 bug 被修了两三次,需要有人挑出赢家。其他修复则丢失了。设计不见了,需要重做。这无所谓,因为你在庞大、庞大的工作堆里不停向前推进,而 Gas Town 既在生产又在消耗这些工作。你可能不是 100% 高效,但你飞起来了。
在 Gas Town 里,你让 Claude Code 做它的事。你是产品经理,Gas Town 是一个创意编译器。你只需要想出功能、设计它们、提交实现计划,然后把工作甩给你的 polecats 和 crew。Opus 4.5 能处理任何合理大小的任务,所以你的工作就是给它制造任务。就这样。
另外,你还需要帮助维持 Gas Town 的运转。大多数时候它能自己跑,但经常出问题。需要你和 worker 们费很大力气才能让它平稳运行。这是一个非常需要双手握着方向盘的编排系统。
如果你不能这样工作,你他妈的还在这里干什么?回你的 IDE 避难去吧。Gas Town 对你不安全。
Gas Town 也贵得要死。如果你需要哪怕想一秒钟钱从哪里来,你就不会喜欢 Gas Town。我终于不得不开了第二个 Claude Code 账号;他们不让你从单个账号里无限提款,所以你需要多个邮箱和多个管道,这一切都很荒唐。我的计算显示,现在 Gas Town 终于起飞了,我下周末之前就需要第三个 Claude Code 账号。它是个现金吞噬机。
Gas Town 用 tmux 作为主要 UI。我不得不学习 tmux。它比我预想的容易,而且有用得多。用了三周,我爱上了 tmux。你也需要学一点 tmux。或者,你可以等到有人为 Gas Town 写出更好的 UI。更好的 UI 会来的。但 tmux 是你现在拥有的。而且值得学。
不管你喜不喜欢,Gas Town 是建立在 Beads 之上的。它实际上是 Beads 的续集:我的《帝国反击战》之于 Beads 的《星球大战》。Gas Town 没有"替代后端"。Beads 是 Gas Town 里发生的一切的通用 Git 支撑数据层(以及控制层,事实证明也是)。你必须用 Beads 才能用 Gas Town。
你可能不喜欢 Beads。如果你觉得 Beads 太强硬太独断,你有的受了。Gas Town 就是我大摇大摆走进 AI 辅助编程公众舆论教堂,抬起腿,放一个会飘遍全世界的响屁。
你们很多人可能会被我的品牌熏到作呕。但我猜会有少数人觉得成为超级英雄这件事足够诱人,愿意无视 Gas Town 的各种怪癖,站到我这边来。这才是工作本该有的样子。这已经是最好的方式,而且只会越来越好。
Gas Town 今年被设计为在三个维度上扩展:(1)模型认知能力提升,(2)agent 变得更兼容 Gas Town,(3)Gas Town 和 Beads 进入前沿模型的训练语料。即使没有这些,agent 们使用 Beads 和 Gas Town 的流畅程度已经让人震惊了。而且是在零训练的情况下。
但现在?就像 19 世纪末的工厂,机器在你不小心的时候能把你开膛破肚。
好了!这差不多是六个不用 Gas Town 的好理由了。如果我还没把你赶走,那我想你就是那种疯子了。撑住。这会是一段漫长而复杂的旅程。我尽量做到从上往下、尽可能简化,但它多少还是像本教科书。
抱歉。但我的辩护是:Gas Town 他妈的太好玩了。我做过的最好的东西。
我们开始吧。
Gas Town 101
Gas Town 的 worker 都是普通的 coding agent,每个被提示扮演七种明确定义的 worker 角色之一。我还会简要介绍一些其他关键概念,比如 Towns 和 Rigs。
有一点要提前说清楚:Gas Town 支持优雅降级。每个 worker 都可以独立工作,或小组协作,你可以随时选择运行 Gas Town 的哪些部分。它甚至支持"无 tmux 模式",用裸奔的 Claude Code session 勉强运行,没有实时消息。速度慢一点,但照样能跑。
七个角色协同工作,维持 Gas Town 运转。有时也需要你出手帮忙——Gas Town 靠汽油和体力各占一半。
以下是关键角色和概念:
小镇(The Town):这是你的总部。我的是 ~/gt,所有项目 Rig 都在它下面:gastown、beads、wyvern、efrit 等等。小镇(Go 二进制程序 gt)负责管理和编排所有 Rig 里的所有 worker。你把它放在一个单独的 repo 里,主要用于存放配置。
钻井平台(Rigs):你纳入 Gas Town 管理的每个项目(git repo)叫做一个 Rig。有些角色(Witness、Polecats、Refinery、Crew)是 per-rig 级别的,另一些(Mayor、Deacon、Dogs)是 town 级别的。gt rig add 及相关命令管理你在 Gas Town 体系内的 Rig。Rig 很容易添加和移除。
监督者(The Overseer):就是你,人类。第八个角色。图里给你画了眼妆。作为监督者,你在系统里有一个身份,有自己的收件箱,可以收发小镇邮件。你是老板、头头、大佬。
市长(The Mayor):这是你平时打交道最多的主要 agent。它是你的礼宾官兼参谋长。如果市长正忙,其他所有 worker 也都是 Claude Code,所以个个都聪明好用。市长通常负责启动大多数工作队列(convoy),并在任务完成时接收通知。
臭鼬(Polecats):Gas Town 是一个工作蜂群引擎。Polecats 是按需在各 Rig 上临时生成的 worker。它们经常以蜂群方式工作,产出 Merge Request(MR),然后交给合并队列(MQ)。合并完成后它们会被完全销毁,但名字会被循环复用。
炼油厂(Refinery):一旦开始大量蜂群工作,你就会遇到合并队列(MQ)问题。多个 worker 会陷入"猴子刀战"——争抢 rebase/merge,场面可以很难看。在蜂群期间 baseline 变化太快,最后几个要合并的 worker 面对的可能是完全认不出来的新 HEAD,需要彻底重新构思和重写自己的改动。这就是 Refinery 的工作:负责智能合并的工程师 agent,一次一个地把所有改动合并进 main。任何工作都不能丢失,但允许上报升级。
见证者(The Witness):当 Polecats 数量多起来后,你会发现需要一个专门的 agent 来盯着它们、帮它们解卡。Gas Town 的推进系统(GUPP)有效,但目前还有点不稳定,有时你需要去催 Polecats 提交 MR,再去催 Refinery 处理它们。Witness 巡逻机制让这个过程趋近完美。
执事(The Deacon):Deacon 是 daemon beacon(守护进程信标)的合称。名字来自 Dennis Hopper 在《未来水世界》里扮演的角色,而那个角色又受到《疯狂麦克斯》里 Lord Humungus 的启发——是个跨宇宙彩蛋。Deacon 是一个巡逻 agent:在循环中执行一套定义好的工作流(patrol)。Gas Town 的守护进程每隔几分钟 ping 一次 Deacon:“去干你的活。” Deacon 再把这个 DYFJ 信号智能地向下传递给其他 town worker,确保 Gas Town 持续运转。
狗(Dogs):灵感来自 Mick Herron 的 MI5 小说里的"Dogs"特工。这是 Deacon 的私人团队。Dogs 与 Polecats 不同,是 town 级别的 worker。它们负责维护工作(清理过期分支等)和 Deacon 交代的零活(比如运行插件)。Deacon 的巡逻任务越来越重,需要帮手,于是 Dogs 诞生了。这样 Deacon 可以专注完成自己的巡逻,而不是被某个步骤卡住动弹不得。Deacon 把杂活甩给 Dogs,Dogs 搞定脏活细节。
Boot(特殊的狗):有一只特殊的狗叫 Boot,每 5 分钟被守护进程唤醒一次,只干一件事:检查 Deacon 的状态。Boot 存在的原因是:守护进程之前老是用烦人的心跳和打气消息打断 Deacon,现在让狗来承受这些。Boot 判断 Deacon 是需要心跳、需要推一把、需要重启、还是干脆别打扰,然后继续去睡觉。
团队(The Crew):Crew 虽然排在最后,却是你在市长之外个人使用最多的 agent。Crew 是 per-Rig 的编码 agent,直接为监督者(你)服务,不受 Witness 管理。你可以给他们取名字,他们拥有长期身份。想开多少就开多少。tmux 快捷键让你用 C-b n/p 在每个 Rig 的 Crew 成员之间循环切换。Crew 是你以前工作流程的直接替代品——就是一堆有名字的 Claude Code 实例,能收邮件,能互相传活。Crew 特别适合设计类工作这种需要大量来回的场景。他们很棒。你会爱上你的团队的。
邮件与消息
Beads 是 Gas Town 里工作的原子单位。一个 bead 是一种特殊的 issue tracker 条目,有 ID、描述、状态、负责人等字段。Beads 以 JSON 格式存储(每行一个 issue),和你的项目 repo 一起用 Git 追踪。小镇邮件、消息(事件)以及其他类型的编排都使用 Beads。
Gas Town 有两级 Beads 结构:Rig beads 和 Town beads。
Gas Town 里同时有两个层面的工作在进行:Rig 级别和 Town 级别。
- Rig 级别的工作是项目工作:让你的项目变得更好。功能、bug 修复等。这些工作由 polecats 和 crew 分担,其他 worker 偶尔介入。
- Town 级别的工作是编排工作,包括巡逻(一长串要遵循的步骤,用链接的 bead 编码)以及一次性工作流,比如发布、或生成跨 rig 的代码评审波次。
这两种工作都使用 Beads,两者之间有一些重叠。总体来说相当灵活,你在哪个 rig 里提 issue 或发起工作并不太重要。所有 worker 都对 Gas Town 的地盘很熟,就算你把活儿丢错地方,他们也不会有什么意见。
所有 rig 级别的 worker(refinery、witness、polecats 和 crew)在需要时完全可以跨 rig 工作。他们可以使用 gt worktree 命令自行克隆任意 rig 然后去修东西。但通常情况下他们只在单个项目里干活。
Beads 支持跨 rig 路由。Gas Town 把 Beads 配置成根据 issue 前缀(比如 “bd-” 或 “wy-”)把 bd create、bd show 这类请求路由到正确的数据库。所有 Beads 命令基本上在 Gas Town 任何地方都能用,自动找到正确的存放位置,就算找错了,迁移 Bead 也很简单。
关于疯狂麦克斯主题的说明
Gas Town 就是 Gas Town。它起初确实有疯狂麦克斯的主题风格,但其实并不那么强烈。所有角色名都不是系列里的正式人名,而且也在引入其他来源的主题风格,包括《慢马》宇宙、《未来水世界》、《猫的摇篮》、《绝命毒师》(很快就会看到),以及显然还有《柳林风声》——从 Nano Banana 的插图来看。
如果哪天有人发来停止侵权函,Gas Town 会像聪明章鱼一样变形成 Gastown——就以不列颠哥伦比亚省美丽的温哥华 Gastown 区命名,而那些 polecats 也只是在另一种不同的杆子上而已。
简而言之,"Gastown"也是这个项目的正确叫法。说完这个……
Gastown 通用推进原理(GUPP)
GUPP 是让 Gas Town 持续运转的动力机制。Claude Code 最大的问题是它会停下来——上下文窗口填满,动力耗尽,然后停止。GUPP 就是我对这个问题的解决方案。
GUPP 的表述很简单:如果你的 hook 上有工作,你必须去执行它。
Gas Town 所有 worker、所有角色,都在 Beads 里(也就是在 Git 里)拥有持久身份。worker 的身份类型由 Role Bead 表示,类似一张描述该角色的领域定义表。每个 worker 还有一个 Agent Bead,是 agent 的持久身份。
Role Bead 和 Agent Bead(以及 Hook)都属于"钉住的 bead(pinned beads)"——它们像黄色便利贴一样浮在 Beads 数据层里,不会像普通 issue 那样被关闭(除非这个身份消失)。它们不会出现在 bd ready(待处理工作)列表里,在各种场景下都会被特殊对待。
在 Gas Town 里,agent 不是 session。Session 是临时的,是 Kubernetes “宠物 vs 牲口"比喻里的"牲口”。Claude Code session 就是 Gas Town 用来处理持久工作的牲口。而那些工作本身、worker 的持久身份、邮件、事件系统、甚至临时编排,全部活在 Beads 里。
在 Gas Town 里,一个 agent 就是一个 Bead,是一个拥有全局唯一地址的单例身份。它有几个槽位,包括一个指向其 Role Bead 的指针(里面有该角色的初始化信息等)、它的邮件收件箱(全部是 Beads)、它的 Hook(也是一个 Bead,用于 GUPP),以及一些管理信息,比如编排状态(标签和备注)。这个 agent 所做的一切历史记录,都保存在 Git 和 Beads 里。
那么 Hook 是什么?每个 Gas Town worker 都有自己的 hook
。它是一个专属于该 agent 的特殊 pinned bead,你把**分子(molecules)**挂在上面——所谓分子,就是 Gas Town 的工作流。
工作怎么挂上去的?用 gt sling,当然。你把工作 sling(甩)给 worker,它就挂到他们的 hook 上。你可以让他们立即开始,或推迟执行,甚至让他们先重启再开始。把活甩出去之后,你就可以去忙别的,他们会自己继续干。
Gas Town 最简单也最妙的一点是:在任何 session 里,任何时候,你都可以说"交接吧",worker 就会优雅地收尾并重启自己。有了 GUPP,只要 hook 上有活,agent 就会自动继续工作。
可惜 Claude Code 礼貌得令人抓狂,GUPP 在实践中并不总是奏效。我们告诉 agent"你必须执行你的 hook",它有时候什么都不做,就那么坐着等用户输入。
于是有了变通方案。
GUPP Nudge(推一把)
Gas Town 的 worker 被要求遵循"物理法则优先于礼貌",并被告知在启动时就要看自己的 hook。如果 hook 上有活,必须不等待地直接开始干。
但现实是,Claude Code 经常要等你打点什么——随便什么——才会去检查邮件和 hook、报到、然后开始工作。有时候自己就动了,有时候不行。这个问题会随时间改善,但现在有时候就是需要推一把。
因为 worker 不总是遵守 GUPP,系统里有各种机制会在 agent 启动后大约 30 到 60 秒内推它一把,有时快一点,有时慢一点,但只要小镇在运行、没进入静默状态,5 分钟内它一定会被推到。
具体方式是用 gt nudge 给 agent 发一个启动戳——这是 Gas Town 的核心实时消息命令,向某个 worker(或整个频道)发送 tmux 通知。它解决了 tmux send-keys 的一些防抖问题,确保 worker 收到通知时就像是用户亲手打进去的一样。这就把 worker 踢进读邮件、看 hook、然后采取行动的流程里。
有了 GUPP Nudge 这个"hack",再加上 Deacon 向下的层级心跳机制,GUPP 总体上就嗡嗡运转起来了,只要还有活,Gas Town 就一直跑。工作队列(convoy)自动启动、完成、落地,不需要人干预。Worker 跨 session 继续执行分子工作流。只要你喂够活,Gas Town 可以干一整夜。
与前任对话——gt seance(通灵)
GUPP Nudge 带来了一个有趣的衍生功能:gt seance,让 Gas Town worker 能够直接与同角色的前任对话。比如当前市长可以和上一任市长沟通,以此类推。实现方式是借助 Claude Code 的 /resume 功能——它允许你重启之前关掉的旧 session。
这个功能很实用,因为经常会出现这种情况:一个 worker 说"好了,我把一大堆工作和建议都交接给继任者了!拜!/handoff",然后消失;新 worker 启动后却一脸懵逼:"什么?我啥都没看到。"以前你只能笨拙地去翻最近 40 来个 session,试图找出哪个是上一任的——而那些 session 全都以"let’s go"开头,因为你一直在手动做 GUPP nudge。非常别扭,几乎不值得费这个劲。
gt seance 的由来是这样的:你在 nudge 里告诉 agent 什么内容其实无所谓。因为他们的提示词对 GUPP、Gas Town 运作原理、以及"你是机器里多么重要的一颗齿轮"之类的东西规定得极其严格,agent 会完全无视你打的任何内容——除非你是在直接覆盖他们的 hook 指令。
所以你只需要说"hi",或者"埃隆·马斯克说月亮是绿色奶酪做的",或者"去干活",agent 就会执行 hook。
我一周前的想法是:既然反正要 nudge 所有 session,我就决定把 Claude Code 的 session_id(以及 Gas Town 角色和 PID)一起塞进 nudge 里。这样每个 /resume session 就有了一个唯一的、有用的、可发现的标题。
有了 gt seance,worker 会在子进程里启动 Claude Code,用 /resume 复活前任,然后问它:“你给我留的东西他妈的在哪儿?”
好时光啊,我跟你说。Gas Town 就是好时光。
我觉得现在差不多可以聊聊 MEOW 栈了。我觉得你准备好了。
工作的分子表达(MEOW)
Gas Town 只是一座深水冰山的尖顶。Gas Town 本身可能活不过 12 个月,但 Gas Town 的骨架——MEOW 栈——可能会存续好几年。它感觉更像是一个发现,而不是一个发明。
首先是 Beads。十月份,我沮丧地告诉 Claude 把我所有的工作放进一个轻量级 issue tracker。我想用 Git 来管它。Claude 想用 SQLite。我们各退一步,Beads 就这样诞生了,整个疯狂的设计只用了大约 15 分钟。这些就是基本工作单元。
接着是 Epics(史诗):带子项的 Bead,子项本身也可以是 Epic。这给了你极大的灵活性来构建自顶向下的计划。Epic 的子项默认是并行的,但你可以在它们之间设置显式依赖关系来强制顺序执行。Epic 允许创建"倒置"计划——最后要做的事是根节点,最先要做的事是 Epic 树的叶节点。有点丑,但 AI 完全能搞定。
然后是 Molecules(分子)。这个想法出现在 12 月 17 日,我从澳大利亚回来几天后。在前两个编排器上的工作让我想把 agent 的工作拆成有序的小任务让它们逐一打勾,就像 TODO 列表。Agent 本来就会这么做,但我想提前设好,这样我可以预先布置好几个小时的工作,让它们按正确顺序原子性地执行。
换句话说,Molecule 就是工作流,用 Bead 串联起来。它们可以有任意形状,不像 Epic 那样受限,而且可以在运行时拼接组合。
然后是 Protomolecules(原分子),类似类或模板——由真实的 Bead 构成,所有指令和依赖关系都预先设置好,是一整张模板 issue 的图(比如一个简单流程里的"设计"、“计划”、“实现”、“评审”、“测试”),你可以把它实例化成一个 Molecule。实例化的过程就是复制所有原分子的 Bead,对其进行变量替换,生成一个真实的工作流。
举个例子:我的 Beads 发布流程有 20 个步骤。Agent 以前很难走完,因为中间有很多等待状态——比如等 GitHub Actions 完成、等 CI 跑完、等各种产物部署好。我不得不不断催促 agent,而他们总是跳过步骤。
有了 Molecule,思路是:为 20 个发布步骤各建一个 Bead,按正确顺序串成链,让 agent 一次走一个 issue。额外的好处是,随着它们认领和关闭 issue,自动产生一条活动流水线。
如果工作流被捕获为 Molecule,它就能在 agent 崩溃、压缩、重启、中断之后存活下来。只要在同一个沙箱里重新启动 agent,让它找到自己在 Molecule 里的位置,从断点继续就行。
Protomolecule 很好用。Claude 坚持用了《无垠太空》里的这个名字,确保我们会被几乎所有大制片公司起诉。但我们很快发现需要一个宏展开阶段,才能正确地用循环和门控来组合 Molecule。于是我为工作流设计了一种源格式——Formulas(公式),用 TOML 格式,被"烹饪"成 Protomolecule,然后在 Beads 数据库里实例化成 wisp 或 mol。
Formula 提供了一种方式,让你能够描述和组合几乎所有的知识工作。我正在为它们搭建一个叫做 Mol Mall 的市场。敬请期待。
最后,我需要一个词来表示"分子化的工作"——以 agent 可以一步一步认领和完成的形式存在的工作。这种工作可以相互组合,分子与分子结合,你可以提前为一整个巨大项目设置好依赖关系,然后让 Gas Town 整个周末不间断地蜂群处理它——如果你够勇敢的话。
这一大片工作分子的海洋,世界上所有的工作,用"guzzoline"(汽油)来表示,虽然我们在文档里不太用这个词。它只是一个 Gas Town 习语,有点像 War Rig——这是某个给定 Rig 在跨 rig Convoy 中的贡献。你会时不时听到,但不是日常命名的重要部分。
非确定性幂等性(NDI)
Gas Town 运行在我称之为"非确定性幂等性"(Nondeterministic Idempotence,NDI)的原则之上。它类似于 Temporal 的确定性、持久重放,但 Gas Town 通过完全不同的机制实现其持久性和执行保证。
在 Gas Town 里,在 MEOW 栈上运作,所有工作都以分子形式表达。这其中有一点代数学问题,是我在过去两周里发现的。Molecule 是工作流。它们可以有复杂的形状,有循环,有门控,实际上是图灵完备的。而工作流的每一步都由一个超级智能 AI 执行。
因为 AI 非常擅长遵循 TODO 列表和验收标准,所以它们在遵循 Molecule 方面是可靠的。它们理解 GUPP 的概念,也理解不论多微不足道都要打勾关 issue 这套官僚程序能把工作记录到实时活动流和永久账本上。这种推理足以让它们在执行过程中保持嗡嗡运转、不跑偏。它们不会"感到无聊",也不太可能犯错,因为它们不需要自己管理 TODO 列表(只在单个小步骤内部管理)。
这意味着分子工作流是持久的。如果一个 Molecule 挂在 agent 的 hook 上,那么:
- Agent 是持久的:一个由 Git 支撑的 Bead。Session 来了又走;agent 一直在。
- Hook 是持久的,也是一个由 Git 支撑的 Bead。
- Molecule 是持久的——一串 Bead,也在 Git 里。
所以 Claude Code 崩溃了,或者 context 用完了,都无所谓。一旦这个 agent 角色的另一个 session 启动,它就会立即开始处理 Molecule 里的那一步(通过 GUPP,或者当它被某个巡逻 agent 推一下时)。如果它发现自己在上一步的中途崩溃了,没关系,它会找出正确的修复方法,执行,然后继续。
所以即使路径是完全非确定性的,结果——你想运行的工作流——最终会完成,“有保证”,只要你不断向它投入 agent。Agent 在过程中甚至可能犯错,但可以自我修正,因为 Molecule 的验收标准假设是由设计 Molecule 的人明确规定的。
有大量边缘情况。对 NDI 的这段描述是过于简化的。Gas Town 不是 Temporal 的替代品。请咨询你的医生 Gas Town 是否适合你。但 Gas Town 确实提供了对于开发者工具来说完全够用的工作流保证!如果你是我的话!
Wisps:临时编排 Bead
教科书里还有一些角落我们应该简单涉及。大多数时候你不关心这些,你关心的是 convoy 启动和完成,以及看活动流和仪表盘。但 Gas Town 的分子"化学"有很多丰富的角落,在编排中被积极使用。
12 月 21 日的一个关键扩展发明是 Wisps——临时 Bead。它们在数据库里,有哈希 ID,表现得像普通 Bead。但它们不会被写入 JSONL 文件,因此不会被持久化到 Git。在它们运行结束时,Wisps 被"燃烧"(销毁)。可选地,它们可以被压缩成一行摘要然后提交到 git。
Wisps 对于高速编排工作流很重要。它们是 Gas Town 工作的气态物质。所有巡逻 agent——Refinery、Witness、Deacon、Polecats——都会为每次巡逻或工作流运行创建 wisp 分子。它们确保工作流以事务方式完成,但不会用编排噪音污染 Git。
巡逻(Patrols)
巡逻是为巡逻 Worker 运行的临时工作流,主要包括 Refinery、Witness 和 Deacon。
巡逻是 agent 循环运行的临时(wisp)工作流。巡逻有指数退避:如果 agent 在巡逻步骤中没有发现工作,它会逐渐进入休眠,等待越来越长的时间才开始下一次巡逻。任何有变更效果的 gt 或 bd 命令都会唤醒小镇,你也可以用 gt 命令自己唤醒,可以启动单个 worker、一组 worker、一个 rig 或整个小镇。
Refinery 的巡逻相当简单。有一些预检步骤来清理工作区,然后处理合并队列直到队列为空,或者需要回收 session。在准备好交接时,Molecule 里还有一些收尾步骤。我正准备给 Refinery 的巡逻加上插件,但还没有。等我加上之后,你就能添加可以干预 MQ 并尝试智能重新排序的插件,把 Gas Town 的后端接入其他系统。
Witness 的巡逻更复杂一些。它要检查 polecats 的健康状况,以及 refinery 的状况。它也会悄悄看一眼 Deacon,确保它没有卡住。而且 Witness 还运行 Rig 级别的插件。
Deacon 的巡逻有很多重要责任。它运行 Town 级别的插件,这些插件可以提供全新的 UI 或能力。Deacon 还参与 gt handoff 的协议和回收 agent session,以及确保一些 worker 被正确清理。Deacon 的巡逻变得足够复杂,我于是添加了 Dogs 作为帮手,Deacon 的私人团队。现在它被提示把复杂的工作和调查交给 Dogs,这样长时间运行的巡逻步骤就不会干扰小镇基于邮件协作的核心事件系统。
Gas Town 插件
Gas Town 把插件定义为"来自 agent 的有协调的或有计划的关注"。Gas Town worker 运行工作流(通常在巡逻循环里),任何工作流都可以包含任意数量的"运行插件"步骤。
Gas Town 的 Deacon 巡逻运行 Town 级别的插件,现在它们通过 Dogs 运行,所以可以运行实际上无限长的时间。我们有一些对定时器和回调的支持,但大多数是生命周期钩子。我还没有在这个子系统上投入太多设计思考,所以如果你想开始使用插件系统,告诉我,我们一起想。
我计划以插件形式实现 Gas Town 的大量附加功能。它们只是没来得及进入 v1 发布。它们大概最终会以 Mol Mall 里的 formula 形式出现。
Convoys(护送队)
好了,呼。你做得很好。我们涵盖了很多理论,而且是特别难的理论,因为这是我过去三周从屁股里掏出来的一堆废话,我用獾和其他东西给它们命名了。但它有一种优雅的一致性和连贯性。基于 Git 数据层里小黄便利贴的工作流编排,作为互连工作海洋里的图节点。
呸!没人在乎,我知道。你想以超人的速度把事情搞定,唯一的限制是你吞 token 的速度。我们来聊聊怎么做。
Gas Town 里的一切,所有工作,都汇总进一个 Convoy。
Convoy 是 Gas Town 的票务或工作订单系统。
一个 Convoy 是一个特殊的 bead,把一堆工作包装成一个你跟踪交付的单元。它不使用 Epic 结构,因为 Convoy 里跟踪的 issue 不是它的子项——它们大多数已经有了另一个父级。
Gas Town 里甩活的基本原语是 gt sling。如果我告诉市长"我们的 tmux session 在状态栏里显示的 rig 数量不对——提个 issue 然后把它甩出去",市长就会为这个问题提一个 bead,然后用 gt sling 把它甩给一个 polecat,polecat 立即开始处理。
真实例子:我经常告诉我的 Beads crew 把 release molecule 甩给一个 polecat。polecat 会走完 20 步发布流程,完成后我会收到 Convoy 已落地/完成的通知。编辑:实际上现在更高级了。当 molecule 处于 Gate 等待状态时(比如等待 GH Action 或 CI/CD),polecat 会消失。然后当 Gate bead 触发时,Gas Town 会唤醒一个 polecat 来继续工作。
听到"issue wy-a7je4 刚完成"会让人困惑。即使你看到了标题,它可能也无法反映那个 issue 所属的更大工作块。所以现在我们把每一个被甩出去的工作单元——从单个 polecat sling 到有人启动的大蜂群——都用一个 Convoy 包装起来。
Convoys 出现在一个每天都在变得更好的仪表盘里;有一个 Charmbracelet TUI,每个 convoy 有可展开的树,你可以看到它的各个被跟踪 issue。UI 和 UX 会改善。这是 Gas Town 的第一天。
Convoy 基本上就是功能。不管是技术债清理、实际功能,还是 bug 修复,每个 convoy 都是 Gas Town 工作订单架构里的一个票务单元。它们很新(大概三四天大?),但已经是迄今为止最有趣的工作方式了。
注意一个 Convoy 可以有多个蜂群"进攻"它(处理它)才能完成。蜂群是临时 agent session 在承接持久工作。管理 Convoy 的人(比如 Witness)会持续回收 polecats 并把它们推向各个 issue。
Gas Town 工作流
Gas Town 最基本的工作流是交接,gt handoff,或者 /handoff 命令,或者就说"让我们交接吧"。你的 worker 会可选地给自己发送工作,然后在 tmux 里直接重启自己的 session。你直接指挥的所有 worker——市长、你的 Crew,有时还有其他人——都需要你告诉他们该交接了。
除此之外,Gas Town 的开发循环和 Claude Code(加 Beads)差不多,只是更多而已。你免费获得蜂群(它们只花钱),你获得一些不错的仪表盘,你获得一种描述工作流的方式,你获得邮件和消息。就……这些了。
我发现 tmux 既容易使用又出奇地强大,而且我才刚刚开始学习它的来龙去脉。它给了我所需的一切:切换到任何 agent、扫描它们都在做什么、在不同相关 agent 组之间循环切换。太好了。
我当然期待 Gas Town 的 Emacs UI。我也确信你们中有些人期待 Web UI。自便吧!
但 tmux 已经够用了。要熟练使用不需要学很多 tmux 命令。我只用几个:
-
C-b s— 列出 session,查看它们,切换到某个 -
C-b b— 向后移动光标(在很多编辑器和 shell 里是C-b)。在 tmux 里只是移动得慢一点。代价很小! -
C-b [— 进入"复制模式",暂停输出,让你可以滚动(ESC退出) -
C-b C-z C-z— 挂起进程回到 shell -
C-b n/p— 循环到组里的下一个/上一个 worker(比如 rig 里的下一个 Crew 成员) -
C-b a— 调出活动流视图(我的配置)
就这些!我发誓,你不需要太多 tmux。它不碍你的事,而且经常帮你的大忙。它还支持远程云 worker(我们几天内会接上),而且可定制性极强。你只需要让 Claude Code 帮你让 tmux 更好用,它就会做到。它会做任何你想要的视图,随你意愿重新绑定按键,做自定义弹窗,whatever。太神奇了,几乎像个迷你 Emacs。
Gas Town 里的规划
Gas Town 需要大量燃料。它既消耗又产生 guzzoline,也就是工作分子。除了保持 Gas Town 在轨道上运行,可能最难的问题就是保持它被喂饱。它消耗实现计划的速度太快,你必须做大量设计和规划来维持引擎的饲料供应。
在消耗侧,你给 Gas Town 喂 epic、issue 和 molecule(构建好的工作流)。它咀嚼它们,生成……好吧,我现在尽量把它控制在 30 个 worker 以内,因为我还没实现超大规模云端的远程 worker(即将推出!),通常除非我真的使劲推市长和 Witness,否则只有十几个活跃的。
但哇。有 12 到 30 个 worker,你可以在一次坐下来的时间里烧完庞大的工作积压,即使你在用做了额外代码评审和测试步骤(因此需要更长时间)的"shiny"或"chrome" polecat 工作流也一样。
在生产侧,你可以使用自己的规划工具,比如 Spec Kit 或 BMAD,然后一旦你的计划准备好了,让一个 agent 把它转化成 Beads epic。如果计划足够大,你可能想要蜂群处理它,在一个大 convoy 里为计划的不同部分生成 epic。
你可以使用 formula 来生成工作。如果你希望每一项编码工作(或设计工作,或 UX 工作)都经过特定模板或工作流,你可以把它定义为一个 molecule,然后"包装"或组合基础工作与你的编排模板。
我实现了一个 Jeffrey Emanuel 的"五规则"formula——这个观察是:如果你让 LLM 以不同焦点区域评审某样东西五次,它会生成更优质的成果和产出。所以你可以拿任何工作流,用五规则来烹饪它,它就会让每一步被评审四次(实现本身算第一次评审)。
这可能会生成非常大的工作流,需要你花费很多小时乃至数天才能处理完,尤其是如果你限制 polecat 数量来控制成本或 token 消耗的话。但 Gas Town 的好处是,一旦工作生成好了,你可以把它挂上 hook,自主地烧完它。
与 Kubernetes 的对比
这是我承诺的 Kubernetes 对比。随意跳过。
Gas Town 确实在一定程度上无意间像 Kubernetes。两个系统都在协调不可靠的 worker 朝着目标前进。两者都有控制层面(Mayor/Deacon vs kube-scheduler/controller-manager)监管执行节点(Rigs vs Nodes),每个节点都有一个本地 agent(Witness vs kubelet)监控临时 worker(Polecats vs Pods)。两者都使用整个系统对齐的事实来源(Beads vs etcd)。这些显然是当你需要大规模驯猫时自然涌现的形状。
最大的区别是,Kubernetes 问"它在跑吗?“而 Gas Town 问"它完成了吗?” K8s 为正常运行时间优化——保持 N 个副本存活,重启崩溃的 pod,永远维持期望状态。Gas Town 为完成优化——完成这项工作,落地 convoy,然后销毁 worker 继续前进。K8s 的 pod 是匿名牲口;Gas Town 的 polecat 是被记功的 worker,其完成记录积累成 CV 链,session 才是牲口。K8s 向连续的期望状态对齐;Gas Town 朝向终结目标推进。引擎形状相似,目的地截然不同。
我没时间做的事
我本想在圣诞节发布 Gas Town,结果错过了。它直到 12 月 29 日晚上 8 点左右才真正开始运作,我是说飞起来,像我设想的那样。它飞了两个小时我才注意到。我一直在和市长聊天,抱怨各种事情,然后修复开始在我周围落地,我意识到我只是通过说话就在塑造整个系统。convoy 在流动和落地,工作在被提交和评审……这是我几个月来一直在追求的东西。而我只在两天前才让它运作起来。足够发布了!
以下是没赶上新年截止日期的内容:
- 联邦化 — 就连 Python Gas Town 也支持 GCP 上的远程 worker。我需要设计联邦化支持,包括扩展你自己小镇的容量,以及与其他人的小镇链接和共享工作。
- GUI — 我甚至没时间做 Emacs UI,更别说好看的 Web UI 了。但有人应该去做,如果没人做,我迟早会搞的。
- 插件 — 我没机会在 molecule 步骤上实现任何功能作为插件,但所有基础设施都到位了。
- Mol Mall — 定义和塑造工作负载的 molecule 的市场和交易所。
- 汉诺塔/MAKER — 我想运行百万步 wisp 但没时间了。
话虽如此,我对确实完成的内容很满意:
- 自我交接顺畅运作——Gas Town 核心内循环工作流
- Slinging 能用,convoy 能用
- 整个 MEOW 栈能用
- Deacon、Witness 和 Refinery 巡逻都能自动运行
- Crew 很好用,比裸 Claude Code 实例好太多
- tmux UI 出乎意料地好用,比我预想的更好
加上我们还得到了一些很酷的功能,比如 gt seance。总的来说,17 天的工作不错。到目前为止。
下次再见
我和你一样精疲力竭了。聊得很开心,但我得回 Gas Town 了。
还有更多内容。这只是尝一口。我会发布更多关于 Gas Town 的博客、视频和内容。如果你想贡献,而且够疯愿意跳上这辆车,加入社区,开始发送讨论、GH Issues 和 PR!
只要记住黄金法则:
- 如果你不是每天同时处理至少五个 Claude Code,不要用 Gas Town。
- 如果你在乎钱,不要用 Gas Town。
- 如果你超过 4 英尺高,不要用 Gas Town。我想在见面会上像索伦一样高得令人印象深刻。
- 不要用 Gas Town。
Gas Town 只有 17 天大,至少这个版本——Python Gas Town 的 Go"移植版"。过去两周见证了整个 MEOW 栈、wisp、巡逻、convoy、作为 bead 的 agent 和身份、作为 bead 的蜂群、作为 bead 的角色、"feed as the signal"创新,以及 Refinery、Deacon 和 Dogs 的添加(相比 Python Gas Town)的发明和实现。以及大量其他东西。
17 天,7.5 万行代码,2000 个 commit。GUPP 两天前才真正开始工作。今年看来会很有意思。
我在十一月把 Gas Town 分享给了 Anthropic,至少是大致轮廓。我觉得我吓到他们了。我从没见过一家公司变得这么保守,这么快。但他们觉得Beads都太有主见了,所以恐怕 Gas Town 会是一个放得太远的屁,如他们所说。
但我已经开始收到一些奇怪的邀约,来自嗅到早期 Gas Town 风声的人,请我坐在家里当我自己:我可以继续研究 Beads 和 Gas Town,只需要偶尔写篇好博客或去参加会议或工作坊就行。我现在有三个这样的邀约。几乎像是在做梦。
这让我想起了我在 Crunchyroll 上看了几集的一部动漫,一只懒惰的熊猫找不到工作,整天向他开咖啡馆的北极熊朋友抱怨。然后有一天,他去了动物园,发现那里有熊猫展区的职位广告。于是他申请了,接受了这份工作,白天坐在那里扮演熊猫,晚上回家。实在太荒唐了。
我就是那只熊猫。
在我找到一家"懂"的公司和团队之前,我不打算回去工作。我厌倦了四处游走,把未来就这样摆在人们面前,挥来挥去,却不被相信。
我宁愿坐在家里,用自己的双手创造未来。我的地产上实际上有六种竹子。我已经是熊猫了,过着我人生中最美好的时光。
如果你想帮我,联系我!无限感谢所有了不起的 Beads 贡献者!
下次再见,带来更多 Gas Town 内容。新年快乐!