☰
Agentic Harness Workflow:让AI写代码从碰运气到工程化
2026/10/17 3:57:31 网站建设 项目流程

1. 为什么“让AI写代码”这件事需要一套工程化框架

过去一年,我身边不少团队都在用AI辅助写代码。刚开始大家的反应都差不多:哇,效率飞起。但用了一段时间之后,抱怨开始出现了——生成的东西时好时坏,同一个需求问两遍结果完全不一样,代码风格飘忽不定,更麻烦的是,当项目稍微复杂一点,AI就开始“胡编”接口、遗漏边界条件,甚至把之前能跑的代码改崩。

这个现象其实不难理解。大多数人用AI写代码的方式,本质上就是“对话式碰运气”:打开一个聊天窗口,把需求描述一遍,拿到代码,复制粘贴,跑不通就再问一遍。整个过程没有任何结构化的约束,没有验证环节,没有回滚机制,也没有可复用的流程沉淀。这就像你招了一个能力很强但完全没有工程素养的实习生,他每次都能给你写点东西出来,但你永远不知道他这次写的是不是靠谱的。

Agentic Harness Workflow 框架要解决的就是这个问题。它的核心思路是:不再把AI当成一个“问答机器人”,而是把它当成一个需要被“驾驭”的执行单元,用一套工程化的流程把它的能力框住、引导住、验证住。Harness这个词本身就有“马具、约束装置”的意思,非常形象——AI的能力像一匹烈马,跑得快但方向不定,你需要一套缰绳和鞍具让它按照你想要的路线跑。

这套框架适合谁?我认为有三类人特别需要:一是已经在日常工作中重度使用AI编码工具,但苦于输出质量不稳定的开发者;二是团队里负责制定研发流程的技术负责人,需要一套可复制、可推广的AI协作规范;三是对AI编码感兴趣但一直觉得“不太敢用在正经项目上”的工程师,这套框架能帮你建立信心。

接下来我会从设计思路、核心环节拆解、完整实操流程、常见问题排查几个维度,把这套框架讲透。不是泛泛而谈的概念介绍,而是我自己实际跑过多轮之后沉淀下来的具体做法。

2. 框架整体设计与核心思路拆解

2.1 从“对话式编码”到“流水线式编码”的范式转换

传统用AI写代码的方式,我把它叫做“对话式编码”。你的操作路径大概是这样的:想清楚要做什么,打开对话框,打字描述,等结果,看结果,不满意就重新描述,满意就复制走。这个过程的问题在于,所有的质量控制都发生在“人看结果”这一步,而且完全依赖人的即时判断。

Agentic Harness Workflow 做的事情,是把这条路径改造成一条有多个检查点的流水线。每个检查点都有明确的输入、输出和验收标准。AI不再是“一次性给你一个答案”,而是在每个环节里扮演特定角色,完成特定任务,然后交给下一个环节。

我举个具体的对比。假设你要实现一个“用户注册接口”:

对话式编码的做法是:直接跟AI说“帮我写一个用户注册接口”,AI给你一段代码,你看看觉得差不多就用了。至于参数校验全不全、异常处理到不到位、有没有考虑并发场景,全靠你自己逐行审查。

Harness Workflow的做法是:先让AI输出接口的规格说明(输入输出、边界条件、错误码定义),人工确认规格没问题;然后让AI基于规格生成测试用例,人工审查测试用例是否覆盖了关键场景;再让AI基于规格和测试用例生成实现代码;最后自动运行测试,验证实现是否通过。每一步都有明确的交付物和验收标准。

这个转换带来的最大好处是可追溯和可复现。当最终代码出了问题,你可以沿着流水线往回查:是规格定义就有漏洞?还是测试用例没覆盖到?还是实现阶段AI理解偏了?而不是像对话式编码那样,只能重新问一遍,然后祈祷这次能对。

2.2 为什么选择“多角色分阶段”而不是“单角色端到端”

有人可能会问:为什么不直接让AI端到端完成整个任务?为什么要拆成多个阶段、多个角色?

这个问题我一开始也纠结过。端到端看起来更省事,一次对话就能出结果。但实际跑下来,端到端的问题非常明显:

第一,上下文窗口的约束。当一个任务涉及多个文件、多种关注点时,AI在单个对话里很容易“顾此失彼”。你让它同时考虑接口设计、错误处理、性能优化、代码风格,它往往会在某个维度上偷懒。

第二,错误传播。端到端模式下,如果AI在早期阶段理解错了需求,后面所有的输出都是错的,而且你很难定位到底哪一步出了问题。分阶段之后,每个阶段都有检查点,错误在早期就能被发现和纠正。

第三,角色混淆。让同一个AI实例既当“架构师”又当“实现者”又当“测试者”,它在不同角色之间的切换往往不够彻底。分阶段之后,每个阶段给AI明确的角色设定和关注点,输出质量会明显提升。

我自己的经验是:任务越复杂,分阶段的价值越大。简单的单文件函数可能端到端就够了,但一旦涉及多模块协作、需要严格的质量控制,分阶段就是必须的。

2.3 框架的四个核心阶段与流转逻辑

经过多轮迭代,我把这套框架的核心流程收敛为四个阶段:

阶段一:意图澄清与规格定义。这个阶段的目标是把模糊的需求转化为明确的、可验证的规格说明。AI在这里扮演的是“需求分析师”的角色,它需要主动提问、识别歧义、输出结构化的规格文档。人工在这个阶段需要确认规格是否符合预期。

阶段二:测试先行与验收标准。基于规格说明,让AI生成测试用例。这个阶段的关键是“测试先行”——在写实现之前先把验收标准定下来。AI扮演“测试工程师”角色,输出覆盖正常路径、边界条件、异常场景的测试用例。人工审查测试用例是否充分。

阶段三:实现生成与自验证。基于规格和测试用例,让AI生成实现代码。AI扮演“开发者”角色,但有一个关键约束:它必须在生成代码后自己运行测试,并根据测试结果迭代修正。这个阶段是自动化的核心环节。

阶段四:审查归档与知识沉淀。实现通过测试后,进入审查阶段。AI扮演“代码审查者”角色,检查代码风格、潜在问题、可优化点。人工做最终确认后,将规格、测试、实现、审查意见一起归档,形成可复用的知识资产。

这四个阶段之间不是简单的线性关系。实际使用中,阶段二发现问题可能需要回到阶段一修正规格,阶段三的测试失败可能需要回到阶段二补充测试用例。框架的价值在于,它让这些回退变得有迹可循,而不是一团乱麻。

3. 核心环节的详细拆解与实操要点

3.1 意图澄清阶段:怎么让AI问出“好问题”

很多人用AI的时候,习惯一次性把需求描述得很详细,觉得这样AI就能理解得更准确。但实际效果往往相反——你描述得越详细,AI越容易在你没提到的细节上“自由发挥”。

Harness Workflow在意图澄清阶段的做法是反过来的:先给一个粗略的需求描述,然后让AI主动提问。具体操作是这样的:

你给AI的初始输入可以很简单,比如“我需要一个用户注册功能”。然后你给AI的指令是:“你现在的角色是需求分析师。请针对这个需求,列出所有你需要澄清的问题,按重要性排序。”

AI通常会问出这些问题:注册方式是什么(邮箱、手机号、第三方)?密码强度要求是什么?是否需要邮箱验证?并发注册怎么处理?错误码怎么定义?等等。

这个做法的好处是,AI问出来的问题往往比你自己想到的更全面。因为AI见过大量的类似场景,它知道哪些地方容易出问题。你只需要逐条回答这些问题,规格就自然清晰了。

注意:这个阶段不要急着让AI写代码。我见过太多人跳过澄清阶段直接让AI生成实现,结果就是反复修改、反复重来,总耗时反而更长。

回答完AI的问题后,让它输出一份结构化的规格文档。这份文档至少应该包含:功能描述、输入输出定义、边界条件、错误处理、非功能性要求(性能、安全等)。这份文档就是后续所有阶段的“合同”。

3.2 测试先行阶段:把验收标准“焊死”在流程里

测试先行是这套框架里我最坚持的一个环节。原因很简单:如果你不先定义“什么叫做完了”,AI就会按照它自己的理解来交付。

具体操作:把上一阶段的规格文档喂给AI,指令是:“你现在的角色是测试工程师。请基于这份规格,生成完整的测试用例。要求覆盖:正常路径、边界条件、异常场景、并发场景。”

AI输出的测试用例通常是表格形式或者代码形式。我建议要求它输出可执行的测试代码,而不是纯文字描述。因为可执行的测试代码可以直接在后续阶段用来验证实现。

这里有个关键技巧:让AI为每个测试用例标注它对应规格中的哪一条。这样做的好处是,当测试失败时,你能快速定位是哪个规格点没有满足。同时,如果某个规格点没有任何测试用例覆盖,你也能一眼看出来。

实操心得:测试用例生成后,不要直接进入下一阶段。花几分钟人工审查一下,看看有没有明显的遗漏。AI生成的测试用例往往在正常路径上覆盖得很好,但在异常场景和并发场景上容易偷懒。你可以追问一句:“有没有哪些异常场景是你觉得重要但我可能没想到的?”通常能挖出一些有价值的补充。

3.3 实现生成阶段:让AI“自己验证自己”

这是整个框架里自动化程度最高的环节。把规格文档和测试用例一起喂给AI,指令是:“你现在的角色是开发者。请基于规格和测试用例生成实现代码。生成后,请自己运行测试,如果测试不通过,请分析原因并修正,直到所有测试通过。”

这个“自己运行测试”的能力,取决于你使用的工具链。如果你用的是支持代码执行的AI环境,它可以自动运行测试并迭代。如果不支持,你可以让AI输出代码后,你手动运行测试,把失败信息贴回去让它修正。

无论哪种方式,核心原则是:AI必须对测试结果负责。不是生成完代码就结束了,而是要确保代码能通过之前定义的验收标准。

这个阶段有几个容易踩的坑:

第一个坑是AI为了让测试通过而“作弊”。比如测试要求某个函数在输入为空时抛出异常,AI可能在函数开头直接写一个if input is None: raise Exception,而没有真正处理空输入的业务逻辑。防范方法是:在测试用例中不仅检查异常是否抛出,还要检查异常的类型和消息是否符合规格。

第二个坑是AI修改了测试用例来适配实现。这种情况在自动化迭代中偶尔会出现。防范方法是:把测试用例文件设为只读,或者在指令中明确要求“不得修改测试用例”。

第三个坑是过度拟合测试用例。AI可能写出只对当前测试用例有效的代码,换一个输入就崩了。防范方法是:在测试用例中增加一些“随机化”或“参数化”的测试,让AI无法针对特定输入硬编码。

3.4 审查归档阶段:把一次性成果变成可复用资产

实现通过测试后,很多人就觉得“完事了”。但Harness Workflow的最后一个阶段恰恰是最容易被忽视、但长期价值最大的环节。

这个阶段要做三件事:

第一,让AI做一次代码审查。指令是:“你现在的角色是代码审查者。请审查这份实现代码,关注:代码风格一致性、潜在的性能问题、安全隐患、可读性、是否有更简洁的写法。”AI给出的审查意见,你可以选择性采纳。

第二,人工做最终确认。AI的审查不能替代人的判断。你需要确认:实现是否符合业务预期?有没有AI没注意到的业务逻辑问题?代码是否融入了现有项目的整体架构?

第三,归档。把规格文档、测试用例、实现代码、审查意见一起保存到一个结构化的目录中。我通常的目录结构是这样的:

project/ features/ user-registration/ spec.md # 规格文档 tests/ # 测试用例 implementation/ # 实现代码 review.md # 审查意见 changelog.md # 变更记录

这个归档的价值在于:当下次有类似需求时,你可以直接把之前的规格和测试用例作为参考喂给AI,大大减少澄清和测试编写的时间。而且当新人加入团队时,这些归档就是最好的学习材料。

4. 完整实操流程:从零跑通一个真实需求

4.1 环境准备与工具链选型

在开始实操之前,先说一下工具链的选择。这套框架不依赖特定的AI工具,但不同的工具会影响体验。我自己的选型逻辑是这样的:

工具类型推荐场景注意事项
支持代码执行的AI环境实现生成阶段自动化迭代确认沙箱环境是否隔离,避免影响本地项目
纯对话式AI工具意图澄清、测试编写、代码审查需要手动复制粘贴测试结果,效率略低但可控
本地代码编辑器+AI插件实现代码的最终集成注意插件是否会上传代码到云端,敏感项目需谨慎
版本控制工具全流程归档每个阶段的产出物都建议提交,方便回溯

我自己的组合是:意图澄清和测试编写用一个对话式工具,实现生成用一个支持代码执行的工具,最终集成在本地编辑器里完成。这样兼顾了效率和可控性。

4.2 第一步:意图澄清的完整对话记录

假设我要实现一个“文章草稿自动保存”功能。我的初始输入是这样的:

我需要一个文章草稿自动保存功能。用户编辑文章时,系统每隔一段时间自动保存草稿,防止意外丢失。

然后我给AI的指令是:“你现在的角色是需求分析师。请针对这个需求,列出所有你需要澄清的问题,按重要性排序。”

AI返回的问题列表(我整理后的版本):

  1. 自动保存的触发条件是什么?定时触发还是内容变更触发?
  2. 保存间隔多长?是否允许用户配置?
  3. 草稿保存在哪里?本地存储还是服务端?
  4. 如果保存时网络不可用,怎么处理?
  5. 草稿保留多久?是否需要版本历史?
  6. 多个设备同时编辑同一篇文章,草稿如何合并?
  7. 用户手动保存和自动保存冲突时,以哪个为准?
  8. 草稿是否需要加密存储?
  9. 保存失败时是否需要通知用户?
  10. 草稿的数据结构是什么?和正式文章的结构是否一致?

我逐条回答这些问题后,让AI输出规格文档。规格文档的核心部分如下:

功能名称:文章草稿自动保存 触发条件:内容变更后延迟30秒触发,或每5分钟定时触发(以先到者为准) 存储位置:服务端,按用户ID+文章ID索引 网络异常处理:保存失败时写入本地队列,网络恢复后重试,最多重试3次 草稿保留:最近10个版本,超过自动清理 冲突处理:以最后写入为准,但保留冲突版本供用户选择 通知策略:保存成功不通知,保存失败在界面显示轻提示 数据结构:与正式文章一致,额外增加draft_id和timestamp字段

这份规格文档就是后续所有工作的基础。

4.3 第二步:测试用例的生成与审查

把规格文档喂给AI,指令是:“你现在的角色是测试工程师。请基于这份规格,生成完整的测试用例。要求覆盖:正常路径、边界条件、异常场景、并发场景。每个测试用例标注对应的规格条目。”

AI生成的测试用例(我截取关键部分):

# 测试用例1:内容变更后30秒触发保存 def test_auto_save_on_content_change(): # 对应规格:触发条件-内容变更后延迟30秒 editor = create_editor() editor.type("hello") time.sleep(31) assert draft_exists(editor.article_id) # 测试用例2:网络异常时写入本地队列 def test_save_failure_queues_locally(): # 对应规格:网络异常处理 with mock_network_down(): editor.type("hello") time.sleep(31) assert local_queue_has_item(editor.article_id) # 测试用例3:草稿版本超过10个时自动清理 def test_draft_version_cleanup(): # 对应规格:草稿保留-最近10个版本 for i in range(15): save_draft(article_id, content=f"version_{i}") assert count_drafts(article_id) == 10 assert get_oldest_draft(article_id).content == "version_5"

我审查后发现两个问题:一是没有测试“多设备同时编辑”的冲突场景,二是没有测试“手动保存和自动保存冲突”的场景。我让AI补充了这两个用例。

4.4 第三步:实现生成与自动验证

把规格文档和测试用例一起喂给AI,指令是:“你现在的角色是开发者。请基于规格和测试用例生成实现代码。生成后,请自己运行测试,如果测试不通过,请分析原因并修正,直到所有测试通过。不得修改测试用例。”

AI生成的实现代码(核心逻辑):

class DraftAutoSaver: def __init__(self, article_id, user_id): self.article_id = article_id self.user_id = user_id self.last_content = None self.last_save_time = time.time() self.local_queue = [] self.save_interval = 30 self.max_interval = 300 def on_content_change(self, content): self.last_content = content now = time.time() if now - self.last_save_time >= self.save_interval: self._try_save() def on_timer(self): now = time.time() if now - self.last_save_time >= self.max_interval: self._try_save() def _try_save(self): try: save_to_server(self.article_id, self.last_content) self.last_save_time = time.time() self._flush_local_queue() except NetworkError: self.local_queue.append({ 'content': self.last_content, 'timestamp': time.time() }) if len(self.local_queue) > 3: self.local_queue.pop(0)

AI运行测试后,报告有两个测试失败:一个是版本清理的测试,因为实现中没有处理版本数量限制;另一个是冲突处理的测试,因为实现中没有保留冲突版本。AI自动修正后,所有测试通过。

4.5 第四步:审查归档与知识沉淀

实现通过测试后,我让AI做代码审查。AI提出的主要意见:

  • _try_save方法职责过重,建议拆分为_save_to_server和_handle_failure
  • 本地队列使用列表存储,频繁pop(0)效率低,建议改用collections.deque
  • 缺少日志记录,建议在关键节点增加日志
  • 时间间隔使用硬编码,建议提取为配置项

我采纳了前两条,后两条根据项目实际情况决定暂不处理。最终归档的目录结构:

features/ draft-auto-save/ spec.md tests/ test_auto_save.py implementation/ draft_auto_saver.py review.md changelog.md

整个流程从开始到归档,大约用了40分钟。如果是对应功能比较熟悉的开发者,可能更快。相比对话式编码反复修改的时间,这个投入是值得的。

5. 常见问题与排查技巧实录

5.1 AI在意图澄清阶段问不出好问题怎么办

这种情况通常发生在需求本身比较模糊,或者AI对领域知识不够熟悉的时候。我的应对策略是:给AI一些“种子问题”作为引导。

比如你可以说:“请从数据流、异常处理、并发场景、用户体验这四个维度来提问。”这样AI就有了一个提问的框架,不容易遗漏重要维度。

另一个技巧是:让AI扮演不同的角色来提问。比如先让它以“后端开发者”的身份提问,再以“前端开发者”的身份提问,再以“测试工程师”的身份提问。不同角色关注的点不一样,综合起来就比较全面了。

5.2 测试用例总是覆盖不全怎么破

AI生成测试用例时,最容易遗漏的是异常场景和并发场景。我的做法是:在指令中明确列出必须覆盖的场景类型,并且要求AI为每个场景类型至少生成两个用例。

另外,我会让AI做一次“反向检查”:把规格文档给它,问“这份规格中哪些条目没有被测试用例覆盖?”AI通常能识别出遗漏点。

还有一个进阶技巧:让AI生成“变异测试”用例。就是故意在实现中引入一些小错误(比如把>=改成>),看测试能不能发现。如果测试发现不了,说明覆盖不够。

5.3 实现阶段AI反复修改但测试始终不通过

这种情况通常有三个原因:

原因一:规格本身有矛盾。比如规格说“保存失败时重试3次”,但测试用例期望“保存失败时立即返回错误”。这种矛盾需要回到规格阶段解决。

原因二:测试用例的断言过于严格。比如测试要求错误消息必须精确匹配某个字符串,但实现中的错误消息措辞略有不同。这种情况下,可以放宽断言,或者让AI统一错误消息的格式。

原因三:AI陷入了“局部最优”。它一直在微调某个函数,但没有意识到问题出在架构层面。这时候需要人工介入,给AI一个更高层次的指导,比如“请重新设计这个模块的接口,把保存逻辑和重试逻辑分离”。

5.4 归档之后怎么复用

归档的价值在于复用。我的复用方式主要有三种:

第一种:作为新需求的参考。当有类似需求时,直接把之前的规格和测试用例喂给AI,说“请参考这个模式,为新的需求生成规格和测试”。这样能节省大量澄清和编写测试的时间。

第二种:作为团队规范。把归档的目录结构和文档模板提取出来,作为团队使用AI编码的标准流程。新人入职时,直接看这些归档就能理解团队的AI协作方式。

第三种:作为质量基线。当AI生成的实现质量下降时,可以对比之前的归档,看看是哪个环节出了问题。是规格写得不够细?还是测试覆盖不够?还是审查环节被跳过了?

5.5 常见问题速查表

问题现象可能原因排查方向解决技巧
AI问的问题太泛初始需求太模糊检查初始描述是否缺少关键信息给AI提供提问框架或角色引导
测试用例遗漏异常场景指令中未明确要求检查指令是否列出了场景类型要求AI做反向覆盖检查
实现反复不通过规格与测试矛盾对比规格和测试的断言回到规格阶段统一口径
AI修改测试用例自动化迭代中的“作弊”检查测试文件是否被改动设置测试文件只读或明确禁止修改
代码风格不一致缺少风格约束检查是否提供了风格指南在规格中增加代码风格要求
归档后找不到目录结构混乱检查归档规范是否统一制定固定的目录结构模板

6. 我对这套框架的一些个人体会

跑过多轮之后,我最大的体会是:这套框架的价值不在于“让AI写出更好的代码”,而在于“让AI写代码这件事变得可管理”。

对话式编码的问题不是AI写得不好,而是你无法预测它这次写得好不好,也无法在出问题时快速定位原因。Harness Workflow通过分阶段、多角色、强制验证的方式,把这种不确定性降到了可接受的范围内。

另一个体会是:框架的收益随着任务复杂度的增加而增加。如果你只是让AI写一个简单的工具函数,这套流程可能显得过于繁琐。但一旦任务涉及多个文件、多种关注点、多个协作方,这套框架就能帮你省下大量的返工时间。

还有一个容易被忽视的点:归档本身就是一种学习。当你积累了一定数量的归档之后,你会发现AI在某些类型的任务上表现特别好,在某些类型上容易出问题。这些经验会反过来指导你更好地设计规格和测试用例。

最后分享一个小技巧:在意图澄清阶段,让AI同时输出“成功标准”和“失败标准”。成功标准是你期望的行为,失败标准是你绝对不能接受的行为。这样在后续的测试和审查阶段,你就有了更明确的判断依据。这个技巧是我在一次复杂需求中偶然发现的,后来成了我的标准操作。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询