Blog

Blog

PHODAL

两周 3 万行代码!我们的 7 个 AI “粪堆”求生编程实践

在过去的两周里,在我们开发 AutoDev Workbench 的过程中,大量地使用 AI 来辅助我们从需求分析、代码生成、测试生成等工作。

之所以借用“粪堆”来比喻,是因为 AI 代码并不比你的同事的代码(PS:自己的代码总是又快又好)写得好多少,而且快速、大规模 AI 生成的实验会存在混乱和无序。我们需要寻找一种更具结构性、高效率、可规模化的方式来使用 AI 智能体编程。

我们将其总结为 7 个实践,我们将其称为:“AI 粪堆求生编程实践”, 尽管生成的代码的可审查性、可维护性及整体质量还存在问题,我们还在使用 AI 进行重构,但是如何从被动变为主动规划,建立更稳健、更具前瞻性的 AI 辅助开发体系变得非常有必要。

简单介绍 AutoDev Workbench

AutoDev Workbench 目标是构建一个 AI 时代的开发者驾驶舱,开发者可以在上面完成大部分的编程工具,而不只是依赖于传统的 IDE。

  • AI 时代的开发者驾驶舱:辅助进行需求分析、代码生成、测试生成等工作。
  • 代码上下文知识预生成:基于代码的 interface、API、文档等信息,预先生成上下文知识,以便于 AI 编程工具能够更好地理解代码。
  • 提供 MCP 服务:AI 编程工具可以通过 MCP(Model Context Protocol)获取已知问题所需要的上下文知识。
  • AI 化的工程项目生成:针对于后端、前端、移动端等不同的技术栈,提供 AI 化的工程项目生成能力。

其核心的 Context Worker 是基于 AutoDev VSCode 开发的,所以部分代码是直接复制的。标题所指的三万行代码是在 Web 上, Web 部分的特点是:

  • 可以使用 v0 来进行原型设计和验证
  • 基于 Next.js,可以快速使用 AI 生成 UI 部分 + 后台代码
  • 代码提交即可部署,最终生成的代码运行在 Vercel 上

从架构和流程上来说,它非常适合于 AI 编程的快速迭代和验证。

1. 脑暴需求:以 DeepResearch 引领开发方向

我们的 AI Coding 的起点是 Google DeepResearch,我们使用它来进行行业的趋势分析、需求脑暴等工作,用来辅助我们进行需求分析和产品设计。 Google DeepResearch 作为一个探索复杂主题并生成详细报告的工具,非常适合进行需要大量信息浏览和研究的任务,帮助用户从对一个领域 “零认知到深度理解”。

我们在 Workbench 的第一个页面 “AutoDev驾驶舱” 里,我们便是让它研究:

AutoDev 驾驶舱:面向预生成代码的 AI 编程。AutoDev 驾驶舱 是我的新特性名称,重点可能是面向预生成代码的 AI 编程,即来了一个需求, 可以自动帮你分析完上下文,等完成后自动编程

随后,我们重新调整了一下方向,转向 “AI辅助需求的知识工程建设”

我在研究 AI 辅助需求的知识工程建设。即用户输入一个一句话需求,可以转换成多步确认,最后生成需求说明书。这样的系统应该怎么设计, 需要哪些知识?比如代码中的隐性知识,类似于信息架构,或者产品说明,这些知识,如何通过 AI 自动生成。

而后,随后研究的深入,慢慢明晰了需求,最终有了一个比较清晰的方向。

DeepResearch 适合从简单问题入手,逐步调整和深化研究方向的策略

2. UI 原型:多 UI 原型快速构建与敏捷试错

与过去开发一个产品需要大量的设计不同,在有了文本生成 UI 之后,我们就可以快速生成多个 UI 原型,并进行验证。相似的,我们可以让 AI 生成了对应的 UI 设计和交互,以交给第二个工具来设计,即 v0、Firebase 等。

由于 Claude 已经过度拟合在编程领域,我觉得它在生成其它任务不太靠谱。除了使用 Google Gemini 之后,我尝试使用 ChatGPT 来生成交互。 我们让 AI 根据上面的草稿生成了一个 UI 交互设计,类似于:

驾驶舱式布局 (Cockpit Layout):将核心工作区置于中央,两侧辅以情境信息和 AI 助手,方便用户全面掌控。……

生成的第一个版本如下图所示:

与我们预期的差不多,驾驶舱式布局、动态交互与即时反馈、知识驱动的可视化以及迭代式精化与质量保障。并且与传统的 UI 设计相比,AI 生成网页时,直接是 可交互的。详细见:https://v0.dev/chat/ai-driven-cockpit-layout-bidTPhZbJbX

有意的是 ChatGPT 也非常的不错,尽管老是把我的交互草稿生成理解为图片生成。但是,在某些场景之下,他的生成还是很靠谱的。如下是我们的 AI 需求助手 的交互图:

结合 DeepResearch 在前面的研究,确实还是挺像这个 AI 时代的交互设计。我陆续使用了 Firebase 等其它工具来进行原型设计和验证,最后发现还是 v0 的工程化最好 —— 代码是可编译的,且可以直接运行。

3. 生成前端:适应 AI 生成架构,降低 AI 辅助摩擦

或者由于 Claude 的原因,当前主流的 AI 生成前端 UI 的工具的技术栈都是:React + Tailwind CSS + Lucide React + Shadcn UI。虽然,不利于 技术栈的多样性,但是在 AI 生成的代码中,使用这些技术栈可以获得更好的效果。也因此,我们需要调整代码结构,以适应 AI 默认生成的代码结构。

在生成 Vercel v0 构建了第一个版本之后,我们就可以基于它的代码来进行开发。v0 并不只是可以给你生成第一个版本的代码,它还可以给你生成后续的其它 UI 代码。 因为,在使用 v0 的时候,我们可以通过:npx shadcn@latest add "https://v0.dev/chat/b/xxx" 的方式来添加生成的代码。这就意味着 V0 倾向于特定的工程架构,以及使用 Shadcn UI 作为组件库,诸如:

  • @app/components/ui,但是在诸如 use-toast 会出现摇摆的

类似于 Tailwind CSS、Shadcn UI 这种开放式架构显然在 AI 时代更有优势,另外 API 的变更会影响 AI 生成的代码。诸如于我们经历了将 Tw4 降级 到 Tw3 的过程,因为新的 API 在 AI 的知识库中是缺少的,会导致大量的错误。

采用适应于 AI 默认生成的架构,显著降低了我们在 AI 辅助开发流程中的摩擦,从而获得了更高质量的AI生成代码和更快的集成速度。

4. 重构以持续协同:精炼代码与加速 AI 后续迭代

AI 编码存在一些典型的问题,例如生成的代码可能存在重复、冗余或不符合最佳实践的情况。我们重构的目标主要是:

  • 面向 AI 提升代码的可生成性。即长代码不适合 AI 理解和再次修改(你也不想再去修改 AI 写的上千行代码吧)
  • v0 上生成的 UI 布局与现有的不致,所以需要结合让本地的 AI 理解新的布局然后再重构。

尽管,提升代码的可读性和可维护性非常重要。即 AI 生成的代码可能存在大量的注释和不必要的代码,这些代码需要被重构和清理 —— 但是从我的角度来说, 我只需要更关注于 AI 生成的代码是否可以被再次生成和修改。与此同时,你会发现每次 AI 编程工具总是几百行、几百行的读取代码,而不是一次性地读取上千行代码。 因此,上下文窗口依旧是一个头疼的问题:

你也不想生成了五百行代码之后,因为上下文超了,然后 AI 改不动你的代码了吧。

这就意味着:

  • 重复代码会影响 AI 后续修改。因为它每次修改都需要反复阅读,会降低速度与生成的准确率。
  • 大量的注释代码会提升你的 token 数。你也不想每次都要为 AI 生成的代码付出更多的 token 成本。

所以,当 AI 生成了代码之后,我们需要在 review 的同时,去掉非必要的注释,特别是行后的注释。当然,你也可以通过提示词来影响 AI 的生成方式, 但是我更喜欢 AI 默认的生成方式,因为它能更让我理解 AI 的”思考方式“。

5. 精准投喂:手动优化上下文,提升 AI 理解力

如果未能明确提供上下文,AI 编程助手在理解语境方面表现不佳,并且还会浪费你的大量宝贵时间和 token。认真构造一个上下文是非常重要的,尤其是当你真的需要 AI 加速你的开发工作时。

此外,由于 AutoDev Workbench 是一个新项目,所以我对于上下文非常了解,我喜欢那种指哪的哪的感觉。而 AI 经常容易检索出错 —— 原因可能大量变化大快, 我的语义化没有跟上,另外我可能也没有给出足够的上下文。主要是我之前研究过主流的 AI 编程工具的检索方式,就没有一个是靠谱的。

此外,我觉得 Next.js 框架的 page.tsx 文件组织方式非常不适合人的检索和 AI 理解。因为它的文件组织方式是基于路由的,而不是基于功能的。你可能 所有的页面的组件都叫 Home(),而不是和路由相关的,特别是 AI 在给你生成 UI 的时候,所以你还需要做一些重构,以更加的语义化。你总不能老是说:

参考 frontend/page.tsx 的布局,修改 golden-path/page.tsx 的布局

因此,理解团队代码中的核心概念、结构和语义,依旧是我们使用 AI 编程的关键,以使我们能提出好的问题,并获得 AI 更好的答案。

6. 智能校验:可视化与自动化测试保障 AI 逻辑

在 AI 一次生成了上千行代码之后,如何快速验证其正确性和逻辑性是一个挑战。我们需要建立一套自动化测试机制,以确保 AI 生成的代码符合预期。诸如于, 典型的方式里可以看到:

  • UI 代码:直接通过手动和浏览器来测试。尽管 UI 测试是一种非常靠谱的方式,但是它实在是太慢了,特别是当你需要频繁地修改 UI。
  • 逻辑代码:通过 AI 生成单元测试和集成测试来验证逻辑的正确性,例如使用 Jest、Vitest 等测试框架来编写测试用例。
  • 后端代码:通过 AI 生成集成测试和端到端测试来验证后端逻辑的正确性,例如使用 Supertest、Cypress 等测试框架来编写测试用例。

通常来说,我们只是验证方式输入和输出是否正确,所以无状态的函数反而是最容易验证的。如果是这样,那么你就不能怪静态方法会变得越来越流行了,每 一个函数单元都可以被独立地测试和验证。也因此,诸如 TypeScript、Kotlin 带有的类型系统和函数式编程范式,能够更好地支持 AI 生成代码的测试和验证。

不过,AI 代码的检验依旧是一个头疼的问题,每次要 Review 几百行代码,总是要苦恼一番。

7. 质量门禁:Lint 与类型推断作为最终防线

为了让我们下次生成 AI 代码的时候,接受率更高,尽可能没有方法、属性引用错误。ESLint + Type 还是作为前端项目的一个门禁,尽管诸如 Cursor 这样的 工具可以修复部分的 Lint 错误,但是反复重试会影响你的开发效率。另外,类型才是 AI 生成的一个核心依赖,缺少类型,AI 生成的代码会有大量的错误。

所以,我主要的开发流程变成在其它 AI 编程工具中生成代码,然后在 WebStorm 中进行校验:

  1. 采用的是 VSCode + Copilot/Cursor 来生成代码
  2. 在 WebStorm 来校验 Lint 和借助 IDE 运行类型推断,以避免无类型的代码大量在代码库中蔓延。
  3. 在 WebStorm 使用 AutoDev 生成提交信息(编写提交信息初稿,再生成真正有意义的提交信息)

此外,我们有了 ESLint 和类型作为检查机制,但是 AI 生成的大量注释代码,依旧是一个暂时没有能解决的痛点。

最后,我们觉得完整的流程里应该包含 AI 自动的 CI/CD 修复,还有对应的线上问题的修复,但是目前来说,我们还没有实现。我们希望在未来的文章中, 能探索更多的最佳实践。

总结

AI 在软件开发中的角色仍在飞速演进。从代码生成、需求分析到测试部署,AI 正逐渐渗透到软件生命周期的每一个环节。我们应该去思考:

  • 提升 AI 交互效率与产出质量:通过更精细的提示工程、上下文管理和工具选择,让 AI 更好地服务于开发目标。
  • 强化代码质量与可维护性: 建立针对 AI 生成代码的有效重构、审查和测试机制,缓解技术债务风险。
  • 优化开发流程与团队协作: 将 AI 无缝融入现有工作流,并促进团队成员在AI辅助环境下的高效协作。
  • 构建可持续的 AI 整合能力: 从被动“求生”转向主动规划,形成一套适应团队特点和项目需求的成熟 AI 辅助开发方法论。

当然,AI 工具依旧还在不断地演进中,我们也在不断地探索和实践中。


或许您还需要下面的文章:

关于我

Github: @phodal     微博:@phodal     知乎:@phodal    

微信公众号(Phodal)

围观我的Github Idea墙, 也许,你会遇到心仪的项目

QQ技术交流群: 321689806
comment

Feeds

RSS / Atom

最近文章

关于作者

Phodal Huang

Engineer, Consultant, Writer, Designer

ThoughtWorks 技术专家

工程师 / 咨询师 / 作家 / 设计学徒

开源深度爱好者

出版有《前端架构:从入门到微前端》、《自己动手设计物联网》、《全栈应用开发:精益实践》

联系我: h@phodal.com

微信公众号: 最新技术分享

标签