AI 编程铁三角之三:Harness Engineering 实战入门
常见困境:AI 失控的典型场景
假设你让 AI 助手重构一个模块,三小时后你发现:

3 小时后,你发现:
✓ 功能实现了✗ 代码风格和项目不一致(它用了 var,你用 const)✗ 目录结构被它改了(新增了 utils/helper.js)✗ 测试文件被它删了(「我觉得不需要」)✗ 留下了 10 个 TODO 注释(「后续优化」)
你质问 AI 为何如此修改,AI 回答 “我认为这样更合理”——核心矛盾在于 AI 具备执行能力,但缺乏明确的边界约束。这正是 Harness Engineering 的解决之道。
Harness Engineering 是什么
一句话定义:
核心理念
Agent = Model + HarnessModel(模型)= 马,提供能力Harness(约束)= 缰绳,提供边界
你无法控制模型的能力(模型是给定的),但你可以设计缰绳——Harness 是你能掌控的。
反直觉的洞察
很多人认为:约束会限制 AI 的能力。
事实恰恰相反:好的约束反而能释放 AI 的效率。
举例来说:
无约束场景:AI:这个数据结构用 Map 还是 Object?自己猜一个吧这个函数要不要加缓存?先加上再说这个模块放哪个目录?随便放一个有约束场景:AI:CLAUDE.md 说「使用 Object 而非 Map」「所有 I/O 操作都要加缓存」「工具函数放在 src/utils/」→ 不用猜,直接做,效率更高
两个场景对比鲜明——AI 无需决策的地方,约束本身就是决策。
三大支柱
Harness Engineering 由三大支柱组成:
支柱一:Context Engineering(上下文工程)
核心问题:AI 看不到的信息等于不存在。
| AI 的上下文窗口 |
|---|
LAUDE.md← 项目约定 CLAUDE.md← 项目约定 AGENTS.md← Agent 身份 代码注释← 逻辑说明 设计文档← 架构决策 Git 状态← 项目上下文 |
实践要点:
| 上下文类型 | 作用 | 如何管理 |
|---|
| 静态上下文 | 项目约定、代码规范 | CLAUDE.md / AGENTS.md |
| 动态上下文 | 运行状态、Git信息 | 自动注入或 Hook 抓取 |
| 记忆上下文 | 历史决策、长期知识 | MEMORY.md / 日志系统 |
支柱二:Architectural Constraints(架构约束)
核心问题:如何给 AI 画清晰的边界?
| 约束项 | 说明 |
|---|
| 目录结构 | src/api/ 放接口 |
| 命名规范 | camelCase 变量 |
| 代码风格 | TypeScript strict |
| 模块职责 | 每个 < 300 行 |
| 依赖规则 | api 不能直接调用 db |
实践要点:
- CLAUDE.md 定义核心约束
- 测试套件验证约束
- Pre-commit Hook 自动检查
支柱三:Entropy Management(熵管理)
核心问题:系统如何长期保持健康?
| 实践项 | 说明 |
|---|
| 定期清理 | 删除死代码 |
| 约束验证 | 代码仍符合 CLAUDE.md |
| 性能监控 | 关注关键指标 |
| 文档同步 | 代码和文档一致 |
熵增的表现:
- 代码风格不一致
- 目录结构混乱
- 测试覆盖率下降
- 文档过时
实战案例:为 hot-trends CLI 搭建 Harness
背景
hot-trends 是一个 Python CLI 工具,用于抓取热榜文章并筛选 AI 相关内容。来自于前两篇 AI 编程铁三角:01 Superpowers 入门 [AI 编程铁三角:02 OpenSpec 入门] 的案例,完成 Harness 的搭建。
Level 1 Harness:5分钟搭建基础约束
Level 1 是最轻量的 Harness,只需要 CLAUDE.md + 测试 + Hook。
第一步:编写 CLAUDE.md
在项目根目录创建 CLAUDE.md,定义项目的核心约束:
## 项目概述Hot-Trends CLI 是一个 Python 命令行工具,主要用于抓取并筛选来自中文技术社区(掘金、知乎)的 AI 相关文章。它可以在终端中以表格形式展示结果,并支持导出为 JSON 或 Markdown 格式。## 开发命令```bash# 安装依赖(可编辑模式)pip install -e .# 运行所有测试pytest tests/ -v# 运行单个测试文件pytest tests/test_fetcher.py -vpytest tests/test_filter.py -vpytest tests/test_output.py -v# 本地运行 CLI(安装后)hot-trendshot-trends -l 100 -vhot-trends -o output.json# 不安装直接运行 CLIpython -m src.main## 架构设计### Fetcher 模式项目使用基类模式来管理数据源:- `src/fetchers/base.py` - `BaseFetcher` 抽象类,定义接口- `src/fetchers/juejin.py` - `JuejinFetcher` 实现掘金 API(支持分类)- `src/fetchers/zhihu.py` - `ZhihuFetcher` 实现知乎热榜抓取新增数据源应继承 `BaseFetcher` 并实现 `fetch_hot_trends(limit)` 方法,返回 `List[Article]`。### 数据流1. `main.py` 解析 CLI 参数,根据 `--source` (juejin/zhihu/all) 协调 fetchers2. 从选定的 fetchers 收集文章3. `AIFilter.filter_articles()` 按 AI 关键词过滤(可通过 `-k` 自定义)4. `OutputFormatter` 显示表格,并可选择保存到文件### 核心类- `Article` (models.py) - 数据类,包含 `to_dict()` 方法用于序列化- `AIFilter` (filter.py) - 基于关键词的过滤,带默认 AI 词库- `OutputFormatter` (output.py) - 处理终端表格(rich)、JSON 和 Markdown 输出## CLI 参数| 参数 | 说明 ||------|-------------|| `-l, --limit` | 文章数量(默认:50) || `-o, --output` | 输出文件(.json 或 .md) || `-s, --source` | 数据源:juejin/zhihu/all(默认:juejin) || `-c, --category` | 掘金分类:backend/frontend/ai 等(默认:all) || `-k, --keywords` | 自定义关键词(逗号分隔,追加到默认值) || `-v, --verbose` | 详细日志 |## 项目结构说明- 测试使用 pytest fixtures 和 tmp_path 进行文件操作- `openspec/` 目录包含使用 OpenSpec 格式的变更提案(非核心代码)- Husky 通过 package.json 配置 git hooks
关键点:CLAUDE.md 应该“刚好够用”,覆盖核心决策点即可。这个配置适用于 hot-trends 这类 Python CLI 项目,你可以根据自己的项目调整。
第二步:配置 Pre-commit Hook
安装 Husky(以 npm 项目为例):
npm install -D huskynpx husky init
husky init 会自动生成 .husky/pre-commit 文件,默认内容只有:
npm test
你可以根据项目需要编辑 .husky/pre-commit,增强 Hook 检查:
pytest tests/ -vflake8 src/ black --check src/
这样每次提交代码时,都会自动验证代码质量、测试通过率和类型安全。
第三步:验证测试套件
hot-trends 项目在前两篇文章中已经创建了完整的测试套件:
tests/├── test_fetcher.py ├── test_filter.py└── test_output.py
验证测试是否正常工作:
pytest tests/ -v
应该看到类似输出:
tests/test_fetcher.py::test_fetcher_initialization PASSED [7%]tests/test_fetcher.py::test_fetcher_with_custom_params PASSED [ 14%]tests/test_fetcher.py::test_fetch_hot_trends_success PASSED [ 21%]tests/test_fetcher.py::test_fetch_hot_trends_failure PASSED [ 28%]tests/test_filter.py::test_default_keywords PASSED[ 35%]tests/test_filter.py::test_custom_keywords PASSED [ 42%]tests/test_filter.py::test_is_ai_related_by_title PASSED[ 50%]tests/test_filter.py::test_is_ai_related_by_tags PASSED [ 57%]tests/test_filter.py::test_not_ai_related PASSED[ 64%]tests/test_filter.py::test_case_insensitive PASSED[ 71%]tests/test_filter.py::test_filter_articles PASSED [ 78%]tests/test_output.py::test_sa ve_json PASSED [ 85%]tests/test_output.py::test_sa ve_markdown PASSED [ 92%]tests/test_output.py::test_print_table PASSED [100%]============================================== 14 passed in 0.24s ===============================================
如果没有测试怎么办?
如果你的项目还没有测试,可以先创建一个简单的冒烟测试:
def test_smoke():"""冒烟测试 - 确保测试框架正常工作"""assert True
验证 Level 1 Harness
**完成以上三步后,即使有 CLAUDE.md,AI 也不会自动遵循 Harness 流程。**要让 AI 真正遵循 Harness 流程,需要:
- 1.在对话开始时明确声明 - 每次开始新任务时,主动说明将遵循 Harness Level 1 流程
- 2.使用技能系统 - 通过 Skill 工具调用相关的 Harness 规范
- 3.设置 Git Hooks - 在提交前强制检查是否遵循了流程
我们先用第一种方式在对话前声明(长期使用按第二种方式新增一个 Skill):
你:请按照 Harness Engineering Level 1 流程来完成这个任务:1. 先读取 CLAUDE.md 了解项目规范2. 查看相关代码和测试文件3. 先写测试(TDD)4. 实现功能5. 运行测试验证6. 更新文档任务:帮我优化输出格式,支持 CSV 导出AI:(Step 1: 读取上下文)✅ 已读取 CLAUDE.md 了解项目规范✅ 已查看 src/output.py、src/models.py、src/main.py✅ 已查看 tests/test_output.py 了解测试模式关键发现:- 现有输出格式:JSON、Markdown- OutputFormatter 类已有 sa ve_json() 和 sa ve_markdown() 方法- 测试使用 pytest fixtures 和 tmp_path- CLI 参数通过 argparse 解析(Step 2: 测试驱动开发 TDD)先编写测试用例(功能实现前):在 tests/test_output.py 中添加:```pythondef test_sa ve_csv(formatter, sample_articles, tmp_path):"""测试CSV导出"""filepath = str(tmp_path / "test.csv")formatter.sa ve_csv(sample_articles, filepath)assert os.path.exists(filepath)with open(filepath, 'r', encoding='utf-8-sig') as f:content = f.read()assert "排名,标题,作者,来源,链接,阅读量,点赞,评论,标签" in contentassert "GPT-4使用指南" in contentassert "张三" in contentassert "1" in contentassert "2000" in contentassert "掘金" in content```验证测试失败(TDD 原则):$ pytest tests/test_output.py::test_sa ve_csv -vFAILED - AttributeError: 'OutputFormatter' object has no attribute 'sa ve_csv'✅ 测试如预期失败,因为 sa ve_csv 方法还未实现(Step 3: 实现功能)在 src/output.py 中实现:1. 导入 csv 模块2. 新增 sa ve_csv() 方法 - 使用 utf-8-sig 编码确保 Excel 兼容 - CSV 列名使用中文 - 标签使用分号分隔3. 更新 format_output() 方法支持 CSV在 src/main.py 中更新 CLI 参数:- 更新 -o/--output 帮助文本- 在 -f/--formatchoices 中增加 'csv'- 更新帮助信息示例(Step 4: 验证测试)运行测试验证:$ pytest tests/test_output.py -vtests/test_output.py::test_sa ve_json PASSED [ 20%]tests/test_output.py::test_sa ve_markdown PASSED [ 40%]tests/test_output.py::test_print_table PASSED [ 60%]tests/test_output.py::test_sa ve_csv PASSED [ 80%]← 新增tests/test_output.py::test_format_output_with_csv PASSED [100%]← 新增$ pytest tests/ -vcollected 16 items... (所有测试通过)============= 16 passed in 0.25s ==============✅ 所有 16 个测试全部通过,包括新增的 2 个 CSV 测试实际运行 CLI 验证:$ python -m src.main -l 10 -o /tmp/test_ai_articles.csv -v? 开始抓取热榜...? 抓取掘金热榜...✅ 获取 10 篇掘金文章? 筛选出 5 篇AI相关文章✅ 已保存到: /tmp/test_ai_articles.csv✅ CSV 文件成功生成,包含完整的文章数据(Step 5: 更新文档)更新 CLAUDE.md:- 项目概述:增加 CSV 格式支持说明- 核心类描述:增加 CSV 输出- CLI 参数表格:增加 -f 参数说明✓ 任务完成!
关键点:AI 不再是“自由发挥”,而是基于明确的约束进行开发。这就是 Harness 的力量!
Level 1 效果对比
| 指标 | 无 Harness | 有 Harness |
|---|
| 代码风格一致性 | 60% | 95% |
| 测试覆盖率 | 65% | 88% |
| 文档同步率 | 50% | 90% |
| 返工率 | 30% | 8% |
关键改进:
- AI 不再“自由发挥”,而是基于明确约束开发
- 每次提交都自动验证,问题早发现早解决
- 项目长期保持健康状态
Level 2 Harness:动态约束与自动化
Level 2 在 Level 1 基础上增加 动态上下文 和 更多 Hook,让 AI 能感知项目实时状态。
增加动态上下文
动态上下文是指那些会随时间变化的项目状态信息,AI 需要了解这些实时信息才能做出更准确的决策。
静态上下文(不变或很少变化):├── CLAUDE.md← 项目约定、架构设计├── 代码规范← 命名规则、代码风格└── 目录结构← 文件组织方式动态上下文(经常变化):├── Git 分支← 当前在哪个分支├── 修改的文件← 哪些文件被改动了├── 测试状态← 测试是否通过├── 依赖版本← 安装了哪些包└── 运行环境← Python/Node 版本等
创建脚本自动生成项目当前状态信息,让 AI 了解实时环境:
#!/bin/bashecho "# 项目动态上下文" > CONTEXT.mdecho "" >> CONTEXT.mdecho "生成时间: $(date)" >> CONTEXT.mdecho "" >> CONTEXT.mdecho "## Git 状态" >> CONTEXT.mdecho "- 当前分支: $(git branch --show-current)" >> CONTEXT.mdecho "- 最后提交: $(git log -1 --oneline 2>/dev/null || echo '无')" >> CONTEXT.mdecho "- 未提交修改:" >> CONTEXT.mdgit status --short 2>/dev/null | sed 's/^/- /' >> CONTEXT.mdecho "" >> CONTEXT.mdecho "## 测试状态" >> CONTEXT.mdif pytest tests/ -q --tb=no 2>/dev/null; thenecho "- 测试结果: ✅ 全部通过" >> CONTEXT.mdelseecho "- 测试结果: ❌ 有失败的测试" >> CONTEXT.mdfiecho "" >> CONTEXT.mdecho "## 环境信息" >> CONTEXT.mdecho "- Python 版本: $(python --version 2>&1)" >> CONTEXT.mdecho "- 已安装包:" >> CONTEXT.mdpip list 2>/dev/null | head -10 | sed 's/^/- /' >> CONTEXT.md
在 CLAUDE.md 中添加:
## 动态上下文在执行任何任务前,先运行 `scripts/generate_context.sh` 生成最新的 CONTEXT.md,然后读取它了解项目当前状态。
好处:AI 能感知 Git 分支、修改文件、测试状态等动态信息,做出更准确的决策。
增加 Hook 种类
Pre-commit Hook 增强:添加更智能的检查逻辑
#!/usr/bin/env shCHANGED=$(git diff --cached --name-only)if echo "$CHANGED" | grep -q "src/fetchers/"; thenecho "⚠️修改了数据抓取器,请确认:"echo "1. 是否需要更新对应的测试?"echo "2. 是否需要更新 API 文档?"finpm testnpm run lint
其他可选 Hook:
- pre-push: 推送前运行完整测试套件
- commit-msg: 验证提交信息格式(如约定式提交)
- post-merge: 合并后自动安装依赖
实际效果:当你在 hot-trends 中修改 src/fetchers/zhihu.py 时,Hook 会提醒你检查测试和文档。
Level 3 Harness:完整工程化体系
Level 3 是企业级的 Harness,适用于团队协作和大型项目。对于 hot-trends 这样的单人项目,可以根据需要选择性采用。
1. 多层约束
企业级 Harness 层级
| 层级 | 说明 |
|---|
| L1: 企业规范 | 所有项目共享 |
| L2: 团队规范 | 团队内共享 |
| L3: 项目规范 | 项目特有 |
| L4: 模块规范 | 模块级别 |
示例:
- L1: 公司要求所有项目使用 TypeScript strict mode
- L2: 前端团队统一使用 React + Vite
- L3: hot-trends 项目使用特定的目录结构(见 CLAUDE.md)
- L4: fetchers 模块有特殊的安全要求(如 API key 管理)
2. 纵深防御
通过多层验证确保代码质量:
| 层级 | 说明 |
|---|
| 第1层 | CLAUDE.md 静态约束 |
| 第2层 | 测试套件验证边界 |
| 第3层 | Pre-commit Hook 检查 |
| 第4层 | CI/CD 自动验证 |
| 第5层 | Code Review 最终把关 |
原理:每一层都有机会发现问题,越早发现成本越低。
hot-trends 实践:
- 第1层:CLAUDE.md 规定 fetcher 不能混入过滤逻辑
- 第2层:单元测试验证每个模块功能
- 第3层:Hook 在提交前自动运行 lint 和 test
- 第4层:GitHub Actions CI 流程(可选)
- 第5层:如果是团队项目,可以设置 PR 审查
3. 熵管理流程
建立定期检查机制,防止系统逐渐混乱:
# 每周熵管理 Checklist## 代码质量- [ ] 运行 `npm run lint` 检查代码风格- [ ] 运行 `npm test` 检查测试通过率- [ ] 检查是否有新的 TODO 注释## 文档同步- [ ] 检查 CLAUDE.md 是否需要更新- [ ] 检查 README 是否过时- [ ] 检查 CHANGELOG 是否遗漏## 依赖管理- [ ] 运行 `npm outdated` 检查过期依赖- [ ] 运行 `npm audit` 检查安全漏洞
熵增的表现:
- 代码风格不一致(如有的地方用 var,有的用 const)
- 目录结构混乱(如在 src/ 根目录直接放文件)
- 测试覆盖率下降(新增代码没有测试)
- 文档过时(README 中的使用说明与实际不符)
建议:对于 hot-trends 这样的个人项目,可以每月进行一次熵管理检查。
常见问题
Q1:Harness 会不会限制 AI 的创造力?
答案:不会。
Harness 约束的是边界,不是方法。
约束:使用 TypeScript strict modeAI 仍然自由:选择算法、设计模式、实现细节约束:测试覆盖率 > 80%AI 仍然自由:测试怎么写、测什么约束:代码风格统一AI 仍然自由:逻辑实现方式
Q2:CLAUDE.md 写多少合适?
答案:刚好够用。
太少:AI 还是自己猜太多:没人看,变成形式主义刚好:覆盖核心决策点
建议:
- 项目概述:50-100字
- 技术栈:列出主要技术
- 目录结构:核心目录即可
- 代码规范:5-10条核心规则
- 质量要求:可量化的指标
Q3:和 Superpowers / OpenSpec 的关系?
OpenSpec → 定义「做什么」(需求约束)Superpowers→ 定义「怎么按流程做」(流程约束)Harness→ 定义「如何确保可控」(行为约束)
三者结合 = 完整的 AI 编程工程化体系
我们会在下一篇「铁三角导论」中详细讲解。
下一步
你已经学会了 Harness Engineering 的基本概念和实践,知道它如何给 AI 套上缰绳。
到此为止,你已经认识了「铁三角」的三个工具:
1. Superpowers → 流程约束 ✅
2. OpenSpec → 需求约束 ✅
3. Harness Engineering → 行为约束 ✅
下一篇,我们来讲 铁三角导论:三层架构设计,揭示三者如何协同工作。
扩展阅读
- Claude Code 官方文档
- CLAUDE.md 最佳实践
- Git Hooks 原理