AI 工程化经验记录
公司准备让开发全部接入 vibe coding,web 端的相关经验做一下记录,以免后续遗忘。
1. 大方向上的想法
大方向上的要求就是接入 vibe coding,提高开发效果。简而言之就是要在工作中用上 AI 开发。
那这里面就有一些要求和规范,最基础的原则就是要让 AI 对我们的帮助是正向的,不会出现删库删代码等恶意操作,不会出现问了他这个代码怎么写他回复歪比巴卜的情况,至于 AI 对我们的帮助正相关性有多少,我个人觉得 AI 模型能力占很大一部分。
GPT 3.5 的时候 AI 改代码还要反复去说不要修改无关的代码、要使用我们项目已有的库、为什么写的代码没有右花括号这种情况,在 GPT 5.5 上已经看不到了。而且 AI 模型现在已经能做到提示词外的功能,比如发现一些我没有让他检查的 bug,没有让他做的优化等。
但是这些操作不一定都是好的,比如有些功能就是产品这么要求的,但是 AI 并不知道历史原因,所以这就需要在 prompt 中限制了。
还有一个点是,我觉得对待 AI 应该是用一个对待新同事的态度 —— 一个有能力的新同事,但是对我们的项目不了解,而且还很健忘(开新窗口之前的记忆就没了,我们做工程化文档就是为了解决这个问题)。那基于这种想法出发,需要让新同事知道什么东西,就告诉 AI 什么东西,想要新同事怎么做,就要求 AI 怎么做。但是有一点是 「AI 不需要被说服,它需要被对齐」,只需要告诉他怎么做就可以了,不需要说太多原因,这就是 AI 和人不一样的地方。
2. 前端 AI 使用的特殊情况
前端用 AI 开发我觉得和后端是不太一样的,因为前端涉及到页面,这种时候就需要模型有多模态的能力,能够识图,如果工具更好一点的话,AI 可以直接操作浏览器去读页面就更好了。
所以在设计的时候就需要考虑 web 的情况,有些情况下需要提供图片,有些情况下需要接入 figma,而且页面的分模块可能还是要人工介入。人和人之间尚且不能形成统一的想法,更何况人和 AI 之间呢。
我们的管理后台项目有一部分接口是我们自己维护的,那我觉得可以在文档里告诉 AI 我们自己开发的接口格式是什么样的,大概在哪个位置,方便 AI 可以把前后端连起来一起去看。
3. 个人开发哲学
我觉得开发哲学这种东西很大程度上和个人相关。
前段时间做了一次 k8s 发布的优化,让我意识到我们现在用的 k8s 不是官方的,而是运维同学做的 k8s。怎么用、好不好用,都和运维同学个人有关。历史代码也是一样的,项目的框架、结构和规范,有很大一部分因素是前人的能力和编程哲学思想。
我觉得 AI 面对问题的想法是一个圆一样发散出去的,会呈现出各种各样的效果。我们加 prompt 的过程就是在对这个圆做裁切,而且是直接裁切掉一个锥形范围。prompt 越多,AI 就能越按照我们的想法去做,但是同样的,AI 的发散性思维就会少很多,会少了很多创意性部分。
但是 prompt 又是一个很好的东西。prompt 越精准,内容越详实,AI 生成出来的效果就越好。「生成一个五一劳动节的庆祝图片」和「生成一个包含 xxx 元素,xxx 风格,有 xxx 文化象征、xxx 内涵的五一劳动节庆祝图片」效果肯定是不一样的。那写 prompt ,就是来平衡「创意」和「可控」的一个过程。
以我个人对 AI 的了解和使用经验,我其实是不愿意做太多限制的,限制太多就会显得很死板,而且我也不相信以我的能力,能够写出比 OpenAI 、Claude 那些厂商更好的 prompt。
所以我的想法就是工程化的部分就只做背景说明和必要的限制,让 AI 能够给我们提供正向帮助就可以了,没有必要要求 AI 必须按照我的道路去走,我的方法可能也不是最佳实践。
再说说 skills 等工具。
AI 现在还是处在一个野蛮生长期,现在的工具还是在不断更新迭代的过程,并没有一个最佳实践。现在 GitHub 那些高星的工具可能暂时性地解决了一些问题,但是从长久来看,我个人认为,都只是阶段性的。随着时间推移,很多工具都会随着模型能力的发展或者 AI 官方下场做的工具覆盖掉。
那对于工具这块,我的想法是不去做硬性要求,只做推荐。有以下几个原因:
- 前面已经说过了,工具迭代速度很快,模型能力发展起来之后,很多工具已经自然死亡了。而且很多工具为了做到够通用,里面 60% 以上的功能我们都用不到,那这些工具除了占用空间,没有任何用处。只有适合我们项目的才是最好的。
- 如果硬性地把工具接入到项目中,在以后有更好的工具的时候,就会出现「船大难掉头」的情况,我们想去迁移到新工具,就会碰到各种各样的阻力
- 现在的 skills 大部分都是内嵌在本地而不是项目内的。像 superpowers 为代表的 skills 类、各种 mcp 工具类、还有一些 plugins 和 hook,都是装在本地 AI 目录下的,那也没必要放到项目内。
4. 文档怎么写
其实最开始的时候我就想把 AGENTS.md 分模块,原因是我们的项目太大了,内容很多,如果想要面面俱到就需要写很多内容,但是内容太多又会挤占过多的上下文,内容太少又不够精准。
所以我就想到了可以分模块来写文档,让 AI 按需要去读指定的文档,后来我才知道有个词叫渐进式披露😅。核心思想是一样的,让 AI 按需求去读文档,既可以节省上下文,又可以做到文档内容详细。
还有一个是步骤上分模块。
我的设想是把文档分为开发前读的、review 需要读的、debug 需要读的,按这种方式去拆分模块内容,每一块都有不同的内容就可以了。但是实操的过程中发现了几个问题,其中最严重的问题就是 debug 文档没办法下手。我当然可以按照现在比较流行的一些 debug 文档来写,但是那些都是很公共的,不够符合我们项目的特性;同时排查 bug 这个东西很依赖经验,现在有一些 bug 报上来我可以很快地定位到 bug 大概在哪里,一些细节不太记得了再去看看代码就行了,但是这些经验很难全部写出来,如果全写出来反而冲淡了文章的信息密度,让文件变成了一个速查表,内容越多,信息密度越低。
5. 对抗文档腐败
之前平老师分享过一个代码腐败的文章,我觉得这个问题也会发生在 AI 文档内。
我们现在是借由 AI 工程化来首次创建这些文档,那这些文档的内容就是当前我们项目的现状。但是随着时间发展,需求不断增多,代码会变化,那 AI 文档如果没有跟着更新,就会出现文档落后的情况。
对抗文档腐败我想到几个方法论:
- 多写引用而不是 copy。告诉 AI 要查组件、页面、方法的相关用户就去看哪个文件,而不是直接把代码贴到文档里。这样文档只是做一个索引,代码更新就更新了,AI 读到的还是最新的代码。
- 适当时机更新文档。在做完大范围变更或者大需求或者一定时间之后,更新文档。一定时间更新文档的原因是一些小的变化积少成多,时间久了也会变成忒修斯之船。但是不要实时更新,频繁更新,文档内容体积就会不断膨胀,又回到了最开始文档占用太多上下文的问题上。
- 文档更新的文档。后期可以考虑怎么写一份让 AI 去读代码更新文档的文档,不要相信人,要相信代码。人可能会懒、会遗忘,但是 AI 大概率不会,让 AI 去读代码,更新文档,比人工维护更方便一点。
6. 管理后台前端实操
1. AGENTS.md
不管是 claude 还是 ChatGPT 还是 cursor 等工具,在启动对话的时候就会默认加载 AGENTS.md 或者 Claude.md 或者 cursor-rules,因为 AGENTS.md 基本上已经成为了规范,我就在入口处做了一个文档。在这个文档里面只需要简单介绍一下项目背景,写几条顶层要求即可,不需要太多内容。同时里面有一个索引,告诉 AI 干什么工作需要去读什么文档,而不是全量读所有的文档。
顶层要求还写了几条红线,我觉得最重要的就是「有问题及时问用户,而不是猜测」。
AI 自己猜这个问题之前碰到过很多次,从最开始用 AI 到现在都有发生,不过模型能力提升之后发生的情况少了,但不是没有了。AI 自己猜就会导致用一些很好用的包,但其实我们项目压根没有;AI 写了一些很优雅的写法,但是我们项目可能就不支持这些关键字;AI 觉得这一块功能没用擅自删除了,但其实这是产品要求或者有其他依赖使用等等。
2. 分模块
模块根据使用时间做了划分,还根据业务场景做了划分。
使用时间
- 开发前。这个文档里面的内容主要是我们项目的一些要求,比如新页面需要写路由、写权限、在哪里创建文件、以及要使用我们自定义的组件。代码风格部分主要是要参考我们之前的风格来写(但是我个人是持保留意见的),尽量复用已有的组件而不是新写组件,可以提高项目的可维护性。新接口要写在哪里,要用指定的方法去调用,而不是直接用 axios/fetch。dva model 写在哪里,放在哪里,还有一些特殊用法等。
- 开发后。这一部分是从我个人使用 AI 开发习惯中得出来的。我习惯用一个 AI 写完之后再用另一个 AI 去做 code review,然后把问题贴给第一个 AI,让他再确定一下是否真的有问题。这样做的原因是第一个 AI 有了上下文,直接去 review 的话会受历史因素影响,新的对话窗口就没有历史问题。code review 文档我是直接参考 codex 的格式来的,codex 的格式我觉得就蛮好的。他会按照优先级排序,然后把问题按不同的等级划分:必须改、建议改、可改可不改,同时还会指出问题在哪里,这样写会有什么影响,建议修改成什么样。
- 自测。按照我个人的使用习惯我是习惯先跑冒烟测试,让 AI 给几个测试用例我点点看看,然后再跑全流程测试,让 AI 给一些测试用例跑一跑,碰到问题就让他去改。现在 app 项目把 e2e 测试搭建起来了,那就可以做 e2e 测试了。可以把测试用例拿过来,让 AI 参考测试用例去做 e2e 测试用例,直接跑一跑看看有没有什么问题。这样我们交付出去的就是一份完成度 80% 以上的功能,测试时间也能减少很多。
业务模块
这个也是我个人的一些想法。因为管理后台有很多不同的功能,这些功能的使用者是不同的,如果只是简单的按代码目录划分不够准确。我按照我的想法先划分出来了用户、直播、运营、财务几大块,在这些模块内填充了这一块需要知道的特殊知识,例如用户模块内告诉 AI 我们的用户id 分为 userid(用户表自增 id,唯一),relaId(用户可自己修改的 id,唯一),Walkmanid(饭角 id,唯一)等,AI 真的需要改这一块的部分再去加载这一部分的知识。
但是这样划分我也觉得不太好,我觉得最重要的原因是精细度和个人能力。精细度指的是划分模块之后需要把内容精细化到何种程度,还是前面的老问题;个人能力指的是我个人的能力做不到非常完整,这令我非常沮丧。
3. 工具
工具这一块我的想法就是去建议而不是要求(详见 3.个人开发哲学部分)。目前行业内用的比较多的就是 superpowers 这个仓库,里面的一些开发哲学虽然我不太认同(比如先把需求变成测试用例,以测试为目标去开发),还有里面有很多用不到的工具,但是好像也没有什么更好的可推广的方案了。其实按照我个人的开发习惯,我觉得我已经能做到他的一些 skills 的功能,只是我没有去封装成一个 skills,但是我也不认为我的习惯就是最佳实践,只是当前阶段最适合我的。
所以我还是会去建议使用 superpowers,虽然这不是最好的,但至少是一个不错的方案。大家都用一样的,那有问题可以互相交流一下,也可以分享一下使用经验,快速拉齐,避免频繁踩坑。(圣斗士不会被同一个技能打败两次的!)
7. 个性化
每个人都有每个人自己的喜好和习惯,我们当前做的这些工程化只是一个「大方向上正确」的东西,但是不够个性化,不够准确。关于这一部分,我的想法是再做一个 personal 文档,在主文档中明确描述这是个人个性化的部分,如果有指令冲突,以 personal 内容为准,同时这一部分内容不进 git。
因为我个人的能力和眼界非常有限,无法做出来非常完善的工程化,所以我选择保留一部分的个性化内容,用这种方式来让更优秀的同事们能有自己想法发挥的空间。就像木桶效应,做这个东西的目的是为了拉高短板,但是对于长板部分,应该给他们更高的发挥空间,而不是限制。
8. 非常个人且无任何背书的想法(不建议参考)
SOUL.md 。
这个东西是我看之前爆出来的 Claude 官方的做法,好像在这么多 AI 模型里面只有 Claude 有这个东西,核心思想就是让 AI 去理解我们的出发点和想法。我觉得 A\ 这么做的原因是「堵不如疏」,在 AI 破甲方面,再多的限制条件都有可能被攻破的一天,那倒不如让 AI 理解为什么我们不想让用户破甲,破甲可能会带来什么危害(举例:告诉 AI 不能教用户做爆炸物,因为这样会危害人类)。其实就是告诉 AI 原因,让 AI 自主地去拒绝一些操作。
我觉得这和人与人之间的沟通很像,我只是简单的告诉你不要做什么事情,你可能会不听(但是 AI 不太会),你可能会只做我要求内的,但是我告诉你为什么不要做,你就能理解这个原因并且发挥一些主观能动性地去做。
表面上看 SOUL.md 和 「AI 不需要被说服,它需要被对齐」是有冲突的,后者的原因是节省 token,但是前者就是在浪费 token。但是在我和 AI 聊了之后我觉得可能不是这样的,具体指令层面,不需要解释原因,直接对齐;原则层面,需要让 AI 理解意图,因为原则要覆盖的是你没法穷举的场景,而且有一些是代码之外的共识。
9. 心理变化
达克效应四阶段: 第一阶段:不知道自己不知道;第二阶段:知道自己不知道;第三阶段:知道自己知道;第四阶段:不知道自己知道。
在做 AI 工程化的过程中,我的心态经历了达克效应的前两个阶段,越往后做越沮丧,知道的越多不知道的就越多。
刚开始我觉得有 AI 的帮助,那我做这个东西应该是很简单的,只需要出一份 AGENTS.md 就可以了。但是在参考别的项目以及自己思考的过程中,我就发现了这个东西其实很难做。我做了一些简单的思考就去拆分模块,但是发现某些模块很难写;在面对工具的时候我总会觉得这些工具都挺好的,但是也都有弊端,不知道怎么选。
我个人在 AI 的使用过程中其实是没有怎么使用过很重的工具,我的想法就是大道至简,模型能力就是一切。因为我见过也用过一些 AI 模型和工具,大概知道 AI 适合做哪些,可以比较好地去把控。但是在需要做团队项目的 AI 工程化的时候,我觉得那些工作流对我个人可能没什么帮助,但是说不定有人就想用这种工作流呢,有人就想用这种 skills 呢,或者可能还有某个我不知道的工具,但是非常好用,我的不知道让我的同事们也跟着走了弯路。
还有就是 FOMO 心理,今天出了一个新模型,明天又出了一个新的 skills,后天又有一个新工具流,在这个过程中其实会有一些 FOMO 心理,总担心自己会错过更好的。
但是我觉得最重要的一点,就是要保持好奇心。
Please keep curious and courage.
10. 文章部分参考和引用
andrej-karpathy-skills/README.zh.md at main · forrestchang/andrej-karpathy-skills
