Agent Harness 工程化实战:为什么生产瓶颈不在模型,而在线束层
Agent Harness 工程化实战:为什么生产瓶颈不在模型,而在线束层很多团队做 Agent 时,第一反应是换模型、补 Prompt、加 few-shot。原型阶段这样做通常有效,因为问题还停留在“答得对不对”。但一旦进入真实业务,问题很快变成另一类:一次任务会跨越十几步甚至几十步中间会调用数据库、浏览器、Shell、检索、审批流工具返回的数据量远大于模型真正需要看到的内容任务会超时、重试、被人工中断,也会在半路恢复成本、安全、审计开始和功能正确性同样重要这时真正限制系统的,不再是模型本身,而是包裹模型的执行系统。论文把这层称为Harness。如果借用后端工程师熟悉的类比,模型更像 CPU,Harness 更像操作系统和运行时:负责调度、隔离、I/O、状态恢复、权限边界和观测。这篇文章不打算把 ETCLOVG 七层重新念一遍,而是回答三个更接近上线前决策的问题:为什么很多 Agent 项目在 Demo 阶段顺利,到了生产环境却不稳定?ETCLOVG 七层里,哪些层会最先成为故障来源,应该按什么顺序补齐?如果你现在只有一个能跑起来的 Agent,什么时候该继续堆 Prompt,什么时候该投入 Harness 工程?一、真正把 Agent 拖垮的,通常不是推理能力先看一个典型场景。某类风控 Agent 在测试环境里表现很好:能读取工单、调用风控规则、查询交易明细,再给出处理建议。上线后却反复出现三种问题:工具返回的 JSON 太长,下一轮模型调用直接撞上上下文上限Agent 为了“确认结果”,反复读写同一批文件,形成失控循环某些高权限工具没有审批闸门,模型一旦误判就会执行危险操作如果只盯着模型,很容易得出错误结论:是不是模型不够聪明?是不是 Prompt 不够清楚?但这类事故往往有一个共同点:失败发生在模型之外。模型没有决定工具返回多少数据,也没有决定是否做上下文裁剪;模型不会天然拥有超时、重试、熔断和审批机制;模型更不会自己提供沙箱隔离和审计日志。它只是在 Harness 给定的边界里做推理。这也是论文提出Binding-Constraint Thesis的原因:在真实任务里,系统表现首先受限于“绑定层”和“约束层”,而不是只受限于模型参数规模。对工程团队来说,这个判断有两个直接含义:如果任务还是单轮问答,Harness 可以很薄如果任务已经进入“多步执行 + 外部副作用”,Harness 就不再是配套设施,而是主系统很多项目的问题不在于“还没上最强模型”,而在于“把需要系统工程解决的问题,交给了模型兜底”。二、从能回答问题,到能稳定做事,中间隔着一层 Harness论文把 Agent 工程的演进拆成了三个阶段,这个划分很有价值,因为它解释了为什么很多团队会在第二阶段和第三阶段之间卡住。Prompt Engineering - Context Engineering - Harness Engineering 问什么 让模型看到什么 让系统安全、稳定、可恢复地跑完这三个阶段并不是互斥关系,而是关注重点发生了变化。1. Prompt Engineering 解决的是“表达问题”这个阶段最关心的是:任务描述是否清楚输出格式是否稳定few-shot 是否覆盖了常见模式它适合单轮任务,也适合副作用很弱的轻量 Agent。问题在于,它默认执行环境是可靠的、工具是可控的、上下文是足够的,而生产环境恰恰不是这样。2. Context Engineering 解决的是“信息选择问题”当任务进入多轮交互后,团队会开始做:RAG 检索会话记忆历史摘要上下文裁剪这一步已经比 Prompt 工程更接近生产,但它仍然主要在解决“模型该看到什么”。如果系统需要长时间运行、调用高风险工具、支持恢复和审计,那么只做好上下文管理还不够。3. Harness Engineering 解决的是“执行系统问题”Harness 工程真正关心的是:任务在哪跑,出错后如何停工具怎么被约束、限流、路由和审批状态怎么持久化,进程挂了如何续跑任务为什么失败,成本花在哪里,谁对外部副作用负责这里需要区分一个常见误判:Context Engineering 仍然以“模型输入”为中心,Harness Engineering 则以“任务生命周期”为中心。只要任务会跨多步执行,并且工具调用会对外部世界产生副作用,系统就已经进入 Harness 问题域。三、ETCLOVG 不是名词表,而是一张故障来源地图论文提出的 ETCLOVG 七层分别是:E:Execution Environment,执行环境与沙箱T:Tool Interface Protocol,工具接口与协议C:Context Memory,上下文与记忆L:Lifecycle Orchestration,生命周期与编排O:Observability,可观测性V:Verification Evaluation,验证与评测G:Governance,治理与安全如果把它当成“分层架构图”,读完容易记不住;但如果把它当成“生产事故会从哪里冒出来的地图”,就容易理解得多。1. 最先出问题的通常是 E、T、C、L这四层直接决定任务能不能跑完。层最常见故障本质问题E命令失控、环境污染、权限越界没有隔离边界T工具超时、参数失真、错误重试没有稳定协议和调用约束C上下文爆炸、目标漂移、重要信息丢失没有做状态压缩和预算分配L任务半路失败、无法恢复、无限循环没有显式状态机和编排机制很多 Agent 原型可以“看起来能跑”,就是因为这四层暂时没有被压力打穿;但只要任务长度、工具数量、租户数量、权限等级任意一个上来,问题就会集中暴露。2. 真正拉开生产差距的往往是 O、V、G这三层不一定最早暴雷,但它们决定系统能不能长期运营。没有O,你知道任务失败了,却不知道到底卡在模型、工具、上下文还是沙箱没有V,你能看到输出,但不知道这次“完成任务”到底是正确完成还是侥幸完成没有G,系统规模越大,风险放大得越快,最后审批、审计、配额、合规都会变成补丁开源项目常常在 E/T/C/L 层做得很亮眼,因为这些层最容易体现“功能跑通”;而企业在真实环境里最终比拼的,往往是 O/V/G 能否让系统可控。四、生产环境里,七层不是平均建设,而是按故障链路补齐很多文章介绍 ETCLOVG 时,会按字母顺序一层层讲。但真实落地通常不是这样。团队不会同时建设七层,而是沿着“最先出事故的路径”补齐。更常见的演进顺序是:先补 E/T/C/L,确保任务可执行、可恢复 再补 O,确保问题可定位 再补 V/G,确保结果可信、边界可控下面按这个顺序看。E:先解决“Agent 到底在哪跑”执行环境最容易被低估,因为 Demo 通常只有一个进程、几个工具、一个测试目录。但生产环境一旦让 Agent 读写文件、执行命令、打开浏览器、访问网络,运行环境本身就成了业务边界的一部分。这里真正要做的不是选一个“最强沙箱”,而是回答两个问题:这个任务允许多大的副作用?为了这点副作用,能接受多高的启动延迟和运维成本?典型隔离方案的权衡大致如下:方案隔离强度启动开销更适合什么任务子进程 / WASM低到中很低纯计算、轻量脚本、无外网副作用Docker 容器中中标准工具链、代码修改、文件操作Firecracker microVM高中多租户、高权限工具、隔离要求高完整桌面 VM很高高浏览器自动化、GUI 测试、桌面软件控制这一步最容易犯的错是一步到位上最重的隔离。对低风险任务,这往往得不偿失。相反,更可行的做法是把任务按风险分级,再映射到不同运行时。下面这个配置示例展示的不是“万能答案”,而是一种生产上常见的思路:先把资源、回收和网络出口显式化。apiVersion:agent.harness.io/v1kind:SandboxPoolspec:runtime:firecrackerminIdle:10maxActive:200resources:cpu:"1"memory:"512Mi"disk:"2Gi"lifecycle:ttlSecondsAfterUsed:300resetStrategy:snapshotsecurity:allowedSyscalls:["read","write","open","close","exit"]networkPolicy:egress:["*.api.openai.com:443","internal-tools:443"]这个配置真正重要的不是firecracker这个单词,而是三件事:有预热池,避免每一步都冷启动有重置策略,避免上一个任务污染下一个任务有出口策略,避免“默认能访问所有东西”如果这三件事没有明确下来,沙箱本身再强,系统也不算真正可控。T:工具协议不是“能调通”就结束Agent 最大的工程复杂度,常常不在模型调用,而在工具调用。工具层容易出现四类问题:模型生成的参数不稳定,导致调用失败单个工具过慢,拖垮整条任务链路高价值工具没有限流和熔断,失败时形成雪崩工具返回内容过长,反过来污染上下文所以工具层真正需要的是“协议化”和“约束化”,而不是给模型多暴露几个 function schema。{"name":"execute_sql","version":"2.1.0","protocol":"mcp","endpoint":"grpc://sql-executor:9090","rateLimit":{"rpm":100,"concurrency":5},"timeout":"30s","schema":{"type":"object","properties":{"query":{"type":"string","maxLength":2000},"database":{"type":"string","enum":["prod_ro","staging"]}},"required":[
