从“写脚本”到 AI 工程化:关于开发工作流、自动化测试与 Agent 能力开放的思考
从“写脚本”到 AI 工程化:关于开发工作流、自动化测试与 Agent 能力开放的思考
本文由 AI 辅助写作
目录
一、问题的起点:从一个“小需求”看到两层工程问题
最近做的工作,大多不是传统意义上的“大项目”。
例如给内部系统补充 CLI 能力、把已有接口封装成命令行工具、开放部分业务能力供 Agent 调用,以及补充测试脚本和本地开发环境。
这些需求单独看都不复杂,甚至有些工作量并不大。但一个现象很值得思考:明明需求本身很小,却仍然需要投入不少开发、联调和验证时间。
这说明问题不在功能本身,而在交付过程。
如果一个需求反复需要人工理解代码、梳理链路、配置环境、验证结果,那么即使功能简单,也会持续消耗时间。而只要一个动作被频繁重复,它就具备被工程化优化的价值。
因此,真正值得关注的不是需求大小,而是:
为什么这些需求无法被更快、更稳定地完成?
继续往下分析,会发现这里其实包含两个层次不同、但彼此关联的问题。
第一层:如何建立可复用的 AI 开发工作流?
这是一个偏工程效率的问题。
当 AI 已经能够参与编码之后,真正影响效率的往往不再是“代码写得快不快”,而是:
- 如何快速理解需求;
- 如何定位代码入口;
- 如何收集上下文;
- 如何分析调用链路;
- 如何验证修改结果;
- 如何沉淀经验供后续复用。
如果这些步骤每次都从零开始,那么 AI 的能力就只能停留在“辅助写代码”。
因此,第一个问题是:
如何沉淀一套 AI 开发工作流,让同类需求能够被快速复用,而不是每次重新探索?
本质上,这是在解决“AI 如何参与软件开发”的问题。
第二层:如何把能力可靠地开放给 Agent?
相比开发工作流,这个问题更加贴近最终交付。
当一个能力需要被 Agent 调用时,仅仅实现接口并不够,还需要考虑:
- 工具如何描述;
- 参数如何约束;
- 返回结构是否稳定;
- 错误是否可恢复;
- 测试是否覆盖关键链路;
- Agent 是否真的能够正确使用。
因此,第二个问题是:
当能力需要开放给 Agent 调用时,应该如何设计工具、测试和验证机制,保证能力真正可用?
本质上,这是在解决“如何为 AI 提供可靠能力”的问题。
两个问题之间是什么关系?
很多时候,人们会把这两个问题分开讨论。
一个属于开发效率,一个属于能力开放;一个偏内部工程,一个偏外部交付。
但在实际工作中,两者往往是一体两面。
开发工作流决定了能力开放的成本。
如果没有标准化的需求分析、代码修改、测试验证和经验沉淀流程,那么每新增一个 Agent 工具,都需要重新理解系统、重新验证链路、重新处理边界情况,成本会随着能力数量增长而不断上升。
反过来,Agent 能力开放又会倒逼工作流成熟。
因为一旦能力需要被 Agent 使用,就必须具备更清晰的描述、更稳定的接口、更完善的测试以及更可靠的验证机制。这些要求最终都会反馈到开发流程本身。
换句话说:
- AI 开发工作流解决的是“如何更高效地生产能力”;
- Agent 能力开放解决的是“如何更可靠地交付能力”。
前者是生产体系,后者是交付体系。
而自动化测试、本地验证环境、标准化工具设计等工程实践,恰好连接了这两个体系。
因此,最近这些看似零散的小需求,最终都指向同一个主题:
在 AI 时代,如何通过工程化手段缩短从需求到交付的路径,并保证结果可靠。
这篇文章也将围绕这两个层次的问题展开:先讨论 AI 开发工作流如何沉淀,再讨论 Agent 能力开放为什么需要更严格的工程体系,以及两者如何共同构成一个完整闭环。
二、第一层问题:AI 写代码已经不稀奇,真正困难的是“可控地交付”
今天再说“AI 能写代码”,其实已经不是什么新鲜事了。
很多简单脚本、接口调用、数据处理、页面小改动,AI 都可以在很短时间内生成一个看似可用的版本。甚至很多过去需要一个下午才能查文档、对参数、调语法的小工具,现在 AI 可能几十秒就能写出雏形。
这件事当然非常震撼。
如果经历过早年那种“手搓代码”的阶段,会更有感触:以前写一个小爬虫、调一个 API、做一个歌单筛选工具,需要不断搜索文档、理解参数、解决语法报错。那种成就感来自于一行一行把东西写出来。
但现在,单纯“写出代码”这件事,已经越来越不稀缺了。
真正稀缺的东西变成了:
- 需求是否被正确理解;
- 代码是否改在了正确的位置;
- 调用链路是否完整;
- 相关边界是否覆盖;
- 旧功能是否被破坏;
- 权限、异常、错误处理是否可靠;
- 测试是否能证明功能真的可用;
- 同类需求下一次是否可以更快完成。
换句话说,AI 时代的核心问题不是“能不能生成代码”,而是:
能不能让 AI 在明确上下文、明确流程、明确验证方式的情况下,稳定地产出可交付代码。
如果没有这套体系,AI 写得再快,也只是“快速生成不确定性”。
它可能帮你节省了编码时间,却把压力转移到了测试、联调、排查和人工 review 上。尤其在真实业务系统里,问题往往不是单文件、单函数、单接口那么简单,而是涉及多个模块、多条链路、多种环境和历史包袱。
AI 可以很快给出一个答案,但它未必知道这个答案在当前工程环境里是否真的成立。
所以越来越觉得,AI 开发最重要的不是 prompt 本身,而是围绕 AI 建立一套完整的工程闭环:
需求理解 → 上下文收集 → 链路分析 → 方案生成 → 代码修改 → 本地验证 → 自动化测试 → 人工复核 → 经验沉淀。
只有这个闭环成立,AI 才不是一个单纯的代码生成器,而是一个可以参与工程交付的开发助手。
三、第一层问题的延伸:为什么需要沉淀 AI 开发工作流?
最开始其实低估了“工作流沉淀”的价值。
刚接触不同需求时,很容易觉得每个需求都长得不一样:这个是接口优化,那个是 Bug 修复;这个是 CLI 接入,那个是 Agent 调用;这个要看 Go 项目,那个要看后端服务;这个涉及鉴权,那个涉及参数转换。
于是每次做需求时,都会重新开始分析:
先看哪里?
入口在哪?
调用链路是什么?
哪个文件负责命令定义?
哪个文件负责接口调用?
鉴权在哪里处理?
测试应该怎么跑?
改完之后怎么证明没问题?
如果每次都重新摸索,那 AI 参与开发的收益其实会大打折扣。
因为 AI 的一次性生成能力虽然很强,但它对项目上下文并没有天然记忆。每次新对话、新需求,都要重新把上下文喂给它。如果上下文不完整,它就容易猜;如果没有标准流程,它就容易漏;如果没有测试闭环,它就容易自信地错。
后来意识到,很多需求虽然表面不同,但底层其实有共性。
比如“新增一个 CLI 命令”这类需求,流程就可以沉淀:
- 先查找已有相似命令;
- 确认命令结构和参数风格;
- 找到对应业务接口;
- 梳理请求参数和返回结构;
- 明确权限和鉴权逻辑;
- 增加命令入口;
- 增加接口调用封装;
- 处理错误信息和异常分支;
- 编写本地测试 case;
- 更新 README 或使用说明;
- 执行本地端到端验证;
- 最后进行人工 review。
再比如“修改已有接口能力”这类需求,也可以沉淀:
- 找到旧实现;
- 梳理调用方;
- 判断字段或行为变更是否兼容;
- 明确影响范围;
- 修改实现;
- 补充回归测试;
- 验证已有命令是否仍然可用;
- 检查 Agent 调用说明是否需要同步更新。
再比如“Bug 修复”类需求,也有比较固定的流程:
- 复现问题;
- 收集日志;
- 确认输入和输出;
- 对比正常 case;
- 缩小问题链路;
- 定位根因;
- 修复问题;
- 补充回归测试;
- 记录问题模式,防止同类问题再次出现。
这些流程看起来朴素,但对 AI 非常重要。
因为 AI 不怕执行步骤,怕的是步骤不明确;不怕写代码,怕的是不知道该看哪些代码;不怕跑测试,怕的是没有可跑的测试。
所以,所谓 AI 开发工作流,本质上是把过去依赖个人经验的隐性知识,沉淀成 AI 可以理解和执行的显性流程。
它不只是“提示词模板”,而是一种工程 SOP。
四、第一层问题的实践:从聊天记录中提炼可复用经验
最近还有一个很强的感受:过去和 AI 的大量对话,不应该只被当成一次性消耗。
很多时候,在 AI 对话里已经完成了大量有价值的工作:
- 解释需求背景;
- 粘贴关键代码;
- 让 AI 分析调用链;
- 讨论不同方案;
- 让 AI 帮忙定位 bug;
- 根据报错继续修正;
- 设计测试 case;
- 总结修改点;
- 生成文档或 review checklist。
这些对话如果不整理,就会沉没在聊天历史里。下一次遇到类似需求时,还是会重新问、重新解释、重新走一遍弯路。
但如果把这些对话抽象出来,它们就是非常宝贵的 workflow 原材料。
比如可以从历史聊天记录里提炼几个问题:
- 这个需求属于哪一类?
- 当时 AI 是从哪里开始分析的?
- 它第一次分析时漏掉了什么?
- 后来补充了哪些上下文?
- 哪些代码位置是关键入口?
- 哪些测试步骤最后证明功能可用?
- 如果下次遇到同类需求,应该提前告诉 AI 什么?
- 哪些检查项可以写进 checklist?
这样做之后,一段聊天记录就不再只是“向 AI 询问如何改代码”的历史,而变成了“如何处理同类需求”的经验样本。
后续可以把需求分成几类,每类沉淀一套标准 workflow:
- 新增 CLI / 新增工具类需求;
- Skill / Agent 能力开放类需求;
- 接口改造类需求;
- Bug 定位类需求;
- 性能优化类需求;
- 测试脚手架和自动化测试类需求。
每一类需求都应该有自己的处理流程、代码入口、常见风险点、测试方式和复核清单。
这样下一次再做类似需求时,就不需要重新从零开始。
第一次做一个需求,也许加上开发、测试和反复修改要两个小时;第二次如果复用 workflow,可能只需要半小时;再往后,当流程、测试和上下文都沉淀下来,可能 10 到 15 分钟就能完成一个相似能力的接入。
当然这个工作也可以交给 Agent 去做。
五、连接两层问题的关键:AI 开发的核心不是“更快写完”,而是“更快验证”
如果说前面讨论的是如何建立开发工作流,那么接下来就会自然进入第二层问题。
因为无论工作流设计得多完善,最终都要回答一个问题:
如何证明交付出来的能力真的可用?
而答案往往不在编码阶段,而在验证阶段。
在真实工程里,开发和测试经常不是均匀分布的。
很多功能写起来并不难,真正耗时的是验证:
- 环境起不来;
- 本地无法调试;
- 依赖线上服务;
- Token 或权限配置复杂;
- 接口文档分散;
- 调用链路不清楚;
- 日志不完整;
- 失败后不知道是参数问题、环境问题还是代码问题。
最近在做某个 CLI 项目时,就遇到过类似问题。
这个项目本身比较臃肿,文档散落在多个地方,还有额外的网关层。因为整个服务无法方便地在本地调试,很多时候只能依赖线上环境联调。
这会带来几个问题。
第一,开发反馈链路太长。
一个小改动如果必须部署或依赖线上环境才能验证,那么每一次试错都会变得很慢。AI 生成代码越快,反而越暴露验证慢的问题。
第二,自动化测试很难做。
如果没有本地可控环境,就很难让 AI 或开发者稳定地跑测试 case。很多验证只能靠人工手动执行,结果就是每次都重复做低效劳动。
第三,新人接入成本高。
如果一个项目必须依赖很多口口相传的环境配置和调试经验,那么新人即使能看懂代码,也很难快速跑通流程。
第四,能力开放会受阻。
如果后续要让 CLI 支持更多业务能力,或者让 Agent 调用更多工具,每新增一个接口都要线上联调,那么规模越大,成本越高。
所以即使很多情况不允许,也应该尽量想办法搭建一个测试脚手架,允许 AI 进行自动化测试,或者参与更多的测试流程。在 AI 开发时代,测试脚手架不是辅助设施,而是核心基础设施。
六、第二层问题的基础:为什么不能只依赖单元测试?
当工具要开放给 Agent 调用时,端到端测试更重要。因为 Agent 不像人一样可以临场猜测、补救、查看内部实现。它依赖工具描述、参数约束和返回结果来行动。一个接口可以调通,不意味着 Agent 可以依照上下文、用户输入正确完成工作。如果工具本身不稳定,Agent 的行为就会放大这种不稳定。
一个参数说明不清楚,可能导致 Agent 反复调用失败;一个错误信息不友好,可能导致它无法自我修复;一个权限边界不明确,甚至可能带来误操作风险。
因此,Agent 能力开放不能只关注“有没有接口”,更要关注“这个工具是否可描述、可调用、可验证、可恢复”。
这也是认为 AI 自动化测试必须前置的原因。
如果大量需求都依赖人工自测,那么开发效率一定会被测试压力拖住。尤其在测试资源有限、上线节奏紧张的情况下,开发侧自测质量会直接影响整体交付效率。
尤其是 CLI 和 Agent 工具这类需求,单元测试只能证明局部逻辑没问题,但不能证明整条链路真的能跑通。
更关键的验证应该是:
- 命令能否正确执行;
- 参数能否正确传递;
- 接口能否正常调用;
- 返回结果是否稳定;
- 错误信息是否可理解;
- 改动是否破坏已有行为。
所以,对这类工作来说,本地测试脚手架和端到端验证非常重要。
它不一定复杂,但必须能让开发者在本地快速确认:这个能力是真的可用,而不是代码看起来写完了。
一个很实用的做法是,让 Agent 调用一个“一无所知”的 Sub Agent 来尝试完成需求。
这个 Sub Agent 不预先提供项目背景、实现细节或额外提示,只给它当前设计好的工具、提示词和文档,让它像一个第一次接触的 Agent 一样去完成任务。
然后观察:
- 它是否能理解需求;
- 它是否能找到正确的工具;
- 它在哪一步卡住;
- 它是否误解了参数或流程;
- 它最终是否成功完成目标。
这些反馈往往比单纯阅读提示词更有价值。
因为很多问题并不是设计者自己能发现的,而是在真正执行过程中暴露出来的。
主 Agent 可以根据 Sub Agent 的执行结果自动发现问题,并进一步自动调整提示词、工具描述、系统设计以及工作流,形成持续优化闭环,从而显著提高迭代效率。
从这个角度看,测试的不只是代码本身,也是在测试 Agent 能否真正理解并使用整个系统。
AI 写代码越快,越需要测试来兜底。否则效率提升很容易变成风险放大。
七、第二层问题的延伸:工具要适合 Agent 使用
当通过测试发现 Agent 经常误用工具、理解错误参数或者无法完成任务时,问题往往已经不只是“接口能不能调通”了。
人用工具时,可以看文档、猜参数、理解上下文,也可以在出错后自己补救。
但 Agent 更依赖明确的工具描述和稳定的输入输出。
因此,一个给 Agent 使用的工具,具备几个特点:
- 工具名清楚,能看出是读操作还是写操作;
- 参数结构明确,尽量减少模糊自由文本;
- 返回结果稳定,方便继续处理;
- 错误信息可理解,最好能提示下一步怎么修正;
- 对写操作有更谨慎的限制和确认机制。
尤其是写操作,不能和读操作混在一起看待。
读操作失败了,通常只是查不到信息;写操作失败或误执行,可能会修改数据、创建资源、触发流程,风险明显更高。
所以加入类似“先读后写”的机制:
在执行某些写命令之前,要求 Agent 先读取命令说明,理解参数、影响范围和风险,再执行真正的写操作。
这不是为了做一个绝对安全的系统,而是为了让 Agent 在行动前多一个明确的理解步骤。
对更敏感的操作,还可以配合 dry-run、preview、confirm 参数、人工确认和操作日志。
工具开放给 Agent,不是简单地把接口包一层,而是要让工具变得可描述、可验证、可恢复、可控制。
八、从个人经验到团队资产:把 AGENTS.md 和 Skill 放进 Git
最后还有一个很实际的问题:这些经验不能只留在个人聊天记录和脑子里。
如果某个项目里,AI 应该怎么读代码、怎么跑测试、怎么调用 CLI、哪些命令有风险、哪些流程需要先确认,这些信息只靠口头传递,就很难复用。
更好的方式是把它们沉淀成项目资产。
比如在仓库里维护:
- AGENTS.md
- Skill 文档
- CLI 使用说明
- 测试命令说明
- 常见问题和注意事项
这些内容应该和代码一样放进 Git 里维护。
这样,新人接手项目时,一般也会使用 AI 参与开发,这时候 AI 能快速接手,根据这些文件获取更稳定的上下文。极大减少探索试错的过程,加快开发效率。
在实际团队里,经常会遇到一个情况:有些项目会把这类 Skill、Agent 配置甚至辅助文档放进 .gitignore,大型项目一般会更加求稳一些,也是可以理解的。
不过,在一般项目中,AGENTS.md 和 Skill 不应该只是个人临时写的提示词,而应该成为项目的一部分。
九、总结
回到最开始的问题。
这些工作表面上只是补 CLI、接接口、写测试、搭本地环境。
但它们背后其实是在解决一个更大的问题:
AI 参与开发之后,团队应该如何把开发流程、工具调用、测试验证和经验沉淀工程化。
AI 能写代码只是起点。
真正重要的是:
- 有清晰的 workflow,让 AI 知道怎么做事;
- 有本地测试和端到端验证,证明能力真的可用;
- 有适合 Agent 调用的工具设计,减少误用和不可控行为;
- 有 AGENTS.md 和 Skill,并放进 Git 里长期维护。
这样,AI 才不只是一次性帮忙写代码,而是能逐渐进入团队的工程体系。
从写脚本,到沉淀工具;
从一次对话,到项目文档;
从个人经验,到团队资产。
这可能就是 AI 工程化最现实、也最值得做的起点。