在过去的两周里,在我们开发 AutoDev Workbench 的过程中,大量地使用 AI 来辅助我们从需求分析、代码生成、测试生成等工作。
之所以借用“粪堆”来比喻,是因为 AI 代码并不比你的同事的代码(PS:自己的代码总是又快又好)写得好多少,而且快速、大规模 AI 生成的实验会存在混乱和无序。我们需要寻找一种更具结构性、高效率、可规模化的方式来使用 AI 智能体编程。
我们将其总结为 7 个实践,我们将其称为:“AI 粪堆求生编程实践”, 尽管生成的代码的可审查性、可维护性及整体质量还存在问题,我们还在使用 AI 进行重构,但是如何从被动变为主动规划,建立更稳健、更具前瞻性的 AI 辅助开发体系变得非常有必要。
AutoDev Workbench 目标是构建一个 AI 时代的开发者驾驶舱,开发者可以在上面完成大部分的编程工具,而不只是依赖于传统的 IDE。
其核心的 Context Worker 是基于 AutoDev VSCode 开发的,所以部分代码是直接复制的。标题所指的三万行代码是在 Web 上, Web 部分的特点是:
从架构和流程上来说,它非常适合于 AI 编程的快速迭代和验证。
我们的 AI Coding 的起点是 Google DeepResearch,我们使用它来进行行业的趋势分析、需求脑暴等工作,用来辅助我们进行需求分析和产品设计。 Google DeepResearch 作为一个探索复杂主题并生成详细报告的工具,非常适合进行需要大量信息浏览和研究的任务,帮助用户从对一个领域 “零认知到深度理解”。
我们在 Workbench 的第一个页面 “AutoDev驾驶舱” 里,我们便是让它研究:
AutoDev 驾驶舱:面向预生成代码的 AI 编程。AutoDev 驾驶舱 是我的新特性名称,重点可能是面向预生成代码的 AI 编程,即来了一个需求, 可以自动帮你分析完上下文,等完成后自动编程
随后,我们重新调整了一下方向,转向 “AI辅助需求的知识工程建设”
我在研究 AI 辅助需求的知识工程建设。即用户输入一个一句话需求,可以转换成多步确认,最后生成需求说明书。这样的系统应该怎么设计, 需要哪些知识?比如代码中的隐性知识,类似于信息架构,或者产品说明,这些知识,如何通过 AI 自动生成。
而后,随后研究的深入,慢慢明晰了需求,最终有了一个比较清晰的方向。
DeepResearch 适合从简单问题入手,逐步调整和深化研究方向的策略
与过去开发一个产品需要大量的设计不同,在有了文本生成 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 的工程化最好 —— 代码是可编译的,且可以直接运行。
或者由于 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生成代码和更快的集成速度。
AI 编码存在一些典型的问题,例如生成的代码可能存在重复、冗余或不符合最佳实践的情况。我们重构的目标主要是:
尽管,提升代码的可读性和可维护性非常重要。即 AI 生成的代码可能存在大量的注释和不必要的代码,这些代码需要被重构和清理 —— 但是从我的角度来说, 我只需要更关注于 AI 生成的代码是否可以被再次生成和修改。与此同时,你会发现每次 AI 编程工具总是几百行、几百行的读取代码,而不是一次性地读取上千行代码。 因此,上下文窗口依旧是一个头疼的问题:
你也不想生成了五百行代码之后,因为上下文超了,然后 AI 改不动你的代码了吧。
这就意味着:
所以,当 AI 生成了代码之后,我们需要在 review 的同时,去掉非必要的注释,特别是行后的注释。当然,你也可以通过提示词来影响 AI 的生成方式, 但是我更喜欢 AI 默认的生成方式,因为它能更让我理解 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 更好的答案。
在 AI 一次生成了上千行代码之后,如何快速验证其正确性和逻辑性是一个挑战。我们需要建立一套自动化测试机制,以确保 AI 生成的代码符合预期。诸如于, 典型的方式里可以看到:
通常来说,我们只是验证方式输入和输出是否正确,所以无状态的函数反而是最容易验证的。如果是这样,那么你就不能怪静态方法会变得越来越流行了,每 一个函数单元都可以被独立地测试和验证。也因此,诸如 TypeScript、Kotlin 带有的类型系统和函数式编程范式,能够更好地支持 AI 生成代码的测试和验证。
不过,AI 代码的检验依旧是一个头疼的问题,每次要 Review 几百行代码,总是要苦恼一番。
为了让我们下次生成 AI 代码的时候,接受率更高,尽可能没有方法、属性引用错误。ESLint + Type 还是作为前端项目的一个门禁,尽管诸如 Cursor 这样的 工具可以修复部分的 Lint 错误,但是反复重试会影响你的开发效率。另外,类型才是 AI 生成的一个核心依赖,缺少类型,AI 生成的代码会有大量的错误。
所以,我主要的开发流程变成在其它 AI 编程工具中生成代码,然后在 WebStorm 中进行校验:
此外,我们有了 ESLint 和类型作为检查机制,但是 AI 生成的大量注释代码,依旧是一个暂时没有能解决的痛点。
最后,我们觉得完整的流程里应该包含 AI 自动的 CI/CD 修复,还有对应的线上问题的修复,但是目前来说,我们还没有实现。我们希望在未来的文章中, 能探索更多的最佳实践。
AI 在软件开发中的角色仍在飞速演进。从代码生成、需求分析到测试部署,AI 正逐渐渗透到软件生命周期的每一个环节。我们应该去思考:
当然,AI 工具依旧还在不断地演进中,我们也在不断地探索和实践中。
围观我的Github Idea墙, 也许,你会遇到心仪的项目