引言
2025 年,AI Agent 从实验玩具变成了生产系统。Claude 能操作电脑、编写代码、管理文件;各种 Agent 框架层出不穷。但开发者很快发现了一个更深层的问题:
上下文工程解决了「给模型什么信息」的问题,但谁来管理这些信息的生命周期?谁来确保模型在正确的时间获得正确的上下文?谁负责在多步任务中维护状态、协调工具、执行约束?
答案不是「更好的提示词」,也不是「更多的上下文」。答案是——一个运行时系统。
就像 CPU 需要操作系统一样,大模型需要一个「Harness」来管理它的运行环境。这就是 Harness Engineering(Harness 工程)——上下文工程的下一个范式。
三次范式转移
AI 应用开发的三次范式转移:
范式 1.0:提示工程(Prompt Engineering)
时间:2022-2024
核心问题:如何写好一段提示词?
代表技术:System Prompt、Few-Shot、CoT
局限:只能做单轮交互,无法调用工具
范式 2.0:上下文工程(Context Engineering)
时间:2025
核心问题:如何设计模型完成任务所需的完整信息环境?
代表技术:RAG、Tool Call、记忆系统、Structured Outputs
局限:缺乏对 Agent 生命周期的系统管理
范式 3.0:Harness 工程(Harness Engineering)
时间:2026-
核心问题:如何构建大模型的运行时操作系统?
代表技术:Skill 模块化、Hook 机制、子 Agent 协调、跨会话状态
定位:上下文工程的「操作系统」层三者关系——每一层都是上一层的超集:
┌─────────────────────────────────────────┐
│ Harness Engineering │
│ (运行时系统 = LLM 的操作系统) │
│ │
│ ┌───────────────────────────────────┐ │
│ │ Context Engineering │ │
│ │ (信息环境设计) │ │
│ │ │ │
│ │ ┌──────────────────────────────┐ │ │
│ │ │ Prompt Engineering │ │ │
│ │ │ (提示词技巧) │ │ │
│ │ └──────────────────────────────┘ │ │
│ └───────────────────────────────────┘ │
└─────────────────────────────────────────┘Harness 是什么?——LLM 的「操作系统」
计算机类比
把大模型应用类比为一台计算机:
┌────────────────────────────────────────┐
│ 应用层 │
│ 编程助手 / 客服 Agent / 数据分析师 │
├────────────────────────────────────────┤
│ Harness(操作系统) │
│ │
│ ├── 指令管理(加载/卸载 Skill) │
│ ├── 工具编排(调用外部 API) │
│ ├── Hook 机制(硬约束执行) │
│ ├── 子 Agent 调度(任务分解) │
│ ├── 状态管理(跨会话记忆) │
│ └── 权限控制(安全边界) │
├────────────────────────────────────────┤
│ 上下文窗口(内存 RAM) │
│ 有限容量,需要高效管理 │
├────────────────────────────────────────┤
│ 大模型(CPU) │
│ 执行推理,但无状态、无记忆 │
└────────────────────────────────────────┘
LLM = CPU:强大的推理能力,但本身无状态
上下文窗口 = RAM:有限的工作空间
Harness = 操作系统:管理资源、调度任务、维护状态为什么需要「操作系统」?
没有 Harness 的 Agent:
用户:「帮我完成这个项目」
Agent 内部:
→ 需要加载哪些指令?(没人管理)
→ 调用哪些工具?(没有编排)
→ 安全边界是什么?(没有约束)
→ 上次做到哪了?(没有状态)
→ 子任务怎么分配?(没有调度)
→ 出错了怎么办?(没有兜底)
结果:要么能力不足,要么失控
有 Harness 的 Agent:
用户:「帮我完成这个项目」
Harness 自动:
→ 分析任务,加载相关 Skill
→ 编排工具调用顺序
→ Hook 检查每一步是否合规
→ 拆分子任务给专业子 Agent
→ 保存进度,支持断点续做
→ 权限控制,防止越权操作
结果:可靠、可控、可复现Harness 的六大核心组件
组件 1:模块化指令装配(Skill)
问题:Agent 能力越多,系统指令越长
一个全能编程助手的指令:
├── 文件操作规范 → ~200 token
├── 测试框架用法 → ~300 token
├── Git 提交规范 → ~200 token
├── 代码审查清单 → ~400 token
├── 文档生成模板 → ~300 token
└── 部署安全规则 → ~500 token
总计:~1900 token
用户说「改个 typo」,却要加载全部 1900 token?
Harness 的解决方案:Skill 模块化
每个 Skill = 独立的指令包
┌─────────────────────────────┐
│ SKILL.md │
│ --- │
│ name: git-operations │
│ description: Execute git │
│ commands following team │
│ conventions │
│ --- │
│ │
│ # Git 操作技能 │
│ ## 提交规范 │
│ - Conventional Commits │
│ ... │
└─────────────────────────────┘
核心思想:只加载当前任务需要的 Skill
→ 用户说「改 typo」→ 只加载文件操作 Skill
→ 其他 Skill 的「名片」始终可见(几十 token)
→ 详细指令按需加载(几百 token)Skill 与 MCP:两条模块化路线的汇合
回顾第四阶段,我们学过 MCP 解决了工具的标准化问题。
现在 Skill 解决的是指令的模块化问题。
它们看似不同,其实都在做同一件事——把 Agent 的能力模块化。
MCP:工具层的标准化
解决的问题:N×M 集成地狱
N 个模型 × M 个工具 → 每个都要单独适配
方案:统一的工具协议
工具提供方实现一次 MCP Server
所有支持 MCP 的模型都能调用
Skill:指令层的模块化
解决的问题:单体 Prompt 膨胀
Agent 能力越多 → 系统指令越长 → 质量越差
方案:指令按需加载
每个能力独立为一个 Skill
只在需要时才加载到上下文
┌──────────────────────────────────────────────┐
│ Agent 的能力 = 指令 + 工具 │
│ │
│ MCP 负责「手」:标准化工具的调用方式 │
│ Skill 负责「脑」:模块化指令的组织方式 │
│ │
│ 没有 MCP → 工具集成混乱,每个都要单独适配 │
│ 没有 Skill → 指令膨胀,上下文被无关内容淹没 │
│ │
│ 两者结合 → 能力的完整模块化 │
└──────────────────────────────────────────────┘从 Function Calling 到 Harness 的演进路线:
阶段 1:Function Calling(2023.6)
→ 模型能调用工具了
→ 但每个工具的接口都是自定义的
→ 指令和工具都写在同一个 prompt 里
阶段 2:MCP 协议(2024.11)
→ 工具接口标准化了
→ 工具可以跨平台复用
→ 但指令仍然是单体 prompt,越来越臃肿
阶段 3:Skill 模块化(2025)
→ 指令也被模块化了
→ 与 MCP 工具配套:加载 Skill → 同时激活对应工具
→ 卸载 Skill → 同时移除对应工具
阶段 4:Harness 工程(2026)
→ 统一编排 Skill + MCP 工具
→ 加上 Hook 约束、子 Agent、状态管理
→ 形成完整的运行时系统
演进逻辑:
先标准化「手」(MCP)
再标准化「脑」(Skill)
最后统一编排(Harness)一个具体例子——Skill + MCP 的协同:
用户:「帮我创建一个 PR」
Harness 的处理流程:
Step 1:分析任务 → 需要 git 操作和代码审查
Step 2:加载 Skill
→ 激活 git-operations Skill(加载提交规范、分支策略)
→ 激活 code-review Skill(加载审查清单)
Step 3:激活 MCP 工具
→ git-operations Skill 关联的 MCP Server(文件操作、git 命令)
→ code-review Skill 关联的 MCP Server(代码 diff、评论接口)
Step 4:执行
→ Skill 提供行为规则:「提交信息用 Conventional Commits」
→ MCP 工具提供执行能力:git add、git commit、gh pr create
→ Hook 检查:提交信息格式对吗?分支名合规吗?
Step 5:卸载
→ 完成后卸载 Skill,释放上下文
→ MCP 工具也从上下文中移除
Skill = 告诉模型「怎么做」(规则)
MCP = 让模型「能做什么」(能力)
Hook = 确保模型「不会做错」(约束)
三者缺一不可组件 2:渐进式披露(Progressive Disclosure)
Harness 的信息加载策略——三层渐进:
Level 1:元数据层(始终加载,~50-100 token)
告诉模型「我有哪些能力」
[git-operations] 执行 git 操作
[code-review] 代码审查
[test-runner] 运行测试
[deploy] 部署发布
Level 2:详细指令层(按需加载,~200-500 token)
模型识别需要某个 Skill 时才加载
用户说「提交代码」→ 加载 git-operations 的 SKILL.md
Level 3:资源层(深度按需)
只在需要具体模板、参考文档时才加载
Token 节省对比:
┌────────────────────────────────────────────┐
│ 单体 Prompt: │
│ System Prompt: 1900 token(全部指令) │
│ 有效利用: ~200 token(git 相关) │
│ 浪费率: ~90% │
├────────────────────────────────────────────┤
│ 渐进式披露: │
│ Level 1(名片): 80 token │
│ Level 2(git 指令): 200 token │
│ 有效利用率: ~100% │
│ 节省: ~84% │
└────────────────────────────────────────────┘四种披露模式:
模式 1:索引优先(Index-First Loading)
先加载索引 → 模型选择 → 加载详细指令
适合:Skill 数量多,任务不确定
模式 2:侦察模式(Scout Pattern)
先快速分析任务 → 确定需求 → 加载对应 Skill
适合:复杂任务,需要先理解再行动
模式 3:分阶段加载(Phase-Based Loading)
按工作流阶段加载/卸载 Skill
编码阶段 → 加载代码 Skill,卸载需求分析 Skill
测试阶段 → 加载测试 Skill,卸载代码 Skill
适合:CI/CD 等线性流程
模式 4:清洁 Skill 文件(Clean Skill Files)
Skill 引用外部资源,不内嵌
SKILL.md 写「遵循 @code-style-guide.md」
只在需要时加载具体规范
适合:知识密集型 Agent组件 3:工具编排与治理
Harness 不仅管理指令,还管理工具:
问题场景:
Agent 有 20 个工具可用
→ 模型每次请求都要看到 20 个工具的 Schema
→ 占用大量上下文空间
→ 模型容易选错工具
Harness 的工具治理:
┌────────────────────────────────────┐
│ 工具注册表 │
│ │
│ 所有可用工具: │
│ ├── filesystem → 文件读写 │
│ ├── git → 版本控制 │
│ ├── http → 网络请求 │
│ ├── database → 数据库操作 │
│ └── ...共 20 个工具 │
│ │
│ 当前任务只需: │
│ └── filesystem(改 typo 只需要它) │
│ │
│ → 只把 filesystem 放入上下文 │
│ → 其他 19 个工具不占用上下文空间 │
└────────────────────────────────────┘
与 Skill 的协同:
加载 git-operations Skill → 同时激活 git 工具
卸载 git-operations Skill → 同时移除 git 工具
→ 指令和工具始终配套组件 4:Hook 机制——硬约束
System Prompt 是「软约束」:
「不要删除文件」→ 模型 99% 遵守,但可能 1% 违反
Hook 是「硬约束」:
模型生成删除命令 → Hook 拦截 → 阻止执行
→ 100% 保证安全
┌──────────────────────────────────────────────────┐
│ Hook 的位置 │
│ │
│ 用户输入 → [Pre-Hook] → 模型推理 → [Post-Hook] → 执行 │
│ ↑ ↑ │
│ 检查输入 检查输出 │
│ 过滤注入攻击 拦截危险操作 │
└──────────────────────────────────────────────────┘
常见 Hook 类型:
Pre-Hook(输入过滤):
→ 检查用户输入是否包含注入攻击
→ 验证参数格式和范围
Post-Hook(输出检查):
→ 检查生成的命令是否在白名单内
→ 验证输出格式是否符合要求
→ 过滤敏感信息泄露
Guardrail Hook(护栏):
→ 阻止特定类型的操作(如删除生产数据)
→ 限制调用频率和并发数
→ 记录审计日志组件 5:子 Agent 与上下文防火墙
复杂任务需要多个 Agent 协作:
主 Agent:「重构这个项目」
┌──────────────────────────────────────┐
│ 主 Agent(协调者) │
│ │
│ 上下文:项目概览 + 任务分配策略 │
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │ 子Agent A │ │ 子Agent B │ │
│ │ 代码重构 │ │ 测试更新 │ │
│ │ │ │ │ │
│ │ 上下文: │ │ 上下文: │ │
│ │ 重构规则 │ │ 测试框架 │ │
│ │ 目标文件 │ │ 测试模板 │ │
│ └──────────┘ └──────────┘ │
└──────────────────────────────────────┘
关键设计:上下文隔离(Context Firewall)
每个子 Agent 有独立的上下文窗口
→ 子 Agent A 不需要看到测试规则
→ 子 Agent B 不需要看到重构规则
→ 避免上下文交叉污染
这就是「上下文防火墙」:
每个 Agent 的上下文被严格隔离
只通过结构化消息进行通信
→ 比把所有信息塞进一个上下文更高效
→ 也更安全(一个 Agent 出错不影响其他)组件 6:跨会话状态交接
Agent 的任务可能跨越多个会话:
会话 1:
用户:「开始重构项目」
Agent:完成了 30%...
→ Harness 保存状态
会话 2(第二天):
用户:「继续昨天的重构」
Harness:恢复上次状态
→ Agent 从 30% 继续
→ 不需要重新理解整个项目
┌──────────────────────────────────────┐
│ Harness 的状态管理 │
│ │
│ 短期状态(会话内): │
│ 当前任务进度、加载的 Skill、活跃工具 │
│ │
│ 中期状态(跨会话): │
│ 项目上下文、用户偏好、工作模式 │
│ │
│ 长期状态(跨项目): │
│ 用户习惯、编码风格、常见任务模式 │
│ │
│ 状态交接 ≠ 记忆 │
│ 记忆是信息的「存储」 │
│ 状态交接是「结构化的进度恢复」 │
│ 包括:做了什么、正在做什么、接下来做什么 │
└──────────────────────────────────────┘约束悖论:为什么限制让 AI 更强
直觉:给 AI 更多自由 → AI 更强
现实:给 AI 更多约束 → AI 反而更可靠
这就是「约束悖论」:
无约束的 Agent:
上下文膨胀 → 注意力稀释 → 输出不可预测
想做什么做什么 → 经常做错事
有约束的 Agent:
上下文精简 → 注意力集中 → 输出可控
只能做被允许的事 → 做得又快又好
类比:
高速公路没有护栏 → 司机紧张,速度反而慢
高速公路有护栏 → 司机放心,速度反而快Harness 的约束层次:
软约束(System Prompt):
「建议使用 Conventional Commits 格式」
→ 模型可能遵守,也可能不
硬约束(Hook):
提交信息必须匹配正则 /^feat|fix|docs|refactor/
→ 不匹配就阻止提交
→ 100% 保证
结构约束(Structured Outputs):
输出必须是特定 JSON Schema
→ 模型被迫生成合法格式
上下文约束(Skill + 渐进式披露):
只加载任务相关的指令和工具
→ 模型看不到不相关的选项
→ 自然不会做出格的事
层层约束,层层保护:
软约束 → 大部分时候有效
硬约束 → 兜底保证
结构约束 → 格式层面
上下文约束 → 信息层面Harness 与上下文工程全景
上下文工程的完整框架(更新版):
┌───────────────────────────────────────┐
│ Harness Engineering │
│ (运行时系统层) │
│ │
│ ├── Skill 模块化(指令管理) │
│ ├── 渐进式披露(信息按需加载) │
│ ├── Hook 机制(硬约束) │
│ ├── 子 Agent 调度(上下文隔离) │
│ └── 状态交接(跨会话管理) │
│ │
│ ┌─────────────────────────────────┐ │
│ │ 上下文工程 │ │
│ │ │ │
│ │ 输入层 │ │
│ │ ├── System Prompt │ │
│ │ ├── Few-Shot 示例 │ │
│ │ └── Structured Outputs │ │
│ │ │ │
│ │ 知识层 │ │
│ │ ├── RAG │ │
│ │ ├── 长上下文 │ │
│ │ └── 记忆系统 │ │
│ │ │ │
│ │ 行动层 │ │
│ │ ├── Tool Calling │ │
│ │ └── MCP │ │
│ │ │ │
│ │ 优化层 │ │
│ │ ├── 上下文管理 │ │
│ │ ├── Prompt Caching │ │
│ │ └── 模型选择 │ │
│ └─────────────────────────────────┘ │
└───────────────────────────────────────┘本节小结
| 概念 | 要点 |
|---|---|
| 三次范式转移 | 提示工程 → 上下文工程 → Harness 工程 |
| OS 类比 | LLM=CPU,上下文窗口=RAM,Harness=操作系统 |
| Skill vs MCP | MCP 标准化「手」(工具接口),Skill 标准化「脑」(指令模块) |
| 演进路线 | Function Calling → MCP → Skill → Harness,先标准化工具,再标准化指令,最后统一编排 |
| 渐进式披露 | 三层加载:元数据→详细指令→资源,节省高达 84% token |
| 工具编排 | 与 Skill 联动,加载 Skill 同时激活对应 MCP 工具 |
| Hook 机制 | 硬约束,100% 保证安全规则被执行 |
| 子 Agent | 上下文防火墙,隔离不同任务的上下文 |
| 跨会话状态 | 结构化的进度恢复,不只是记忆 |
| 约束悖论 | 限制越多,AI 反而越可靠 |
思考题
- 回顾第四阶段学的 MCP,它和 Skill 在「模块化」这个理念上有什么异同?为什么工具先被标准化(MCP),指令后来才被标准化(Skill)?
- 如果你为一个 AI 客服设计 Harness,你会设置哪些 Hook?它们分别检查什么?
- 约束悖论在日常生活中有类似的例子吗?为什么限制反而能带来更好的表现?