Harness Engineering:2026年顶级AI工程师停止写代码的真相——从百万行代码实验到五大核心制品全解析
2026年2月,OpenAI一个小团队交付了100万行生产代码。没有一行是手写的。人类做的事情,是设计一套让AI Agent变得可靠的环境系统——这套系统现在有了名字:Harness Engineering。
一、背景:为什么2026年所有人都在谈Harness
如果你在过去一年里用过AI编码助手(Claude Code、Cursor、Copilot、Codex),大概率经历过这样的崩溃时刻:
- 让AI改一个按钮颜色,它直接把整个页面布局重写了
- 明明说了「单文件不超过200行」,几轮对话后AI写了个1000行的巨无霸
- 让AI修一个Bug,结果修出了三个新Bug
- 跑了一晚上Agent,第二天发现它在一个循环里打了6小时转
这些问题在过去一年里被反复讨论。大多数人的解法是:换一个更强、更贵的模型。
但2026年的数据告诉我们,这是一个方向性错误。
一个研究者对同一个AI模型、同一套测试基准做了两次实验。唯一不同的,是模型周围的Harness(缰绳系统)。
- 第一次得分:42%
- 第二次得分:78%
同一模型,36个百分点的差距,全部来自Harness。
LangChain在行业标准测试Terminal Bench 2.0上,用同样的模型,只是换了Harness,从30名开外跃升至前5名。
OpenAI的Codex团队用这套方法论,仅凭3人团队、0行手写代码、5个月时间,交付了超过100万行生产代码。
这意味着什么?
2026年,AI编程的瓶颈从来不在模型,而在你围绕模型搭建的那套「缰绳」够不够好。
二、核心概念:什么是Harness Engineering
2.1 最简洁的定义
ThoughtWorks给出了一个精准的公式:
Agent = Model + Harness
Harness是除了模型之外的一切:
- 约束Agent不跑偏的规则
- 捕捉错误的反馈回路
- 告诉Agent当前处境的文档
- 它被允许使用的工具
去掉Harness,模型只能在代码库里瞎摸。加上合适的Harness,它就成了一个能交付生产代码的系统。
2.2 马具的隐喻
这个名字来自马具(Harness)。
一匹马强壮但不可预测。没有缰绳、鞍和嚼子,它想去哪就去哪。骑手的核心工作不是让马变聪明,而是通过装备设计让马的力量变得可控。
AI Agent也是一样。模型很强大,但没有合适的Harness,它会:
- 按自己的理解随意修改文件
- 在同一个地方反复犯同样的错误
- 上下文窗口耗尽后无声地丢弃需求
- 产出的代码在本地能跑,上线就炸
Harness Engineering的目标,就是成为那套「缰绳+鞍+嚼子」。
2.3 操作系统类比:最精准的技术比喻
Hugging Face的Philipp Schmid给出了一个绝妙的技术类比:
| 传统系统 | AI Agent系统 |
|---|---|
| CPU(原始算力) | Model(原始推理能力) |
| 内存(有限的、易失的工作内存) | 上下文窗口(有限的、易失的工作区) |
| 操作系统(管理CPU看到什么、什么时候看到) | Harness(管理模型的行为边界) |
| 运行在上面的应用 | Agent(最终交付产物的载体) |
模型很强大,但如果没有操作系统来管理内存、调度任务、执行规则,它就只是一块硅片。
大多数人在用Agent时,实际上缺少这样一个「操作系统层」——这也是为什么很多Agent在生产环境中不稳定。
三、2026年的关键实验:数据说话
3.1 OpenAI的百万行代码实验
2026年2月,OpenAI的Codex团队面临一个现实挑战:需要快速交付Sora Android应用,团队规模有限。
他们的解法不是雇更多人或换更强模型,而是设计了一套严格的Harness:
- 严格的依赖流规则:Types → Config → Repo → Service → Runtime → UI,每层只能依赖下层
- 分布式的AGENT.md文件:在代码库各角落嵌入AI引导文档
- Agent直连CI/CD:每次提交自动触发完整测试流水线
- JSON特性追踪器:跨会话记录每个特性的完成状态
结果:
- 4名工程师,28天,Play Store排名第一
- 崩溃率低于0.1%
- Codex每周处理70%的内部Pull Request
- 全程0行手写代码
3.2 Anthropic的三Agent架构实验
Anthropic遇到了另一个问题:当Agent评估自己的产出时,它倾向于给自己打高分——即使质量明显不达标。
自我评估行不通。Agent同时充当学生和老师,缺乏客观性。
他们的解法是三个专业化Agent:
┌─────────────────────────────────────────┐
│ Sprint 规划阶段 │
│ ┌──────────┐ ┌──────────┐ │
│ │ Planner │→ │Evaluator │→ 达成契约 │
│ │ (规划者) │ │ (评审者) │ │
│ └──────────┘ └──────────┘ │
│ ↑ ↑ │
│ 人类审查确认 ← 契约 ← 人类审查确认 │
└─────────────────────────────────────────┘
↓ 契约锁定
┌─────────────────────────────────────────┐
│ Sprint 执行阶段 │
│ ┌──────────┐ ┌──────────┐ │
│ │Generator │→ │Evaluator │→ 产出代码 │
│ │ (生成者) │ │ (评审者) │ │
│ └──────────┘ └──────────┘ │
└─────────────────────────────────────────┘
- Planner:把两句话的提示词展开成完整的产品规格
- Generator:每个sprint实现一个特性
- Evaluator:用浏览器自动化测试运行中的应用,像真实用户一样操作
关键洞察:让一个独立的评估者变得严格,远比让生成者对自己的工作保持批判要容易得多。
效果对比(Anthropic A/B测试真实数据):
| 方案 | 成本 | 耗时 | 结果 |
|---|---|---|---|
| 无Harness单Agent | $9 | 20分钟 | UI可用,但核心功能有缺陷 |
| 完整Harness(3-Agent) | $200 | 6小时 | 功能完备,UI精致,业务逻辑正确 |
22倍的成本差距,换来的是一个真正可交付的产品,而不是只在截图里好看的demo。
3.3 LangChain的Terminal Bench逆袭
LangChain在Terminal Bench 2.0上用同一个模型跑了两次:
- 旧Harness:52.8分(30名开外)
- 新Harness:66.5分(前5名)
唯一的区别就是Harness设计。
3.4 Vercel的减法哲学
Vercel走了相反的方向——他们砍掉了Agent 80%的工具。
结果性能反而更好了。
这个发现很反直觉,但道理很简单:工具越多,Agent越容易陷入「工具选择瘫痪」,在决策上消耗的token比实际工作还多。
四、五大核心制品:Harness的具体构建块
4.1 制品一:AGENT.md / CLAUDE.md(上下文引导文件)
最通用、最容易上手的Harness制品。
这是分布在代码库各处的Markdown文件,Agent在每次会话开始时读取它们,就像新工程师入职时的引导文档。
# AGENT.md - 项目AI助手指南
## 技术栈
- 后端:Go 1.24 + GORM
- 前端:React 18 + TypeScript 5
- 数据库:PostgreSQL 17
- 部署:Docker + K8s
## 编码规范
- 单文件不超过200行
- 错误必须返回,panic只用于不可恢复场景
- 所有公共API必须有单元测试覆盖
- 提交前必须运行 `make lint && make test`
## 架构决策记录
- 使用六边形架构(Ports & Adapters)
- 数据库迁移使用 golang-migrate,不允许手动DDL
- API版本管理:/api/v1/* 前缀
## 当前进行中的工作
- 用户权限模块重构(进行中,预计本周完成)
- 不要修改 auth/ 目录下的文件(稳定区)
## 硬规则
- 禁止删除文件(只允许归档到 archived/ 目录)
- 禁止修改 .env 文件(配置变更走 ConfigMap)
- 所有数据库操作必须在事务中
核心原则(来自ETH Zurich对138个仓库的研究):
- 保持简短:60行以内。超过这个长度,Agent开始忽略它
- 只写通用规则:不要列目录(Agent可以自己发现)
- 不要条件规则:「如果做X则Y」会让Agent困惑
- 人类写,不要AI生成:研究发现AI生成的AGENT.md实际上会降低性能,且多消耗20%的token
4.2 制品二:JSON特性列表(进度追踪器)
当Agent跨多个会话构建一个完整应用时,每次会话的上下文窗口都是空白的。Agent怎么知道哪些已经做完了?
靠一个JSON文件。
{
"project": "电商后端API",
"version": "2.1.0",
"lastUpdated": "2026-08-15T10:30:00Z",
"features": [
{
"id": "auth-jwt",
"name": "JWT认证",
"status": "done",
"verifiedAt": "2026-08-10",
"verificationMethod": "e2e tests passed"
},
{
"id": "product-crud",
"name": "商品CRUD",
"status": "done",
"verifiedAt": "2026-08-12",
"verificationMethod": "api tests passed"
},
{
"id": "order-state-machine",
"name": "订单状态机",
"status": "in_progress",
"startedAt": "2026-08-14",
"blockers": ["payment-webhook integration not ready"],
"acceptanceCriteria": [
"pending→paid transition works",
"paid→shipped transition works",
"cancelled refunds inventory"
]
},
{
"id": "inventory-reservation",
"name": "库存预占",
"status": "todo",
"priority": "high",
"dependsOn": ["order-state-machine"]
}
]
}
Agent的会话启动序列:
1. 读取 progress.json
2. 找到 status="in_progress" 且无blockers 的特性
3. 读取该特性的 acceptanceCriteria
4. 实现功能
5. 运行验证
6. 更新 status="done" + verifiedAt
7. 提交代码
为什么用JSON而不是Markdown? Anthropic发现Agent意外覆盖JSON的概率比Markdown低得多。这在小细节,但在6小时无人值守运行中,这类差异的累积影响相当可观。
4.3 制品三:会话初始化例程(Session Init)
每次会话都用同样的方式启动。每一次都是。
Anthropic的7步启动序列:
# session_init.py - 每个Agent会话的第一个动作
def session_init():
# Step 1: 确认工作目录
current_dir = verify_workspace()
# Step 2: 读取 git 日志和进度文件
git_log = run("git log --oneline -20")
progress = read_json("progress.json")
# Step 3: 找到优先级最高的未完成项
next_feature = find_next_feature(progress)
# Step 4: 启动开发服务器(如果需要)
if needs_dev_server(next_feature):
start_dev_server()
# Step 5: 运行基础端到端验证
baseline = run_e2e_check()
if baseline != "passing":
log(f"⚠️ 基线检查未通过: {baseline}")
# 记录但不阻塞
# Step 6: 实现一个特性
implement_feature(next_feature)
# Step 7: 提交并更新进度
commit_with_description(next_feature)
update_progress(next_feature, "done")
没有这套流程,Agent需要花前20分钟搞清楚当前状态。有了它,Agent立刻进入工作状态。
4.4 制品四:Sprint契约(Sprint Contract)
在Agent写任何代码之前,先由两个Agent协商。
┌──────────────────────────────────────────────────────┐
│ Sprint 契约协商 │
│ │
│ Generator Agent Evaluator Agent │
│ ┌─────────────┐ ┌─────────────┐ │
│ │「我要构建: │ ──────────→ │「审查: │ │
│ │ 用户积分 │ │ 方案完整? │ │
│ │ 等级系统」 │ │ 验收标准 │ │
│ └─────────────┘ │ 明确?」 │ │
│ ↑ └─────────────┘ │
│ └──────────── 反馈/修改 ──────────── → │
│ │
│ ↓ 双方达成一致 │
│ ┌─────────────────────┐ │
│ │ 契约锁定,开始实现 │ │
│ └─────────────────────┘ │
└──────────────────────────────────────────────────────┘
契约模板:
{
"sprintId": "sprint-2026-08-15-001",
"feature": "用户积分等级系统",
"generatorProposal": {
"approach": "在 PostgreSQL 中使用 enum 存储等级,积分计算通过触发器自动更新",
"files": ["models/user_level.go", "services/points.go", "migrations/xxx_add_level.sql"],
"estimatedTokens": 8000
},
"evaluatorReview": {
"completeness": "PASS - 覆盖所有验收标准",
"successCriteria": [
"积分增加后等级实时更新",
"等级变更触发通知事件",
"历史积分记录可查"
],
"concerns": ["触发器方案在高频场景下性能需实测验证"],
"decision": "CONDITIONAL_APPROVE - 先用触发器,性能瓶颈出现再优化"
},
"agreedContract": {
"approach": "PostgreSQL 触发器方案",
"verificationRequired": ["单元测试", "集成测试", "性能基准测试"],
"rollbackPlan": "如果 QPS>1000 时 P99>50ms,切换为应用层计算"
}
}
核心价值:这本质上是设计评审,只是参与者换成了AI。规划步骤由AI独立完成,能显著提升输出质量。
4.5 制品五:结构化任务模板(Impact Map)
在Agent写代码之前,Harness先分析真实代码库,产出一份基于实际情况的影响图:
# analyze_impact.py
def generate_impact_map(task: str) -> dict:
"""
分析任务并产出基于真实代码库的影响图。
不要臆造路径和API,全部基于代码库实际内容。
"""
codebase = analyze_codebase()
# 找到相关的真实文件
relevant_files = find_related_files(task, codebase)
# 找到真实存在的符号名(函数、结构体、接口)
real_symbols = extract_symbols(relevant_files)
# 找到可以遵循的现有模式
existing_patterns = find_patterns(relevant_files)
# 生成具体的验收标准
acceptance_criteria = define_acceptance(task, real_symbols)
return {
"real_file_paths": relevant_files,
"real_symbols": real_symbols,
"existing_patterns": existing_patterns,
"acceptance_criteria": acceptance_criteria,
"estimated_scope": "medium" # small/medium/large
}
影响图示例输出:
影响范围分析:用户积分等级系统
相关真实文件:
- models/user.go (User 结构体在此)
- services/loyalty.go (现有积分服务)
- internal/event/ (事件系统)
- migrations/ (数据库迁移)
真实符号名(可复用):
- User.Level (enum)
- LoyaltyService.AddPoints()
- EventBus.Publish()
现有模式(遵循):
- 所有 Service 以 *_test.go 结尾的测试文件
- 错误返回格式:errors.Wrap(err, "context")
- 事务边界在 Repository 层
验收标准:
[1] 调用 AddPoints(100) 后 User.Points = 100 且 Level 自动计算
[2] Level 变更触发 'user.level_changed' 事件
[3] 历史积分可通过 /api/v1/users/:id/points 查询
为什么这很重要:大多数团队跳过这一步。结果Agent只能猜测文件结构,编造不存在的API端点,产出的代码与现有代码库风格脱节。先给Agent提供基于真实代码库的上下文,产出质量会好得多。
五、三大阵营的技术路线对比
三个团队撞上了同一堵墙,然后各自造了不同的梯子。
5.1 OpenAI:环境优先(Environment First)
核心理念:把环境设计得足够严密,让Agent产出的代码从一开始就具备可审查性。
核心机制:
- 严格的依赖层次(Types → Config → Repo → Service → Runtime → UI)
- 分布式AGENT.md文件
- Agent直连CI/CD
# OpenAI Codex 的依赖流规则示例
dependency_rules:
allowed_dependencies:
- types: ["config", "errors"]
- config: ["errors"]
- repo: ["types", "config", "errors"]
- service: ["repo", "types", "errors"]
- runtime: ["service", "repo", "types", "errors"]
- ui: ["runtime", "service", "repo", "types", "config", "errors"]
enforcement: "strict" # 违反则CI失败
适合场景:大型、长期维护的项目,代码质量要求高。
5.2 Anthropic:执行与评审分离(Separation of Duties)
核心理念:自我评估行不通。让生成者和评审者彻底分开。
核心机制:三个专业Agent(Planner/Generator/Evaluator)+ JSON进度追踪
关键原则:
- 一次只做一个sprint
- 每个sprint必须有明确验收标准
- Evaluator使用真实环境验证(浏览器自动化、API测试)
# Anthropic 风格的 Evaluator 实现
class BrowserEvaluator:
"""像真实用户一样操作,验证功能是否真正可用"""
def evaluate(self, feature):
self.browser.goto(f"http://localhost:{PORT}")
if feature == "user_level_upgrade":
# 模拟用户操作流程
self.login_as("test_user")
self.purchase_item(sku="premium_999")
# 验证等级是否真的变了
level = self.get_user_level()
assert level > self.BASELINE_LEVEL, f"等级未更新: {level}"
# 验证事件是否真的触发了
event = self.wait_for_event("user.level_changed")
assert event is not None, "事件未触发"
return "PASS"
适合场景:对输出质量要求极高、需要像真实用户一样验证的场景。
5.3 ThoughtWorks:2×2框架(Feedforward × Feedback)
核心理念:将所有Harness控制沿两个维度分类,形成结构化矩阵。
| 计算型(确定性,毫秒级) | 推理型(LLM,秒级) | |
|---|---|---|
| 前馈(行动前) | 类型系统、Linter、架构规则 | 规格文档、约束描述 |
| 反馈(行动后) | 测试套件、覆盖率分析、变异测试 | LLM代码审查器、行为验证器 |
核心洞察:只有前馈或只有反馈都不够,两者都需要。
前馈(Feedforward)= 引导Agent走向正确方向
反馈(Feedback)= 确认Agent没有走偏
没有反馈的Harness只是一个带了额外步骤的prompt。
没有前馈的Harness无法预防,只能事后救火。
适合场景:需要在架构层面建立长期规范的团队。
六、五条共识原则:三个团队殊途同归
三个团队从未协调过,但独立得出了完全相同的结论。
原则一:上下文胜过指令
让Agent看到世界的当前状态,效果始终优于抽象地告诉它该做什么。
❌ 错误做法:
"在这个项目里,User 结构体在 models/user.go,
积分服务在 services/loyalty.go,请遵循现有模式"
✅ 正确做法:
直接给Agent真实文件路径、真实符号名、真实验收标准
让它自己去理解和遵循
基于真实文件路径工作,产出的代码自然能融入代码库。基于模糊描述工作,结果往往是臆造的文件路径和编造的API。
原则二:规划和执行必须分开
让Agent在同一个pass里既规划又执行,产出不可靠。
❌ 错误做法:
"实现一个用户积分系统,请先规划方案再实现"
✅ 正确做法:
先运行独立的规划阶段(Planner Agent / Sprint契约)
产出物经过审查后,才开始实现
规划步骤不一定要人来完成,但它必须是一个独立的环节,产出物在实现开始前需要经过审查。
原则三:反馈回路不可商量
没有反馈的Harness只是一个带了额外步骤的prompt。
前馈(告诉Agent该做什么)
+
反馈(告诉Agent做对了没有)
↓
真正的Harness
OpenAI让Agent接入CI/CD和可观测性系统。Anthropic使用专门的Evaluator Agent通过浏览器自动化进行测试。ThoughtWorks将其形式化为「传感器」。
三种方案,同一条原则。
原则四:一次只做一件事
试图一次做太多的Agent会耗尽上下文,失去连贯性,无声地丢弃需求。
Anthropic的标准流程:
读取进度 → 选一个特性 → 实现 → 提交 → 重复
强制渐进式推进,是每个成功Harness的共性。
原则五:代码库本身就是文档
如果一条规范、约束或架构决策没有写在代码库里,Agent就不会知道。
没有人为Agent单独维护一个知识库。仓库本身就是唯一的事实来源。
七、悖论:为了删除而构建
7.1 Harness衰减(Harness Decay)是真实的
Anthropic从Opus 4.5升级到Opus 4.6时,Sprint分解这个原本不可或缺的环节变得多余了——模型规划能力的提升使它不再必要。
Opus 4.5: Sprint分解 + 逐Sprint评估
Opus 4.6: 去掉Sprint分解 + 单次评估(节省38%成本)
Opus 4.7: 模型开始自验证 → Evaluator角色进一步缩小
这就是Harness衰减。Harness中的每个组件都编码了一个「模型做不到什么」的假设。随着模型能力提升,这些假设逐渐过期,对应的组件变成了负担。
7.2 Build to Delete
Philipp Schmid的建议:Build to delete。
设计每个Harness组件时就考虑它是可移除的。
定期关掉某个组件,看输出质量是否有变化。
如果没变化——删掉它。
- Manus在6个月里重构了5次Harness
- LangChain一年调整了3次
- Vercel砍掉80%的工具后性能反而更好
这些频繁的重构不是工程能力不足的表现,而是在快速进步的模型之上构建系统的必然结果。
保留无用的Harness组件,每次运行都会消耗额外的token,却没有任何质量收益。
7.3 成本趋势:更好的模型 = 更简单的Harness = 更便宜
更好的模型
↓
模型能力提升,部分Harness组件变多余
↓
删掉过时组件
↓
运行成本降低,产出速度加快
趋势线:更好的模型 = 更简单的Harness = 更便宜的运行 = 更快的产出。
八、工程实战:手写一个最小化Harness系统
理论讲完了,来点实际的。我们手写一个最小化的Harness系统,感受一下它的运作方式。
8.1 核心结构
project/
├── .harness/
│ ├── config.json # Harness配置
│ ├── progress.json # 进度追踪
│ └── rules/
│ ├── architecture.md # 架构规则
│ ├── testing.md # 测试规范
│ └── git.md # Git规范
├── agent.py # Agent入口
└── session_init.py # 会话初始化
8.2 Harness配置
// .harness/config.json
{
"version": "1.0.0",
"model": "claude-sonnet-4",
"context": {
"maxTokens": 180000,
"strategy": "progressive" // 渐进式上下文:按需加载skills
},
"tools": {
"allowed": ["read", "edit", "exec", "grep", "test"],
"denied": ["delete", "trash"],
"requireConfirmation": ["git push --force", "DROP TABLE"]
},
"quality": {
"minTestCoverage": 80,
"lintStrict": true,
"requireReview": true
},
"feedback": {
"preCommit": ["make lint", "make test"],
"postCommit": ["make build"],
"onFailure": ["save_context", "log_error"]
}
}
8.3 Agent入口
#!/usr/bin/env python3
# agent.py - Harness-aware AI Agent入口
import json
import subprocess
from pathlib import Path
from session_init import SessionInit
class HarnessAgent:
def __init__(self, workspace: str):
self.workspace = Path(workspace)
self.harness_dir = self.workspace / ".harness"
self.config = self._load_config()
self.progress = self._load_progress()
def _load_config(self) -> dict:
with open(self.harness_dir / "config.json") as f:
return json.load(f)
def _load_progress(self) -> dict:
progress_file = self.harness_dir / "progress.json"
if progress_file.exists():
with open(progress_file) as f:
return json.load(f)
return {"features": []}
def run(self):
# 会话初始化
init = SessionInit(self.workspace, self.config, self.progress)
session_context = init.execute()
# 选择下一个工作项
next_feature = self._select_next_feature()
if not next_feature:
print("✅ 所有特性已完成")
return
print(f"📋 开始实现: {next_feature['name']}")
print(f" 验收标准: {next_feature['acceptanceCriteria']}")
# 实现特性
self._implement(next_feature, session_context)
# 反馈验证
if self._verify(next_feature):
self._mark_done(next_feature)
self._commit(next_feature)
else:
print("❌ 验证失败,保留工作区供人工介入")
def _select_next_feature(self) -> dict | None:
"""选择优先级最高且无blockers的未完成特性"""
for feature in self.progress.get("features", []):
if feature.get("status") != "done":
blockers = feature.get("blockers", [])
if not blockers:
return feature
return None
def _implement(self, feature: dict, context: dict):
"""实现特性(调用AI模型)"""
prompt = self._build_prompt(feature, context)
# 这里调用实际的AI模型(Claude API / OpenAI API等)
result = self._call_model(prompt)
# 应用变更
self._apply_changes(result)
def _verify(self, feature: dict) -> bool:
"""运行质量门禁"""
print("🔍 运行质量门禁...")
# 前馈检查
checks = self.config.get("quality", {})
if checks.get("minTestCoverage"):
coverage = self._run_coverage()
if coverage < checks["minTestCoverage"]:
print(f"❌ 覆盖率不足: {coverage}% < {checks['minTestCoverage']}%")
return False
# 执行预提交检查
for cmd in self.config.get("feedback", {}).get("preCommit", []):
result = subprocess.run(cmd, shell=True, capture_output=True)
if result.returncode != 0:
print(f"❌ 前馈检查失败: {cmd}")
print(result.stderr.decode())
return False
print("✅ 质量门禁通过")
return True
def _mark_done(self, feature: dict):
"""更新进度文件"""
for f in self.progress["features"]:
if f["id"] == feature["id"]:
f["status"] = "done"
f["verifiedAt"] = subprocess.run(
["date", "-u", "+%Y-%m-%dT%H:%M:%SZ"],
capture_output=True, text=True
).stdout.strip()
break
with open(self.harness_dir / "progress.json", "w") as f:
json.dump(self.progress, f, indent=2)
def _commit(self, feature: dict):
"""提交代码"""
subprocess.run(["git", "add", "-A"], check=True)
subprocess.run([
"git", "commit", "-m",
f"feat: {feature['name']} ({feature['id']})"
], check=True)
print(f"✅ 已提交: {feature['name']}")
if __name__ == "__main__":
import sys
workspace = sys.argv[1] if len(sys.argv) > 1 else "."
agent = HarnessAgent(workspace)
agent.run()
8.4 会话初始化
# session_init.py
import subprocess
import json
from pathlib import Path
class SessionInit:
def __init__(self, workspace, config, progress):
self.workspace = Path(workspace)
self.config = config
self.progress = progress
def execute(self) -> dict:
"""执行7步会话初始化"""
print("🔧 Harness会话初始化...")
# Step 1: 确认工作目录
self._verify_workspace()
# Step 2: 读取git日志和进度
git_log = self._read_git_log()
last_session = self._get_last_session_info(git_log)
# Step 3: 分析代码库状态
codebase_state = self._analyze_codebase()
# Step 4: 构建上下文摘要
context = {
"workspace": str(self.workspace),
"git_log": git_log,
"last_session": last_session,
"codebase_state": codebase_state,
"config": self.config,
"progress": self.progress
}
# Step 5: 读取架构规则
rules = self._load_rules()
# Step 6: 构建Agent上下文提示
agent_context = self._build_context_prompt(context, rules)
# Step 7: 验证基线状态
self._verify_baseline(context)
print("✅ 初始化完成\n")
return context
def _read_git_log(self) -> str:
"""读取最近20条git提交"""
result = subprocess.run(
["git", "log", "--oneline", "-20"],
capture_output=True, text=True, cwd=self.workspace
)
return result.stdout
def _analyze_codebase(self) -> dict:
"""分析代码库结构"""
stats = {
"files": 0,
"lines": 0,
"languages": {},
"test_coverage": 0.0
}
# 统计文件
for ext in ["*.go", "*.py", "*.ts", "*.js"]:
files = list(self.workspace.rglob(ext))
stats["files"] += len(files)
# 运行覆盖率(如果存在)
coverage_result = subprocess.run(
["make", "coverage"],
capture_output=True, cwd=self.workspace
)
if coverage_result.returncode == 0:
# 解析覆盖率输出
stats["test_coverage"] = self._parse_coverage(coverage_result.stdout)
return stats
def _load_rules(self) -> dict:
"""加载Harness规则文件"""
rules_dir = self.workspace / ".harness" / "rules"
rules = {}
for md_file in rules_dir.glob("*.md"):
rules[md_file.stem] = md_file.read_text()
return rules
def _build_context_prompt(self, context: dict, rules: dict) -> str:
"""构建注入给AI模型的上下文"""
lines = [
"# 会话上下文",
"",
f"工作目录: {context['workspace']}",
f"代码库统计: {context['codebase_state']['files']} 文件, "
f"{context['codebase_state']['test_coverage']}% 测试覆盖率",
"",
"## 最近Git提交",
context["git_log"],
"",
"## Harness规则",
]
for name, content in rules.items():
lines.append(f"\n### {name}.md")
lines.append(content)
return "\n".join(lines)
九、2026年的工程现实:这套方法论值多少钱?
9.1 成本-质量权衡
Anthropic的A/B测试数据非常清晰:
| 方案 | 成本 | 产出质量 |
|---|---|---|
| 无Harness | $9/次 | Demo级(看起来能用,上线就崩) |
| 完整Harness | $200/次 | 生产级(功能完备,可交付) |
22倍成本差距换来的是从不可用到可交付的质变。
对于核心业务系统,一次生产故障的代价远超$191。对于快速迭代的创业项目,无Harness的快速产出反而更划算。
9.2 模型升级的影响
模型升级(如Opus 4.5 → 4.6)
↓
Harness成本下降(部分组件不再必要)
↓
但绝对成本仍在上升(更好的模型更贵)
↓
最终趋势:
更好的模型 + 更简单的Harness = 性价比持续提升
9.3 哪些团队真正需要这套方法论?
需要Harness Engineering的团队:
- 大型、长期维护的代码库(>10万行)
- 对代码质量要求高的团队(金融、医疗、航空)
- 需要无人值守AI Agent的场景(CI/CD流水线)
- 多团队协作的大型项目
不一定需要的团队:
- 快速MVP验证阶段
- 小型一次性项目
- 高度临时的实验代码
十、总结:环境比模型更重要
2026年,Harness Engineering之所以重要,是因为它揭示了一个被长期忽视的真相:
AI编程的瓶颈,从来不在模型多聪明,而在你围绕模型搭建的那套缰绳够不够好。
LangChain用同一个模型,从30名开外跃升至前5名,靠的不是换模型。
OpenAI用3人团队交付100万行生产代码,靠的不是雇更多程序员。
Anthropic用$200成本做出真正可交付的产品,靠的不是用最强的模型。
他们共同做的一件事是:停止追逐更好的模型,开始设计更好的环境。
对于正在择业、想提升或刚入门的程序员来说,这个趋势意味着什么?
2026年的核心竞争力,不是「会写代码」,而是「会设计让AI可靠工作的环境」。
你会写prompt不等于你懂Harness。你会调用API不等于你能构建可靠的反馈回路。
Harness Engineering是AI工程时代的第一性原理。它不是某个框架,不是某个工具,而是理解AI Agent系统如何真正运作的底层逻辑。
现在学它,你领先半步。
等所有人都在谈的时候,你已经在设计下一代Harness了。
附录:Harness Engineering快速检查清单
□ 每个仓库有 AGENT.md / CLAUDE.md(<60行,人类编写)
□ 有 JSON 格式的进度追踪器
□ 有固定的会话初始化流程
□ 规划和执行是分离的(独立评审环节)
□ 有明确的反馈回路(测试、CI/CD、可观测性)
□ 一次只做一个sprint/特性
□ 定期运行 Build-to-Delete 检查
□ 代码库结构本身就是文档(无需额外知识库)
本文覆盖的五大核心制品、三个技术阵营、五条共识原则,均基于2026年真实工程实践数据。如有疏漏,欢迎指正。