skip to content
大嘴碎碎念
Table of Contents

Vibecoding 开发过程记录

我开发了一个 Telegram User Bot (链接),整个开发过程依然全程使用了 Aider。回顾这个过程,我发现有不少值得分享的经验和思考。

LLM选择

起初,我因为 Gemini 2.5 Pro 作为思考模型响应首字较慢,等待过程令人有些不耐,所以在项目前半程主要使用了 DS v3。DS v3 在速度和成本效益方面表现出色,堪称性价比之选。 然而,随着项目的推进,我发现 Gemini 的大上下文窗口优势非常明显。相比之下,使用 DS 模型时,必须时刻关注任务的规模以避免超出其上下文限制;一旦超出,就需要重新规划提示(prompt),这无疑会浪费大量时间。

工具选择

工具方面,我依然选择了 Aider,并且越用越顺手,没有更换的打算。值得一提的是,这次我完全没有使用 Aider 的 /architect 模式,原因我将在下文详述。

vibecoding 面对的问题

在我看来,对于非一次性脚本的 AI 辅助编码项目而言,其核心目标在于确保项目的可控性。 可控性体现在两方面:一是对项目的人为掌控,二是对 LLM行为的有效引导。 LLM 因其上下文容量、注意力机制及可能产生的幻觉等限制,并非完全可靠。有趣的是,人脑在处理复杂信息时也面临类似的挑战,甚至在某些方面可能表现出更大的不确定性。 那么,解决方案是什么?答案是:文档。

开发模式

我阅读了 Cline 关于 Memory Bank 的理念后, 发现这是一种简单而高效的项目控制方法。

简单来说,Memory Bank 就像一个自文档化系统:在 LLM 每次行动前后,都通过文档化的形式对项目信息进行压缩,并为 LLM 的后续行动提供指导。 这种模式具有诸多优点:

  • 文档化的形式能够自动描述项目的目标和当前状态,使 LLM 无需通过分析全部源码来理解项目,从而避免了上下文窗口被大量代码占据的问题。
  • 文档本身即构成提示(prompt),用于指导 LLM 的下一步行动。
  • 文档有助于自动拆分任务,减小当前任务的规模,从而保证 LLM 的注意力集中,尽可能减少幻觉的产生。
  • 文档对人类友好。特别是当你指导 LLM 一步步迭代文档时,你会对项目的进展和方向更有信心。

这些优点完美地解决了 Vibecoding 项目所面临的可控性问题。

然而,我对 Cline 和 Roo Code 的具体实现方式不太认同。我不喜欢那种一次性发送大量请求并生成大量代码的模式,因为这样产出的代码往往缺乏透明度,让人对其可靠性存有疑虑。

因此,我使用 Aider 实践了 Memory Bank 的开发思路。这个过程相当有趣,下面我将详细介绍具体做法。

Aider 中使用 Memory Bank 的开发过程

首先,我创建了一份编号为 RFC-001 的 RFC(Request for Comments)文档,并将其添加到 Aider 的可编辑文件列表中。然后,我使用 /ask 模式与 LLM 讨论需求细节。 每次讨论后,我都会使用 /code 指令让 LLM 修改 RFC 文档。基于这份文档,我们进行了反复迭代,直到我对需求的清晰度和完备性感到满意为止。 LLM 在这个过程中确实帮助我发现了不少设计上的潜在不足。

RFC 文档完善后,我将其设置为只读状态,并新建了一份 IMP (Implementation) 文档,用于规划具体的实现步骤,同时将此 IMP 文档添加到 Aider 的可编辑文件列表中。 接着,我再次使用 /ask/code 模式重复上述的迭代过程,最终得到了一份清晰的实现步骤清单。这份 IMP 文档中的每个步骤前都带有一个表示完成状态的标记(例如 [] 代表未完成)。

最后,我将项目本身的规则文件(rules)和 RFC 文档设置为只读,并将 IMP 文档置于可编辑状态,然后让 LLM 开始逐一实现这些步骤。 每完成一个步骤,我就会在 IMP 文档中将其对应条目标记为已完成(例如,将 [] 修改为 [x])。我发现,到了后期,我向 LLM 发出的指令几乎都是“请实现第 X 步”,这种重复性的提示甚至让我感到有些单调。

如果你对此感兴趣,可以查阅我项目中的这两份文档:RFC-003-用户机器人设计.mdIMP-001-RFC003-UserBot.md。同时,它们的 Git 提交记录也清晰地展示了迭代的过程,并且 Aider 自动生成的 commit message 确实非常方便。

在这个过程中,还有一个最大的惊喜:通过详细的 IMP 文档和 Aider 自身的 repomap,LLM 能够非常精确地定位到需要修改的代码。 我的直观感受是,这种方式在准确性上远超一些常见的 RAG (Retrieval Augmented Generation) 技术。通常情况下,当我指示 LLM 实现某一步骤时,它会先进行一番思考和规划(输出其思考过程),然后明确指出需要编辑哪些文件。此时,Aider 会提示我将这些文件加入可编辑列表,LLM 随后会基于更新的文件信息重新分析并执行操作,这个交互过程非常高效且有趣。

这种开发方式在流程上相当顺畅,但调试过程却颇具挑战。基本上,遇到错误时,我会将报错信息直接提供给 LLM,让它尝试自行修正。 问题在于,随着项目规模的增加,单纯依赖 LLM 进行错误修复的模式,很容易导致代码质量逐渐下降,陷入“修复一个 bug,引入数个新 bug”的困境,最终可能演变成难以维护的局面。

如果再次采用这种开发模式,我计划在 RFC 阶段就更清晰地定义使用场景。然后在 IMP 文档阶段,我会引导 LLM 首先根据这些使用场景编写单元测试,之后再进行具体的代码实现。

最后

对我而言,AI 编程最大的优势在于它极大地降低了启动项目的门槛,促使我将想法付诸实践。以往,即便有很多构思,也清楚自己有能力实现,但在真正开始动手前,总会因为预期的繁琐而感到犹豫,难以迈出第一步。有了 AI 的辅助,开始一个新项目似乎不再那么令人望而却步了。