近年来关于“vibe coding”的文章层出不穷。Indragie Karunaratne、Edward Yang 与 Cloudflare 的一些案例引发了广泛关注。这些项目往往有三个共通点:创作者本身已是该领域专家、应用为只读型因而容错度高,或者是在一个标准明确、设计空间有限的领域中展开。
然而,作者最近使用代理型编码方式构建了一个系统,目标是在24小时内抓取十亿个网页。这个项目的不同之处在于:
- 核心概念虽简单,但在大规模下设计空间极其广阔;
- 存在关键环节,其中的 Bug 可能带来严重后果(如“礼貌”问题);
- 明确追求一个客观指标的极致(吞吐量);
- 项目中只有不到 4% 的代码是手写完成的。
这篇文章详细说明了 AI 编码方式的助益与局限,并配有代码片段与对话日志链接。
结论预告:整体而言,AI 赋能效果显著。 作者主张,这些经验在构建其他高性能系统时也具有参考价值,尽管有一定前提条件。
一、工具与设置
作者使用了 Cursor(一个支持 AI 助理的 IDE),主要搭配 Claude 模型进行开发。没有使用后台 Agent(当时仍处于预览阶段)。尽管一些工程师如 Steve Yegge 早已将此类“聊天编码”模式称为“即将成为历史的古董”,作者仍选择坚持使用 Cursor,理由包括:
- 不喜欢频繁更换开发工具,更愿意深入理解所处理的问题;
- Cursor 的 tab 补全功能在业界依旧领先;
- 编码过程中需要始终“贴近”代码本身,Cursor 的交互方式使他能高效维持这种联系。
在整个项目中,总共有 32,169 行代码变动,仅有 1253 行是手写,约占 3.75%。
项目于 5 月底开始,当时仍是业余时间进行(最初使用 Gemini 2.5 Pro,后转为 Claude 4 Opus)。经历了 8 套完全不同的系统设计与无数实验后,作者利用 7 月 4 日所在的假期专心推进,最终实现目标。回顾整个过程,若能使用后台代理或并行机制,或许能节省大约一周的开发时间。
二、问题本质
AI 能带来多大帮助,取决于问题本身的形状——包括:
- 瓶颈所在:是编码、实验,还是用户沟通?
- AI 在该领域的可靠性:如 Claude 写 Metal Shading Language 时比写 CUDA 更容易出错;
- 所需监督强度:Bug 严重程度不同,例如写网页 UI 与写起搏器的容错要求天差地别。
本项目涉及一个陌生领域。虽然作者在实时 C++、网页应用、开发者工具和 GPU 内核方面经验丰富,但数据密集型系统与所用的数据库技术对他而言皆属全新。
关键挑战包括:
- 设计空间庞大;
- 实验周期长、性能信号噪声大、内存泄漏等问题仅在长时间运行后显现;
- 成本受限;
- 某些 Bug 在大规模下代价高昂(如违反“礼貌性”,重复抓取 URL)。
三、Vibe 编码 + 手动审查
因为某些错误(如不遵守 crawl delay)在大规模运行时可能对网站造成伤害,所以纯粹依赖“vibe coding”并不可取。
虽然难以实现全覆盖测试,但作者通过“实时技术债控制”+“多轮交互生成 + 手动代码审查”的方式维持了系统质量。具体手段包括中途 spot-checks(局部核查)、最终细致 code review。过程中 AI 模型确实也出现了不少错误,例如:
- SQL 后端设计中,Claude 使用了
SELECT FOR UPDATE但错误地应用在临时表(CTE)上,导致竞争条件使两个 worker 可抓取同一 URL; - 使用 Python 的哈希函数对域名分片,而 Python 的哈希并不在进程间稳定,导致破坏互斥性;
- Redis 的布隆过滤器初始化方式错误,误认为
BF.EXISTS若键不存在会抛异常。
部分问题通过 spot-check 被及时发现,另一些则是在 review 代码时才浮现。更隐蔽的是性能类问题,例如:
- 冗余逻辑拖慢爬虫速度;
- 不必要的字段存储增加内存峰值并诱发 OOM;
- 请求默认记录 cookies 引发内存泄漏。
这些问题多通过小规模运行和日志分析来排查。尽管最终仍需作者亲自介入 debug,但 AI 显著降低了初期开发难度,尤其在使用陌生技术时:无须搜遍文档与教程,只需一句 prompt 便可生成可用实现。
四、快速探索设计空间
以往构建高性能系统,开发者通常会:
- 阅读相关文章、博客与论文;
- 列出多个方案及其利弊,筛选出可行子集;
- 编写原型并进行基准测试。
但因时间、人力与上下游优先级影响,往往只能实现有限子集。如今,通过代理编码,作者完全跳过第 2 步,且大幅降低第 3 步成本。
作者共实现了 8 种主要架构,吞吐量从每秒 <20 页提升至 10,800 页,提升两个数量级。更重要的是——这些设计的快速试错大多数建立在他并不熟悉的技术栈上。
即便起初的设计很“愚蠢”,但由于试错代价极低,实验过程快速推进,而最终结果依旧高效稳定。
五、编码 vs 实验瓶颈
近年来有人提出“编码从未是软件开发瓶颈”的观点。作者认为这种说法在很多语境下并不成立。以 Figma 为例:
- 初始版本由 JS 编写,后迁至 asm.js 编译的 C++;
- 渲染曾用 HTML 和 SVG,最后转向自研 WebGL 渲染栈;
- 构建了自定义 DOM、合成器与排版引擎。
这段经验说明:编码能力是设计空间探索速度的关键决定因素。
作者认为,现代开发任务正在从“编码受限”转向“实验受限”或“沟通受限”。而团队能否意识并应对这一变化,将直接影响其竞争力。
六、AI 的“品味”
AI 是否具备系统设计上的“品味”?作者的结论是:“视领域而定,尚难定论”。
例如:
- Gemini 最初提出使用 SQLite,尽管需求中明确设定了每 24 小时处理五千万网页的目标;
- 当指出问题后,Gemini 反而“坚持己见”;
- Claude Opus 则在没有明确提示的情况下提出 Redis 是更优方案,表现得更像一位高级工程师。
尽管最终决定权仍掌握在人类手中,但 Opus 的行为显示出较强的问题洞察与补全能力。
七、AI = 机器中的配对编程伙伴
尽管 AI 有时像个“热情但生疏的实习生”,但其在熟悉领域中的压缩经验极具价值,例如:
- 阅读性能分析报告(如识别 select 系统调用表示 IO 等待);
- 操作二进制与十六进制数据(如恢复 Redis dump 文件);
- 添加性能诊断工具(如
pympler); - 分析 Redis 日志发现 OOM 错误源于
vm.overcommit_memory配置缺失。
八、度量与可视化:vibe 编码的完美用例
在副功能模块中,如监控仪表板、数据可视化等,AI 编码非常高效。尽管这些模块也曾出现单位标注错误等 Bug,但总开发成本大幅降低。
例如作者曾这样提示:
“我想为爬虫添加指标收集与可视化功能,目前仅有日志输出。我希望能像 rudimentary DataDog 那样实时查看和聚合指标……不确定应选用 Prometheus / Grafana,想先聊聊再开始编码。”
AI 立即提供了合理建议并配套代码。
九、AI 不具备时间感知能力
AI 在生成计划时仍然像人类一样设想时间表,但其自身不具备“时间认知”,可能选择非常慢的实现方式:
- 💬 将数据迁移脚本设计成逐项处理而非批处理;
- 💬 用
dd bs=1逐字节复制文件而非使用head -c截断。
十、上下文仍是瓶颈
大模型的上下文理解仍有缺陷,导致错误推荐。例如明明文档说明该爬虫只支持单机运行,AI 仍建议使用 Redis cluster。
作者启用了 Cursor 的“memory”功能,但未见明显改进。反而发现将项目文档与关键对话放置在 prompt 最前更有效。Claude 等新模型能良好利用 grep 功能,因此在代码较小的项目中,这种策略已足够。
大多数 AI 错误,实则源于提示不足或上下文缺失。
十一、“冗余 = 性能敌人”
逻辑上正确但冗余的代码,往往导致严重性能问题。例如:
- 不过滤纯文本内容;
- 多余的 HTML 清洗步骤将解析速度减半;
- 不必要的字段(如
content_bytes)大幅提高内存使用; - 未正确关闭 Cookie 存储导致隐性内存泄漏;
- Redis 中的
visited:*键占用 2 倍空间; - SQL 客户端仍残留在 Redis 后端中。
在重构后,作者常需手动“减肥”,或让 AI 自审自己的代码。
十二、总结
作者原拟将本文标题定为“AI 带我走上更高抽象层”,但最终改为更精准的版本。
AI 的确显著拓展了单人开发的系统规模——作者不仅能在业余时间完成复杂系统,还能尝试多个设计方案。但这也意味着,基础功更重要了。
AI 仍然存在大量小错误、大问题。真正能从中受益的人,是那些愿意深入理解、掌握全栈并持续校验的人。
未来是否仍是如此?尚难预测。这项技术强大而日新月异。David Crawshaw 的话或许道出了真谛:
“这是一个需要好奇心与谦逊的时代。”