万字长文:从 Spec Coding 到 Harness,AI Coding 的两次范式转变与实践
本文讨论了 AI Coding 从 2025 年至今的两次范式转变,包括 Vibe Coding、Spec Coding 流派的特点与局限,以及 OpenAI 提出的 Harness Engineering(约束工程)理念,还介绍了相关实用工具,为现实编码中应用 AI Coding 提供参考。关键要点包括:
- AI Coding 流派演变:2025 年被视为 AI 编程元年,先有 Karpathy 提出的 Vibe Coding,主张“聊天编程,只看结果”,但产出多为“大号 demo”,难适用于严肃软件;后诞生 Spec Coding 流派,内部分为“规即源码”“以规为锚”“先规后码”三类,核心是通过文档约束 AI,但存在 Spec 不可控、维护难等问题。
- Harness Engineering 理念:OpenAI 在内部超 100 万行代码的试点项目中提出该理念,核心是构建约束 AI 的环境,让 AI 基于测试用例、lint 工具等自动迭代代码,无需人工编写代码,仅需维护约束体系,有望成为 AI 软件工程的终态方向。
- AI 软件工程的未来猜想:未来程序员仍会存在,工作模式将转变,一种是“软件工厂”论,即程序员开发“约束工程”作为软件工厂,由 AI Agent 负责实际编码;另一种是“范式转换”论,程序员工作将类似算法工程师“调参”,通过调整约束环境让 AI 符合开发要求。
- 实用 AI Coding 工具:介绍了 Ralph Loop(解决长程任务上下文爆炸问题,通过本地存储进度重启模型)、OpenClaw(适合前端及内部提效项目开发部署,所见即所得)、Superpowers(灵活的开源 Spec Coding 框架,可拆分使用)。
去年(2025)是公认的 AI 编程元年,X上的AI大V Karpathy(卡帕西)在试用了 Cursor 后大为震惊,认为人类以后不需要关心技术细节,于是提出了 Vibe Coding 的概念。
AI Coding江湖从此血雨腥风,去年年底,又诞生了 Spec Coding 流派。他们走向两个极端,Vibe Coding 主张“聊天编程,只看结果”的,而 Spec Coding 却 “长篇大论”,一个需求甚至能写个三四篇文档(prd, plan, tasks)。
但是,你又如何能确定这些长篇大论的文档,AI 真的能够遵守呢?
今年年初 OpenAI 在内部的一个新项目中彻底实践 AI Coding 后,提出了 Harness engineering 的理念。还是要以严格工程的方式确保AI能够完全遵守约束,未来工程师可能更多地是在搭建约束AI进行工作的环境,而不是亲自开发代码。这或许能给我们一点未来 “AI软件工程” 终态的启发。
最后我们还是要回归现实,咱们不参与门派之争,也不一定有机会像 Open AI 一样完全从0开始实践一个AI工程项目。但我们也可以在工作中尽可能地吸收百家之长,一步一步脚印地提升工作效率。
读完本文,你将有下面收获。相信我,不会浪费时间:
- 最近一年来 AI Coding 思想流派的演变与缘由
- 了解公司内外,AI Coding 的实用工具
- 如果在现实编码工作中逐步地应用 AI Coding
第一章 流派之争
起源:Vibe Coding
Vibe Coding 按照 Andrej Karpathy(卡帕西)的说法,就是 “完全沉浸在氛围里,拥抱指数式增长,甚至忘记代码本身的存在”。
虽然没有特别严格的定义,按照大多数人非专业程序员的操作,大概就是 “和AI边聊边写代码,大概试一试没问题,就交付”。
这种方式从 0 开始做一些工具还比较爽,却很难真正落到程序员日常工作中在做的严肃软件产品上。
最后出来的往往是个”大号 demo”,看起来功能都有,但细节经不起推敲。有人戏称其为 许愿编程。
事实上,工程严谨性本身是与AI无关的事情。试想是一个桥梁工程,肯定不会有人因为桥是“AI制造”,就不需要任何严格的结构和承重评估,走一走没问题,就直接通车了。
反叛:Spec Coding
声称实践 “Spec Coding” 的人和框架很多,但是细看他们的实际操作却完全不同。
所以 Spec Coding 门派表面一团和气,内部其实四分五裂。就像金庸小说中,华山派的剑宗和气宗一样。
它至少有三种不同的形式,从激进到保守:
三种形式的分类参考文章 Understanding Spec-Driven-Development
规即源码(Spec-as-source)
定义:将 Spec 作为项目的唯一 “源文件” 进行维护。迭代需求时,人类只修改 Spec,不再接触任何代码。
追溯 Spec Coding 概念的提出,这或许是最接近其原始含义的定义。
Spec Coding 的概念最早由 OpenAI 的工程师 Sean Grove 在 演讲 中提出。
在演讲中,他批判 Vide Coding 存在 “根本性缺陷”:保留生成的代码却丢弃关键的提示词,如同“撕碎源码却精心控制二进制文件”。
他还响亮地提出了 “Specs: Write once, run everywhere.” 的口号,让人仿佛又回到了 Java虚拟机 提出的时代。只不过现在 “run everywhere” 的不再是 Java 语言,而是自然语言。
但是这个口号对于现有大模型的能力显然过于理想。Spec 的不可控性是个严重的问题,哪怕只是改了一个句式,即使语义完全没有改变,也可能导致生成出来的代码完全不一样的。更何况模型也在快速迭代更新,模型更新后,哪怕用同样的 Spec, 生成的代码也完全不同。这简直是测试验证的灾难。自然语言的模糊性就决定了 “run everywhere”或许永远不会成为可能。
以规为锚(Spec-anchored)
定义:Spec和代码同时进行维护。Spec保留在代码仓库中用于后续维护和迭代
既然还是离不开代码,很多框架就只能屈服于现实,同时维护规范和代码。
市面上的 Spec Coding 工具框架基本都属于此类,比如 CLI 工具 Spec-Kit,OpenSpec 和 BMAD,以及 IDE 工具 Trae Solo Spec 和 Qoder Quest Spec 等等
他们首先会定义一套标准的规范流程。比如 Spec Kit 定义的 Spec -> Plan -> Tasks 的流程。在 Spec 阶段只需要编写与技术架构无关的需求文档;具体的技术架构则在 Plan 阶段再进行决定;到 Tasks 则拆解成模型可以一条条执行的任务。
标准流程看似严谨,实际可能可能过于死板。Spec-Kit 定义 Plan 阶段的初衷是 “未来可以根据Spec随意切换技术栈”,但是这极有可能是个 “伪需求”,因为等到项目需要切换技术栈的那一天,Spec 早就过时了。
另外,它们除了提供标准的开发流程外,还会提供一套标准的 Spec 管理和归档的目录规范。比如 Spec-Kit 会在项目的 ./spec 目录中,按如下结构保留历史所有的 spec:
project/
├── specs/
│ ├── branch-a/ # branch-a spec 目录
│ │ ├── checklists/
│ │ ├── contracts/
│ │ ├── spec.md
│ │ ├── plan.md
│ │ ├── tasks.md
│ ├── branch-b/ # branch-b spec 目录不过他们虽然保留了历史上全部的 Spec 文件,但是并不建议用户去修改这些文件,而是始终新建一个 Spec 表明自己的修改意图,在 Spec-Kit 社区曾经讨论过这个问题 Discussion。
所以保留的这些 Spec 其实只能算是一个历史记录,不能认为是 “源文件”。
这些 Spec 框架,到底是否属于 Spec-anchored,也是存在争议的。有人认为它们其实更倾向下面一种更保守的类型。
先规后码(Spec-first)
定义:仅维护代码,不维护 Spec。Spec 仅用于单次迭代的代码生成,用完即抛,不会被保存到代码仓库中
这是最保守的一种 Spec Coding 方式,而且因为不需要和其他同事进行 “维护 Spec” 的约定,也是最适合个人开始实践的方式。
大多数人说自己在 “实践 Spec Coding”,大概率就是这种方式。只要不是直接在聊天框里让大模型干活,而是先编写一个详细的 markdown 文档,再让模型根据文档干活,都可以认为自己是在 “Spec Coding”。
现实中我见过的大部分用了 spec 工具的开发者,也是直接将 specs/ 目录加到 .gitignore 中使用的,此时的开发方式确实更接近 Spec-first。
这虽然有点偏离 Spec Coding 提出者的 “宏伟规划”,但却比较务实。
总结
从 Spec-coding 到 Spec-first,我们发现 Spec 主导的范围越来越小,从整个项目的生命周期,到只能主导某一次的代码变更。
这种模式下最的问题就是 Spec维护问题。
过年期间,AI 编码插件 Augment Code 在官方 X 上发表了一篇文章批判 Spec Coding 的文章,题为 What spec-driven development gets wrong。文中犀利地指出代码才是最好的文档,Spec 的最终宿命一定是过时和腐烂,长期反而会误导模型和团队新人。
不过 Spec Coding 也有可取之处,先讨论清楚背景和计划,再动手去做,这是人类几千年来取得成功的智慧结晶。至于 Spec 完成后是否还需要继续维护,尚存争议。
回应:Harness Engineering
从上面,我们可以看出,Spec Coding 流派至少有三个问题没有解决:
- Spec 编码后结果还需要人工测试,Review。有点经验的程序员都知道,测试并修复bug的时间,一般比写代码的时间要多好多倍。
- 如何保证 Spec 的遵守?文字描述不一定真的管用,而且太长的 Spec 会导致模型的注意力被稀释。
- 过期的 Spec 如何维护
在 AI Coding 发展如此之快的背景下,很快就有团队写文回应这三个问题。
在我们过年的时候,OpenAI 发布了一篇题为 Harness engineering: leveraging Codex in an agent-first world 的 AI Coding 实践文章。OpenAI 做了一个内部试点项目,所有代码都用 AI(Codex) 编写,目前已超过100万行代码。参与其中的工程被要求 “不允许写一行代码”,只能用测试用例,lint 等方式对 AI 进行 “约束”,最终实现了效率大幅提升,AI 能够最长连续执行 6 个小时的长程任务。
Harness 原指将动物拴在桩上的系带,全文想表达就是构建一个约束 Agent 行为,让其往人类想要方向迭代的环境。也有人将其翻译为 “治理”,“框架”。但我觉得 “约束” 才是最恰当的,最符合原文想要表达意思的翻译。
“约束工程” 的想法也是符合直觉的,“测试用例是最好的文档” 相信程序员都会对这句话深有体会。文档很快会过时,但是有 CI CD 保证的测试用例一定是和代码一致的。
通过回答 Spec 存在的3个问题,我们来看看 “约束工程” 的主要想法是什么:
- 如何减少人工测试和 Review?让AI拥有完整的上下文(比如日志,Metrics等等),打通集成测试自动化链路,前期先和 AI 一起构造完备的测试用例。开发阶段,AI 并不是仅仅完成功能代码就了事,还要让 AI 继续在测试用例的反馈中不断迭代修复代码。最终保证 AI 代码的正确性,无需人工 Review 和验证。
- 如何保证 Spec 的遵守?Agent 和人一样,仅靠口头约束,是很难保证规则的100%执行的,并且 Prompt 越长,能够遵循的比例越低。还需要一些强制约束的补充,比如 lint 工具,就在文中被重点强调了。这个 lint 工具是 OpenAI 团队专门为这个项目开发的,除了有常规 lint 工具都有的代码规范进行检查,还包含对架构的校验(举个例子,架构分层中,api层不能直接调用infra层,必须先调用service层)。Agent 每次开发任务完成后,都要调用 lint 工具进行一次校验。如果校验不通过,lint 工具会给出对应的提示。模型可以很容易根据工具提示修复。
- 过期的 Spec 如何维护?OpenAI 团队专门开发了一个定时任务,定时扫描代码库,用一个专门的智能体判断其中是否有代码和 Spec 的不一致之处,并进行修复。不过我个人对这种方法的意义是存疑的,既然 Spec 信息能直接从代码中推出来,那就没必要重复存一份,需要的时候临时询问就行了。
Anthropic 之前也发表一篇用 Agent Team 重写 C 编译器的文章 Building a C compiler with a team of parallel Claudes。让智能体连续数周的持续工作,最终写出了一个完全兼容 GCC 的编译器。
这除了 Agent Team 功不可没之外,更重要的是 GCC 编译器本身就是人类历史的最好的 “约束工程” 实践之一。GCC 测试套件经过37年发展和数千名工程师的持续完善,已成为编译器质量验证的黄金标准。模型通过不断通过测试套件验证自己的代码并持续迭代,人类只需要查看测试用例的通过情况就可以,达到了最少量的人工介入。
因为强大的编码模型出现的时间还不是很长,现在很多程序员还保留了 “旧观念”,认为项目的 “主工程” 才是最重要的。单元测试,集成测试以及CI CD等都只是项目的 “周边”,提早开发是 “浪费时间”。
OpenAI 在文中呼吁我们改变这种旧观念,未来单元测试,集成测试以及CI CD构成 “约束工程” 等不再是 “周边” 和 “浪费时间”,而是所有项目从一开始就需要基础设施。程序员的主要精力将投入到“约束工程”的维护中,而过去认为最重要的“主工程”,则全权交给 AI 进行开发。
AI 软件工程的终态?
- “软件工厂” 论:未来程序员不再是开发软件,而是开发一个个 “软件工厂”,Agent在其中作为工人进行真正的软件开发。类比下前文中的 “约束工程”,可以认为 “约束工程” 就是一个软件工厂。这个说法来自于 Django 框架的联合创始人 Simon Willison 在 X 上发起的讨论。链接
- “范式转换” 论:未来软件工程师的工作方式会越来越接近 “算法工程师”。“算法工程师” 的工作方式是什么呢?有句黑话叫做 “玄学调参”,就是调教模型更好地适应任务。而软件工程师的工作也会变成调教Agent以更好地开发当前开发的项目。这是一种软件工程范式的转变,从之前确定性的代码逻辑推理,变成和算法类似的非确定性的 “调参”。类比之前的 “约束工程”,就是不断地调整 “约束环境”,让模型以更加符合人类要求的方式开发项目。这个说法来源我和朋友的一次讨论,目前没发现明确来源。
两周前,OpenAI 又基于 Harness Engineering 的理念开源了项目管理工具 Symphony,在这个工具里,人只管咔咔提交任务,Agent昼夜不眠的完成这些任务。工程师和主工程代码完全隔离,只需要在 Agent 完成工作时,简单看下 CI 状态,以及 Agent 提交的一小段功能录屏就可以。很有 “软件工厂” 那味了。
第二章 实用工具
公司内部非常常见的 Trae,Trae CLI(Coco),Claude Code,CodeX,AIME等我就不说了,讲一些相对比较少见的,或者一些组合技巧。
需要注意的是,在AI日新月异的今天,所有的工具和技巧都会很快过时,需要经常探索有没有更好的方法。
Ralph Loop
当 AI Agent 跑几天甚至数周的超长程任务时有个致命问题,就是随着运行时间越来越长,Agent 的上下文越来越长,表现也会越来越差(当然,可能你的钱包会更先受不了)。虽然可以配置自动压缩,但是压缩常常导致重要的信息丢失。
Ralph Loop 顾名思义,是一个循环,但它位于 Claude Code 之类的编程工具上层,通过反复重新启动 Claude Code,避免模型的上下文爆炸。中间的上下文,则持久到 progress.txt 和 git commit 中。Claude Code 每次重启后的第一件事,就是去读这些,找到之前的进度和记忆。
Ralph Loop 用伪代码表示如下:
将用户需求拆分成任务:prd.jsonwhile 存在未完成任务 and 小于设置的最大迭代次数:
从 progress.txt 和 git commit 中了解当前正在进行的任务,以及达到的进度
从 prd.json 中取出优先级最高的还未完成的任务
完成任务后,将这一次的进度和发现更新到 progress.txt,并且总结完成情况进行 git commit
Ralph Loop 虽然简单粗暴,但是实践下来,却是远比 Agent Team 更好的长程任务执行方式。Agent Team 虽然通过拆分 Agent 节约了一部分上下文,但是依旧会导致上下文不断累积,并且一旦中断,状态无法恢复。Ralph Loop因为进度都存在本地,结构简单,出了问题,随时可以重新执行。
Ralph Loop 的具体使用方式见其 Github 首页:Ralph
OpenClaw
这里指远程部署的 OpenClaw,我用的是公司内部的 OpenClaw 开发机(具体配置方式见
Devbox OpenClaw / Clawdbot开发机使用指南 | Devbox OpenClaw/Clawdbot developer computer guide),虽然也有人本地部署,但是个人觉得价值不大,对于程序员,本地不如直接用 Claude Code,现在 Claude Code 也支持远程连接了,参考 Continue local sessions from any device with Remote Control。
OpenClaw 也可以写代码吗?
有人会用它操作 Claude Code 或者 CodeX 写代码,但是个人实践下来不用这么复杂,接入一个代码能力还可以模型,直接让它写,也能不错的效果。
最方便的是前端项目的开发,让它开发完成后直接部署,立马就能看到效果,不满意再让它调整,所见即所得。
我最喜欢用它做一些团队内部的提效项目,这种项目用户不多,能用就行。用 OpenClaw 开发,我完全不用关心它是如何部署的,数据又是怎么存的。只需要在它部署好之后,访问一下开发机对应端口,点一点页面,大概没问题,就可以交付使用了,这才是真正的 “Vibe Coding”。
比如我部署在开发机上的用于上班时间冥想放松的网页 WorkPause。其中本文还有一个对应的 PPT,也是 OpenClaw 帮我制作并部署的 AI Coding PPT。
Superpowers
反问
候选方案
里面还有很多其他好用的 Skill,比如用于问题排查的根因诊断 Skill systematic-debugging。读者可以自行发现。
Bytedcli
最近 CLI-Anything 爆火,人们越来越意识到,看似古董的 CLI,反而是最适合 Agent 使用的模式。
其实字节早就有可以操作各种研发平台的 cli 工具 - Bytedcli(具体安装和使用方式见
bytedcli - 字节研发工作流程 CLI、Skill 和 MCP | bytedcli - bytedance Workflow CLI, Skill and MCP)。
使用 Bytedcli 可以让 Agent 开发完成后,实现自动部署,自动测试,大大节省人力。也可以很方便地实现一些重复工作的自动化。
我就用 Bytedcli 给 OpenClaw 做了一个修改代码并自动提交MR的 Skill,这样当我老板又@我做小需求的时候,我直接把需求转发给龙虾就可以了。(≖ ‿ ≖)✧
公司还有更多其他CLI工具,比如用于操作 Codebase 的
🥷
Skill
字节内部的 Bytedance Skills 已经有非常丰富的 skill 可以使用,包括使用 bytedcli 的 skill Bytedance tools。
但是实践下来还远远不够。特别是关于内部库的使用,比如 ByteMetrics,ByteRedis,Overpass RPC 这些,直接让 Trae 去写相关代码是不行的,因为没有相关知识,常会产生各种幻觉。
理想情况下应该由中间件团队统一提供内部库相关的 Skills,不幸的是,目前还没有。
遇到这种情况,要么就是祈求有好心人已经实现了这个 Skill,比如 Overpass RPC 的 Skill 10x-rpc-builder。要么就是自己动手。
自己动手其实也没有特别复杂,中间件都有自己的文档,用 AI 根据文档直接生成即可。不过这些文档的访问容易有权限问题,所以我一般让 Aime 去读这些文档并生成 Skill,然后将其下载到本地使用:
关于 Skill 的原理,过于老生常谈,我就不多说了,简单理解为 一段可以被触发的提示词模板。具体看我同事的另一篇文章 从热潮到反思——什么是 Skills
AGENTS.md
AGENTS.md 是在和模型每次对话时,都会默认加载的提示词。
对于这里应该写什么的,每个人有不同的看法,有人甚至认为要把整个项目的 Wiki 放进去。但我表示反对。
- 项目的部署架构:部署架构是没有办法从代码直接推理出来的,AI 不知道它当前看的代码究竟被部署到了哪几个集群,每个集群之间的区别又是什么,集群间的相互调用要怎么处理。如果不知道这个信息,让 AI 做涉及到集群间交互的需求时,或者咨询相关问题时,就会出现幻觉和错误。所以我在 Agents.md 里专门放了一小段描述部署架构
# 部署架构项目有BOE(测试)环境和生产环境。
在每套环境中,该项目分为多个集群部署,每个集群部署的都是该项目的一个副本,代码相同。但是核心运行的模块不同。
agent 集群:对外提供 http 接口,其 base url 可以通过
models.config.get_settings().agent_domain获取evaluation 集群:负责调度 Queue 的创建和 Task 的执行,核心
services.scheduler_service.SchedulerService中的定时调度任务executor 集群:负责消费并执行 Queue 中的 Task,核心逻辑是
executor/executor.py。Worker 也是在其中的隔离环境运行,Worker 的核心逻辑位于worker.py项目的核心概念有哪些,它们之间的关系是什么?这样和模型聊天的时候,大家对某个名词理解就是一致。对于我所维护的调度系统,我在里面画了一张简单的图,说明几个调度组件之间的核心关系
+-----------+
| scheduler |
+-----------+
|
task1, task2
v
+--------+
| Queue |
+--------+
/ \
/ \
task1 task2
v v
+----------------------+ +----------------------+
| executor0 容器 | | executor1 容器 |
+-----------+----------+ +-----------+----------+
| worker00 | worker01 | | worker10 | worker11 |
+-----------+----------+ +-----------+----------+这样的 Agents.md 就非常简洁,二三十行就表达清楚了所有关键的信息。
模型选择
曾几何时,人们觉得未来会有一个统一的大模型一统天下。
今年大家的观点已经大幅转变,模型之间的差异化是确实存在,就像不同的人有不同 “个性”一样。正如Kimi创始人杨植麟在一次访谈中说:“智能Taste的差异是巨大的”。
经过一年的使用,大家对常见模型的调性基本已经形成了共识:
图片摘自 TRAE 国际版 SOLO 模型选择指南(下)
第三章 现实应用
和工具一样,在 AI 日新月异的今天,现实应用的范式也会很快过时,并且很多也只是对现状妥协的产物。
需要经常探索,持续迭代,才能最大化 AI 在软件工程中的效率。
迭代范式的两次升级
关于升级 AI Coding 的迭代范式,最自然的方式是,逐渐发现工作中的痛点和耗时部分,然后应用 AI 工具去解决和提效。
如果只是哪天突然心血来潮,就激进地说要 “全面 AI”,或者 “为了 AI 而 AI”,那么必然会遭遇失败。我们去年就有这样的失败经验,一方面是因为模型能力不够,另一方面也是无法准确击中现实开发的痛点。
我从 Vibe Coding 到 Spec Coding 的动机非常简单:就是单纯觉得和模型对话的窗口太小,限制了我向模型输入复杂需求,和进行深度思考的能力。我的性格本来也是喜欢先想清楚再干的,先和 AI 讨论清楚方案再干的方式,刚好和我的性格也非常 match。
但是在实践中逐渐发现,写代码其实只占需求迭代的很小一部分时间,更多的时间是在做人工验证+bugfix。
Spec Coding
注:原文此处为在线画板或外部图片占位,离线归档时已移除;本文已补充结构化示意图辅助理解。
上面的流程图看起还是会有些抽象,这里以我最近做的一次需求迭代为例:
需求案例:coze coding agent 接入RL(强化学习)训练沙箱
阶段
内容
产物
技术调研阶段
调研沙箱 sdk 的接入方案
沙箱SDK使用Skill:sandbox-sdk-python
(Aime)
结论:使用沙箱 python sdk
需求拆解阶段
以方便逐步验证
子需求
(人工)
- 技术调研阶段-Aime:Aime我觉得是和各种内部文档打通得最好的工具了,包括字节云文档,飞书文档,以及不知名中间件网站上的文档,读取这些东西完全不用担心权限稳定。写出来的飞书文档又好看,所以这个阶段我用起来很顺了。通用的 Agent 工具,像 Trae,和飞书,字节云文档打通起来不免有一些难搞的权限问题。这一部分的成果可以通过生成 Skill 传递给下一阶段。
- 需求拆解阶段-人工:目前“需求拆解”需要的业务背景知识和人际交流还是太多,到底怎样方便验证,怎样客户才能接受,都需要程序员沟通和做决定。虽然可以在中间辅助思考一下,但是主体还是人
经过一段时间的实践,我们发现。实际工作中只有 20% 的时间在写 Spec 和代码。另外 80% 的时间都在测试和进行 bugfix。我们只将这 20% 的部分自动化,而另外 80% 几乎纯手工完成,无异于 “捡了芝麻丢了西瓜”。
其实整个代码实现阶段,只有产出 Spec 是需要人深度参与的,brainstorming 技能的反问和多候选方案机制,提升对系统认知的同时,也能帮助程序员大大打开思路。Spec 产出后,完全让 AI 进行发布测试和 bugfix,就能大大提升效率。这也是下面章节的内容。
Harness
我比较反对一上来就照搬 OpenAI 套路,实施彻底的 Harness。OpenAI 毕竟是拿一个新项目进行的实验,而大多数程序员手头都是老项目,俗称“屎山”。这些项目可能单测,CI CD 都不完备,甚至没有统一的编码和架构规范,完全实施 Harness 成本太高,甚至不一定可行。
比较自然的方式是,多研究自己平时的测试行为,尝试用 AI 逐渐将其自动化,让 AI 代表你对软件开发进行“约束”。循序渐进地将事情推进下去。
比如虽然项目没有单元测试(更多的单元测试混乱,不知道哪些有效),但是每次开发完后,你都会在 PPE 上部署一个泳道,请求接口,最后去 argos 上看看有没有错误日志。你就可以尝试用 Bytedcli 将这个过程自动化,先录入测试用例,之后让 AI 开发需求,完成代码后自动部署,自动测试并查看 argos,如果有问题也自动修复,直到测试用例全部通过。
顺着这个思路,分享一个我们团队实践的案例。
案例:Marscode Sandbox Executor 自动化开发实践
注:原文此处为在线画板或外部图片占位,离线归档时已移除;本文已补充结构化示意图辅助理解。
技术调研阶段 和 需求拆解阶段,还是和上面的 Spec Coding 章节保持一致。这里重点优化的是代码实现阶段。
阶段
输入
工具
产物
Spec产出
技术调研产出的Skills
Trae + Superpowers
Spec
测试用例产出
人工
测试用例
自动化代码编写和验证
测试用例+Spec
Trae Solo
测试报告
测试报告Review
测试报告
人工
人工验收结论:是否需要下一轮
我们约定了测试用例为如下的 toml 格式,每个用例包含4个字段:
- id:当前文件唯一的用例编号,直接从0开始递增即可
- name:用例的名称
- description:用例的描述,QA智能体会根据用例的描述对结果进行语义验证
- data:执行该用例所需要的一些数据,对于我们来说,其实就是待测试接口的请求体
test-reports-01.txt
最后依靠程序员 Review 测试报告进行兜底,因此测试报告的内容必须是非常丰富的,程序员如果觉得不对劲,可以用这些信息再去复核。UI 类的 QA 测试最好还要包含一个操作录屏,方便人类对整个操作过程进行复核。
完整的方案见:
RL Sandbox fix loop自动开发验证方法。注意,因为 Marscode Sandbox Executor 是部署在自建 K8S 集群上,不是部署在 TCE 上的,所以发布方法跟普通应用不一样,不具备参考价值。普通 TCE 应用可以考虑用上文提到的 bytecli 将测试代码自动部署到泳道中。
时间管理大师:三维任务划分
时间管理在 AI Coding 很少有人提,但我却觉得是每个实践者都绕不开的话题。
特别是当你的技能成熟之后,AI 能够连续运行很久,中间你又去干什么呢?
为此,我从两个维度对任务进行了分类,分别是任务的长短和约束的强弱。长短用来体现任务的大小,约束用来体现项目的用例和规范的完善程度。
注:原文此处为在线画板或外部图片占位,离线归档时已移除;本文已补充结构化示意图辅助理解。
“长程强约束” 是最适合 AI 开发的项目,用比较流行的话来说,就是 “Agent Native”。这种项目的用例和规范都是显式存在,自动化测试保证 AI 不会把代码改坏,lint 工具保证 AI 的代码符合工程规范。所以才胆敢让 Agent 连续数周地执行重构,而不用怕跑偏。这不是什么新方法,传统的优秀软件工程都像这样,比如 gcc 编译器,只不过 AI 让大家没有理由再偷懒了而已。
Ralph Loop 我认为是目前最适合 “长程强约束” 任务的工具了。也是 Open AI 在 Harness engineering 一文的实践中所使用的工具。
而程序员大多数手动在维护的 “屎山代码”,大多是 “短程弱约束” 项目,首先项目没有完善的规范和用例,全凭口口相传,以及程序员自己对业务的推断;其次,这个项目很重要,线上有很大的流量,不能只是随便搞搞就上线。这种项目一般不敢让 AI 跑特别长的任务,长任务的不可控性会让上线成为灾难。一般只让 AI 生成局部代码,并且程序员会对这个代码进行详细 Review,理解原理,确保没问题后,再生成下一段。这个时候就只适合使用 IDE 模式的 Trae,依旧以 IDE 为主要的工作模式,AI 只做局部代码生成的辅助。
- 短程弱约束:我每天投入主要精力的琐碎业务需求
目前最限制程序员生产力的情况就是:能够做到 “长程强约束” 的任务还是太少。从业界的实践来看,大多集中于编译器和解释器项目。但是世界上做编译器,解释器的程序员还是太少了,业务价值就很低。大多数程序员在做的事情还是属于 “短程弱约束”。
但是相信随着大模型的能力越来越强,“约束工程” 越来越得到人们的重视。会有更多的项目被逐步被改造成可以进行 “长程强约束” 任务的形式。期待着未来的这一天。
如何衡量AI的使用程度?
如果你一直读到这里,会发现我全文都没有提 Token 消耗量,或则 AI 生成代码占比之类的事情。虽然现在考核比较多,但是我觉得不重要。
我赞成的理念是:Agent 要尽可能长时间地运行,最理想情况是 24 小时都在执行。
最理想的 AI 效率衡量指标不是 AI 生成代码占比,也不是 Token 消耗量,而是 Agent 等待时间。
正如 “在 PC 运算中,CPU 不应该等待硬盘访问,要尽可能地减少 io wait 的时间” 一样。人机协作也要减少 “human wait”:
注:原文此处为在线画板或外部图片占位,离线归档时已移除;本文已补充结构化示意图辅助理解。
所有 AI Coder 真正应该追求的目标是:将Agent等待时间降为0。
