第一章 Harness 的本质:压缩、解压与约束的必然性
核心命题:理解 Agent 为何需要 Harness,必须从 LLM 的已知行为特征出发。本章沿一条推演路径展开:LLM 的能力是有限的 → 不确定性是结构性的 → 约束(Harness)是必然的。“压缩/解压”框架为这条路径提供直觉理解,但三类不确定性本身是独立于框架可验证的经验事实;Harness 的必要性植根于这些事实,而非植根于框架本身。
方法论声明
本章使用”压缩”与”解压”作为理解 LLM 的核心框架。请明确区分以下三层含义:
- (a) 描述性类比:“训练是压缩”是对预训练过程的直觉性描述——数据规律被编码进参数权重。这是类比,不是严格的信息论陈述(Shannon 信息论中的压缩指向可还原编码,LLM 训练并不满足这一条件)。
- (b) 启发性模型:“推理是有损解压”是理解推理不确定性的启发式框架——Prompt 激活了训练时编码的规律,但激活过程受训练覆盖范围的约束。这是工作模型,不是精确的物理描述。
- (c) 经验性论断独立于框架:1.2 节中的三类不确定性(分布外填充、分布偏移、自信度误校准)是 LLM 已知的经验性问题,具有独立于”压缩/解压”框架的实验基础。框架为理解它们提供了统一的直觉,但不是这些问题存在的证明前提。
1.1 LLM 的智能边界
LLM 的”智能”不是凭空涌现的,而是压缩的产物。预训练的本质是:将数万亿 token 的人类书写(逻辑、常识、因果链、风格、事实)压缩进数百亿参数的权重矩阵。以 GPT 级别的模型为例,其压缩比大致是千倍量级——用原始数据量的千分之一存储”能够重新生成”这些数据的规律。
这种压缩为什么能产生智能?因为高效压缩迫使模型学习通用规律,而非死记硬背。一个无法压缩的存储器只能记住见过的内容;一个真正实现高压缩比的模型,必须提取出数据背后的生成规律——这个规律,就是我们所说的”知识”。
压缩比决定了能力的上限与局限的类型。参数越多,可表达的规律越精细;但无论参数多少,有限的权重都无法完美覆盖无限的人类表达空间。压缩是有损的——这不是工程缺陷,而是数学必然。
1.2 推理的不确定性:三类结构性来源
LLM 的行为模式揭示了三类可被独立观察、反复验证的不确定性来源:
-
分布外填充:当查询超出训练数据的覆盖范围,模型不会拒绝回答,而是将输出向最近的已知模式靠拢——产生听起来合理但实际错误的输出。这是大量”幻觉”现象的主要来源之一,可在不依赖任何理论框架的情况下被实验观察到。
-
分布偏移:训练数据中的系统性偏差会被编码进权重,并在推理时系统性地再现——不是随机噪声,而是方向一致的错误倾向。其表现是模型对特定类型事实的重复性错误,且对提示方式的改写不敏感;提示工程可部分缓解,但难以完全消除。
-
自信度误校准:模型的置信度信号与输出信号来自同一套生成机制,没有独立的”是否失真”检测通道。结果是模型对错误输出表现出与正确输出相同的高置信度——这是最危险的属性,因为它使错误不可被模型自身识别。(注:RLHF 训练后模型会习得对不确定内容使用”我认为”、“可能”等语言级对冲,但这是习得的表达模式,不构成独立的失真检测机制。)
这三类不确定性是经验事实,不依赖任何特定理论框架。压缩/解压模型在此提供的是统一的直觉理解:将训练理解为”将数据规律编码进权重”,将推理理解为”根据 Prompt 激活并展开这些规律”。在这个框架下,三类不确定性的来源变得直觉可见——训练覆盖的边界产生分布外填充;编码时的偏差在激活时被放大,产生分布偏移;共享的生成机制使失真检测成为结构性不可能,进而产生误校准。
关键推论:无论用何种框架描述,这三类不确定性的共同特征是——它们不是”模型还不够好”的暂时问题,而是任何有限参数模型面对无限输入空间时的结构性必然。提升模型能力可以降低不确定性的幅度,但无法将其归零。这个推论是理解 Harness 必要性的逻辑基础。
1.3 约束是结构必然:从不确定性到 Harness
既然不确定性是结构性的、不可被模型自身消除,那么对可靠输出的追求只能转向外部约束——在模型之外构建一个装置,让”期望的输出”成为不确定性收敛的方向,而非随机游走的结果。这就是 Harness 存在的根本理由。
从”有损解压”到”Harness 是解压装置”:一个无损压缩格式(如 ZIP)可以完美还原原始内容;一个有损压缩格式(如 JPEG)需要质量参数和编码规范才能控制失真。LLM 是极度有损的压缩——Harness 是为这个解压过程提供”质量参数与编码规范”的装置。没有 Harness,解压结果的质量完全由压缩时的运气决定。
将这一直觉具体化:Agent 完成任务的过程,本质上是在一个可能性空间中搜索——从某个起点出发,通过一系列可执行的操作,寻找到达目标的路径。
- 无约束时:可执行的操作集合是开放的,搜索空间的分支因子与路径深度均不受控,搜索成本指数增长——不确定性在高维空间中自由扩散,既无法计算,也无法收敛。
- Harness 介入后:Harness 界定允许的操作集合,并精确描述任务起点与目标,从而将指数搜索压缩到可行域。这不是搜索效率的优化,而是搜索可行性的前提。
示例:代码生成任务——起点是当前代码库状态;可执行操作包括文件编辑、测试运行、工具调用;目标是通过所有测试的特定功能实现。Harness 一方面界定允许的操作范围(只允许使用指定工具),另一方面精确描述目标(测试通过的可验证标准)。这两个约束共同将不确定性从”可能产生任何输出”收窄到”在可行域内搜索”。
1.4 趋同演化:理论预测与经验观察
如果 Harness 是结构必然而非工程偏好,那么一个可检验的预测是:独立构建 Harness 的工程团队,应当在核心设计方向上高度趋同——即使他们从未相互参照。
经验观察与这个预测方向一致。所有成熟的 Harness 系统都包含相同的核心元素:反馈回路(Loop)、输入约束(System Prompt)、上下文管理(Context)、生命周期管理(Hook 机制)、行动边界(Tool 权限)、计划层(Plan)。差异仅在细节实现的精巧程度,而非结构。
需要说明的是:这种趋同的方向与理论预测一致,但趋同的原因是多重的——结构压力是其中之一,社区知识传播(论文、开源框架、工程博客)同样在加速趋同。我们无法从观察到的趋同现象中,将”结构压力的必然推论”与”知识扩散的自然收敛”完全分离。本书将这一观察用作与理论方向一致的佐证,而非”结构必然性”命题的独立证明(注:鱼鳍与鲸鳍的类比适用于其中的结构压力部分,但现实中的知识传播使类比不完全成立)。
四个可观察的结构压力依然成立:不确定性需要约束,上下文有限性需要管理,副作用的不可逆性需要分级,人类监督的成本需要最小化。每一个独立开发 Harness 的团队都会面对这四个压力;理论预期它们指向相同的解法——经验观察支持这一预期。
本书的根本关切,正是回答这些设计的为什么,而非怎么做。
章末案例剖析
以下是同一个代码审查任务在两种工程范式下的对比实录——用来为本章的抽象论证提供更具体的形式。案例中的数据(运行次数、检出率、token 消耗等)均为基于作者工程实践的说明性示例,旨在量化呈现两种范式的结构性差异,而非精确的实测基准。
任务设定:对一个包含 15 个代码文件改动的 Pull Request 进行审查。要求:识别潜在 Bug、安全风险和性能问题;给出可操作的修改建议;不评论风格问题(交由 linter 负责);输出格式适合直接写入 PR comment。diff 中存在两处已知问题:一处函数返回值未检查的空指针风险(位置明显),以及一处跨文件的潜在竞态条件(需要关联两个文件才能识别)。将上述两个任务对各运行 10 次,观察输出的一致性、内容质量与 token 消耗。
方案 A:无结构 Prompt
Prompt 仅包含”请审查这段代码,找出问题并给出建议”,后接完整 diff 内容。
10 次执行的观察:输出长度方差极大——3 次超过 2000 字(包含风格评论和与 diff 无关的架构建议),2 次不足 200 字(泛泛意见,无可操作建议),5 次居中但内容高度重叠。Bug 检出率不稳定——空指针风险 6 次被识别,竞态条件只有 2 次被识别,两者同时识别的只有 1 次。4 次输出提到了 diff 中根本不存在的”安全漏洞”,描述有理有据,但指向的代码行不在 diff 范围内。平均每次消耗约 1,200 output token,但 token 的有效信息密度——即每百 token 对应的可操作建议数——均值仅 0.8 条。
方案 B:分层 Harness
在方案 A 的基础上,引入四层约束:
System Prompt 约束——明确角色边界(“你是专注于 Bug 和安全风险的审查员,不评论风格问题”),定义输出格式(“每个问题使用 JSON 结构表达:{severity, location, description, suggestion}”),以及任务边界(“只分析 diff 中明确存在的代码行,不推断未包含的上下文”)。
Context 约束——不将完整代码库粘入上下文,而是注入两类精简信息:当前 diff 涉及函数的签名索引(帮助模型识别跨文件调用关系),以及一份已知的高风险 API 列表(将注意力定向至训练数据中出现频率较低的安全模式)。
Plan 约束——将”审查 15 个文件”分解为按文件依赖关系排序的 5 个子任务,每次处理 3-4 个关联文件。这防止了上下文窗口被无关文件稀释,同时迫使模型在具有足够关联上下文的条件下处理每个子问题。
Post-Hook 验证——对每次 LLM 输出运行 JSON Schema 校验(强制结构合规)和去重(合并指向同一代码行的重复问题)。不合规输出触发一次重试;重试失败则向人工升级。
10 次执行的观察:输出全部符合 Schema,平均每个问题 120 字,无无关内容。空指针风险 10 次全部识别;竞态条件 8 次识别(2 次因 Plan 分组边界未将两个关联文件归入同一批次而遗漏,原因可追溯)。幻觉率从 40% 降至 0%。平均每次 output token 减少至 740,可操作建议密度升至每百 token 2.3 条。
约束-不确定性对应关系
| 不确定性来源(§1.2) | 收敛该不确定性的约束层 | 收敛机制 |
|---|---|---|
| 分布外填充(幻觉) | System Prompt 的范围限制 | ”只分析 diff 中明确存在的代码行”在模型开始推理前截断了其向训练数据中相似代码”靠拢”的路径——不确定性在扩散前被边界收窄 |
| 分布偏移(竞态条件检出率低) | Context 的精准注入 | 高风险 API 列表将注意力定向至训练数据中出现频率低因而被系统性低估的安全模式,抵消了”常见 Bug 优先”的方向性偏差 |
| 自信度误校准(格式与内容失控) | Post-Hook 的结构验证 | Schema 约束使”输出听起来有信心但结构随意”的情况无法通过后处理——将误校准从”不可见”变为”可检测的验证失败”,从而变为可处理的工程问题 |
这个对比揭示了一个核心结论:三类不确定性各需不同机制收敛,没有任何单层约束能同时处理全部三类。方案 A 只有 System Prompt 这一层——它能在一定程度上约束输出风格,但无法修正分布偏移(这需要 Context),也无法将误校准变为可检测的失败(这需要 Hook)。从”提示词工程”到”Harness 工程”的转变,本质不是”Prompt 写得更好了”,而是在 Prompt 之外,为其他两类不确定性建立了对应的约束层——这正是本章 §1.3 论证的形态:外部装置补偿了模型在结构上无法自我消除的不确定性。