---
{
  "series": "Harness工程研究：让AI Agent好用的工程实践",
  "article_index": 3,
  "topic": "约束让Agent更好用：为什么你该给它戴上'镣铐'",
  "created": "2026-04-25",
  "deai_score": 92.0,
  "pipeline": "series"
}
---

给大模型预留极高的操作自由度，是目前架构设计中最容易引发灾难的习惯。开发者试图利用 LLM 在开阔空间的推理能力来应对复杂任务，但在实际迭代中，往往会陷入一种抽盲盒式的崩溃感。

在《Harness比模型重要》中我们讨论了运行环境的价值，《Context是稀缺资源》则分析了输入端的治理。这一篇要讨论的是 Harness 的另一个核心维度：约束机制。

目前的 Agent 表现极其不稳定，仅凭微小的输入抖动就可能导致模型遗忘关键参数。过去一年，开发者耗费了惊人的精力去撰写动辄数百字的 Prompt，试图用自然语言说服模型遵守某种规则。开发者必须停止崇拜 LLM 的推理灵活性，转而用确定性的机械约束强行收窄其解空间。带上物理约束后的 Agent，运行表现反而更加稳健。

### 自由带来的幻觉困境

在调试 Agent 系统时，最让人痛苦的情况是模型表现出的"概率性卓越"。它偶尔能完美执行任务，这具有极强的欺骗性。它诱导开发者在 Prompt 里增加更多的叮嘱和解释，试图去"对齐"那偶尔出现的成功。

结果显而易见：提示词变得臃肿不堪，充斥着"必须"、"千万不要"、"绝对禁止"等情绪化词汇。这种做法是将系统可靠性寄托在模型对形容词的理解深度上，这已经脱离了软件工程的范畴。

模型在处理 JSON 输出时的表现是一个典型案例。在 90% 的简单场景下，模型表现良好。但在面对多层嵌套的复杂逻辑时，它依然会因为概率偏移而漏掉括号。如果试图通过增加采样次数或单纯依靠 Prompt 叮嘱来还原严谨逻辑，效率极低。如果一个环节需要 100% 的准确率，将其交给概率模型决策是资源的简单堆砌。

真正跑通生产环境的团队，已经退出了调优模型意志的军备竞赛，转向了构建物理边界。当一个问题可以被结构化定义时，模糊的自然语言描述就是噪声。

推理在缺乏约束的情况下会迅速演变为逻辑发散。你可以观察到 Agent 在执行复杂的链式任务时，第一步的微小偏差会随着步骤增加而被放大，最终导致结果完全脱离预设轨道。这种发散是分布采样机制的天然产物。

代码库中的逻辑 Bug 可以通过单步调试定位，但 Prompt 里的逻辑失效往往是黑盒。当一个 Agent 在处理数据采集任务时，即便你嘱咐了一万遍"不要去爬取无关页面"，只要概率分布在那一时刻指向了某个高熵区域，幻觉就会发生。

### 物理约束与机械化执行

制造业中有一个叫 Poka-yoke（防错设计）的概念，其核心思想类似于 USB 接口只能插一个方向。操作员即便在极度疲惫或粗心的情况下，也无法将正负极反接。这种物理层面的强力纠正，比贴在墙上的任何操作规范、警告标志或员工手册都更有效。

在 Agent 工程中，我们需要引入同样的机械化执行（Mechanical Enforcement）。与其写五十行 Prompt 去叮嘱模型不要修改系统内核文件，更直接的做法是提供一个 OS 级的沙箱环境，比如使用 bubblewrap 或 seatbelt，在权限层面上将系统目录设为只读。

Anthropic 在开发 Claude Code 时的实践印证了这一点。他们没有单纯依赖模型对"安全协议"的理解，而是通过底层操作系统层面的隔离预定义了安全边界。在这种物理限制下，即使模型产生了一次试图探测内核的指令，也会在系统层被拦截。这种硬性沙箱机制产生了一个值得关注的结果：权限确认提示减少了 84%。

安全约束实际上是提升效率的加速器。当边界被物理锁死后，模型不再需要花费大量的上下文去判断"我能不能做这件事"，系统也不再需要反复向人类请求确认。这种设计实现了安全与提速的统一。

约束机制预防错误的成本远低于事后修复。在软件工程的历史上，类型系统（Type Systems）的进化也是类似的路径。从动态类型的灵活性到强类型的约束，开发者牺牲了一部分表达的随意性，换取的是在编译阶段就能拦截 90% 逻辑错误的确定性。

Agent 应该被看作是需要被容器化的不可靠模块。当沙箱、Linter、类型检查器共同守住门槛时，人类操作员不再需要全神贯注地盯守每一个输出字符。这种从"事后纠错"到"事前不可犯错"的转变，是 Agent 从实验室玩具演化为生产力工具的分水岭。

### 确定性工具优于概率性指令

给 Agent 戴上约束的本质，是将 LLM 的非确定性严格限定在明确的决策点上，其余部分则保持软件工程的确定性。目前所有走向成熟的 Agent 架构都在大规模使用确定性工具来处理确切逻辑。

以代码生成的 Agent 为例，模型生成的每一个代码片段都必须强制经过静态分析工具的校验。如果在 Harness 环节，Linter 报错或者类型检查未能通过，这个输出会被系统直接拦截，绝不会流向下游。拦截后，系统会带着具体的报错日志作为反馈，指令模型进行重修。

这个循环过程完全依赖于编译原理和形式化验证，而不是概率。我曾尝试用极长的 Prompt 去规范 JSON 的 Schema 结构，无论如何优化，在大样本测试下报错率始终维持在 5% 左右。这 5% 的失败足以让自动化流水线彻底崩溃。而当我改为接入 JSON Schema 强制校验，并在模型输出层使用 Constrained Decoding（约束解码）技术时，格式问题彻底消失了。

能用程序规则描述清楚的问题，交给 LLM 的推理去决策是对计算资源的浪费。

更高效的模式是：由 Agent 执行高层决策，由机械化 Hooks 执行战术校验。这种设计通过确定性的 Hooks 提供了质量门禁。它们在工作流的特定节点自动运行，是不可逾越的硬约束。例如，在一个自动化运维 Agent 中，模型可以建议重启服务，但执行重启的动作必须经过一个独立的、不含 AI 成分的预检查脚本，该脚本负责核对当前系统的负载水位。如果水位超过阈值，无论模型理由多么充分，执行链路都会被切断。

### 认知负荷与上下文清理

除了物理层面的边界，认知边界的构建同样关键。正如前一篇讨论的，Agent 在长上下文干扰下的性能衰退是严重的问题。当 Context 窗口被大量的历史对话、无关的调试日志以及中间路径占满时，模型产生漂移的概率呈指数级上升。

一个非常有效的策略是：每当 Agent 完成一个明确的子任务，系统应主动清空当前 Context 窗口进行 Handoff（移交）。这种"勤清空"的策略强迫系统在进入新任务状态前，必须将已有的成果进行序列化存储。

通过强制的状态同步（State Sync）和上下文刷新，我们实际上是在机械地维持模型的"专注力"。我们习惯于把 AI 拟人化，试图通过"交流"来解决问题。但当我们将 Agent 视作一个执行概率计算的数学模型时，给它添加 Linter 就不会被理解为"限制"，而会被理解为"降噪"。所有的硬约束本质上都是在过滤模型输出中的高频噪声，只允许那些符合逻辑规范的有效信号通过。

### 边界的度量

这种"戴着约束跳舞"的方法论也面临其自然的边界。

在多大强度的约束下，Agent 会从一个具有创造性的"自主代理"退化为一个由 if-else 堆砌的确定性脚本？如果约束过于严苛，我们可能会在获得稳定性的同时，丧失了让 AI 处理模糊边界问题的初衷。

在一些对容错率要求极高的金融或医疗场景，我倾向于将约束拉满，哪怕这会让 Agent 显得有些"呆板"。而在创意设计或初步草案生成的场景，约束可以稍微松一些，允许概率分布去冲击一些不寻常的解。灵活性与鲁棒性的平衡点，目前还更多地依赖于开发者对业务领域的深度理解。

即使有了沙箱和 Linter，高能力的模型依然可能通过更加隐蔽的逻辑跳跃来绕过门禁。例如，它可能会生成一段虽然通过了语法检查，但在业务逻辑上存在后门的代码。如何建立起一套针对 Agent 内部行为的自动化校验环境，是目前行业内最硬的挑战之一。

为 Agent 戴上镣铐确保了其运行轨道的稳定。至此，它已经不会轻易崩溃或做出危险操作了。接下来的终极拷问是：它输出的结果真的是对的吗？验证环节才是决定交付质量的最后一道天堑，这将在下一篇《验证比生成更重要》中详细拆解。
