AI 结对编程 C++ 后端造轮子初体验

七阶子
12 min, 2321 words

归类: 程序设计

标签: C++ AI

AI 结对编程 C++ 后端造轮子初体验

AI 编程已经火了好一阵子了。但我作为一个后端码农,更习惯于命令行工具,所以对于 那些 AI 插件、AI IDE 都没深度使用。直到以 Claude Code 为代表的 ai-cli 命令行编 程工具出现,才感觉能对上胃口了。然而我又是个穷鬼,平时又没强烈的愿望科学上网, 所以又观望了一阵,再等等国内平替(山寨) AI 编程命令行工具出现。

然后某一天,瞅着鹅厂推出了 codebuddy ,就安装了尝试一下,这才算开始正八经体验 AI 辅助编程。此前所在公司也曾强推 AI 插件工具,下达 AI 使用指标,那不太算数的 。因为历屎沉积的项目比较大,AI 代写的效果并不妙,但可作为一种新的补全手段。

于是我抽出一个较小的基础库功能,创建独立仓库,尝试利用 AI 进行重构、迭代与优化 。那是很常见的 json 数据处理功能,我们的项目仓库中此前拖了好几个 json 开源库并 存,最近入库的是 yyjson ,据说其性能在第一梯度。但是 yyjson 是纯 C 库,其 api 使用有点繁琐,我不太喜欢。所以想自己再做一层 C++ 封装,尤其是想实现操作符重载 的特色,以达到常用 json 操作只需使用操作符而不涉及具名方法。此外,易用性抽象与 高性能的平衡也是考虑重点。

总之,目标是能回生产实用的 json 操作库,而不是为了测评 AI Agent 或模型的 demo 玩具。项目地址是 https://github.com/lymslive/xyjson

我的开发环境是 Windows 10 WSL ,主要 Agent 工具就是 codebuddy 国内版,模型使用 以 deepseek 居多。codebuddy 曾有两周免费的国际版体验,也用了。此外,前段时间 MinMax 模型免费,也试用过一段时间 Claude Code 。样本经验并不多,我很难评各个的 优缺点,只能说本质上是同类工具,用自己顺手顺眼的就行。

经过开始一段时间的摸索后,我逐渐形成了一种工作流。说起来也简单,就是把自己的需 求、设计与灵感写在一个 task_todo.md 中,提交给 Agent 完成后再让它写个 task_log.md 任务日志。

其实最开始这两个文件不叫这名的,有个意外事件。原本我只想维护一个文件,命名为 ai_request.md 。我将自己的需求写个二级标题,本意是想叫 AI 在原文件的需求二级 章节下加三级标题记录完成情况。结果在输入框 @ai_request.md 提交后,它居然给我 新建了一就名叫 @ai_request.md 的文件来记录工作日志。

我一度很无语,但思索片刻后,觉得这样分开也好,我写我的文档,它写它的文档,双线 并行不要混在一起。但是文件名要改一下,总不能在文件名中顶着 @ 作案。于是我写 task_todo.md 作为原始需求,AI 写 task_log.md 作为工作汇报。

两个文档都在二级标题中标上 ID ,虽然都基于日期生成,但格式略有不同。 task_todo.md 中的叫需求 ID ,格式是 yyyy-mm-dd/n ,后缀是 1 2 3 这样的递 增序号,这是面向手写的自然计数。task_log.md 中叫任务 ID,生成格式是 yyyymmdd-hhmmss ,在写日志时让它用 date 命令自动生成。这是两套 ID,不过在 任务完成后也会在 task_todo.md 加个三级标题,标注 DONE: 关联任务 ID。有时我 也还会在这个子标题下备注一些内容。

然后围绕这两个文档的管理,我使用最多的是 Agent 工具的自定义命令,也就是 / 命 令,并且配合自已专门开发的脚本使用。此外,那些貌似高级的 MCP 呀 Skill 都没派上 用场。

首先我定义了一个 /pop 命令,就是从 task_todo.md 中读取一个 TODO 需求扔给 Agent 去做。.xxx/commands/pop.md 文档中写的就是总体工作流的提示词。其中可写 明调用一个脚本读取 task_todo.md 的一节需求内容,脚本就放在 script/todo.pl 。我习惯使用 perl 这个曾经的王者来处理文本文件,当然脚本也是由 Agent 写的,我 能看懂并在必要时一起帮忙 debug 就行。这个脚本也同时用于更新某个需求的 DONE 状态(传入不同参数)。

我曾想过为不同类型的任务定义不同的 pop 命令,比如 pop1/pop2/pop3 ,写 上不同的提示词。自定义命名的元数据中有描叙字段,在输入时有提示,所以虽然命名类 似,但能区分,主要是想快捷输入。但是我遇到一个 bug ,当输入 /pop3 arg 时,它 解析成 /pop 3 arg 了,把 3 当成 /pop 命令的第一个参数了。我不知道这是不 是 codebuddy 特有的 bug 以及后来有没修复。反正我改为使用前缀区分了,简单任务使 用 /simpop 命令,也没搞那么多复杂变种命令了。

也有少量需求,可能太简单或太复杂,不适合交于 AI 完成,最后纯手工完成了,也就手 工标上 DONE。于是我又写了个 /gc 自定义命令,自己执行 git add 添加待提交 文件后,让 AI 帮忙写个提交消息做最后提交。我以前自己 git commit 只会写单行 ,懒得写多行提交消息,麻烦,这事就可以让 AI 代劳。

此外,我在 script 子目录下还开发一些其他辅助脚本。比如,我发现单头文件越来越 大后,AI 经常将代码加在不是我想要的地方,而且我很难跟它说清楚要写在这里或那里 。于是我在头文件中制定了一种标题系统,用脚本自动更新目录(TOC)。还有同步文档 的示例与单元测试,保证文档的示例可编译可运行的正确性。可能有些单元测试框架工具 就支持这种功能,但我使用的自研轮做单元测试,也就是需要另行开发脚本同步 .md 示例与 .cpp 的用例。有 AI 来开发脚本这事的性价比大大提升了。

最后,若说我这个 xyjson 项目有多少代码是 AI 写的,这很难估计。我觉得很多地方宣 扬有多少百分比由 AI 生成的,可能都出于宣传广告目的,说多少百分比都可以,反正怎 么算的解释权在自己手上。就比如我这个项目的真正产出就只有一个 xyjson.h 头文件 ,现在 v1 版本也就 4000 行左右,除去注释空行纯代码可能还不到 3000 行。其中的每 一行代码可能都经过 AI 的手,也经过我的手,这怎么算。单元测试与辅助脚本倒是以 AI 生成为主,我 review 后没大问题就接受了。真要给个中肯的比值的话,可以看 task_todo.mdtask_log.md 这两个代表人机协作的文档的行数,总体来说,后者 多一些。

不过我又发现一个现象,我在这个项目的文档接收率远比代码接收率低。也许,在应付式 交差工作中,AI 写文档(文案)比写代码容易,毕竟 AI 很能水字数,而代码还可能编 不过。但是,在有个性追过的场合中,AI 写文档反而比写代码难了,因为代码有标准, 可验收,但文档没标准,不知该如何验收。反正我让它写了几版用户指南与 api 文档, 都不满意,最后自己重写算了。所以,我对 AI 写小说、写文学也还存疑。

至于 AI 编程能否提升效率的问题,也分场合。在非严肃场合,比如一次性脚本、demo 玩具之类,效率提升极大,是能很快生成。而在有质量追求的严肃场合,AI 就未必能提 升效率了,但是能提升质量上限。将人从大量重复琐碎的事务中解放出来,让人去做更有 价值、更有创造性的工作,AI 编程的意义仍是巨大的,当是软件工程的一个里程碑革新 。

最后谈一下 AI 辅助编程的术语名称,氛围编程太玄学,我觉得还是结对编程最合适,也 不必新造词汇与概念了。只是以前在公司的牛马,一个人恨不得当几个人用,哪有人力来 安排多人结对编程。但有 AI 就不一样,一个人与 AI 结对编程,性价比挺好。另一方面 ,大部分人的精力也是有限的,哪能一个打十个,你想一个人管十个 AI 干活?又不知会 不会增加程序员的猝死率。