Harness Engineering 实战:如何让 AI 写代码可靠性提升 10 倍

0 阅读10分钟

"同一个模型,只改 Harness,人工审查时间从每 100 行 2 小时降到 15 分钟"


有个朋友公司内部要做一个效率工具。

前端 + 后端 + 数据库,大概 2 万行代码。

要求:两周交付。

要是以前,肯定得拉上两三个同事一起干。

但这次,只有朋友一个人,加一个 AI 助手。

结果:

  • 10 天完成,提前 4 天交付

  • AI 写的代码,人工审查时间从每 100 行 2 小时降到 15 分钟

  • 上线后无严重 bug

注意:这些数据是我从朋友那了解到,他自己记录的,不是精确测量。

但效率提升 10 倍,这个感受是真实的。


01

先说说遇到的问题。

问题 1:AI 写的代码,不符合我的项目规范。

要求用 TypeScript,它写 JavaScript。

要求用 ESLint,它不写 lint 配置。

要求函数不超过 50 行,它写 200 行。

问题 2:AI 经常忘记之前的约定。

说"用这个 API",它忘了,换成另一个。

说"这个文件别动",它动了。

说"先写测试",它后写。

问题 3:AI 写的代码,没法直接跑。

缺依赖、少配置、路径错误……

每次都要手动修。

问题 4:AI 陷入循环,反复改同一个文件。

改来改去,越改越乱。


02

一开始,用的是 Prompt Engineering。

写了一个超长的系统提示词:

"你是一个资深工程师。请用 TypeScript 写代码,遵守 ESLint 规范,函数不超过 50 行。先写测试,再写实现。用 XXX API,别动 YYY 文件……"

有用吗?

有点用,但不多。

AI 还是经常忘记。

为什么?

因为提示词是"软约束"。

AI 可以听,也可以不听。

现在想要的是"硬约束"。


03

然后,开始设计 Harness。

设计的 Harness 架构,分四层:

┌─────────────────────────────────────┐
│         编排层 (Orchestration)       │
│   任务分解 | 子 Agent 管理 | 模型路由   │
├─────────────────────────────────────┤
│         中间件层 (Middleware)        │
│   Lint 检查 | 类型检查 | 测试验证       │
├─────────────────────────────────────┤
│         工具层 (Tools)               │
│   文件系统 | 命令行 | 浏览器 | Git      │
├─────────────────────────────────────┤
│         约束层 (Constraints)         │
│   系统提示词 | 项目规范 | 架构规则       │
└─────────────────────────────────────┘

核心思想:

不是靠 AI 自觉,是靠系统强制。


04

第一层:约束层(Constraints)

这是最底层,定义 AI 的行为边界。

写了三个文件:

AGENTS.md(项目总规范)

# 项目规范
## 技术栈
- 语言:TypeScript 5.4+
- 框架:React 18 + Node.js 20
- 数据库:PostgreSQL 15
## 代码规范
- 函数不超过 50 行
- 文件不超过 500 行
- 必须写单元测试
- 必须通过 ESLint 和 TypeScript 检查
## 禁止事项
- 不许删除任何文件
- 不许修改 config/ 目录
- 不许使用 eval()
- 不许硬编码密钥

docs/architecture.md(架构文档)

# 架构规范
## 目录结构
src/
  ├── controllers/  # 控制器层
  ├── services/     # 服务层
  ├── models/       # 数据模型
  └── utils/        # 工具函数
## 依赖方向
controllers → services → models → utils
不允许反向依赖

.cursorrules(AI 专用规则)

# AI 编码规则
1. 每次修改前,先读取相关文件
2. 写完代码后,立即运行测试
3. 如果测试失败,必须修复后再提交
4. 如果不确定,先问人类

这三个文件,每次对话前都会注入到上下文。

AI 不可能说"我不知道规范"。


05

第二层:工具层(Tools)

这是 AI 的手和脚。

给了 AI 五个工具:

1. 文件读写工具

interface FileSystem {
  readFile(pathstring): string
  writeFile(pathstring, contentstring): void
  deleteFile(pathstring): never // 不允许删除
}

2. 命令行工具

interface Terminal {
  run(command: string): { stdout: string; stderr: string; code: number }
}

3. 浏览器工具

interface Browser {
  navigate(urlstring): void
  screenshot(): string
  click(selectorstring): void
}

4. Git 工具

interface Git {
  commit(message: string): void
  push(): void
}

5. 搜索工具

interface Search {
  web(querystring): string[]
  code(symbolstring): string[]
}

关键点:

每个工具都有清晰的描述和参数。

AI 知道什么时候用什么工具。


06

第三层:中间件层(Middleware)

这是 Harness 的核心。

写了四个中间件:

中间件 1:Lint 检查

function lintCheck(code: string): { passbooleanerrorsstring[] } {
  // 运行 ESLint
  const result = runESLint(code)

  if (!result.pass) {
    // 把错误信息注入上下文,让 AI 重写
    injectContext(`代码未通过 Lint 检查:${result.errors.join('\n')}`)
    return { passfalseerrors: result.errors }
  }

  return { passtrueerrors: [] }
}

中间件 2:类型检查

function typeCheck(code: string): { passbooleanerrorsstring[] } {
  // 运行 TypeScript 编译器
  const result = runTSC(code)

  if (!result.pass) {
    injectContext(`类型检查失败:${result.errors.join('\n')}`)
    return { passfalseerrors: result.errors }
  }

  return { passtrueerrors: [] }
}

中间件 3:测试验证

function testValidation(): { passbooleanfailuresstring[] } {
  // 运行单元测试
  const result = runJest()

  if (!result.pass) {
    injectContext(`测试失败:${result.failures.join('\n')}`)
    return { passfalsefailures: result.failures }
  }

  return { passtruefailures: [] }
}

中间件 4:循环检测

function loopDetection(): void {
  // 跟踪文件编辑次数
  const editCount = getEditCount(currentFile)

  if (editCount > 5) {
    injectContext(`警告:你已经修改这个文件${editCount}次了,请换个思路`)
  }

  if (editCount > 10) {
    // 直接停止,让人类介入
    stopAndNotifyHuman()
  }
}

每个中间件都是强制执行的。

AI 写的代码,必须通过所有检查才能提交。


07

第四层:编排层(Orchestration)

这是 Harness 的大脑。

设计了一个简单的任务编排流程:

1. 接收任务 → 2. 分解子任务 → 3. 分配给子 Agent → 4. 收集结果 → 5. 合并代码

具体实现:

async function orchestrate(task: string): Promise<void> {
  // 1. 任务分解
  const subtasks = await decomposeTask(task)

  // 2. 并行执行
  const results = await Promise.all(
    subtasks.map(t => runAgent(t))
  )

  // 3. 合并代码
  const mergedCode = mergeResults(results)

  // 4. 最终验证
  if (!finalValidation(mergedCode)) {
    // 失败就回滚
    rollback()
    throw new Error('验证失败')
  }

  // 5. 提交
  commit(mergedCode)
}

这样做的好处:

大任务拆小,并行执行,快速验证。


08

说说效果。

之前(只用 Prompt):

  • 人工审查时间:每 100 行代码 2 小时

  • 返工率:约 60%

  • AI 反复修改次数:平均 5-6 轮

之后(用 Harness):

  • 人工审查时间:每 100 行代码 15 分钟

  • 返工率:约 8%

  • AI 反复修改次数:平均 1-2 轮

效率提升:约 10 倍。

注意:这是朋友个人项目的数据,不是严格实验结果。

但 LangChain 的实验数据是严格的:

同一个模型,只改 Harness,分数从 52.8 提升到 66.5。


09

我举个具体案例。

任务:实现一个用户登录功能。

之前的流程:

1.我写 Prompt:"请实现用户登录,用 JWT,加密码加密……"

2.AI 写代码

3.我审查,发现一堆问题

4.我让它改

5.它改完,还有问题

6.我再让它改

7.反复 5-6 轮

8.最后我自己上手修

耗时:3 小时。

现在的流程:

  1. 我写任务:"实现用户登录功能"

  2. AI 读取 `AGENTS.md`,知道要用 JWT 和密码加密

  3. AI 写代码

  4. Lint 检查,不通过,打回重写

  5. 类型检查,不通过,打回重写

  6. 测试验证,不通过,打回重写

  7. 全部通过,自动提交

耗时:40 分钟。

人类做什么?

看着 AI 干活,最后验收一下。


10

最后,说三个踩过的坑。

坑 1:系统提示词写得太长。

一开始,写了一个 5000 字的提示词。

结果:AI 根本记不住。

后来,把它拆成三个文件,每次只注入相关的。

效果好了很多。

坑 2:中间件检查太严格。

一开始,要求 100% 通过才能提交。

结果:AI 卡在一个地方,反复过不去。

后来,加了"降级机制":

如果反复 5 次过不去,就通知人类介入。

坑 3:工具描述不清晰。

一开始,工具的描述写得很简单。

结果:AI 经常用错工具。

后来,给每个工具都写了详细的使用示例。

AI 就知道什么时候用什么了。


11

回到开头的问题:

怎么让 AI 写代码更可靠?

答案:不是换更好的模型,是设计更好的 Harness。

同一个 GPT-5.2-Codex,LangChain 只改 Harness,分数从 52.8 提升到 66.5。

同一个模型,我改了 Harness,bug 率从 35% 降到 3%。

模型是引擎,Harness 是方向盘。

引擎再好,没有方向盘,车也开不远。

2026 年,真正的护城河不是模型。

是你设计的 Harness。


Harness 组件清单:

层级

组件

作用

约束层

AGENTS.md

项目总规范

约束层

docs/architecture.md

架构文档

约束层

.cursorrules

AI 专用规则

工具层

文件系统

持久化存储

工具层

命令行

执行脚本

工具层

浏览器

网页交互

工具层

Git

版本控制

中间件层

Lint 检查

代码规范验证

中间件层

类型检查

TypeScript 验证

中间件层

测试验证

单元测试验证

中间件层

循环检测

防止无限循环

编排层

任务分解

大任务拆小

编排层

模型路由

选择合适模型


关于作者

作者:近 20 年技术生涯,待过大厂也创过业。 懂大厂的规范与困境,也懂创业公司的敏捷与无奈。 懂技术也懂商业,实践用技术重构传统业务。公众号「AI 提效随笔」主理人。

欢迎转发,转载请注明出处。


📌 觉得有用?欢迎:

点赞 - 让更多人看到

转发 - 分享给需要的同事/朋友

关注 - 不错过后续更多精彩内容分享