本文记录一个真实的企业级 Java 后端项目(Spring Boot 2.7 + MyBatis-Plus)如何基于krio从零构建 AI Agent Harness 体系的完整实践。


一、问题:AI Agent 在企业级项目中为什么不好用?

把 AI Agent 扔进一个有 20 万行代码的企业级 Java 项目,你会发现四个核心痛点:

痛点

表现

后果

没有记忆

每次对话都是全新的,上次犯的错这次照犯

同样的问题反复出现,用户反复纠正

没有纪律

规则遵守率 60-90%,不是 100%

代码风格不一致、架构约束被突破、命名乱来

没有业务知识

只会写代码,不懂业务逻辑

按自己的理解"自由发挥",写出逻辑正确但业务错误的代码

没有质量保障

写完就完了,不验证

编译不过、测试不跑、回归问题无人发现

这四个痛点不是 Prompt Engineering 能解决的——你不可能每次对话都手动把所有规则、业务知识、验证流程重新告诉 Agent 一遍。

需要的是一个系统性的解决方案:Harness Engineering。

二、框架:Harness Engineering 的四个维度

Prompt Engineering 解决"怎么跟 AI 说话"。Context Engineering 解决"给 AI 看什么"。Harness Engineering 解决"怎么让 AI 在企业级项目中持续、可靠地干活"。

Harness Engineering(最外层 - 整个 Agent 系统的设计)
  |-- Context Engineering(上下文工程 - 管理所有喂给 LLM 的信息)
  |     |-- Prompt Engineering(提示工程 - 优化指令文本)
  |     +-- 工具定义、RAG、消息历史、MCP 数据、仓库知识库...
  |-- Architectural Constraints(架构约束 - 确定性的强制执行)
  |-- Entropy Management(熵管理 - 持续的质量维护)
  +-- Workflow Control(工作流控制 - Agent 的运行时管理)

四个维度对应四个痛点:

痛点

维度

核心问题

没有业务知识

Context Engineering

怎么给 Agent 精准的上下文?

没有纪律

Architectural Constraints

怎么用确定性约束概率性行为?

没有质量保障

Workflow Control

怎么让验证和流程自动跑起来?

没有记忆

Entropy Management

怎么让系统自我进化、不重复犯错?

三、实践:我们怎么做的

3.1 Context Engineering — 给 Agent 精准的上下文

核心问题:Agent 每次干活都需要知道"规矩是什么"和"业务是什么",但不能把所有信息一股脑塞进去(token 有限、噪音会降低遵守率)。

我们的解法:分层加载 + 领域文档 + 知识图谱。

Steering 规则:分层按需加载

Steering 是 Kiro 的规则文件机制,我们按"加载时机"分为两类:

类型

文件

加载时机

内容

always(6 个)

项目规范、工作流规则、自成长规则、Spec规范、Karpathy编码准则、code-review-graph

每次对话

Agent 的"基本功"——技术栈、流程、行为准则

fileMatch(3 个)

Java编码规范、MyBatis规范、Spring规范

编辑对应文件时

Agent 的"专业技能"——只在需要时加载

关键设计决策:Steering 只写可执行约束,禁止写科普性内容。

反例:"新表和老表的区别在于主键生成策略不同..."(科普,Agent 看了也不知道该怎么做)

正例:"新表 Entity 必须继承 BaseEntity,审计字段由 FieldFill 自动填充,禁止手动 set"(约束,Agent 直接遵守)

领域文档:业务知识库

每个业务领域在 docs/domain/{领域名}/ 下维护五个标准文档:

文档

内容

优先级

为什么需要

业务规则.md

状态机、校验规则、计算公式、边界约束

P0

Agent 缺了它就会"自由发挥"业务逻辑

API契约.md

接口路径、入参出参、错误码

P1

保证接口设计一致性

数据模型.md

表结构、字段含义、索引策略

P2

避免 Entity 字段凭空添加

决策记录.md

每次重要决策的 what/why/影响

P3

避免推翻已有决策

领域概述.md

领域边界、核心实体关系、上下游依赖

P4

理解领域全貌

消费方式:Spec 创建时 requirements.md 引用业务规则和决策记录,design.md 引用 API 契约和数据模型。开发完成后代码变更反向更新文档,形成正向循环。

冷启动问题用 domain-doc-builder Skill 解决——Agent 扫描代码生成初稿,人工校验修正。

MCP 知识图谱:结构化代码理解

通过 code-review-graph MCP Server 提供代码知识图谱,Agent 探索代码时优先用图谱(比 grep 更快、消耗更少 token、提供调用者/依赖方/测试覆盖等结构化上下文)。

3.2 Architectural Constraints — 用确定性约束概率性

核心问题:Steering 规则的遵守率是 60-90%,不是 100%。10-40% 的情况下 Agent 会违反规则而不自知。

我们的解法:确定性检测脚本 + 编码规范 + 项目规范。

确定性检测层(Lint 脚本)

核心理念来自 OpenAI Codex:linter 的错误信息本身就是修复指令——Agent 看到报错就知道怎么改。

脚本

检测什么

为什么不能靠 Steering

lint-cross-domain.bat

领域 A 的 Service 直接 import 领域 B 的 Service

跨域调用规则复杂,Agent 容易"觉得这次可以例外"

lint-exception-msg.bat

异常信息硬编码中文(应使用 message.properties 的 key)

Agent 图省事直接写中文字符串

lint-temp-files.bat

工作区有临时文件残留

子代理执行失败时可能留下临时文件

错误输出设计原则——四要素,让 Agent 看到就能自己修:

[LINT FAIL] {规则名称}
文件: {文件路径}:{行号}
违规: {具体违规内容}
修复: {修复指令,Agent 可直接执行}

不是告诉 Agent "你错了",而是告诉它"你错了,这样改"。

编码规范的确定性约束

Steering 规则中的编码规范(Java编码规范、MyBatis规范、Spring规范)通过 fileMatch 在编辑对应文件时自动加载,确保 Agent 写代码时"看得到规矩"。但看得到不等于遵守——所以 Lint 脚本作为确定性兜底。

两层防线的关系:

  • Steering 规范 = 事前约束(告诉 Agent 怎么做,遵守率 60-90%)

  • Lint 脚本 = 事后检测(检查 Agent 有没有做到,遵守率 100%)

3.3 Workflow Control — 让流程自动跑起来

核心问题:Agent 没有记忆,不能指望它"记住"该跑测试、该更新文档、该做审查。

我们的解法:Hook 自动化 + Spec 结构化工作流 + 子代理专业化分工 + Skill 能力包。

Hook:极简自动化(仅 3 个)

经过四轮演进,从最初的 7 个 Hook 精简为 3 个:

Hook

触发时机

做什么

执行复盘

agentStop(每次 Agent 结束)

回归测试(改了 Java 就跑 mvn test)+ 三步复盘(摘要→问题检测→模式提取)

冒烟测试

手动触发

验证核心 API 端点是否正常响应

Spec 归档

手动触发

将已完成的 Spec 归档到季度目录

为什么从 7 个精简到 3 个?因为发现 Steering 规则 always-on 可以替代大部分 askAgent 类型的 Hook——Steering 已经告诉 Agent "什么时候必须做什么",不需要额外的 Hook 提醒。Hook 只保留"Agent 想跳也跳不过"的自动化。

Spec 工作流:结构化功能迭代

一次功能开发的完整流程:

需求输入 → 需求澄清(Skill)→ requirements.md → 方案比对 → design.md → tasks.md → 子代理执行 → 文档更新 → 归档

每个功能切片按"垂直切片三件套"编排:

Task 1: {功能} - 开发        ← Kiro 原生执行
Task 1-review: {功能} - 审查  ← 并行调用 3 个 reviewer 子代理
Task 1-test: {功能} - 测试    ← 调用 test-writer 子代理

子代理:专业化分工(6 个)

子代理

职责

什么时候用

codebase-explorer

代码库探索

Spec 创建前理解代码结构

debugger

Bug 根因分析

Bug 涉及多个 Service 调用链

reviewer-compliance

业务规则合规审查

每个功能切片开发完成后

reviewer-exception

异常处理质量审查

同上,并行执行

reviewer-test-coverage

测试覆盖缺失审查

同上,并行执行

test-writer

测试编写

三个 reviewer 返回后

核心理念:活可以分出去,思考不行。主代理自己消化信息、做出判断、给出明确方向,再委派给子代理执行。

Skill:可复用能力包(7 个)

Skill

做什么

什么时候触发

domain-doc-builder

从代码扫描生成领域文档

"补全XX领域文档"

requirement-clarifier

需求澄清 / 需求覆盖度审查

Spec 创建前 / "审查需求覆盖"

harness-reviewer

审查 Harness 体系一致性

"审查规则"、"体系审查"

skill-creator

指导创建新 Skill

"创建 Skill"

systematic-debugging

结构化调试方法论

遇到 Bug 时

verification-before-completion

完成前验证

即将声称工作完成时

using-superpowers

Skill 使用规范

每次对话开始

五层验证体系

层级

验证什么

怎么保证不被跳过

L0 即时诊断

语法和类型错误

Steering 规则约束:改了 Java 就跑 getDiagnostics

L1 编译

代码能否编译

Steering 规则约束:阶段后置 / vibe coding 结束前

L2 静态检查

架构约束

Lint 脚本(确定性,不依赖 Agent 推理)

L3 单元测试

业务逻辑正确性

tasks.md 编排保证

L4 全量测试

是否引入回归

执行复盘 Hook 保证(Agent 想跳也跳不过)

3.4 Entropy Management — 让系统自我进化

核心问题:AI Agent 没有记忆,每次对话都是全新的。如果规则不持久化,同样的错误会反复出现。

我们的解法:三个机制 + 规范演进日志。

三个核心机制

机制

触发方式

做什么

重复检测

Steering 规则 always-on

用户重复要求同一件事 2 次以上 → 提炼为规则写入 Steering

问题反思

执行复盘 Hook

执行失败/用户纠正 → 分析根因 → 系统性缺陷则固化规则

模式提取

执行复盘 Hook

每次执行结束 → 正向提取值得沉淀的模式

规则固化标准

不是所有发现都值得写入规范。三个条件全部满足才固化:

  1. 可复现性:这个问题会在未来再次出现

  2. 可执行性:规则足够具体,Agent 能直接遵守(不是"注意代码质量"这种空话)

  3. 通用性:不是只针对某一次特殊情况

判定验证

区分"个案"和"系统性缺陷"的方法:

换一个全新 Agent(没有本次对话的上下文),执行同样的任务,仅凭当前 Steering 规则,能否避免这个问题?

能避免 → 个案,不需要固化。不能避免 → 系统性缺陷,必须提炼规则。

禁止用"下次会注意"、"下次会更严格"等无法持久化的承诺替代规则固化。没有记忆的智能体,必须靠规则而非承诺。

规范演进日志

docs/规范演进日志.md 记录每次规则变更的来源、内容和原因。只追加,不修改。是整个自成长体系的"审计轨迹"。

四、知识流转闭环

整个 Harness 的核心逻辑是一个自增强的正向循环:

graph TB
    A["开发新功能"] -->|引用| B["领域文档(已有知识)"]
    A -->|Steering 自动加载| C["项目规范 + 编码规范"]
    A -->|执行| D["代码产出"]
    D -->|Hook + Lint 自动验证| E{通过?}
    E -->|否| A
    E -->|是| F["功能完成"]
    F -->|覆盖更新| B
    F -->|如有流程改进| C

    G["执行中出错"] -->|执行复盘 Hook| H["提炼新规则"]
    H -->|写入| C
    H -->|记录| I["规范演进日志"]

    J["用户重复要求"] -->|Steering always-on| H

每次开发都消费已有知识,同时沉淀新知识。每次出错都提炼新规则,下次不再犯。

五、踩坑清单(精选)

现象

固化的规则

Hook 过多反而低效

7 个 Hook 中 4 个被 Steering 覆盖,形成冗余

精简为 3 个,其余由 Steering 覆盖

概率性检测不可靠

askAgent 类型的 Hook 依赖 Agent 推理,遵守率不稳定

能用脚本检测的不用 Agent 推理

子代理编译试错

子代理写测试时编译了 6 次

编译验证最多 1 次,先读完再写

运行时规则写错位置

子代理委派约束写在 Spec 编写规范中,子代理执行时看不到

按生效时机判断写入位置

新旧表混淆

Entity 规范只描述了老表模式

提取规范时至少各看一个新文件和老文件

Entity 字段凭空添加

子代理给 Entity 加了设计文档中没有的字段

Entity 字段必须严格来源于设计文档

大文件逐段替换卡住

翻译 2000 行文件时逐段 strReplace 卡住

超过 10 次工具调用则暂停提出替代方案

Skill 被绕过

Agent 跳过 Skill 自行手动执行

Steering 规则强制触发兜底

重复检测 Hook 无效

promptSubmit Hook 无法检测跨对话的重复

改为 Steering 规则 always-on

反思深度不够

Agent 用"下次注意"搪塞

反问验证:换一个全新 Agent 能否避免?

六、落地路线图

阶段

时间

做什么

搭骨架

半天

核心 Steering(项目规范 + 工作流规则 + 自成长规则)+ 执行复盘 Hook + 规范演进日志

提取编码规范

半天

从代码中提取 Java/MyBatis/Spring 规范,配置 fileMatch 条件加载

搭建子代理和 Skill

1 天

6 个子代理 + domain-doc-builder + requirement-clarifier + Spec 规范

补核心领域文档

每领域 1-2 天

用 domain-doc-builder Skill 扫描代码生成初稿,人工校验

搭建确定性检测层

半天

Lint 脚本 + 冒烟测试脚本

进入正循环

持续

Spec 工作流开发 + 自成长体系运转 + 定期 harness-reviewer 审查

七、核心理念

这套 Harness 的本质是:

用确定性的机制(Steering 规则、Hook 自动化、Lint 脚本、子代理审查)约束概率性的 AI Agent,同时通过自成长体系让确定性的机制本身也在持续进化。

不是让 Agent 更聪明,而是让 Agent 犯错的空间更小。