人物雷达|Mitchell Hashimoto:每次 agent 犯错,就改造环境

人物雷达|Mitchell Hashimoto:每次 agent 犯错,就改造环境

一个被反复删除的 issue

2025 年春天,Ghostty 的 GitHub 仓库里出现过一个很短的插曲。

有用户在 issue 里贴了另一个终端模拟器的源代码片段,希望 Ghostty 参考实现。Mitchell Hashimoto 很快把这段代码删掉了,并留下一条说明:Ghostty 是 MIT 许可,对方是 GPL,贴进来就污染了整条上游。

几小时之后,那位用户回来了,补上一条看似合理的建议:“那你让 ChatGPT 生成一段类似的代码就行。”

Mitchell 没有立刻同意,也没有立刻拒绝。他反问了一句——“这样做安全吗?是不是只是把代码通过一个模型洗了一遍?”

这是一个微小到几乎不值得记录的交互。但在今天回看,它几乎是 Mitchell 所有 AI 观点的浓缩:他愿意使用 AI,但不相信任何关于 AI 的“捷径叙事”;他接受不确定性,但不愿意用自信掩盖不确定。

过去两年,硅谷工程师里谈 AI 的声音被分成两派。一派是布道者,宣称编程即将终结;一派是反对者,认定 agent 只是高级补全。Mitchell Hashimoto 很少被归进任何一派,但他在自己的博客、Zed 的访谈、Heavybit 的播客、Open Source Ready 的长对话里,一砖一瓦地搭起了第三种姿态——AI agent 并没有那么神秘,它只是软件工程里一个新的、需要被工程化的对象。

这个姿态里,最常被引用的一句话是他自己写下来的:“当 agent 犯错,就花时间工程化一个解决方案,让它不再犯同样的错。”

他把这件事叫做 harness engineering。

一个“不愿意交付自己不理解的代码”的人

要理解 Mitchell 的这套哲学,不能从 AI 开始,要从终端开始。

在自己网站上,他把现在的身份写得极简——主要在做 Ghostty;曾在 HashiCorp 做过约四年 CEO、五年 CTO、两年个人贡献者,2023 年离开公司。HashiCorp 旗下的 Vagrant、Packer、Consul、Terraform、Vault、Nomad、Waypoint,今天几乎是云基础设施的默认词汇。他把一家公司做到上市之后选择抽身,回到一个没有融资计划、没有商业化路径的开源终端项目上,这在硅谷是个很任性的选择。

但只要把这些工具连起来看,会发现一条不算太隐秘的主线:他做的每一样东西,几乎都在回答同一个问题——怎么让开发环境变得可描述、可复制、可被机器执行?

Vagrant 解决本地开发环境的复现;Terraform 解决云基础设施的声明;Nix 让整台桌面可以 as code 地重建;Ghostty 是终端,仍然是环境的一部分。他在 Open Source Ready 谈 Nix 时顺便说过一句,自己对 Nix 的兴趣,其实是想要一种可靠、一致、可被代码重建的桌面。这句话放在 Terraform 的早期也完全成立。

所以当 Mitchell 进入 agent 时代,他看它的视角不是“模型崇拜”,而是“环境工程”。对他来说,agent 不是黑箱智能体,而是一个会在环境里读文件、执行程序、调用工具、观察结果、继续行动的系统。既然它要行动,环境就必须纠错;既然它会重复犯错,系统就该把这些错误沉淀成规则、脚本和反馈回路。

从“改比写还慢”到“强迫自己复现”

Mitchell 并不是 AI 乐观派的天然成员。

在《My AI Adoption Journey》里,他承认自己第一次认真用 Claude Code 的体验相当糟糕——生成的代码要大改,改完比自己写还慢,他一度怀疑这东西是不是真的能用。

他没有就此下结论。相反,他做了一件很笨的事:先用手写 commit 把一个任务完成,然后关掉答案,让 agent 在看不到自己答案的前提下,复现同等功能和质量的结果。

这个过程他承认很痛苦,因为它妨碍了正常交付;但他坚持了下来,因为这是他建立“直觉”的唯一方式——agent 到底适合什么、不适合什么,不是读 paper 读出来的,是一个一个任务试出来的。

这段经历让他得到三条非常朴素的原则:

  • 任务要拆小。 不要把一个模糊的大目标丢给 agent。
  • 模糊需求要拆成规划和执行两个阶段。 先想清楚做什么,再让 agent 动手。
  • 最重要的:给 agent 一种验证自己工作的办法。 只要它能自己跑测试、自己看输出,它往往能自己修好。

很多人读到第三条时会愣一下。这不就是 CI、测试、lint、端到端脚本吗?是的。这正是 Mitchell 的风格——他不造新词,他把老工程师的常识原样搬进 AI 时代。过去我们说“不要让人记住规则,让系统执行规则”;现在他说,“不要指望 agent 下次变聪明,要把这次错误变成环境的约束”。

Harness Engineering:错误不是事故,是系统的缺口

Harness 这个词本身不新。LangChain 早就把它写进定义里:Agent = Model + Harness。模型提供智能,harness 让智能变得可用——文件系统、bash、沙箱、工具、状态、反馈回路,都是 harness 的一部分。

Mitchell 的贡献不在术语,而在一种工作习惯:他把所有 agent 的错误都当作系统缺口,而不是模型愚蠢。

在 Zed 的访谈里,他把 harness 的形式拆成两类——

第一类是“更好的隐式提示”,最典型的载体是 AGENTS.md。如果 agent 总是跑错命令、找错 API、误解子系统,就把这些经验写进项目根目录或子目录的指导文件。Ghostty 的 src/inspector/AGENTS.md 就是个小而典型的例子:它告诉 agent,inspector 类似浏览器开发者工具;去哪里找 dcimgui.h;如何查 widget 示例;macOS 构建要加哪些参数;这个包没有单元测试。没有一句宏大的 AI 理论,全是具体到命令、文件、API 的环境说明。

第二类是“真正的程序化工具”——截图脚本、过滤测试脚本、可重复的构建命令、轻量的模拟环境。前者改变 agent 的认知上下文,后者改变 agent 的行动能力和反馈质量。

两者结合起来,就是一句话——agent 找不到 API,就写下 API 的位置;用错构建命令,就把正确命令写进去;不知道如何验证 UI,就给它截图工具;一再破坏架构边界,就写结构性测试或 lint 规则。

这和 prompt engineering 是两条不同的路径。prompt engineering 是语言技巧,收益随对话消失;harness engineering 是基础设施,收益会复利累积。Mitchell 相信的是后者。

16 个 session,8 个小时,$15.98 和一个“slop zone”

2025 年 10 月,他写了一篇《Vibing a Non-Trivial Ghostty Feature》,公开展示自己如何用 AI 辅助完成一个真实的非平凡功能——在 macOS 上不打断用户的自动更新提示。

文章里最诚实的数字是这些:16 次 agentic coding session,token 成本 15.98 美元,估计墙钟时间约 8 小时。他承认自己确实比纯手写快了,尤其是 SwiftUI 细节迭代那部分;但他更强调的不是成本,而是工作结构——AI 最大的价值,不是每行代码变便宜,而是他离开电脑时,机器仍然能帮他产生候选。

这篇文章另一个被反复引用的部分,是他对“slop zone”的描写。

所谓 slop,是指 agent 生成的代码看起来合理、能跑、甚至能过测试,但里面藏着关键 bug。他试了几次更具体的 prompt,失败。常规的工程师本能会告诉你:再换一个 prompt,再换一个模型,再等 Claude 4.6 出来。

Mitchell 的选择是——停下来,自己学,自己研究。他在文章里写了一句很重的话:“如果 agent 找到了解法,我会学习;如果我不理解,我就回退。我不交付自己不理解的代码。”

这句话在他所有 AI 表达里,分量最重。它把 AI 工作流里最模糊的那块——责任——钉死了。你可以让 agent 试、写、改、跑测试、找资料;但最终合进代码库的是你,用户坏了不会说“这是 Claude 写的”,维护者不能把不可理解的复杂性推给模型。人工 review 不是流程,是工程伦理。

架构师不外包,junior engineer 要护栏

Mitchell 反复强调一个类比:与 agent 协作,像指导一个 junior engineer。

把一个开放式问题丢给 junior,经常是灾难。把一个边界清楚、护栏齐全、验证明确的小问题丢给 junior,他往往能做得很好。AI 目前处在类似状态。

所以他从来不把架构外包。他负责代码结构、数据流、状态放在哪里;他把问题切成合适的形状,然后让 agent 在那个形状里行动。他甚至说过一句话:如果你只对 agent 说“这个 bug 存在,修一下”,它可能真能修,但很可能是用一种锤子砸钉子的方式把症状敲掉,留下长期不可维护的债。

这不是对 agent 的不信任,而是对任务分配的成熟判断。优秀的工程师不会把所有任务平均分给团队,他会按能力、上下文、风险和验证成本分配。对待 agent 也是如此——它擅长什么?Mitchell 的经验是:重构、重命名、整理结构、清理死代码、填空式的样板代码,几乎总能做得很好。它不擅长什么?开放式架构、高性能数据结构、小众语言。

Zig 是他最常举的反例。Ghostty 底层是 Zig,但 Zig 的训练数据太稀。Mitchell 的 workaround 很务实——让 agent 用它更熟悉的 C、Rust、Swift 或 Python 写方案,再由自己转成 Zig。他后来在 Heavybit 访谈里补充过一句:“让它直接写大段 Zig,它常常幻觉出不存在的语法。”

这是 AI 时代成熟工程师的一种姿态:不追求一个模型解决所有问题,而是按任务形状分配工具。

X + AI 救不了底层不成立的东西

外界常把 Mitchell 误认成 AI 怀疑派,其实他只是反对一种特定的姿态——把 AI 当作产品的遮羞布。

在 Open Source Ready 的访谈里,他批评过一批所谓 AI 产品:邮件客户端本身不好用,只是加了 AI 功能;笔记应用本身功能割裂,只是加了 AI 总结。他的判断是,AI 集成可以做得很好,但用户最终仍然要使用完整产品,如果基础体验不成立,AI 救不了它。

这句话背后仍然是同一条工程哲学:基础要扎实,环境要可靠,工具要真的解决人的问题。 一个混乱的代码库加上 agent,不会变成可维护系统,只会变成一个被 AI 放大的混乱代码库。AI 是放大器,放大的是你已有系统的性质——清晰的环境被放大为效率,混乱的环境被放大为 slop。

他对开源的判断也受此影响。在 The Pragmatic Engineer 的访谈总结里,他认为 AI 让“看起来合理但实际低质量”的贡献变得太容易,开源会从 default trust 走向 default deny。这不是说开源不再欢迎贡献,而是说维护者必须建立新的过滤机制——更明确的贡献规范、更强的测试、更严格的 review,更少对“看起来像样”的默认信任。

不变的底色:让机器做机器该做的事

WIRED 在 2019 年写过一篇关于 Mitchell 的人物报道。文章里有一句他自己的话:“我这辈子做的事情有一条连续的线索——自动化那些我不想做的事。人擅长创造,计算机应该做重复劳动。”

这句话放在 2026 年几乎可以一字不改地成立。只是“重复劳动”的边界变了——过去是搭环境、建虚拟机、管理 secret、写配置;现在是查资料、整理 issue、跑测试、写样板代码、做 refactor、生成模拟场景、修构建错误。变化的是工具,不变的是原则。

所以 Mitchell 并不认为 AI agent 让工程师消失。他只是认为工程师的位置要往上挪一格——过去大量时间花在亲手写代码,现在要有一部分时间转向设计“agent 能成功工作的环境”;过去经验沉淀在资深工程师脑子里,现在要沉淀进 AGENTS.md、脚本、测试、文档和约束;过去 review 主要是看人写的代码,现在 review 还要看 agent 是否被正确约束,错误是否被系统性预防。

一个朴素的、很难被模型淘汰的原则

与 Mitchell 同时代的 AI 声音里,不乏宏大叙事。有人说编程死了,有人说工程师会剩下 1/10,有人说三个月后这一切都将被改写。Mitchell 从不说这些话。他在每一次访谈里都很小心地划分自己的边界——这块我用得很好;那块我不知道;这里我不想过度自信;那里我需要法院先给答案;这个技巧三个月后可能失效。

也正因为他不给大判断,他的小判断才格外可信。

“每次 agent 犯错,就改造环境” 这句话之所以有力量,是因为它把 AI 的不确定性转化成了工程的确定性。你不能保证模型下次一定聪明,但你可以让错误更容易被发现;你不能保证 agent 永远不误解,但你可以把误解写进规则;你不能保证代码永远正确,但你可以让测试、脚本、日志、截图和 review 形成闭环。每一次失败都变成环境的一次升级,系统就会越用越好。

这就是 Mitchell Hashimoto 的朴素工程哲学——不要迷信智能,设计环境;不要反复提醒,建立机制;不要把错误看成偶然,把错误看成可工程化的信号。

AI agent 时代真正成熟的工程师,可能不是最会写 prompt 的人,而是最会把一次错误变成永久护栏的人。