在这里插入图片描述

概述。

“既然是 AI,本应是来解放人类的,不应该让人类更疲惫。”

过去一年,很多开发者都沉迷过一种工作方式:打开大模型 IDE 插件,一边听歌一边 Vibe Coding,看着 AI 嗖嗖产出代码,感觉效率拉满。直到午夜一两点,你还在反复重启服务、手动点点点测试,然后对着日志一顿 Ctrl+C/Ctrl+V 喂给模型,最后身心俱疲。

如果你也有类似经历,我将会尝试给出一条更可持续、更“工程化”的道路:通过构建自动化反馈闭环,让 AI 自己写、自己测、自己修、自己重构,开发者转而做规则、环境和基础设施的设计者,而不是深夜一个人“和 Bug 搏斗的人类”。

本文将围绕以下几个问题展开:

  • 为什么大部分人的 Vibe Coding 体验那么差?
  • 如何利用 TDD 和端到端测试,为 AI 搭建“自助验证”的闭环?
  • 如何用“非退化性”的思路,让 AI 逐步重构出高质量代码?
  • 在这种工作流下,模型“多强”还重要吗?
  • 如果你想落地一套类似方案,应该从哪里开始做改造?

一、Vibe Coding 为什么容易把人搞到“红温”?

1.1 典型的“AI 编程噩梦”流程

先回顾一个很多人都很熟悉的场景:你要做一个聊天机器人插件。

典型流程大致如下:

  1. 把需求、接口文档、项目结构说明丢给大模型。
  2. 让模型生成第一版插件代码。
  3. 本地部署插件,启动服务、接上真实平台(比如 QQ、Telegram、某内部 IM)。
  4. 手动发几条消息做交互测试。
  5. 发现逻辑不对或者直接报错。
  6. 打开日志,复制错误堆栈、请求参数等,再喂给模型。
  7. 模型“分析一波”,生成修正版代码。
  8. 你再部署、再测试、再踩坑……

在这个循环中,一个 Bug 可能要来回折腾好几轮,等功能“看起来能跑了”的时候,代码往往已经略显凌乱,充满临时补丁、条件分支和“先这么写能跑就行”的妥协。 想重构又担心改坏,整个人被锁死在桌子前。

从资源消耗上看,这样的流程有几个明显问题:

  • 人类成为闭环里的“胶水”:部署、运行、点点点、粘日志。
  • 问题定位高度依赖人工眼力上下文记忆
  • 模型每一轮修改都需要你“亲自批准并执行”,导致极高同步成本。

1.2 根本原因:缺乏反馈闭环

如果从系统角度审视这条链路,会发现一个关键事实:AI 写的代码,大多数时候不能一次跑通;但 AI 又拿不到即时且系统性的反馈。

虽然你已经把需求、文档和示例都交给了模型,它在“理论上”具备写出功能代码的前置条件,但落地时仍然存在几个断点:

  • 模型本身不会“点按钮”、不会操作 GUI,它无法直接驱动你的真实客户端或运维环境。
  • 它没有固定的、结构化的“检查机制”,不知道什么叫“通过了所有关键路径”。
  • 每次执行代码、收集日志、重新运行,全部由人类来做。模型像在黑箱里“盲射”。

本质上,这是一个没有打通反馈通道的控制系统:模型永远在开环输出,而不是在闭环优化。

如果你来自传统工程背景,会很自然地想到两套经典思路:

  • 测试驱动开发(TDD)
  • 端到端(End-to-End,E2E)测试

接下来我们就从这两点出发,看看如何把“老方法”嫁接到“新工具”上。


二、构建自动化闭环:让 AI 自己写、自己测、自己修

高效 AI 编程的关键不在于写出多炫的提示词,而在于帮模型搭起一个稳定、自洽的反馈闭环:模型输出代码→自动运行→收集反馈→模型根据反馈迭代,尽量把人从这个循环里剥离出去。

整体思路可以拆成两步:

  1. 回到 TDD:让模型自己写测试、自己守住测试。
  2. 构建端到端测试平台:让模型能在“接近真实环境”的场景里自测。

2.1 步骤一:回归 TDD,让 AI 负责 Red-Green-Refactor

TDD 的经典流程是:Red → Green → Refactor

  • Red:先写测试,此时测试必然失败。
  • Green:编写最小实现,让测试通过。
  • Refactor:在测试保护下重构代码结构。

在 AI 参与的场景里,一个重要的改写是:让模型而不是人类来负责整个 TDD 循环

这意味着,你要在提示词和项目规范里明确几件事:

  1. 先写测试再写实现

    • 对于每个功能模块,先让模型根据需求编写单元测试(或集成测试)。
    • 明确要求:不允许先写实现再“补测试”,否则模型会默认走“直接写功能”这条更近的路。
  2. 模型必须自己运行测试

    • 通过脚本、CLI 或 CI 任务,让模型能触发测试运行,并读取测试输出(成功/失败、失败原因、堆栈)。
    • 在提示词中写明:每轮修改结束,必须重新运行对应测试套件。
  3. 出错后首先根据测试反馈自修复

    • 模型拿到测试报错信息后,需要给出“错误原因分析 + 修复方案 + 修复后的代码”,而不是靠人类手动告诉它错在哪。

举个简化版提示词例子(以 Claude Code 为例,可以通过修改 CLAUDE.md 来约束行为):

你是本项目的自动化开发代理,请严格遵循以下流程:

1. 对于每个新功能:
   - 先根据需求编写单元测试和必要的端到端测试脚本。
   - 运行测试套件,确认测试失败(Red)。

2. 根据测试失败信息实现功能代码:
   - 写出最小可行实现,使前述测试通过(Green)。
   - 再次运行测试,确认所有相关测试通过。

3. 在测试保护下进行重构(Refactor):
   - 优化代码结构、命名和抽象,但禁止改变对外行为。
   - 每次重构后必须重新运行全部测试,确保无回归。

严禁:
- 在未运行测试的情况下提交代码修改。
- 删除或简化测试以“制造通过”假象。

通过这种规范,你在项目层面告诉模型:测试是地板,不是天花板。模型的行为围绕测试约束来展开,而不是围绕“写出看上去合理的代码块”。

当然,TDD 主要保障的是局部逻辑正确性,还不足以覆盖完整业务流程。这就引出第二步:给 AI 提供一个可以进行端到端自测的平台。

2.2 步骤二:构建端到端测试平台 ——

单元测试验证函数或模块级别的正确性,但很多 Bug 并不局限于某个函数,而是出现在消息流转、状态同步、外部依赖、配置组合等整体链路中。

特别是在“聊天机器人”场景下,真实流程大致是:

  • 用户发送消息 → 机器人框架接收到事件 → 经过中间件、插件处理 → 机器人回复消息。

传统做法是“上号测试”:

  • 真登录 QQ/Telegram/企业 IM。
  • 手动发消息观察回复。
  • 一旦有 Bug,就回到代码、日志、模型那里继续循环。

这种方式对 AI 来说几乎不可用,因为模型:

  • 不能操作 GUI 客户端。
  • 不能自己在真实网络环境中发消息。
  • 拿不到完整、结构化的行为反馈。

解决思路很直接:把聊天场景抽象成“命令行里的可编排流程”

2.2.1 从“上号测试”到 CLI 模拟器

以 AstrBot(一个机器人框架)为例,核心洞察是:AstrBot 的本质是“输入消息 → 处理 → 输出响应”,与是否连上真正的 QQ 客户端无关。

基于这一点,可以开发了一个 AstrBot CLI 测试平台

  • 通过命令行模拟“发送消息”“接收响应”。
  • 可以在 CLI 中重启服务、加载不同插件配置。
  • 日志输出也可以被模型读取和解析。

在这样的环境里,AI 的工作流可以变成:

  1. 写完插件或改完代码。
  2. 通过 CLI 触发一组预设的 E2E 测试流程:
    • 比如“用户发送 /fish 指令 → 应返回钓鱼结果并更新用户资产”。
  3. 如果输出不符合预期:
    • 模型读取 CLI 输出和日志。
    • 自行分析错误原因,修改代码。
  4. 再次运行同一组 E2E 测试,直到全部通过。

这套机制的关键价值在于:把整个业务流程缩进了一个模型可以理解和操作的“文本接口”中

2.2.2 实际效果:35 分钟搞定一个复杂插件

一个具体例子是:开发一个“钓鱼游戏”插件,需求包括:

  • 尽可能多的鱼类品种。
  • 稀有度系统(不同鱼有不同稀有度)。
  • 金钱系统(钓鱼获得收益、购买工具)。
  • 概率系统(不同鱼命中率不同)。
  • 钓鱼工具系统(杆、饵等影响概率)。
  • 聊天文字交互。
  • 用户信息记录与签到功能。

在搭好 AstrBot CLI 测试平台之后,他只需要:

  • 给模型说明 CLI 如何使用、有哪些指令。
  • 描述清楚插件需求和预期交互流程。

剩下的时间模型在 CLI 环境里自主循环:写代码 → 运行 E2E 测试 → 看日志 → 修 Bug。AI 自主工作约 35 分钟,就通过了所有测试用例和端到端测试,产出了可直接使用的插件。

相比之下,之前那种“写几分钟代码就得让人类上线帮忙测试”的模式,不论体验还是效率,都要差一大截。


三、从“能跑”到“好维护”:用“非退化性”驱动 AI 重构

当你有了 TDD + E2E 测试构成的“安全网”,功能基本能稳定跑起来了。 但这并不意味着代码已经达到了“可读、可维护、可拓展”的水准。

AI 生成的首版代码往往存在这些问题:

  • 命名不一致、抽象层次混乱。
  • 模块边界模糊,“一把梭哈”式的大函数。
  • 缺乏错误处理和防御式编程。
  • 与项目整体架构风格不匹配。

如果此时你亲自下场重构,就又回到“人类背锅”的老路。更合理的方式是:继续让 AI 重构,但要有一套保证质量“只会上不下”的机制

这就引出了一个有趣的概念:非退化性

3.1 什么是“非退化性”?

“非退化性”下的定义是:

当模型带着一个具体问题审查代码时,不会把正常代码误判为问题,同时能准确识别出真正有问题的代码。

这个能力听上去并不花哨,却极其关键。稍微形式化一点,可以从三个方面来理解:

  1. 单次审查有效性

    • 对于给定问题(例如“违反单一职责原则”),模型在通读代码后,总能找到一些确实存在的改进点。
  2. 多次迭代收敛

    • 你围绕同一个问题反复让模型审查和修改,随着次数增加,相关问题的数量会逐步减少,而非反复打转甚至恶化。
  3. 跨问题维度的整体演进

    • 如果你设计了一组覆盖不同维度的问题清单(如 SOLID、DDD 分层、防御式编程、日志规范等),并按清单逐项优化,那么在“每个问题的修复不引入新问题”的前提下,经过足够多轮迭代,代码会在所有这些维度上逐渐达到“合格线”。

当然,现实中的模型并不完美,“不会引入任何新问题”这个条件难以完全满足。 但我们可以通过前面构建的测试安全网来约束它:

  • 单元测试+E2E 测试覆盖了关键逻辑。
  • 每次重构后必须通过所有测试,否则改动作废或需要重新修复。

在这个前提下,即便模型某些层面理解并不充分,它也很难把整体质量越改越差,这便是“非退化性”在工程实践里的意义。

3.2 实际重构方法:问题清单 + 测试安全网

在操作层面,可以把重构阶段设计为三个步骤:

  1. 构建测试安全网

    • 确保前期的单元测试和 E2E 测试已经覆盖了主要业务路径。
    • 尤其是边界条件、异常分支、关键数据流等,都要有对应测试。否则重构阶段模型容易“改对功能、改坏细节”。
  2. 预设问题清单

    • CLAUDE.md 或类似项目说明文件中,列出你关心的重构维度,例如:
      • 是否满足 SOLID 原则(单一职责、接口隔离、依赖反转等)。
      • 是否遵守项目约定的 DDD 分层(领域层、应用层、基础设施层)。
      • 是否具备足够的防御式编程(输入校验、错误处理、日志、超时等)。
      • 是否统一了日志格式、错误码体系。
    • 这些条目越具体、越可检查,模型的“非退化性”越容易发挥作用。
  3. 迭代优化

    • 每次让模型聚焦一个或少数几个问题,例如:“请你仅围绕防御式编程和错误处理,对以下代码进行审查与重构”。
    • 模型给出修改建议和改动后的代码。
    • 运行测试套件,如果有用例失败,要求模型在不放宽测试的前提下修复问题。
    • 不断重复,直到某个问题维度基本“无处可改”。

这套流程有两个显著好处:

  • 让模型聚焦:带着一个具体问题看代码,模型更容易深入理解上下文,而不是泛泛而谈。
  • 易于控制节奏:你可以按需挑选维度和迭代次数,而不是一次性让模型“大重构”,避免“翻车”成本过高。

四、模型不一定要最强,但工作流必须足够好

在这样的工作流下,一个常见问题是:还需要追逐最强模型吗?

4.1 中等模型 + 好闭环,也能写出好项目

从前面的分析可以看出,只要模型具备以下基本能力:

  • 能根据自然语言需求“会做题”,理解业务逻辑。
  • 能写出基础可运行的代码。
  • 能读懂测试报错和日志,并围绕这些信息修改代码。

在强反馈闭环和测试安全网的前提下,通过“非退化性”反复迭代,理论上它也可以写出足够好的项目。作者甚至大胆推演:一个“中等的国产模型”,只要满足上述能力,就可以通过这种方式产生相当质量的代码。

这对团队的启发是:

  • 不一定所有项目都要用最贵、最强的闭源模型。
  • 对于结构较清晰、业务复杂度有限的项目,工作流设计可以抵消一部分模型能力的短板

4.2 那我们还需要更强的模型干什么?

那更强的模型还有什么价值?

  • 更强的模型可以更高效地“做题”,即在需求复杂、约束众多的情况下更快给出合理解法。
  • 更擅长对非常复杂的问题进行建模,比如跨系统的数据一致性、复杂状态机等。
  • 拥有更强的长上下文理解能力,能对大型项目、多模块日志进行整体分析。
  • 在遇到棘手 Bug 时,较小模型可能会陷入反复无效的思考,而强模型更有机会“跳出坑”。

换句话说,工作流设计是锚点,模型能力是上限

  • 没有闭环的强模型,很容易变成“更快写出更多 Bug 的工具”。
  • 有良好闭环的中等模型,可以稳扎稳打完成不少项目。
  • 强模型在良好闭环中,才能真正把潜力释放到“解决高复杂度问题”上。

五、如果你想落地:一套可执行的改造路径

如果你希望在自己的团队或个人项目里实践这套思路,可以考虑按以下步骤落地。

5.1 第一步:梳理项目的“输入-处理-输出”链路

先不急着写任何 Prompt 和自动化脚本,从系统视角画清楚这个项目的主流程:

  • 用户或外部系统发来什么样的输入?
  • 系统内部大致如何处理?涉及哪些模块、数据流?
  • 系统会以什么形式输出结果?给用户界面、给第三方 API、写库、发消息?

目标是用“文本 + 命令”的方式模拟出这条链路。例如:

  • 对于 Web API 项目,你可以用 HTTP 客户端脚本(curl、HTTPie、pytest + requests)。
  • 对于聊天机器人,可以用 CLI 模拟器包裹框架事件。
  • 对于数据处理管道,可以用命令行脚本触发 ETL 流程并检查结果文件或数据库状态。

这一步不是 AI 做的,而是开发者发挥“系统设计能力”的地方。

5.2 第二步:搭建 CLI 端到端测试平台

参考 AstrBot CLI 的思路,在你的项目中搭一个“AI 可操作”的端到端测试接口:

  • 所有关键业务流程都可以通过命令行触发:
    • 例如 app-cli simulate-user-flow --scenario signup_and_purchase
  • 测试结果以结构化但可读的文本形式输出,便于模型理解:
    • 包括请求、响应、关键状态变化以及异常信息。
  • 在设计时尽量避免复杂人机交互,比如:
    • 不要出现“按任意键继续”之类的步骤。
    • 尽量使用幂等或可重置的测试数据。

你可以把这个 CLI 平台看成是给 AI 准备的一套“虚拟实验室”:它在里面折腾多少次,真实生产环境都不会被污染。

5.3 第三步:强化测试体系(单测 + E2E)

在 CLI 平台搭起来之后,为 AI 准备两层“安全网”:

  • 第一层:单元测试
    • 覆盖核心算法、关键业务逻辑、边界条件。
  • 第二层:端到端测试
    • 模拟从用户输入到系统输出的完整路径,验证业务故事是否成立。

注意:这两层测试不是为 CI 而写,而是明确为“AI 的自助开发”而写的。你可以在测试描述中多写一点自然语言注释,帮助模型理解每个用例在业务上的意义。

5.4 第四步:规范化 AI 开发流程与提示词

在基础设施完成之后,再回到 AI 层面,设计好你的“工作协议”:

  • 写一份项目级说明(类似 CLAUDE.md),包含:
    • 项目结构说明。
    • 测试命令使用方法。
    • CLI 平台指令说明。
    • TDD 工作流要求(Red-Green-Refactor)。
  • 为不同任务设计对应提示词模板:
    • 新功能开发模板。
    • Bug 排查与修复模板。
    • 重构与风格统一模板。
  • 把“必须运行测试”“不得绕过测试”写入约束,并让模型每次生成代码时显式列出其运行过的测试命令及结果。

提示词不需要写得“高大上”,关键是让 AI 按正确的流程工作。你真正投入精力的,应该是流程和工具本身,而不是反复雕刻单条 Prompt。

5.5 第五步:迭代优化工作流,从“红温经验”中学习

在一次次 Vibe Coding“红温”的经历中,不应该继续在低效流程上浪费时间,而应把精力投入到分析经验、重构工作流上。

这也是这套方法背后的隐含主线:

  • 不要把大模型当成“更快的手”,而要把它当作“可以被训练的代理”。
  • 人类最有价值的工作,是站在更高层去设计规则、环境和反馈机制。
  • 每次踩坑后,都问自己:这个坑是不是可以通过一个新测试、一个新 CLI 命令或一个更清晰的流程规范避免?

长期来看,这种“系统思维 + 工具化 + 反馈闭环”的方式,会比盲目的 Vibe Coding 更可持续,也更适合团队协作和多人维护。


结语

AI 不是更快的键盘,而是可驯化的编程系统

通过引入反馈闭环、构建 TDD+E2E 的测试安全网、让 AI 在 CLI 实验室里自我迭代,并用“非退化性”的视角规划重构过程,我们可以把 AI 从“写代码的工具”升级为“可以被调度的开发代理”。

在这条路上,模型“多强”固然重要,但更重要的是你为它搭建了怎样的世界:是否有清晰的任务、严密的测试、安全的试错空间以及可回溯的迭代轨迹。

如果你已经对深夜红温的 Vibe Coding 心生倦意,不妨从今天开始,先为你的项目搭一个小小的 CLI 实验室,写上几条 E2E 测试,然后让 AI 在里面先“玩一会儿”。 你会发现,当反馈闭环真正打通之后,自己可以离开屏幕更久,而项目却在稳步向前

在这里插入图片描述

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐