Harness Engineering 实战:用 Claude Code 搭建 AI 编程驾驭系统

Harness Engineering 实战:用 Claude Code 搭建 AI 编程驾驭系统

上一篇我们讲了 Harness Engineering 的概念——AI Agent = 模型 + Harness。概念懂了,但怎么落地?

这篇文章用一个真实的 AI 编程工具 Claude Code,手把手带你搭建一套完整的 Harness 系统。学完之后,你不仅能用在 Claude Code 上,这套思路也适用于 Cursor、OpenAI Codex、Windsurf 等任何 AI 编程工具。

为什么选 Claude Code 做实战?

三个理由:

  1. 它是 Harness Engineering 的标杆产品 — Claude Code 的设计理念完美体现了 Harness 的 6 个原则
  2. 它是免费的 — 读者可以零成本跟着操作
  3. 它是终端工具 — 没有 GUI 干扰,Harness 的配置更透明,更容易理解

如果你还没用过 Claude Code,建议先读我们的 Claude Code 从安装到精通 再回来。

前置准备

确认已安装 Claude Code:

claude --version
# 输出: Claude Code 2026.x.x

# 如果没有,安装:
npm install -g @anthropic-ai/claude-code

进入你的项目目录:

cd your-project
claude

原则一实战:明确边界 —— 写一份 CLAUDE.md

CLAUDE.md 就是 Claude Code 的"入职须知"。它放在项目根目录,Claude Code 每次启动都会自动加载。

基础模板

在项目根目录创建 CLAUDE.md

# 项目概述
这是一个 React + TypeScript 的电商前端项目,使用 Vite 构建,Tailwind CSS 样式。

## 技术栈
- 框架: React 18 + TypeScript 5
- 构建: Vite 5
- 样式: Tailwind CSS 3
- 路由: react-router-dom v6
- 状态管理: Zustand

## 代码规范
- 使用 ESModule 导入,不使用 require
- 组件用函数式组件 + hooks,不用类组件
- 命名:组件 PascalCase,工具函数 camelCase
- 每个组件文件不超过 200 行
- 注释用英文,代码中的用户可见文字用中文

## 禁区(红线规则)
- 不要修改 package.json 中的依赖版本
- 不要直接修改 node_modules 中的任何文件
- 不要修改 vite.config.ts,除非用户明确要求
- 不要直接推送到 main/master 分支
- 不要修改 .env 系列文件

## 操作规范
- 修改代码前先阅读相关文件,理解上下文
- 每次修改前说明你打算改什么
- 修改完成后运行 `npm run typecheck` 确认类型检查通过
- 优先使用项目已有的组件和工具函数,不要重复造轮子

## 验证要求
- 改完代码后运行 `npm run build` 确认构建通过
- 如果有测试,运行 `npm run test` 确认测试通过
- 说明你做了什么验证,以及结果如何

关键要素解析

这份 CLAUDE.md 包含了四类规则,缺一不可:

规则类型 作用 示例
项目概述 让 AI 知道这是什么项目 技术栈、项目定位
代码规范 让 AI 写出风格一致的代码 命名规则、文件长度限制
禁区 告诉 AI 哪些事不能做 不推主分支、不改依赖版本
操作规范 告诉 AI 做事的流程 先说明再改、改完跑检查

经验之谈CLAUDE.md 不要太长。超过 200 行之后,AI 的注意力会明显下降。把核心规则放在前面,详细规范可以拆分到 docs/ 目录里按需加载。

原则二实战:精准信息 —— 分层加载上下文

Claude Code 的上下文加载是分层的,理解这个机制才能用好它:

┌─────────────────────────────────┐
│  系统提示词(System Prompt)     │ ← Claude Code 内置,用户不可控
├─────────────────────────────────┤
│  CLAUDE.md(项目级规范)         │ ← 你写的,每次对话自动加载
├─────────────────────────────────┤
│  对话历史(当前会话)            │ ← 自动管理,旧内容会被压缩
├─────────────────────────────────┤
│  工具返回结果(文件内容等)      │ ← AI 主动读取,按需加载
└─────────────────────────────────┘

实战技巧

  1. CLAUDE.md 当"索引"而非"百科全书" — 只放核心规则和项目概览,详细文档放到 docs/ 里让 AI 按需读取
  2. @import 引用外部文件 — Claude Code 支持在 CLAUDE.md 中引用其他文件,可以按模块拆分规则
  3. 定期清理对话 — 用 /compact 命令压缩旧上下文,保持工作区整洁
# CLAUDE.md 中使用引用拆分

## 核心规则(始终加载)
- 不推主分支
- 不改依赖版本
- 先说明再改

## 详细规范(按需参考)
- 组件规范: 参考 docs/component-guide.md
- API 规范: 参考 docs/api-conventions.md
- 测试规范: 参考 docs/testing-guide.md

原则三实战:合理权限 —— 沙箱与工具控制

Claude Code 提供了细粒度的权限控制。在项目根目录创建 .claude/settings.json

{
  "permissions": {
    "allow": [
      "Read",
      "Glob",
      "Grep",
      "Edit",
      "Write",
      "MultiEdit"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Bash(sudo *)",
      "Bash(git push *)",
      "Bash(npm publish *)",
      "Bash(npm version *)",
      "WebFetch"
    ],
    "ask": [
      "Bash(git *)",
      "Bash(npm run *)",
      "Bash(npx *)"
    ]
  }
}

权限分三层

权限级别 含义 适用操作
allow 自动放行,不需要确认 读文件、搜索、编辑代码
deny 直接拒绝,不允许执行 删除文件、推代码、发布包
ask 每次执行前询问你 git 命令、npm 命令、网络请求

配置思路

  • 读操作全部 allow(看文件不会闯祸)
  • 写代码操作 allow(这是 AI 的核心任务)
  • 删除/推代码/发布全部 deny(不可逆操作)
  • git/npm 命令设为 ask(需要人工判断)

这样配置后,Claude Code 可以自由地读写代码,但每次执行 git 命令或 npm 命令前都会先问你,既保证了效率又控制了风险。

原则四实战:流程编排 —— 用子 Agent 拆分任务

Claude Code 内置了子 Agent 机制,可以把复杂任务拆分给多个 Agent 并行执行。

场景:重构用户模块

假设你要重构一个用户模块,涉及 5 个文件。不要一次性让 AI 改所有文件:

错误做法

帮我重构用户模块的所有代码

正确做法

帮我重构用户模块,按以下步骤执行:
1. 先阅读 src/models/user.ts 和 src/api/user.ts,理解现有结构
2. 提出重构方案,等我确认后再动手
3. 按以下顺序逐个修改:
   a. 数据模型层 (models/)
   b. API 层 (api/)
   c. 组件层 (components/)
   d. 路由配置 (router/)
   e. 测试文件 (__tests__/)
4. 每改完一层,运行 typecheck 确认无误

使用 Plan 模式

Claude Code 有个 Plan 模式,先规划再执行:

# 进入 Plan 模式
> /plan

# Claude Code 会先列出计划,等你确认后才动手

这个模式的价值:在执行之前给你审查和纠偏的机会,避免 AI 一上来就跑偏。

原则五实战:独立验证 —— 不让 AI 自己判自己

这是最容易被忽略但最关键的原则。AI 写完代码后,必须用独立的机制验证。

方案一:让 Claude Code 跑测试

CLAUDE.md 中加入验证规范:

## 验证清单
每次修改代码后,必须执行以下验证:
1. `npm run typecheck` — TypeScript 类型检查
2. `npm run lint` — ESLint 代码检查
3. `npm run test -- --coverage` — 单元测试 + 覆盖率
4. `npm run build` — 构建验证

如果任何一步失败,分析错误原因并修复,不要跳过。

方案二:配置 Pre-commit Hook

使用 husky + lint-staged 在提交前自动验证:

# 安装
npm install -D husky lint-staged

# 初始化
npx husky init

# .husky/pre-commit
npx lint-staged
// package.json 中添加
{
  "lint-staged": {
    "*.{ts,tsx}": ["eslint --fix", "prettier --write"],
    "*.{css,json}": ["prettier --write"]
  }
}

这样即使 AI 忘了跑测试,提交时也会被自动拦截。

方案三:写测试用例让 AI 通过

CLAUDE.md 中要求:

## 测试要求
- 每次新增功能必须包含对应的单元测试
- 测试文件放在 __tests__ 目录下
- 测试用例要覆盖正常路径和异常路径
- 修改代码后所有测试必须通过

核心思路:把验证标准写成文字,让 AI 自己证明自己是对的,而不是靠你人工检查。

原则六实战:容错机制 —— 让错误可恢复

AI 会犯错,关键是犯错后能快速恢复。

技巧一:善用 Git 分支

CLAUDE.md 中强制要求:

## 分支规范
- AI 的所有修改必须在分支上进行
- 分支命名: ai/功能描述
- 修改完成后不自动合并,等用户手动确认

这样即使 AI 改坏了,一个 git checkout main 就能恢复。

技巧二:用 /compact 控制上下文

长对话中 AI 可能会"忘记"前面的内容。用 /compact 命令压缩上下文:

/compact
# Claude Code 会把之前的对话压缩成摘要

什么时候该 compact

  • 对话超过 20 轮之后
  • 切换到不相关的任务时
  • AI 开始重复问你已经说过的问题时

技巧三:断点续传

如果 AI 的输出被截断(Claude Code 有输出长度限制),用以下方式续写:

继续
# 或
从上次中断的地方继续完成

Claude Code 会从上次的进度继续。

技巧四:紧急停止

Escape 可以立即停止 AI 当前的工具调用。如果 AI 正在批量修改文件时跑偏了,连按两次 Escape 可以完全中断。

完整配置汇总

把上面所有配置汇总,一个完整的 Claude Code Harness 系统长这样:

your-project/
├── CLAUDE.md                    # 原则一:明确边界
├── .claude/
│   └── settings.json           # 原则三:权限控制
├── .husky/
│   └── pre-commit              # 原则五:独立验证
├── docs/
│   ├── component-guide.md      # 原则二:分层信息
│   ├── api-conventions.md
│   └── testing-guide.md
├── package.json                # lint-staged 配置
└── src/

CLAUDE.md 核心模板(可直接复制使用):

# 项目概述
[一句话描述项目是什么]

## 技术栈
[列出核心依赖和版本]

## 代码规范
[3-5 条最关键的规则]

## 禁区(绝对不能做的事)
- [规则1]
- [规则2]
- [规则3]

## 操作规范
1. 修改前先阅读相关文件
2. 说明修改计划,等确认后动手
3. 改完运行 typecheck + lint + test
4. 在分支上修改,不直接操作 main

## 验证清单
- [ ] TypeScript 类型检查
- [ ] ESLint 检查
- [ ] 单元测试
- [ ] 构建验证

## 分支规范
- 所有修改在 ai/ 前缀的分支上进行
- 不自动合并,等用户确认

一句话总结

Harness Engineering 不是某个具体的功能,而是一种设计思维——在 AI 能干活之前,先设计好怎么约束它、引导它、验证它、容错它。用 CLAUDE.md 写清边界,用权限控制保障安全,用独立验证确保质量,用 Git 分支兜底容错。四件套齐了,你的就从"用 AI 写代码"升级成了"驾驭 AI 写代码"。


下一篇预告:《Harness Engineering 行业对比:Claude Code vs OpenAI Codex vs Cursor》——三大 AI 编程工具的 Harness 设计横向测评,看看谁的驾驭系统更完善。