Agent工程化三层架构

摘要

大语言模型(LLM)Agent 生产化的核心障碍并非模型能力,而在缺乏围绕非确定性模型的外部可靠性约束体系。本文将 Agent 工程化划分为编排、隔离、运维三层:编排层以 Harness 循环推进任务,以幂等键与终止条件抑制失败扩散;隔离层以四档沙箱与最小权利界定操作边界,不可逆操作强制交人工审核;运维层以追踪三轴与持久执行保可观测性与长期可靠性。实证表明,同一模型在不同 Harness 配置下表现差异显著,三层协同是实现 Agent 生产化的关键。

关键词:Agent 工程化;Harness;幂等键;沙箱;最小权利;人工审批;可观测性;Durable Execution


1 定义与架构划分

1.1 Agent 工程化的定义

Agent 工程化是围绕 LLM 构建的一整套系统层 基础设施,把模型的"生成能力"转化为可执行、可约束、可追溯的"行动能力"。Anthropic 在 Building Effective Agents 中把 Agent 定义为"在扩展时间内独立运行、使用各种工具完成复杂任务的系统",并强调工程实践的关键是简单可组合的模式,而非复杂框架1。

这一系统层在学界称 Harness (脚手架/执行栈)。Harness-Bench 将其定义为"管理上下文、工具、状态、约束、权限、追踪与恢复的系统层,在模型输出与外部行动之间做中介"2。Anthropic 在 SWE-bench 技术报告中也明确指出,Agent 是"模型 + 软件脚手架"的组合,脚手架负责生成 prompt、解析输出并管理交互循环3。

1.2 三层架构的职责划分

工程实践围绕"如何在不可靠的模型上构建可靠系统",形成三条互补技术栈:

  • 编排层,决定循环的形状(推进节奏与终止)
  • 隔离层,决定单步的爆炸半径(能碰什么、谁来批准)
  • 运维层,决定长期可信度(能否解释、续跑与审计)

#mermaid-svg-aRnOW94Li2YLE1Mc{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-aRnOW94Li2YLE1Mc .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-aRnOW94Li2YLE1Mc .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-aRnOW94Li2YLE1Mc .error-icon{fill:#552222;}#mermaid-svg-aRnOW94Li2YLE1Mc .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-aRnOW94Li2YLE1Mc .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-aRnOW94Li2YLE1Mc .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-aRnOW94Li2YLE1Mc .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-aRnOW94Li2YLE1Mc .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-aRnOW94Li2YLE1Mc .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-aRnOW94Li2YLE1Mc .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-aRnOW94Li2YLE1Mc .marker{fill:#333333;stroke:#333333;}#mermaid-svg-aRnOW94Li2YLE1Mc .marker.cross{stroke:#333333;}#mermaid-svg-aRnOW94Li2YLE1Mc svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-aRnOW94Li2YLE1Mc p{margin:0;}#mermaid-svg-aRnOW94Li2YLE1Mc .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-aRnOW94Li2YLE1Mc .cluster-label text{fill:#333;}#mermaid-svg-aRnOW94Li2YLE1Mc .cluster-label span{color:#333;}#mermaid-svg-aRnOW94Li2YLE1Mc .cluster-label span p{background-color:transparent;}#mermaid-svg-aRnOW94Li2YLE1Mc .label text,#mermaid-svg-aRnOW94Li2YLE1Mc span{fill:#333;color:#333;}#mermaid-svg-aRnOW94Li2YLE1Mc .node rect,#mermaid-svg-aRnOW94Li2YLE1Mc .node circle,#mermaid-svg-aRnOW94Li2YLE1Mc .node ellipse,#mermaid-svg-aRnOW94Li2YLE1Mc .node polygon,#mermaid-svg-aRnOW94Li2YLE1Mc .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-aRnOW94Li2YLE1Mc .rough-node .label text,#mermaid-svg-aRnOW94Li2YLE1Mc .node .label text,#mermaid-svg-aRnOW94Li2YLE1Mc .image-shape .label,#mermaid-svg-aRnOW94Li2YLE1Mc .icon-shape .label{text-anchor:middle;}#mermaid-svg-aRnOW94Li2YLE1Mc .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-aRnOW94Li2YLE1Mc .rough-node .label,#mermaid-svg-aRnOW94Li2YLE1Mc .node .label,#mermaid-svg-aRnOW94Li2YLE1Mc .image-shape .label,#mermaid-svg-aRnOW94Li2YLE1Mc .icon-shape .label{text-align:center;}#mermaid-svg-aRnOW94Li2YLE1Mc .node.clickable{cursor:pointer;}#mermaid-svg-aRnOW94Li2YLE1Mc .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-aRnOW94Li2YLE1Mc .arrowheadPath{fill:#333333;}#mermaid-svg-aRnOW94Li2YLE1Mc .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-aRnOW94Li2YLE1Mc .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-aRnOW94Li2YLE1Mc .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-aRnOW94Li2YLE1Mc .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-aRnOW94Li2YLE1Mc .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-aRnOW94Li2YLE1Mc .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-aRnOW94Li2YLE1Mc .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-aRnOW94Li2YLE1Mc .cluster text{fill:#333;}#mermaid-svg-aRnOW94Li2YLE1Mc .cluster span{color:#333;}#mermaid-svg-aRnOW94Li2YLE1Mc div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-aRnOW94Li2YLE1Mc .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-aRnOW94Li2YLE1Mc rect.text{fill:none;stroke-width:0;}#mermaid-svg-aRnOW94Li2YLE1Mc .icon-shape,#mermaid-svg-aRnOW94Li2YLE1Mc .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-aRnOW94Li2YLE1Mc .icon-shape p,#mermaid-svg-aRnOW94Li2YLE1Mc .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-aRnOW94Li2YLE1Mc .icon-shape .label rect,#mermaid-svg-aRnOW94Li2YLE1Mc .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-aRnOW94Li2YLE1Mc .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-aRnOW94Li2YLE1Mc .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-aRnOW94Li2YLE1Mc :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Act 带副作用
产生 trace 与状态
反馈健康信号
运维层
追踪三轴与健康信号
Checkpoint 与续跑
隔离层
四档沙箱
最小权利与审批门
用完即收
编排层
Harness 循环五阶段
重试与幂等
终止条件
成本预算

图1 Agent 工程化三层架构协同关系

三层并非串行流水线,而是同一执行栈上的正交切面:编排层每轮循环调用隔离层的沙箱与审批门,运维层持续采集两层产生的 span、状态与审计记录213。


2 生产化的四类痛点

2.1 LLM 本身的不可靠性

LLM 作为 Agent 的决策方,天然具备三种使传统工程手段失效的特性:非确定性 (同一 prompt 重试可能生成不同参数)、幻觉与"幽灵成功" (报告任务完成却实际失败)、对 prompt injection 敏感 (外部输入可改写决策)。这要求重构传统 CRUD 场景的"重试 + Idempotency-Key"模式------重试时模型可能生成不同参数,单纯哈希 payload 会导致重试无法命中61。

2.2 脚手架差异的实证

Harness 对性能的影响有实证支撑。Anthropic 在 SWE-bench Verified 指出"同一底层模型在不同脚手架下表现差异显著",开源社区也通过优化脚手架在同一模型上获得显著提升3。Harness-Bench 对 5194 条轨迹的统计表明,性能在"模型-Harness 配置"层面存在实质差异,能力应在配置层报告而非归因于基础模型2。Anthropic 另一项研究还发现,基础设施配置差异即可使 Terminal-Bench 2.0 相差 6 个百分点(p < 0.01),超过多数榜单顶尖模型的相对差距5。

2.3 越权与不可逆操作风险

OWASP 在 LLM06:2025 Excessive Agency 中系统梳理了越权典型模式:LLM 获得超出必要的权限(如 UPDATE/INSERT/DELETE 一并授权)、以高权限通用身份连接下游、未经确认即执行高影响操作4。缓解原则是"仅授予最低必要的扩展与函数,并对高影响操作做独立验证与人工批准"4。

2.4 成本失控与循环

Agent 生产化另一大痛点是成本与循环失控。一次任务可能跨多个 provider、产生用户不可见的推理 token,也可能 spawn 子 Agent 重复计费,账单通常按 token × 单价实时累加9。若缺显式终止条件与预算熔断,Agent 会陷入 HTTP 200 持续烧钱的循环,而这类失败在传统 APM 视角下"看似成功"815。


3 方法机制与实现

3.1 编排层

编排层回答"Agent 如何推进",核心是 Harness 循环、幂等防御、终止条件与成本预算四模块。

3.1.1 Harness 循环五阶段

Agent 循环可抽象为五阶段:Perceive(感知)→ Reason(推理)→ Plan(规划)→ Act(执行)→ Observe(观察) ,循环往复直至命中终止条件13。Anthropic 在 SWE-bench 技术报告中描述该循环为:"脚手架把模型上一步动作的结果并入下一步 prompt,持续采样直到模型认为任务完成或超出 200k 上下文"3。
#mermaid-svg-RfC1FclN66SpOqZ2{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-RfC1FclN66SpOqZ2 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-RfC1FclN66SpOqZ2 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-RfC1FclN66SpOqZ2 .error-icon{fill:#552222;}#mermaid-svg-RfC1FclN66SpOqZ2 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-RfC1FclN66SpOqZ2 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-RfC1FclN66SpOqZ2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-RfC1FclN66SpOqZ2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-RfC1FclN66SpOqZ2 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-RfC1FclN66SpOqZ2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-RfC1FclN66SpOqZ2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-RfC1FclN66SpOqZ2 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-RfC1FclN66SpOqZ2 .marker.cross{stroke:#333333;}#mermaid-svg-RfC1FclN66SpOqZ2 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-RfC1FclN66SpOqZ2 p{margin:0;}#mermaid-svg-RfC1FclN66SpOqZ2 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-RfC1FclN66SpOqZ2 .cluster-label text{fill:#333;}#mermaid-svg-RfC1FclN66SpOqZ2 .cluster-label span{color:#333;}#mermaid-svg-RfC1FclN66SpOqZ2 .cluster-label span p{background-color:transparent;}#mermaid-svg-RfC1FclN66SpOqZ2 .label text,#mermaid-svg-RfC1FclN66SpOqZ2 span{fill:#333;color:#333;}#mermaid-svg-RfC1FclN66SpOqZ2 .node rect,#mermaid-svg-RfC1FclN66SpOqZ2 .node circle,#mermaid-svg-RfC1FclN66SpOqZ2 .node ellipse,#mermaid-svg-RfC1FclN66SpOqZ2 .node polygon,#mermaid-svg-RfC1FclN66SpOqZ2 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-RfC1FclN66SpOqZ2 .rough-node .label text,#mermaid-svg-RfC1FclN66SpOqZ2 .node .label text,#mermaid-svg-RfC1FclN66SpOqZ2 .image-shape .label,#mermaid-svg-RfC1FclN66SpOqZ2 .icon-shape .label{text-anchor:middle;}#mermaid-svg-RfC1FclN66SpOqZ2 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-RfC1FclN66SpOqZ2 .rough-node .label,#mermaid-svg-RfC1FclN66SpOqZ2 .node .label,#mermaid-svg-RfC1FclN66SpOqZ2 .image-shape .label,#mermaid-svg-RfC1FclN66SpOqZ2 .icon-shape .label{text-align:center;}#mermaid-svg-RfC1FclN66SpOqZ2 .node.clickable{cursor:pointer;}#mermaid-svg-RfC1FclN66SpOqZ2 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-RfC1FclN66SpOqZ2 .arrowheadPath{fill:#333333;}#mermaid-svg-RfC1FclN66SpOqZ2 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-RfC1FclN66SpOqZ2 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-RfC1FclN66SpOqZ2 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RfC1FclN66SpOqZ2 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-RfC1FclN66SpOqZ2 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RfC1FclN66SpOqZ2 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-RfC1FclN66SpOqZ2 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-RfC1FclN66SpOqZ2 .cluster text{fill:#333;}#mermaid-svg-RfC1FclN66SpOqZ2 .cluster span{color:#333;}#mermaid-svg-RfC1FclN66SpOqZ2 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-RfC1FclN66SpOqZ2 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-RfC1FclN66SpOqZ2 rect.text{fill:none;stroke-width:0;}#mermaid-svg-RfC1FclN66SpOqZ2 .icon-shape,#mermaid-svg-RfC1FclN66SpOqZ2 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RfC1FclN66SpOqZ2 .icon-shape p,#mermaid-svg-RfC1FclN66SpOqZ2 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-RfC1FclN66SpOqZ2 .icon-shape .label rect,#mermaid-svg-RfC1FclN66SpOqZ2 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RfC1FclN66SpOqZ2 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-RfC1FclN66SpOqZ2 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-RfC1FclN66SpOqZ2 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 未命中终止条件
命中终止条件
Perceive 感知
Reason 推理
Plan 规划
Act 执行
Observe 观察
Terminate 优雅退出

图2 Harness 循环五阶段示意

阶段 职责 失败模式 工程护栏
Perceive 接收用户输入、工具返回、错误信号 上下文污染 上下文分层与来源标注
Reason LLM 基于当前上下文决策 幻觉、prompt injection 系统提示词约束 + 外部校验器[1](#阶段 职责 失败模式 工程护栏 Perceive 接收用户输入、工具返回、错误信号 上下文污染 上下文分层与来源标注 Reason LLM 基于当前上下文决策 幻觉、prompt injection 系统提示词约束 + 外部校验器[1] Plan 复杂任务拆解为子任务 无边界规划 确定性逻辑前置[1] Act 调用工具/API/DB/代码执行 越权、重复调用、误操作 四层幂等防御 + 沙箱[4] Observe 检查结果并判断是否完成 误判完成、循环打转 终止条件 + 断路器[7])
Plan 复杂任务拆解为子任务 无边界规划 确定性逻辑前置[1](#阶段 职责 失败模式 工程护栏 Perceive 接收用户输入、工具返回、错误信号 上下文污染 上下文分层与来源标注 Reason LLM 基于当前上下文决策 幻觉、prompt injection 系统提示词约束 + 外部校验器[1] Plan 复杂任务拆解为子任务 无边界规划 确定性逻辑前置[1] Act 调用工具/API/DB/代码执行 越权、重复调用、误操作 四层幂等防御 + 沙箱[4] Observe 检查结果并判断是否完成 误判完成、循环打转 终止条件 + 断路器[7])
Act 调用工具/API/DB/代码执行 越权、重复调用、误操作 四层幂等防御 + 沙箱[4](#阶段 职责 失败模式 工程护栏 Perceive 接收用户输入、工具返回、错误信号 上下文污染 上下文分层与来源标注 Reason LLM 基于当前上下文决策 幻觉、prompt injection 系统提示词约束 + 外部校验器[1] Plan 复杂任务拆解为子任务 无边界规划 确定性逻辑前置[1] Act 调用工具/API/DB/代码执行 越权、重复调用、误操作 四层幂等防御 + 沙箱[4] Observe 检查结果并判断是否完成 误判完成、循环打转 终止条件 + 断路器[7])
Observe 检查结果并判断是否完成 误判完成、循环打转 终止条件 + 断路器[7](#阶段 职责 失败模式 工程护栏 Perceive 接收用户输入、工具返回、错误信号 上下文污染 上下文分层与来源标注 Reason LLM 基于当前上下文决策 幻觉、prompt injection 系统提示词约束 + 外部校验器[1] Plan 复杂任务拆解为子任务 无边界规划 确定性逻辑前置[1] Act 调用工具/API/DB/代码执行 越权、重复调用、误操作 四层幂等防御 + 沙箱[4] Observe 检查结果并判断是否完成 误判完成、循环打转 终止条件 + 断路器[7])

表1 Harness 五阶段职责与护栏

3.1.2 重试与幂等

幂等设计的关键差异:Agent 的调用方是 LLM 而非确定性客户端代码。Stripe 官方幂等文档指出,幂等键应显式传入请求头,API 缓存首次响应并在重试时返回相同结果,参数不匹配时应显式报错而非静默二次执行6。这一原则在 Agent 场景需扩展为多层防御69:

层级 防御点 典型实现
L1 目标端原生幂等 优先使用上游提供的幂等能力 Stripe Idempotency-Key header[6](#层级 防御点 典型实现 L1 目标端原生幂等 优先使用上游提供的幂等能力 Stripe Idempotency-Key header[6] L2 幂等键落库 数据库唯一约束 + 状态机 (agent_run_id, step_id, tool_name) 作为主键,状态机流转 processing/success/failed L3 写后读回验证 读回比对声明意图 通过确定性 wrapper 读回结果比对,而非信任模型返回的"成功" L4 本地调用记录 短事务内提交 calling 状态再外呼 重试时若本地已 success 直接返回,不再外呼)
L2 幂等键落库 数据库唯一约束 + 状态机 (agent_run_id, step_id, tool_name) 作为主键,状态机流转 processing/success/failed
L3 写后读回验证 读回比对声明意图 通过确定性 wrapper 读回结果比对,而非信任模型返回的"成功"
L4 本地调用记录 短事务内提交 calling 状态再外呼 重试时若本地已 success 直接返回,不再外呼

表2 幂等防御的典型分层

幂等键三条铁律:

  • 其一,键应从稳定结构上下文派生(如 (run_id, step_id, tool_name)),而非从 LLM 输出哈希------同一 prompt 重试可能生成不同参数;
  • 其二,粒度对齐业务动作而非执行实例,太粗会错误去重、太细会让重试无法命中;
  • 其三,参数不匹配时按 Stripe 模式显式报错6。
3.1.3 终止条件与多路熔断

Agent 不应仅靠模型自行判断"任务完成"。LangChain 官方 Middleware 提供 ModelCallLimitMiddleware 与 ToolCallLimitMiddleware,用于"防止 runaway agent 产生过多 API 调用""在生产部署中强制成本控制",到达上限时可优雅终止(end)或抛异常(error)7。综合工程实践,生产级终止条件至少含五路798:

终止类型 触发条件 典型默认值 命中后行为
目标达成 模型显式产出 final answer --- 优雅退出
步数上限 达到 max_model_calls 或 max_tool_calls 由配置项决定[7](#终止类型 触发条件 典型默认值 命中后行为 目标达成 模型显式产出 final answer — 优雅退出 步数上限 达到 max_model_calls 或 max_tool_calls 由配置项决定[7] 返回"达上限"标记 时间上限 wall-clock 超时 Claude Code 默认请求超时 10 分钟[8] 保存 checkpoint 后终止 预算上限 token / 美元 / API 调用次数超限 按任务等级配置[9] 熔断 + 告警 无进展检测 重复同一 tool call 与参数、观察结果无变化 连续若干次即熔断 触发断路器) 返回"达上限"标记
时间上限 wall-clock 超时 Claude Code 默认请求超时 10 分钟[8](#终止类型 触发条件 典型默认值 命中后行为 目标达成 模型显式产出 final answer — 优雅退出 步数上限 达到 max_model_calls 或 max_tool_calls 由配置项决定[7] 返回"达上限"标记 时间上限 wall-clock 超时 Claude Code 默认请求超时 10 分钟[8] 保存 checkpoint 后终止 预算上限 token / 美元 / API 调用次数超限 按任务等级配置[9] 熔断 + 告警 无进展检测 重复同一 tool call 与参数、观察结果无变化 连续若干次即熔断 触发断路器) 保存 checkpoint 后终止
预算上限 token / 美元 / API 调用次数超限 按任务等级配置[9](#终止类型 触发条件 典型默认值 命中后行为 目标达成 模型显式产出 final answer — 优雅退出 步数上限 达到 max_model_calls 或 max_tool_calls 由配置项决定[7] 返回"达上限"标记 时间上限 wall-clock 超时 Claude Code 默认请求超时 10 分钟[8] 保存 checkpoint 后终止 预算上限 token / 美元 / API 调用次数超限 按任务等级配置[9] 熔断 + 告警 无进展检测 重复同一 tool call 与参数、观察结果无变化 连续若干次即熔断 触发断路器) 熔断 + 告警
无进展检测 重复同一 tool call 与参数、观察结果无变化 连续若干次即熔断 触发断路器

表3 终止条件的多路熔断设计

无进展检测的关键是定义"什么算一样"------同参数、同观察或状态无变化均可作判据。命中安全停止时须返回"最佳答案"或部分结果,而非悬挂或静默截断。

3.1.4 成本预算

Langfuse 将 LLM 成本管理拆为四层递进:"先在 token 层精确追踪,再归因到用户/会话/特性,再设阈值告警,最后优化",并指出最大的成本错误通常是测量错误 而非用量错误------如同一个调用被 gateway 与 SDK 重复记录、缓存 token 被重复计数、模型名匹配不上价格表、阶梯定价按平价计算9。在 Agent 场景,四维预算统一由 middleware 实现、挂在 Act 层之前:

  • token 预算 :按 run 级别设 hard cap,通过 middleware 在每轮 LLM 调用前检查剩余额度7
  • 步数预算 :与终止条件的 max_calls 共用计数器,避免重复实现7
  • 时间预算 :wall-clock watchdog 独立于单次 LLM 调用超时,Claude Code 默认请求超时 10 分钟、可通过 API_TIMEOUT_MS 调整8
  • 金额预算 :按模型单价表实时累加,超阈值走熔断而非仅告警------告警滞后于成本累计,熔断才能止损9

3.2 隔离层(权限与审计)

隔离层回答"Agent 能碰什么",核心是沙箱分档、最小权利与不可逆操作的审批门。

3.2.1 四档沙箱

沙箱的核心矛盾:Agent 会执行"不是你写也无法 review"的代码------可能来自客户 build 步骤、学生提交、或 Agent 刚读网页后决定执行的 shell 命令10。Fly.io 与 Northflank 的共识是主流隔离原语存在信任边界差异 :容器共享宿主内核、仅适合受信代码;gVisor 用用户态内核拦截 syscall,仍共享内核边界;Firecracker 等 microVM 给每个 workload 独立 guest 内核,隔离最强1011。

档位 隔离技术 适用场景 权限边界
T1 Wasm 组件 无 ambient authority,按 import 声明授权 单 purpose 工具、MCP server 仅 import 声明的能力
T2 容器 Docker / Podman,共享内核 受信代码、已有代码库内的 Agent namespace + cgroup,需限制网络[10](#档位 隔离技术 适用场景 权限边界 T1 Wasm 组件 无 ambient authority,按 import 声明授权 单 purpose 工具、MCP server 仅 import 声明的能力 T2 容器 Docker / Podman,共享内核 受信代码、已有代码库内的 Agent namespace + cgroup,需限制网络[10] T3 硬化容器 / gVisor 用户态内核拦截 syscall 运行 LLM 生成的不完全可信代码 syscall 级拦截,仍共享内核[10][11] T4 microVM Firecracker / Kata Containers,独立内核 开放式 coding agent、任意 shell 最强隔离,worst case 是"扔掉容器"[10][11])
T3 硬化容器 / gVisor 用户态内核拦截 syscall 运行 LLM 生成的不完全可信代码 syscall 级拦截,仍共享内核[10](#档位 隔离技术 适用场景 权限边界 T1 Wasm 组件 无 ambient authority,按 import 声明授权 单 purpose 工具、MCP server 仅 import 声明的能力 T2 容器 Docker / Podman,共享内核 受信代码、已有代码库内的 Agent namespace + cgroup,需限制网络[10] T3 硬化容器 / gVisor 用户态内核拦截 syscall 运行 LLM 生成的不完全可信代码 syscall 级拦截,仍共享内核[10][11] T4 microVM Firecracker / Kata Containers,独立内核 开放式 coding agent、任意 shell 最强隔离,worst case 是"扔掉容器"[10][11])[11](#档位 隔离技术 适用场景 权限边界 T1 Wasm 组件 无 ambient authority,按 import 声明授权 单 purpose 工具、MCP server 仅 import 声明的能力 T2 容器 Docker / Podman,共享内核 受信代码、已有代码库内的 Agent namespace + cgroup,需限制网络[10] T3 硬化容器 / gVisor 用户态内核拦截 syscall 运行 LLM 生成的不完全可信代码 syscall 级拦截,仍共享内核[10][11] T4 microVM Firecracker / Kata Containers,独立内核 开放式 coding agent、任意 shell 最强隔离,worst case 是"扔掉容器"[10][11])
T4 microVM Firecracker / Kata Containers,独立内核 开放式 coding agent、任意 shell 最强隔离,worst case 是"扔掉容器"[10](#档位 隔离技术 适用场景 权限边界 T1 Wasm 组件 无 ambient authority,按 import 声明授权 单 purpose 工具、MCP server 仅 import 声明的能力 T2 容器 Docker / Podman,共享内核 受信代码、已有代码库内的 Agent namespace + cgroup,需限制网络[10] T3 硬化容器 / gVisor 用户态内核拦截 syscall 运行 LLM 生成的不完全可信代码 syscall 级拦截,仍共享内核[10][11] T4 microVM Firecracker / Kata Containers,独立内核 开放式 coding agent、任意 shell 最强隔离,worst case 是"扔掉容器"[10][11])[11](#档位 隔离技术 适用场景 权限边界 T1 Wasm 组件 无 ambient authority,按 import 声明授权 单 purpose 工具、MCP server 仅 import 声明的能力 T2 容器 Docker / Podman,共享内核 受信代码、已有代码库内的 Agent namespace + cgroup,需限制网络[10] T3 硬化容器 / gVisor 用户态内核拦截 syscall 运行 LLM 生成的不完全可信代码 syscall 级拦截,仍共享内核[10][11] T4 microVM Firecracker / Kata Containers,独立内核 开放式 coding agent、任意 shell 最强隔离,worst case 是"扔掉容器"[10][11])

表4 四档沙箱对比

Northflank 强调生产级沙箱需纵深防御 :隔离边界、资源限制、网络控制、权限范围与监控缺一不可11。关键原则:绕过审批(如 Claude Code 的 bypass permissions mode)只有在沙箱边界之后才可接受 ,且沙箱内不应有生产凭证、共享状态写权限或通往关键系统的网络路径411。

3.2.2 最小权利与审批门

每个工具先按两轴分类:可逆性 (能否撤销)与爆炸半径 (破坏扩散多远),再落入权限档位。OWASP LLM06 建议"仅授予最低必要的扩展与函数",并对高影响操作要求"独立验证与批准"4。OpenAI Agents SDK 提供了工程参考:工具可声明 needs_approval,运行时把待审批项作为 interruption 暴露给外层 RunState,人工决策后从同一状态续跑;审批覆盖跨 handoff 与嵌套 Agent.as_tool() 场景12。

Tier 示例 默认行为
Auto-run 读文件、GET、list 执行 + 记录
Log-only write 写草稿、append 队列 执行 + 记录完整 payload
Human approval 发外部邮件、扣款、部署、DELETE/DROP、改 prod 配置 暂停 + 路由到人[4](#Tier 示例 默认行为 Auto-run 读文件、GET、list 执行 + 记录 Log-only write 写草稿、append 队列 执行 + 记录完整 payload Human approval 发外部邮件、扣款、部署、DELETE/DROP、改 prod 配置 暂停 + 路由到人[4][12] Blocked 破坏性 shell、prod 裸 shell、凭证外传路径 直接拒绝[4])[12](#Tier 示例 默认行为 Auto-run 读文件、GET、list 执行 + 记录 Log-only write 写草稿、append 队列 执行 + 记录完整 payload Human approval 发外部邮件、扣款、部署、DELETE/DROP、改 prod 配置 暂停 + 路由到人[4][12] Blocked 破坏性 shell、prod 裸 shell、凭证外传路径 直接拒绝[4])
Blocked 破坏性 shell、prod 裸 shell、凭证外传路径 直接拒绝[4](#Tier 示例 默认行为 Auto-run 读文件、GET、list 执行 + 记录 Log-only write 写草稿、append 队列 执行 + 记录完整 payload Human approval 发外部邮件、扣款、部署、DELETE/DROP、改 prod 配置 暂停 + 路由到人[4][12] Blocked 破坏性 shell、prod 裸 shell、凭证外传路径 直接拒绝[4])

表5 按 blast radius 分层的权限档位

审批门 payload 四要素 :做什么(精确 tool call + 参数)、为什么(推理链与原始请求)、爆炸半径(影响记录数/环境/金额)、一键 approve/deny/edit(超时默认 deny )124。

3.2.3 用完即收与不可逆人工审核

用完即收指一次性凭证、临时 token、任务结束即销毁的 session,避免长活凭证成为重放攻击面;工具结束后释放沙箱、清空环境变量,下次任务重新签发。

不可逆操作必须人工审核 是 OWASP 的明确防护要求4,OpenAI Agents SDK 将其工程化为可序列化的暂停-续跑:工具需审批时 SDK 暂停、返回 interruptions,决策后从同一 RunState 恢复12。这把"人工审核"从流程建议升级为执行栈层级的强约束。

3.3 运维层(监控与恢复)

运维层回答"能否看得见、跑得久",核心是追踪三轴、健康信号、checkpoint 与 durable execution。

3.3.1 可观测与审计

AI Agent 可观测的目标是"出错时能回答'为什么 Agent 这样做'"------传统 APM 在 Agent 场景是盲的,因为 Agent 能返回结构良好却语义错误的结果、做三次多余的工具调用、或陷入 HTTP 200 持续烧钱的循环1415。OpenTelemetry GenAI semantic conventions 在官方仓库定义四个 Agent span 类型:create_agent、invoke_agent、invoke_workflow、execute_tool,span 名称为 create_agent {gen_ai.agent.name}、kind 为 CLIENT13。Datadog 说明,遵循该规范的 span 可经 OTLP 直接接入观测后端,无需重复埋点14。

轴 内容 典型工具
执行轴 嵌套 span 树:Trace → invoke_workflow → invoke_agent → execute_tool → LLM call Langfuse、Arize Phoenix、Datadog[13](#轴 内容 典型工具 执行轴 嵌套 span 树:Trace → invoke_workflow → invoke_agent → execute_tool → LLM call Langfuse、Arize Phoenix、Datadog[13][14] 成本轴 每 span 记录 input_tokens / output_tokens / cached_tokens / reasoning_tokens,向上聚合 Langfuse Token & Cost Tracking[15] 审计轴 Append-only、结构化、含时间戳与审批人 自建 hash chain)[14](#轴 内容 典型工具 执行轴 嵌套 span 树:Trace → invoke_workflow → invoke_agent → execute_tool → LLM call Langfuse、Arize Phoenix、Datadog[13][14] 成本轴 每 span 记录 input_tokens / output_tokens / cached_tokens / reasoning_tokens,向上聚合 Langfuse Token & Cost Tracking[15] 审计轴 Append-only、结构化、含时间戳与审批人 自建 hash chain)
成本轴 每 span 记录 input_tokens / output_tokens / cached_tokens / reasoning_tokens,向上聚合 Langfuse Token & Cost Tracking[15](#轴 内容 典型工具 执行轴 嵌套 span 树:Trace → invoke_workflow → invoke_agent → execute_tool → LLM call Langfuse、Arize Phoenix、Datadog[13][14] 成本轴 每 span 记录 input_tokens / output_tokens / cached_tokens / reasoning_tokens,向上聚合 Langfuse Token & Cost Tracking[15] 审计轴 Append-only、结构化、含时间戳与审批人 自建 hash chain)
审计轴 Append-only、结构化、含时间戳与审批人 自建 hash chain

表6 Agent 可观测的追踪三轴

健康信号 须超越"是否 200":任务完成率、工具调用成功率、审批门 deny 率(异常升高可能提示 prompt injection)、断路器触发次数、每成功任务成本、子 Agent spawn 深度分布等14152021。

3.3.2 故障恢复与续跑(Checkpoint 与 Durable Execution)

Checkpoint 与 Durable Execution 是两个不同概念 。LangGraph 的 Checkpointer 在每个 super-step 保存状态快照,以 thread_id 组织,支持人机协同、时间旅行调试、容错执行与会话记忆16。其 interrupt() 可在任意节点调用,触发时保存状态并等待,经 Command 再入图,返回值即恢复时传入的 payload17。

但 checkpoint 不等于 完全 durable execution------Temporal 把它定义为"Workflow 在崩溃、网络超时或多日等待人工审批后自动恢复",并把 ReAct 循环每步作为持久化任务由 worker 重启1819。差异的关键在重放边界 :checkpoint 恢复时 interrupt 前的代码可能再跑一次,因此 node 边界必须工程化 replay 边界,副作用靠幂等防御兜底161718。

Durable pause 实战要点:

  1. interrupt() 须设计为幂等边界------假设 interrupt 前的副作用可能被重放,配合 L1--L4 幂等防御兜底617
  2. 审批流持久化是独立工程------需追踪"哪个 run 在等谁审批",审批到达后精准 re-enter 到正确的图步骤;OpenAI Agents SDK 通过序列化 RunState(含 approvals、tool input、嵌套 resumption)实现12
  3. 重放状态须完整序列化:对话历史、中间变量、已消耗的预算计数器、幂等键------漏掉任何一个都会导致 resume 后行为不一致1619
  4. 故障演练是必做项:定期 kill worker、模拟审批超时、断网重连,验证 checkpoint 恢复

4 效果评估与适用边界

4.1 效果与实证

三层架构的效果在两个维度均有公开数据。能力维度 :Anthropic 报告称,通过优化脚手架(Tool Using Agent 设计 + error-proof 工具接口),升级后的 Claude 3.5 Sonnet 在 SWE-bench Verified 达 49%,超越此前 45% 的 SOTA3;Harness-Bench 的 5194 条轨迹统计进一步证明,完成率、过程质量、效率与失败行为在"模型-Harness 配置"层面差异显著,应报配置级结果而非归因于基础模型2。稳定性维度 :Temporal 的 durable execution 支持 Workflow 在崩溃、网络超时或多日等待人工审批后自动恢复,已用于 OpenAI 生产基础设施1918。

4.2 局限与适用边界

三层架构并非零成本:复杂度开销 ------四档沙箱 + 审批门 + 追踪三轴需跨编排、隔离、运维三团队协同,小团队落地门槛高;延迟开销 ------每次工具调用要过权限判定、审批路由与 span 采集,延迟敏感场景需权衡;测量成本 ------Langfuse 指出成本最大错误来自测量而非用量,instrumentation 本身就是持续工程9。

适用边界 :三层架构的价值密度随任务危险性与长时性递增。低风险、短周期、单轮交互的简单任务可用轻量 Harness;涉及外部副作用、不可逆操作、多日审批或需审计合规的生产级 Agent,三层不可或缺41119。

适用边界 :三层架构的价值密度随任务危险性与长时性递增。低风险、短周期、单轮交互的简单任务可用轻量 Harness;涉及外部副作用、不可逆操作、多日审批或需审计合规的生产级 Agent,三层不可或缺41119。

总结

给不可靠的 LLM 套三层约束------编排层管"怎么循环推进"、隔离层管"能碰什么"、运维层管"看得见且跑得久",三层协同才能让 Agent 从"演示里能跑"变成"生产里可信"。


知识点

复制代码
Agent 工程化三层架构
├── 1 定义本质与三层划分
│   ├── Harness 系统层定义
│   └── 三层架构图
├── 2 生产化的四类痛点
│   ├── LLM 不可靠性
│   ├── 脚手架差异实证
│   ├── 越权风险
│   └── 成本与循环
├── 3 方法机制与实现
│   ├── 3.1 编排层
│   │   ├── 五阶段循环
│   │   ├── 幂等四层防御
│   │   ├── 终止条件
│   │   └── 四维预算
│   ├── 3.2 隔离层
│   │   ├── 四档沙箱
│   │   ├── 最小权利与审批门
│   │   └── 用完即收与不可逆人审
│   └── 3.3 运维层
│       ├── 追踪三轴
│       ├── checkpoint 与 durable execution 差异
│       └── durable pause 四要点
├── 4 效果评估与适用边界
│   ├── 效果实证
│   └── 局限与边界

参考文献

1 Anthropic. "Building Effective Agents." Anthropic Engineering Blog , 2024.

2 X. Tan et al. "Harness-Bench: Measuring Harness Effects across Models in Realistic Agent Workflows." arXiv:2605.27922 , 2026.

3 Anthropic. "Claude SWE-Bench Performance." Anthropic Research , 2024.

4 OWASP GenAI Security Project. "LLM06:2025 Excessive Agency." OWASP LLM Top 10 2025 , 2025.

5 Anthropic. "Quantifying Infrastructure Noise in Agentic Coding Evals." Anthropic Research , 2026.

6 Stripe. "Idempotent Requests." Stripe API Reference .

7 LangChain. "Prebuilt Middleware - ModelCallLimitMiddleware and ToolCallLimitMiddleware." LangChain Documentation .

8 Anthropic. "Error Reference - Claude Code." Claude Code Documentation .

9 Langfuse. "LLM Cost Management: Track and Control Spend." Langfuse Engineering , 2025.

10 Fly.io. "Firecracker vs gVisor: Sandbox Isolation for Untrusted Code." Fly.io Learn , 2025.

11 Northflank. "How to Sandbox AI Agents in 2026: MicroVMs, gVisor and Hardened Containers." Northflank Blog , 2026.

12 OpenAI. "Human-in-the-Loop - OpenAI Agents SDK." OpenAI Agents SDK Documentation .

13 OpenTelemetry. "Semantic Conventions for GenAI Agent and Framework Spans." OpenTelemetry GitHub , 2025.

14 Datadog. "Datadog Agent Observability Natively Supports OpenTelemetry GenAI Semantic Conventions." Datadog Blog , 2025.

15 Langfuse. "Token & Cost Tracking." Langfuse Documentation .

16 LangChain. "Persistence - LangGraph." LangChain Documentation .

17 LangChain. "Interrupts - LangGraph." LangChain Documentation .

18 Temporal. "The Definitive Guide to Durable Execution." Temporal Blog , 2025.

19 Temporal. "Durable AI." Temporal Documentation .

20 Langfuse. "AI Agent Observability, Tracing & Evaluation with Langfuse." Langfuse Blog , 2024.

21 K. Nguyen. "AI Agent Observability 2026: Tracing & Monitoring Stack Guide." Digital Applied, 2026.


相关推荐
Solange__2 小时前
AI材质生成、图片贴图和材质扫描怎么选?按5类3D资产比较PBR、可编辑与授权
人工智能·3d·ai·自然语言处理·材质·贴图·游戏策划
高洁012 小时前
边缘AI与大模型轻量化:让智能跑进每一个终端
人工智能·python·深度学习·机器学习·迁移学习
MoRanzhi12033 小时前
第6篇(中)· 使用 PyQt5 实现 2048 高性能计算版:无头后台求解与三档运行模式
python·pyqt·数据持久化·多进程·进程间通讯·后台任务·断点续跑
Metaphor6925 小时前
Python 自动化办公:如何轻松在 PDF 中导入与导出表单数据
python·pdf·自动化
紧跟先前的步伐11 小时前
Go AI Agent 实战 06|JSON 结构化输出与 Go 后端校验
人工智能·ai·golang
Maynor99613 小时前
WorkBuddy 一键接通 gpt-6.1-sol:MomoAI / TryAllAPI 把最新模型接到桌面
人工智能·gpt·ai·大模型·编程工具
外收内放14 小时前
面向对象高级(实战案例)
开发语言·python·学习
专业程序开发源14 小时前
springboot欧缇蔓月子中心管理系统82697-计算机课程设计、毕业设计
java·spring boot·后端·python·spring·django·课程设计