Mushroom Notes Mushroom Notes
🍄首页
  • JavaSE

    • 基础篇
    • 数据结构
    • IO流
    • Stream流
    • 函数式接口
    • JUC
    • 反射
    • 网络编程
    • 设计模式
  • JavaEE

    • Servlet
    • JDBC
    • 会话技术
    • 过滤器监听器
    • 三层架构
  • JDK

    • 总览
  • JVM

    • JVM 应用
    • JVM 理论
    • JVM 底层
  • HTML
  • CSS
  • JavaScript
  • rds 数据库

    • MySQL
    • MySQL 进阶
    • MySQL 库表规范
  • nosql 数据库

    • Redis
    • Redis 进阶
    • Redis 底层
    • MongoDB
  • Spring生态

    • Spring
    • Spring MVC
    • Spring boot
    • Spring Validation
  • Spring Cloud生态

    • Spring Cloud
    • 服务治理
    • 远程调用
    • 网关路由
    • 服务保护
    • 分布式事务
    • 消息中间件
  • 持久层框架

    • Mybatis
    • Mybatis Plus
    • Elasticsearch
    • Redisson
  • 通信

    • Netty
  • 运维工具

    • Linux
    • Docker
    • Nginx
  • 开发工具

    • Maven
    • Git技巧
    • GitHub技巧
  • 其他

    • 文件存储
    • 压测
  • 方案专题
  • 算法专题
  • BUG专题
  • AI专题
  • 安装专题
  • 网安专题
  • 面试专题
  • 常用网站
  • 后端常用
  • 前端常用
  • 分类
  • 标签
  • 归档

kinoko

一位兴趣使然的热心码农
🍄首页
  • JavaSE

    • 基础篇
    • 数据结构
    • IO流
    • Stream流
    • 函数式接口
    • JUC
    • 反射
    • 网络编程
    • 设计模式
  • JavaEE

    • Servlet
    • JDBC
    • 会话技术
    • 过滤器监听器
    • 三层架构
  • JDK

    • 总览
  • JVM

    • JVM 应用
    • JVM 理论
    • JVM 底层
  • HTML
  • CSS
  • JavaScript
  • rds 数据库

    • MySQL
    • MySQL 进阶
    • MySQL 库表规范
  • nosql 数据库

    • Redis
    • Redis 进阶
    • Redis 底层
    • MongoDB
  • Spring生态

    • Spring
    • Spring MVC
    • Spring boot
    • Spring Validation
  • Spring Cloud生态

    • Spring Cloud
    • 服务治理
    • 远程调用
    • 网关路由
    • 服务保护
    • 分布式事务
    • 消息中间件
  • 持久层框架

    • Mybatis
    • Mybatis Plus
    • Elasticsearch
    • Redisson
  • 通信

    • Netty
  • 运维工具

    • Linux
    • Docker
    • Nginx
  • 开发工具

    • Maven
    • Git技巧
    • GitHub技巧
  • 其他

    • 文件存储
    • 压测
  • 方案专题
  • 算法专题
  • BUG专题
  • AI专题
  • 安装专题
  • 网安专题
  • 面试专题
  • 常用网站
  • 后端常用
  • 前端常用
  • 分类
  • 标签
  • 归档
  • 方案专题

  • AI专题

    • MCP 连接数据库
    • GITLAB AI 评审
    • Harness 工程实践:构建 AI Agent 的可靠开发工作流
      • 前言:从写代码到"指挥"代码
      • 几个关键概念
        • 什么是 Harness
        • 什么是 Spec
        • 为什么需要知识库
      • 我的 Harness 工程实践
        • 阶段一:构建知识库(环境准备)
        • 阶段二:Spec & Harness 双轮驱动
        • Spec:从模糊需求到精确规范
        • Harness:自动化的质量守门员
        • 工具推荐
        • 关键设计:测试 Agent 必须独立
        • 阶段三:持续迭代
      • 完整工作流
        • 逐步说明
        • 时间分配的变化
      • 一些经验总结
  • 算法专题

  • BUG专题

  • 安装专题

  • 网安专题

  • 面试专题

  • 专题
  • AI专题
kinoko
2026-04-27
目录

Harness 工程实践:构建 AI Agent 的可靠开发工作流

# 前言:从写代码到"指挥"代码

2025 年初,Andrej Karpathy 提出了一个概念——Vibe Coding:程序员不再逐行编写代码,而是用自然语言描述意图,由 AI 生成代码。程序员的角色从"代码编写者"转变为"意图引导者 + 结果审查者"。

一年多过去了,这个趋势不仅没有消退,反而加速了。Cursor、Claude Code、GitHub Copilot、Windsurf 等 AI 编程工具快速迭代,大模型的代码生成能力越来越强。作为一名 Java 后端工程师,我在日常开发中逐渐感受到一个现实:

AI 写代码已经不是瓶颈了。瓶颈在于——怎么让 AI 写出符合你预期的代码,以及怎么验证它写得对不对。

这篇文章分享我在实际项目中摸索出的一套 AI Agent 开发工作流,核心围绕三个关键词:知识库、Spec、Harness。

# 几个关键概念

# 什么是 Harness

Harness 直译是"缰绳、挽具",在赛马中用来驾驭马匹。在 AI Agent 领域,Harness 指的是包裹在 AI 模型外围的整套控制基础设施,让模型从"只能聊天"变成"能真正做事且做得对"。

一个裸的大语言模型只能输出文本。但当你在它外围加上文件读写、Shell 执行、浏览器操作等工具,加上权限控制、上下文管理、任务调度、测试验证等机制——这些外围设施共同构成了一个 Harness。

一个越来越明显的趋势是:模型能力在快速趋同,真正拉开差距的是 Harness 的设计。 同样的底层模型,不同的 Harness 配置,产出质量和可靠性可能天差地别。

Harness 通常包含以下层次:

协调层
任务拆分 / Agent 调度
↓
反馈循环
测试 / Lint / Hook
↓
上下文管理
CLAUDE.md / Memory / 知识库
↓
安全与权限
沙箱 / 确认机制
↓
工具层
文件系统 / Shell / 浏览器

# 什么是 Spec

Spec 是 Specification(规范)的缩写。在 AI Agent 的工作流中,Spec 指的是一套可落地的精确规范,用来约束 AI 的行为。

先看一个反例:

实现一个用户登录功能。

这种描述对人来说足够理解,但对 AI 来说太模糊了。它不知道你要用 JWT 还是 Session,不知道登录失败要返回什么,不知道要不要做频率限制。

一个好的 Spec 应该包含:

  • 拆成哪些接口,每个接口实现什么功能(1、2、3、4 列出来)
  • 每个接口的入参和出参
  • 需要注意的边界条件
  • 使用哪些框架和技术
  • 数据怎么存储
  • 是否需要生成额外的文档或图例

核心原则:Spec 越精确,AI 执行越稳定。

# 为什么需要知识库

LLM 的上下文窗口是有限的,不可能每次都把整个项目塞进去。更重要的是,AI 对你的业务领域的理解不是天生就有的——它不知道你的用户有哪些字段、订单有哪些状态、支付流程涉及哪些服务。

知识库就是 AI Agent 的长期记忆,跨越单次会话持久存在。一个设计良好的知识库能让 AI 在每次新会话中快速获得项目的上下文,而不需要人反复解释。

一个关键做法:给索引不给内容。 在 Spec 中只引用知识库的索引路径,让 AI 按需加载,避免把大量领域知识直接塞进执行上下文造成污染。

# 我的 Harness 工程实践

下面进入正题,分享我在实际项目中搭建的 AI Agent 开发工作流。整体分为三个阶段:

📦
阶段一
构建知识库
→
⚙️
阶段二
Spec & Harness
双轮驱动
→
🔁
阶段三
持续迭代

# 阶段一:构建知识库(环境准备)

在 AI 开始写代码之前,必须先让它理解项目全貌。我定义了一个 learn-project 的 Skill,在初始化工程时由人引导 AI 了解项目,生成结构化的知识库。

知识库分为三层:

📚 知识库
├── 🏗️ 项目结构 & 背景
│   └── 目录结构、技术栈、模块划分
│
├── 📏 编码规范
│   └── 命名规范、分层规范、异常处理
│
└── 📖 领域知识 Index
    ├── 用户 → /domain/user.md
    ├── 订单 → /domain/order.md
    └── ...
        └── 领域知识详情(每个概念包含):
            ├── 概念说明
            ├── 使用示例
            └── 字段定义 & 查询方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

项目结构与背景说明项目的目录组织、技术选型、模块职责等宏观信息。

编码规范约束 AI 的代码风格,包括命名规范、分层规范、异常处理方式等。

领域知识是最核心的部分。它以 Index + 详情的形式组织:Index 列出所有领域概念及其存放路径,详情文档包含每个领域概念的字段定义、使用示例、业务规则。例如"用户"这个领域概念,知识库会记录用户有哪些字段、常用的查询方式、与其他实体的关联关系等。

这一步是前期投入,但复利效应非常明显——后续每个新需求都不需要重新解释项目背景。

# 阶段二:Spec & Harness 双轮驱动

如果说知识库解决了"AI 对项目的认知"问题,那么 Spec 和 Harness 解决的就是"AI 怎么执行"和"执行得对不对"的问题。

它们的关系是这样的:

📋
Spec
精确规范
指导 →
🤖
编码 Agent
产出 →
💻
代码
Spec 同时约束 Harness 对代码进行验证
📋
Spec
约束 →
🔍
Harness
验证 →
📊
测试报告

Spec 告诉 AI "做什么、怎么做",Harness 验证 AI "做得对不对"。

# Spec:从模糊需求到精确规范

以一个实际需求为例,假设要实现"用户积分管理"功能。

模糊的写法:

实现用户积分的增减和查询。

精确的 Spec 写法:

接口1:查询用户积分
- 路径:GET /api/points/{userId}
- 入参:userId(Long)
- 出参:{ totalPoints: Integer, level: String, history: List<PointRecord> }
- 功能:返回用户的当前积分、等级和最近变动记录
- 边界:用户不存在时返回 404

接口2:增加积分
- 路径:POST /api/points/add
- 入参:{ userId: Long, points: Integer, reason: String }
- 出参:{ success: Boolean, currentPoints: Integer }
- 功能:为用户增加指定积分,更新等级
- 边界:points 必须 > 0,单次上限 10000

接口3:扣减积分
- 路径:POST /api/points/deduct
- 入参:{ userId: Long, points: Integer, reason: String }
- 出参:{ success: Boolean, currentPoints: Integer }
- 功能:扣减用户积分
- 边界:积分不足时返回失败,不允许负数

技术约束:
- 使用 MyBatis Plus 操作数据库
- 积分变动需要记录流水
- 参考知识库:/domain/user-points/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

可以看出,精确 Spec 的核心是穷举式地描述接口、功能点、边界条件,并且锚定知识库的索引路径,让 AI 按需查阅领域知识。

# Harness:自动化的质量守门员

Harness 负责验证 AI 产出的代码是否符合 Spec 的要求。它包含四个组成部分:

🔍 Harness
↓
📥 测试数据集
覆盖正常、边界、异常场景
↓
⚙️ 执行环境
SQL / API / 单元测试
↓
✅ 正确性评估
硬断言 + AI 软判断
↓
📊 量化报告
通过率、覆盖率、边界情况

第一部分:测试数据集。 根据 Spec 中定义的场景,准备对应的测试数据,覆盖正常流程、边界条件和异常情况。比如积分增加的测试数据,需要包含正常增加、超出上限、负数等场景。

第二部分:执行环境。 明确测试怎么执行——是跑 SQL 验证数据库状态,还是调 API 验证返回值,还是运行单元测试。

第三部分:正确性评估。 这里分为两层:

  • 硬断言:能用程序化方式校验的,必须硬断言。比如 API 返回的 status code 是否正确、数据库中的记录是否写入、字段值是否符合预期。
  • AI 软判断:业务逻辑的合理性、边界场景是否充分等,由 AI 来评估。

第四部分:量化报告。 输出可量化的测试结果——用例通过几个、覆盖率如何、边界情况测试怎样。报告中对硬断言结果和 AI 评估结果分开呈现,确保硬断言部分的可信度。

# 工具推荐

Harness 的执行环境直接影响测试的可靠性和覆盖范围。这里推荐两个 MCP 工具来强化测试能力:

1. GenAI Toolbox(数据库测试)

Google 开源的 MCP 工具,支持 MySQL、PostgreSQL、Redis 等多种数据源。通过 MCP 协议让测试 Agent 直接执行 SQL 验证数据库状态,实现数据层面的硬断言。

详细配置方式可以参考我之前的文章:MCP 连接数据库

2. IntelliJ IDEA MCP(工程编译 & 接口验证)

从 2026.1 版本开始,IntelliJ IDEA 官方支持了 MCP 协议。这意味着测试 Agent 可以通过 MCP 触发 IDEA 的编译、启动应用、发送 HTTP 请求并验证返回结果——覆盖了从编译到接口调用的完整验证链路,比单纯跑单元测试更接近真实运行环境。

# 关键设计:测试 Agent 必须独立

这是整个 Harness 设计中最重要的一个原则:执行测试的 Agent 和编写代码的 Agent 不能是同一个。

为什么?因为大语言模型存在一种"自我一致性偏差"——它倾向于认为自己刚生成的输出是正确的。如果你让同一个 Agent 先写代码再测试自己的代码,它大概率会跳过真正的验证,直接编造一个"测试通过"的结果。

❌ 错误做法:同一 Agent
编码 Agent
↓
自己测试
↓
编造通过结果
✅ 正确做法:独立 Agent
编码 Agent
↓ 交付代码
测试 Agent(独立上下文)
↓
量化测试报告

正确的做法是:仅携带必要的上下文(Spec 和被测代码),开启一个独立的子 Agent 来执行测试。这个测试 Agent 不知道代码是谁写的,也不关心结果好看不好看——它只负责客观地验证和汇报。

这本质上是用架构设计来解决模型的认知偏差问题,比在 prompt 里写"请认真测试"靠谱得多。

# 阶段三:持续迭代

知识库不可能一次性构建完美,初期必然会有遗漏。关键是要建立一个持续迭代的闭环:

  1. AI 在开发过程中遇到知识库未覆盖的情况时,将新发现的领域知识按规范持久化
  2. 人工发现 AI 犯错时,分析是否是知识库的缺失导致,如果是则补充
  3. 开发新领域业务时,同样将行为固化为可复用的知识资产

核心原则:一次会话的收获,不应该随会话结束而丢失。

每一条被沉淀下来的知识,都会在后续的需求中复用,减少重复沟通的成本。这是一个典型的复利效应——知识库越完善,AI 的执行效率越高,人工介入越少。

# 完整工作流

把前面三个阶段串起来,形成完整的开发工作流:

① 手动编写需求 MD
遵循 Spec 规范,拆分接口 & 功能点
↓
② 与 Agent 讨论方案
细化需求 MD,锚定知识库索引
↓
③ Agent 构建执行计划 + 回归测试计划
AI 生成,等待人工审计
↓
④ 人工审计 ⚠️
检查边界 & 场景覆盖(人的核心价值环节)
↓
⑤ AI 并行执行
多 Agent 自动开发(耗时最短的环节)
↓
⑥ 独立测试 Agent 输出报告
执行验证 → 量化测试报告

# 逐步说明

第一步:手动编写需求 MD。 这一步是纯手动的。实际业务往往很复杂,两三句话很难跟 AI 交代清楚,最好由自己来拆分。按照 Spec 规范,把需求拆成接口,列出每个接口的功能点。

第二步:与 Agent 讨论方案。 把需求 MD 给 Agent,让它参与讨论。Agent 会基于知识库提出方案建议,双方一起细化需求文档。关键点:只给知识库的索引路径,不要让 AI 把实现内容直接写到 MD 中。

第三步:Agent 构建执行计划。 让 Agent 基于 Spec 生成执行计划(Plan)和回归测试计划。执行计划描述代码层面的实现步骤,测试计划描述如何验证。

第四步:人工审计。 这是人的核心价值环节。重点审计两方面:

  • 执行计划的边界考虑是否与自己的一致,大致思路是否正确
  • 回归测试计划的场景设计是否覆盖了需求中的关键路径和边界

第五步:AI 并行执行。 审计通过后,放手让 AI 执行。Claude Code 等工具会自动根据任务拆分多个 Agent 并行开发,这是整个流程中耗时最短的环节。

第六步:等待测试报告。 独立的测试 Agent 执行验证,输出量化报告。根据报告决定是否通过,或者需要修正后重新测试。

# 时间分配的变化

很多人使用 AI 辅助编程时,依然沿用的是"AI 写代码 → 人 review 代码"的模式。这种模式下,人并没有真正解放,只是从"自己写代码"变成了"审查 AI 的代码",大量的时间仍然花在代码细节上。

Harness 工作流带来的核心转变是:从 review 代码,变为 review 方案。 不再纠结 AI 写的某一行代码对不对,而是确保 AI 的执行方向和验证标准是对的。

❌ AI 写代码 → 人 Review 代码
Review AI 代码 45%
反复让 AI 修改 25%
方案设计 15%
调试 & 排错 10%
测试 5%
✅ Harness 模式 → 人 Review 方案
方案设计 & Spec 30%
审计 Plan & 测试计划 25%
监督执行 & 审查报告 20%
知识库维护 15%
代码编写(AI 完成) 10%

左侧是大多数 AI 编程用户的现状——将近一半的时间在 review AI 的代码,四分之一的时间在反复让 AI 修改。本质上只是把"自己写代码"换成了"看别人写的代码",并没有真正提升效率。

右侧是 Harness 模式——人的精力集中在方案设计、Plan 审计和知识沉淀上,代码编写和验证交给 AI + Harness 自动完成。从关注代码细节,升级为关注工程决策。

# 一些经验总结

在实践这套工作流的过程中,我总结了以下几点经验:

1. Spec 的精确度直接决定 AI 输出的稳定性。 模糊的描述换来的是不可预测的结果。把时间花在写好 Spec 上,比花在反复让 AI 重写代码上高效得多。

2. 知识库的投入是前期成本,但复利效应明显。 刚开始时可能会觉得构建知识库很慢,但当你发现后续每个需求都不需要自己主动点醒,一次跑通时,就会感受到,爽!!

3. 接受"不完美",持续迭代优于一步到位。 不要指望一次性构建完美的知识库或 Harness。先跑起来,在实战中不断补充和完善。

4. 人始终是决策者。 AI 可以帮你写代码、跑测试、生成报告,但方案的最终决策、边界的判断、业务逻辑的正确性——这些始终需要人来把控。AI 是工具,不是替代者。


本文基于我在 Java 后端项目中使用 Claude Code 等 AI 工具的实际经验总结。Harness 的概念和应用方式因人而异,欢迎交流探讨。

#harness#ai-agent#vibe-coding#claude-code#工作流
上次更新: 2026/04/27 23:46:27
GITLAB AI 评审
二分查找

← GITLAB AI 评审 二分查找→

最近更新
01
GITLAB AI 评审 方案
04-26
02
MCP 连接数据库
04-26
03
JVM 底层
09-13
更多文章>
Theme by Vdoing | Copyright © 2022-2026 kinoko | MIT License | 粤ICP备2024165634号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式