Skip to content

AI coding 复刻 CC98 过程中的经验于思考

这两周工作不算太忙,打算复刻 98 前端部分,之后就一直在不断尝试着自己对 AI coding 的一些思考与想法。现在复刻之旅大概进行了一半左右,复刻版本在样式和功能上已经和 98 本体很贴近了

看一下项目内的代码行数,发现居然都已经有了七八万行(有效的逻辑部分代码约有三万多行),而这中间没有一行是手写的。这个过程小有收获,希望能把这些经验与思考总结并分享出来,抛砖引玉,共同探讨

bash
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 Language              Files        Lines         Code     Comments       Blanks
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 CSS                       2          439          364           19           56
 HTML                      1           13           13            0            0
 JavaScript                6          687          619           14           54
 JSON                     88        24207        24205            0            2
 SVG                       2           25           25            0            0
 TypeScript              170        16111        14396          552         1163
 YAML                      2         8898         7137            0         1761
─────────────────────────────────────────────────────────────────────────────────
 Markdown                 40         6472            0         4695         1777
 |- BASH                   7           56           51            3            2
 |- CSS                    1            9            8            0            1
 |- YAML                   1            6            6            0            0
 (Total)                             6543           65         4698         1780
─────────────────────────────────────────────────────────────────────────────────
 Vue                     100         1512         1300            0          212
 |- CSS                   69         7642         6587            0         1055
 |- HTML                  97         4075         3948            0          127
 |- JavaScript            99         6214         5640           21          553
 (Total)                            19443        17475           21         1947
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 Total                   411        76366        64299         5304         6763
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

搭建让 agent 更加舒适的环境

我个人认为 Agent 其实是一个对代码库不熟悉的高级开发工程师,为了让 Agent 辅助我们进行准确而又高效的开发,我们需要在短时间内让 Agent 上手整个代码库。为了做到这一点,我们可能会做许多工程上以及知识上的处理

agent ready 的知识体系

现在 Coding Agent 的工具一般都会遵守社区内的规范,比如在一轮对话开始的时候,会将项目的 agents.md 文件注入到上下文当中。这就给我们提供了渐进式加载项目知识的可能

根据下面的两篇文章和实践,我尝试将项目的知识体系搭建了起来。在后面迭代的过程中,这套知识体系确实发挥了不小的作用

比如在任务开始前,agent 会先了解项目的大致结构、协作方式、环境初始化等信息;在任务结束之后,也可以使用 Agent Browser 或其他工具,来对项目的质量及可靠性进行测试,并更新项目中过时的文档。这一套可以说是社区内比较经典的做法了(表现形式可能不同,如目录的命名),值得每一个项目去尝试

bash
文档知识库
├── AGENTS.md             # 知识入口
├── ARCHITECTURE.md       # 架构地图
├── DESIGN.md             # 设计规范
└── docs/
    ├── collaborating.md  # 协作
    ├── frontend.md       # 前端
    ├── quality.md        # 质量
    ├── security.md       # 安全
    ├── dependency.md     # 依赖
    ├── adr/              # 架构决策
    ├── exec-plans/
   ├── active/       # 进行中的计划
   └── completed/    # 已完成的计划
    └── ubb/              # UBB 专项文档

相信原厂调教

之前社区流行过很多流程性的 skill,比方说 Superpowers、spec-kit、gstack 等。在刚出来那会儿,大家对这些 skill 是好评很多

但最近我在推特等社群看到越来越多的开发者抛弃了这些流程性的 skill,转而使用一些更加轻量化的提示词,比方说 TW93 的 Waza,还有 grill-me 等等。它们非常容易结合进现有的项目,并且不会特别刻意地约束模型的行为

我感觉这就是优秀流程被训练到模型内部的体现(尤其 GLM GPT 系列),无须冗长的提示词,模型自己就会沿着一个大家认可的流程去开发,比如经典的需求设计实现计划编码实现测试循环最终交付流程

INFO

丢一个暴论,Skill 就不应该去承担流程串联的工作,它更多地应该作为与其他服务进行交互的一种粘合剂。比方说使用 CLI 或者 MCP

这也是我不喜欢 Skill 这种单一形式工具的原因。我更喜欢的是 Plugin 那种将一套完整能力打包到一起的结构,既完美解决了分发和版本控制,又能够提供足够的能力,让模型将更多的注意力放在实际工作上,而非准备环境上

更舒适的开发体验

现在有一个词叫作 DX(Developer experience),指的是开发者对他开发时候的工具,工作流,氛围的感受。虽说好的开发环境不一定代表着我们能写出优秀的代码,但是一旦体验过现代 IDE 或者良好的 coding agent 工具,是一定回不去之前刀耕火种的开发流程的(相信学过小白汇编的同学深有体验),下面是我开发时的一些有关改善 DX 的一些经验

稳定可复现的环境

这个标题很难不让人联想到一些概念,容器nix沙箱……,我也有同感,不过我这里要介绍的层级要浅一些,因为在 98 开发的过程中并没有使用到这些技术。我这里指的是前端环境的控制,包括但不限于运行时管理(Node.js 版本),依赖管理(pnpm)等,做到这个不难,我认为主要是两点:

  1. 选一个有良好的包管理的语言,前端技术栈就很好,或者其他类似 go、rust 等语言
  2. 选一个成熟优雅的工具链:前端技术栈我推荐 Vite plus,虽然新,但是真的显著提升 DX,能很好的管理运行时与依赖,同时不影响本机已有的环境

我也看好前面说的沙箱等概念,因为他确实能简单的提供稳定可复现的环境,现在社区或者 coding agent 公司也在探索这方向,设想以后只要连接一个远程仓库,开一个对话即可在类似本地的环境进行开发调试,并且是无条件并行,这很符合我对 agent coding 的想象

成熟的工具链

这里的工具链一时半会也说不完,单 98 这个仓库来说,就有很多可以说道的方面:

  1. 编译打包等杂活:oxc、rolldown、ts7 系列,这些工具能显著提升开发时候的体验,单就 ts7 就可以将 TypeScript 编译速度提升一个数量级,rolldown 更是能保证整个编译打包的时间压缩到几秒内
  2. 并行开发自然少不了 worktree,但是原生的 worktree 如果不搭配一些工具链就是纯纯花架子,毕竟你不能指望模型每次都生成正确的代码,正确是建立在验证的基础上的,而没有环境是无法进行验证的。我这里推荐 worktrunk + portless 来处理本地的多会话开发,

有一个小想法,worktree 开发是不是天生对某些语言不太友好,比如 rust,构建时间长,产物体积大,这些可以通过软链或者生态演进来改善吗?

不同层面的 loop

Loop Engineering 是最近很火的一个概念,大体上指的是编码流程、外部事件响应、自我改进这些层次的东西,详细信息可以参考下面的几篇文章

我这里强烈推荐看第一篇文章,感觉他这里面提到的几个层级很有代表性,尤其是第三级有关 agent 系统和其他系统进行交互的部分,有种 OpenAI symphony 的感觉

即时反馈

这里的即时反馈更多的是由工具链带来的。

验证这个步骤可以从多个层次去看:

  1. 静态层面:我们可以使用各种各样的工具,如 lint、fmt、language server 工具去进行 check
  2. 运行时的正确性保障:我们可以从项目单测、e2e 测试,以及实际的浏览器测试进行验证

对于前者简单的静态验证,我们这里选用的是 Oxlint,加上 build typecheck 等命令来保证。后者的话,我们使用 Vitest 去编写测试代码,然后还引入了 agent browser 来确定项目里面对浏览器操控的能力。

定时任务

定时任务也是有多种的实现方式。我这里主要想到了两类:一块是 CI/CD,另一块是各种 coding agent 自带的自动化任务

我目前用定时任务来每天整理项目过期的知识,以及每周对依赖包进行审计。其实按理说,第一个应该是交给 coding agent 的 automation 去做的,但是由于我没有开发机,而 Codex 在电脑休眠的情况下是不会运行的,所以我们这里最终还是选择上了 GitHub 的 CI/CD

NOTE

说来现在的配置都是通过定时任务去启动。我感觉应该还可以接入各种 web hook,在更精细的时机启动 agent。或者是让 agent 自己去轮询,然后通过某些规则让它决定是否停止。这算是比较简陋的一个实现

微妙的思考

我的存在?

由于整个开发流程都是 agent 做的,我没有去实际编写任何一行代码,所以我不禁思考,这里面我起到的作用是什么?我似乎只是编撰了项目的知识还有技术选型。从这个角度考虑的话,其实开发的门槛已经被大大降低了。开发者不需要去理解任何一行代码,他只需要知道哪些是最佳实践,就可以让项目快速地推进并交付。这也是软件工程的目标。

我之前不担心 AI 会替代开发者,是因为我知道它们生产出来的东西并不是开发者真正想要的东西,而且也不能够保证质量。比如看似厉害的前端页面生成,其实在真正开发的场景里面根本用不到。但是现在我在实践后,感觉又有一种危机:一个井然有序的项目,哪怕是一个从来没有开发经验的人来输入指令,也很有可能去实现软件的演进

harness 是文档?是骨架?是 CI/CD?

我不清楚我做的这么简单的事情算不算是 Harness 的实践,不过如果从初衷和定义上来看,应该是的。Harness 就是用来约束我们的行为,让软件能够更好地进行开发(无论是质量还是速度上)。这么说的话,Harness 确实是上面的任何一种。凡是能够有效约束模型行为的任何行为与建设,似乎都算是 Harness 建设

画饼

篇幅已经很长了,还有很多没有讲到的内容,比方说测试环境、鉴权的保存、代码质量等,以后有机会再慢慢总结吧