一个月前,一个普通的 Web 请求在DEV上在 Rails 内部大约耗时 70 毫秒,P99 响应时间很多时候超过 1 秒。如今,在 Better Stack 中每天大约采样的 300,000 个请求里,这个数字降到了 16 毫秒。

每个请求的数据库时间从 39 毫秒降到不足 12 毫秒。视图渲染从 12 毫秒降到 2.6 毫秒。Redis 时间从 7 毫秒降到 1.3 毫秒。在过去 30 天里,我们向Forem合并了 475 个拉取请求。这类工作对扩展性和用户体验至关重要,但在面对其他需要推进的进展时,总是很难被优先处理。

DEV performance data

这些提升对用户体验来说是巨大的。不再有间歇性的变慢,也不再难以应对高流量的峰值时段。这解决了一个长达十年的痛点。

我们之所以能够优先推进这些性能改进,是因为设计了一个反馈循环,并从这个项目的日常事务中抽身出来。

我们通过搭建一个软件工厂并跳出循环来实现这一点。

在智能体开发的第一阶段有一个几乎所有人都会踩的陷阱。你不再敲语法,这感觉像是一种杠杆,结果却发现自己被提升成了人类中间件。你变成了仪表盘和终端之间的剪贴板:整个下午都在微调提示词、照看 CI 的偶发失败、给 diff 盖章放行。你不再手写代码,但也没有在做深入的工程工作。你是一个有心跳的 API 端点。

跳出这个陷阱花了数周时间,在OpenHands和 Agent Client Protocol (ACP) 之上构建并重新配置自主循环。目标不只是让 DEV 更快。而是把系统性维护与那些值得人类品味的、创造性的定制项目分开。

照料一年生植物

在Design for Churn,我曾提出,代码库正开始变得不像建筑,而更像花园。当写代码很昂贵时,持久性是你获得回报的方式。当重写变得廉价时,你的投资就转向那些不会更替的东西:土壤、苗床和灌溉系统。把强契约、schema 和测试放在边缘,内部的代码就可以持续翻新而不扰动根系。

10 月初,我与智能体以交互方式做了这种园艺工作,交付了 31 个 PR,将平均延迟从 70ms 降到 50ms。收益是真实的,但每次查询审计仍然需要我启动会话、粘贴上下文,并把分支一路护送到合并。

10 月 19 日,我们搭建了一个持久化的自托管 OpenHands hub,把这些习惯变成了闭环系统。自那以后,已有 444 个 pull request 合并进 Forem:351 个来自自主循环(172性能 PR、93测试套件提速、32Rust 原生重写、29依赖升级、20生产错误修复,以及5issue 到 PR)之外,还有 93 个由我直接推动的定制 PR。

我们一路上弄坏的每一个配置

你无法靠一个写着“让应用更快”的 cron job 得到一个可用的软件工厂。我们经历了半打配置,每一个都诞生于观察前一版本失败的过程。

从代码阅读到实时遥测。我们最早的perf-loop读取 Ruby 文件并猜测瓶颈,产出的微优化几乎没能让图表动一下。当我们把 Better Stack 的 ClickHouse span 和一个只读 Postgres 网关(forem-db-query)接入每个预检快照,并包裹在隐私保护层中之后,一切都变了。一旦智能体在动文件之前就能看到实时顺序扫描、未使用的索引和按端点的计算开销,每个 PR 都必须对照真实流量来证明自己的价值。

从一个模型到跨家族路由器。我们一开始固定使用 Claude Opus 5.5(claude-acp),从 macOS Keychain 同步 OAuth token。在触及配额上限和 token 刷新冲突之后,我们构建了一个三提供商路由器,覆盖 Claude Opus 5.5、OpenAI 的codex-acp(GPT-6.1 Sol),以及通过 Antigravity CLI 接入的 Google Gemini 4 Argon(agy),先通过反向 WebSocket 隧道连接到我的 Mac,然后在 Linux 上以 Medium 推理级别原生安装。每个循环以轮询方式轮换,冷却上限为 8 小时,每当 PR 修复失败时就切换模型家族。

从共享检出到隔离工作树。在一个容器中并行运行八个循环,暴露了 Git 和 Linux 的每一个尖锐边缘。并行拉取触发了git gc冲突,一次启动崩溃留下了过期的.gitconfig.lock,僵尸进程不断堆积,直到我们添加了tini作为 PID 1。我们将每次运行移入分离头指针的 git 工作树,并带有自愈锁清理,同时在每个 cron 前放置确定性的 Python 门控,使完整队列在 2 秒内以零 token 消耗退出。

从一个循环到专用床。随着简单的 SQL 优化被清除,我们将工作拆分为正交循环,白天以 10 分钟为周期(7am-7pm ET,周末为四分之一节奏),并带有 5/10/20/40 分钟的指数退避 PR 检查:

  • perf-loop用于 ActiveRecord 查询、Redis 缓存和视图 partial,在打开的 PR 之间强制类别正交性。
  • rust-loop将热点 Ruby 路径移植到gems/forem_native通过magnus,限制为一个打开的 PR,使预编译二进制永不冲突,并由 1,000 输入的差分规格验证。
  • test-loop解析 30 个 Knapsack RSpec 分片以削减FactoryBot变动和缓慢的系统规格。
  • error-loop和deps-loop带有严格过滤器,跳过超时、模糊 bug 和补丁噪音。
  • github-pr-reviewer和pr-merge-loop,其中不同模型家族的第二视角审计员检查影响范围,并在 CI 通过后自动合并低风险的性能和测试 PR。

系统化土壤,定制果实

真正的回报不是 475 个 PR 的数量,甚至不是 16ms 的响应时间。而是那另外 93 个拉取请求所发生的事。

因为我不再花早晨寻找顺序扫描或在标签页之间路由堆栈跟踪,我有了深入工作的头脑空间。当循环压缩查询和规格时,我花交互式会话重新设计我们的主页信息流如何演进(添加定向桶、年龄多样性权重和粘性重复访问配置),分四个阶段现代化 JavaScript 交付以缩小application.js达 71%,base.js达 55%,构建 L1 本地 Redis 缓存,并制作可观测性扩展来观察整个系统工作。

照料这个系统并在高杠杆的边缘上工作,终于感觉像是迈过了 AI 辅助软件开发中那种尴尬的中间状态——人只是个肉路由器。棕地与绿地项目之间的恰当互动,以及让工作日更高效、更有创造力的工具,都已经到位了。