Harness Engineering 入门教程(四):从零搭建你的第一个 Harness
约 8 分钟2206 字0 次阅读

Harness Engineering 入门教程(四):从零搭建你的第一个 Harness
引言
前三篇我们学了概念、技术原理和架构设计。这一篇是实战——从零搭建你的第一个 Harness。
不追求一开始就搭完整六层。从 P0(立即可做、投入产出比最高)开始,然后逐步进阶。
一、环境准备
1.1 选择你的第一个 Agent
| Agent | 特点 | 适合人群 |
|---|---|---|
| Claude Code | Anthropic 官方,深度集成 Claude 模型 | 已在用 Anthropic 模型 |
| OpenCode | 开源,多模型支持,社区活跃 | 喜欢开源、想自己定制 |
| OpenClaw | 多渠道接入(飞书/Telegram),Skills 系统 | 需要接入国内 IM 工具 |
| Cursor | IDE 集成,协作功能强 | 喜欢 IDE 环境 |
建议新手从 Claude Code 或 OpenCode 开始,文档最完善,社区最大。
1.2 基础环境检查
# Node.js(Claude Code 需要)
node --version # 需要 18+
# Git(版本控制必须)
git --version
# 你的 API Key
# OpenAI / Anthropic / OpenRouter
二、P0 级:立即可以做的三件事
2.1 创建 AGENTS.md
AGENTS.md 是 Harness 的入口文件。每次 Agent 启动时自动加载。
第一步:放在仓库根目录
touch AGENTS.md
第二步:写什么?
❌ 错误写法:把 AGENTS.md 当成超级 System Prompt,把所有规则都塞进去。
结果:上下文被撑爆,Agent 反而更蠢。
✅ 正确写法:AGENTS.md 当目录用,约 100 行,指向深层文档。
# AGENTS.md — 入口文件
## 角色
你是一个 [你的技术栈] 工程师,专注于 [领域]。
## 项目结构
- `src/` — 源代码
- `tests/` — 测试文件
- `docs/` — 文档
## 开发约定
- 代码风格:见 `.eslintrc`
- 提交规范:见 `CONTRIBUTING.md`
- API 设计原则:见 `docs/api-guidelines.md`
## 当前任务状态
[每次开始新任务时更新此section]
## 近期常见错误
[每次 Agent 犯错后,在这里加一条规则]
第三步:渐进式披露
把详细规则放在子文档里:
project/
├── AGENTS.md # 入口,约100行
├── docs/
│ ├── api-guidelines.md # API设计详细规范
│ ├── testing-guide.md # 测试规范
│ └── style-guide.md # 代码风格详细说明
└── .claude/
└── settings/ # Agent 配置
2.2 构建自定义 Linter
为什么 Linter 是最好的起点?
- Computational(确定性强)——结果可预测
- Fast(毫秒级)——每次变更都能跑
- 直接告诉 Agent 错在哪里、怎么改
OpenAI 的 Linter 设计原则:
报错消息里不光告诉你哪里错了,还直接告诉你怎么改。Agent 在被纠错的同时就被"教会"了正确的做法。
示例:自定义架构 Linter
假设你的项目有分层架构规范:Controller → Service → Repository
# linters/arch_check.py
"""检查Controller不直接调Repository"""
import ast
import sys
class ArchViolation(ast.NodeVisitor):
def __init__(self, filename):
self.filename = filename
self.violations = []
def visit_Call(self, node):
# 检查是否是 Repository 类的调用
if isinstance(node.func, ast.Attribute):
if node.func.attr.endswith('Repository'):
# 确认调用者不是 Service
context = getattr(self, 'current_class', '')
if context and not context.endswith('Service'):
self.violations.append(
f"{self.filename}:{node.lineno}: "
f"Repository直接调用发生在非Service层。"
f"应通过Service间接调用。"
)
self.generic_visit(node)
在 pre-commit hook 中运行:
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: architecture-check
name: Architecture Linter
entry: python linters/arch_check.py
language: system
files: src/.*\.py$
2.3 把团队知识放进仓库
核心原则:写在 Slack 或 Google Docs 里的知识,对 Agent 来说等于不存在。
所有 Agent 需要知道的东西,必须作为版本控制的制品放在仓库里:
project/
├── AGENTS.md
├── docs/
│ ├── onboarding.md # 新人上手指南
│ ├── architecture.md # 架构文档
│ └── runbooks/ # 运维手册
├── scripts/
│ └── setup.sh # 环境搭建脚本
└── .env.example # 环境变量示例
反面教材:
"Slack 上讨论过这个服务用 Redis 做缓存,文档存在 Notion 里"
→ Agent 完全不知道这条信息。
正确做法:
"把 Slack 讨论结论写成 runbook 放进
docs/runbooks/cache-strategy.md"
→ Agent 每次启动都能读到。
三、P1 级:做好之后可以考虑的
3.1 分层管理上下文
当 AGENTS.md 开始变长时,把它拆分成多个文件:
# AGENTS.md(主入口)
## 项目概览
[50行项目基本信息]
## 开发指南
详见 [docs/dev-guide.md](docs/dev-guide.md)
## 测试要求
详见 [docs/testing.md](docs/testing.md)
## 近期变更
详见 [.claude/changelog.md](.claude/changelog.md)
3.2 建立进度追踪文件
Anthropic 的做法:
# progress.md
## 当前任务
- 用户认证模块重构
## 已完成
- [x] 设计认证流程
- [x] 实现 JWT 生成
- [ ] 实现 Refresh Token 轮转
## 障碍
- 暂无
## 下一步
1. 实现 Refresh Token 过期逻辑
2. 添加单元测试
Agent 每轮开始时读取,完成后更新。这样即使上下文重置,也能从文件恢复。
3.3 给 Agent 端到端验证能力
Anthropic 在实践中集成了 Playwright MCP——让 Agent 能够:
- 启动浏览器
- 导航到页面
- 点击按钮
- 验证页面内容
# 安装 Playwright MCP
npx @anthropic/mcp-server playwight
这样 Agent 不只"写代码",还能"验证代码是否真的解决了问题"。
四、创建第一个 Skill
4.1 Skill 的标准结构
my-skill/
├── SKILL.md # 必须:触发条件和核心指令
├── scripts/ # 可选:确定性逻辑
│ └── do_something.py
└── references/ # 可选:详细文档
└── api_docs.md
4.2 SKILL.md 怎么写
---
name: code-review
description: 代码审查Skill。当用户说"审查这段代码"、"帮我review"、"检查有没有bug"时触发。
---
# Code Review Skill
## 快速用法
用 `scripts/review.py`:
```bash
python scripts/review.py --file <文件路径>
检查项
- 安全性:SQL注入、XSS、凭证泄露
- 错误处理:所有外部调用是否try-catch
- 测试覆盖:核心逻辑是否有测试
输出格式
## 发现的Issue
1. [严重] 第23行:直接拼接SQL
2. [中等] 第45行:缺少超时处理
## 建议
1. 使用参数化查询
2. 添加 30s 超时
注意事项
- 只检查已明确标记的文件
- 不自动修改代码,只报告问题
### 4.3 Description 是关键
**Description 决定什么时候触发这个 Skill**。
好例子:
```yaml
description: 代码审查。当用户说"审查这段代码"、"帮我review"、"检查有没有bug"、"review PR"时触发。
坏例子:
description: 这个Skill可以审查代码,支持多种检查。
(坏在哪里:没有触发场景,Agent 不知道什么时候该用它)
五、P2 级:有余力再考虑
5.1 Agent 专业化分工
Carlini 在编译器项目中的做法:
- 去重 Agent:专门检测并删除重复代码实现
- 优化 Agent:专门做性能优化
- 文档 Agent:专门补文档
- 核心 Agent:做主要开发
每个 Agent 只处理一件事,上线时按需调用。
5.2 定期垃圾回收
OpenAI 的实践:
一开始每周花 20% 时间手动清理 AI 生成的低质量代码。后来自动化了——后台 Agent 定期扫描文档不一致、架构违规、冗余代码,自动提交清理 PR。
没有清理,熵会积累——AI 生成的代码质量会逐渐下降。
5.3 可观测性集成
把 Chrome DevTools Protocol 接入 Agent 运行时:
- Agent 能自己抓 DOM 快照
- 自己截图
- 自己量性能指标
这样"把启动时间降到 800ms"就从模糊愿望变成了 Agent 可以自己测量、验证的目标。
六、自检清单
你的第一个 Harness 达到什么水平了?
| Level | 特征 | 检查项 |
|---|---|---|
| Level 0 | 无 Harness | □ 没有 AGENTS.md |
| Level 1 | 基础约束 | □ AGENTS.md 已创建 □ 自定义 Linter 已配置 □ 团队知识已进仓库 |
| Level 2 | 反馈回路 | □ CI/CD 集成 □ 自动化测试 □ 进度追踪文件 |
| Level 3 | 专业化 | □ Skill 已创建 □ 上下文分层管理 □ Agent 分工 |
总结:从 P0 开始,不要追求完美
第一件事:创建 AGENTS.md,把它当目录而不是手册
第二件事:写一个自定义 Linter,让错误消息带修复指引
第三件事:把团队知识从 Slack 搬进仓库
之后:根据需要逐步添加进度追踪、技能分工、熵管理。
记住 Mitchell Hashimoto 的话:
"每一行 AGENTS.md 对应一个历史失败案例。这不是写完就扔的静态文档,是一个持续积累的防错系统。"
标签:#AI #Agent #HarnessEngineering #入门教程 #AGENTS.md #Skill