Agent Harness工程实战:从循环、上下文到沙箱与验证的稳定运行设计
1. 从能跑到跑得住Harness 工程到底在解决什么很多人第一次接触 Agent 开发注意力几乎全放在模型本身——提示词怎么写、工具怎么调、输出怎么解析。等真正把 Agent 丢进一个需要连续跑几十分钟甚至几小时的任务里才会发现真正让人头疼的根本不是模型聪不聪明而是这套东西能不能稳定地跑下去。Harness 工程要处理的恰恰就是这后半段问题。我习惯把 Harness 理解成套在模型外面的那层壳。模型是发动机Harness 是底盘、变速箱、油路、仪表盘和刹车系统的总和。发动机再强底盘散架了车照样跑不起来。一个完整的 Harness 通常要管四件事怎么驱动模型一轮一轮地思考与行动Agent 循环、每一轮该给它看什么信息上下文管理、它动手时在什么环境里动沙箱、以及怎么判断它这一轮干得对不对验证。如果任务时间拉长还要额外处理状态持久化、断点恢复、资源回收这些长时运行的问题。这篇文章面向的是已经写过一两个 Agent Demo、但一放到真实任务里就各种翻车的开发者。我会按循环—上下文—沙箱—验证—长时运行这条主线把每一层的设计动机、常见坑和可落地的做法讲清楚。你不需要什么特殊框架用最朴素的代码也能把这套东西搭起来关键是理解每一层为什么必须存在。先说一个反直觉的结论大部分 Agent 失败案例根因不在模型能力而在 Harness 设计。同一个模型换一套 Harness任务成功率能从三成提到七成以上。这个差距不是玄学而是循环控制、上下文裁剪、环境隔离和结果校验这些工程细节一点点攒出来的。下面逐层拆。2. Agent 循环不是 while(true) 那么简单2.1 循环的基本形态与终止条件设计最朴素的 Agent 循环长这样把任务和当前状态发给模型模型返回一个动作执行动作把结果塞回状态再发给模型如此往复直到模型说我完成了或者达到某个上限。伪代码大概是这样state init_state(task) for step in range(MAX_STEPS): action model.decide(state) if action.type finish: return action.result observation execute(action) state update(state, action, observation) return fallback_result(state)看起来简单但这里每一个环节都有讲究。首先是终止条件。只靠模型自己说完成是极其危险的模型经常在任务没做完时就自信地宣布结束或者陷入我再检查一遍的死循环。我的做法是三重保险模型主动声明完成、达到最大步数、以及一个独立的完成度校验后面验证那节会讲。三者任一触发就退出退出时记录退出原因方便事后分析。其次是步数上限怎么定。拍脑袋设个 50 或者 100 都不靠谱。合理的做法是先跑一批样本统计正常完成任务所需的步数分布取 P95 再乘个 1.5 作为上限。比如你发现 95% 的任务在 20 步内完成那上限设 30 左右比较合适。设太小会误杀正常任务设太大则一旦模型卡住会白白烧掉大量调用。2.2 单步与多步动作什么时候该让模型一次做多件事新手常犯的一个错误是让模型每一步只做一个原子操作比如读文件一步、改一行一步、保存一步。这样循环次数暴涨上下文迅速膨胀而且模型很容易在中间步骤丢失全局目标。另一种极端是让模型一步输出一大段包含多个操作的脚本结果一处出错整段作废还很难定位。我的经验是按语义单元划分动作而不是按原子操作。一个语义单元是完成一件有独立意义的事比如定位并修复这个函数里的空指针问题可以是一步它内部可能包含读文件、搜索、编辑多个底层操作但对循环来说它是一个整体。判断标准是如果这个动作失败了你是希望整体重试还是局部重试希望整体重试的就归为一步。2.3 循环中的错误处理重试、回退与升级循环里一定会遇到错误工具调用失败、模型输出格式不对、外部服务超时。这里最忌讳的是无脑重试。我一般分三档处理瞬时错误网络抖动、限流原地重试带指数退避最多 3 次。可恢复错误格式解析失败、参数缺失把错误信息作为观察结果喂回模型让它自己修正给它 2 次机会。不可恢复错误权限不足、目标文件不存在直接终止当前动作把错误升级到循环层由循环决定是换策略还是放弃。关键点是错误信息要原样喂回模型不要自己加工成操作失败了这种模糊描述。模型看到真实的报错栈往往能自己找到修复路径。我见过太多 Harness 把错误吞掉只返回一个布尔值结果模型完全不知道发生了什么只能瞎猜。提示给每个动作打上唯一 ID把动作、观察、错误都按 ID 串起来存日志。排查问题时这条链路比任何监控指标都管用。3. 上下文工程决定 Agent 上限的隐形战场3.1 上下文窗口不是越大越好现在模型动辄支持几十万 token 的上下文很多人就觉得那我全塞进去不就行了。实测下来这是灾难。上下文越长模型对中间部分的注意力越弱所谓lost in the middle而且成本和延迟都线性上涨。更麻烦的是无关信息会稀释关键信息让模型做出错误判断。我的原则是上下文里只放当前决策必需的信息。历史步骤不需要全量保留保留最近若干步的详细内容更早的压缩成摘要。工具定义只放当前任务可能用到的不要把所有工具一股脑塞进去。文件内容按需读取不要预加载整个代码库。3.2 上下文的分层组织我通常把上下文分成四层从稳定到易变排列层级内容更新频率处理方式系统层角色设定、总体规则、输出格式几乎不变固定放在最前任务层当前目标、约束条件、验收标准任务级任务开始时写入记忆层关键结论、已确认事实、踩过的坑低频增量追加定期压缩工作层最近几步的动作与观察高频滑动窗口超出即摘要这样分层的好处是压缩时你知道该动哪一层。工作层可以大胆裁剪记忆层要谨慎系统层和任务层基本不动。很多 Harness 把所有东西混在一个列表里压缩时无从下手只能粗暴截断结果把关键约束也截掉了。3.3 摘要与压缩的实操细节压缩不是简单地把文字变短而是保留决策相关信息丢弃过程噪音。比如我读取了 config.py看到里面有 200 行配置第 47 行是数据库地址这种压缩后应该是config.py 第 47 行定义了数据库地址而不是读取了配置文件。具体做法上我倾向于让模型自己生成摘要但给它明确的模板保留做了什么决定、基于什么证据、产生了什么结果、还有什么未决问题。同时我会保留原始日志到磁盘摘要只是喂给模型的工作副本需要追溯时随时能翻原始记录。这一点很重要——摘要是有损的永远不要让它成为唯一记录。还有一个容易被忽略的点压缩时机。不要等上下文快满了才压缩那时候你已经没有余量做一次高质量的摘要了。我一般设在窗口用量的 70% 触发压缩留出 30% 的缓冲。压缩本身也是一次模型调用也要算进预算。4. 沙箱让 Agent 的手脚有地方施展又不闯祸4.1 为什么必须有沙箱Agent 要真正干活就得能执行命令、读写文件、访问网络。这些能力一旦放开风险就来了一条rm -rf可能删掉重要数据一个死循环可能吃满 CPU一次误操作可能污染生产环境。沙箱的核心目的就两个隔离影响范围和限制资源消耗。我见过不少团队为了图快直接让 Agent 在开发机上跑结果某次任务里模型自作主张清理了临时文件把别人没提交的代码一起删了。这种事故一次就够记一辈子。沙箱不是可选项是底线。4.2 隔离级别的选择隔离强度从低到高大致有这么几档按你的风险承受能力和任务需求选进程级隔离单独起一个进程限制 CPU、内存、文件描述符。轻量但文件系统还是共享的。目录级隔离给每个任务分配独立工作目录配合只读挂载和路径白名单。适合文件操作类任务。容器级隔离用容器把整个运行环境封起来文件系统、网络、进程空间都独立。这是目前最主流的选择隔离性和开销平衡得比较好。虚拟机级隔离最强隔离开销也最大一般只在处理不可信代码时才用。对大多数 Agent 任务容器级隔离是甜点区。启动一个干净容器把任务需要的文件挂进去任务结束直接销毁不留痕迹。4.3 资源限制的具体参数光隔离不够还得限资源否则一个失控的 Agent 能把宿主机拖垮。我常用的限制项和参考值# 容器资源限制示例 --cpus2 # CPU 核数上限 --memory4g # 内存上限 --memory-swap4g # 禁用 swap避免拖慢 --pids-limit256 # 进程数上限防 fork 炸弹 --read-only # 根文件系统只读 --tmpfs /tmp:size512m # 临时目录给有限可写空间 --networknone # 默认断网按需开放网络这块要特别说。默认应该断网需要联网时再按白名单开放特定域名。很多 Agent 任务根本不需要外网开放网络只会增加数据泄露和意外调用的风险。如果确实要联网也要限制出站方向别让它能随便连。4.4 文件系统的读写策略一个实用技巧是分层挂载基础环境只读工作目录可写输出目录单独挂载。这样即使 Agent 把工作目录搞乱了基础环境也不受影响而且输出物集中在一处方便收集。另外所有写操作最好走一层影子文件系统任务成功后再合并回真实位置失败就丢弃。这相当于给文件操作也加了事务语义。注意沙箱里也要设超时。单个命令执行超过阈值比如 5 分钟就强制杀掉否则一个卡住的命令会让整个任务挂死。5. 验证怎么知道 Agent 真的做对了5.1 验证的三个层次Agent 说我完成了和真的完成了之间隔着一条鸿沟。验证要分三层做格式验证输出是否符合预期结构。这是最基础的用 schema 校验就行。事实验证Agent 声称的事实是否属实。比如它说我修改了第 47 行那就去读第 47 行确认。目标验证任务的整体目标是否达成。这是最难也最重要的往往需要独立的检查逻辑。很多 Harness 只做了第一层结果模型输出格式完美但内容全错。三层都做才能把成功率真正提上去。5.2 用测试作为验证手段如果任务本身有可执行的验收标准那验证就简单了——跑测试。改代码的任务跑单元测试写脚本的任务跑一遍看输出配置类任务做一次 dry-run。能自动验证的绝不靠模型自评。我习惯在任务开始时就明确验收命令是什么写进任务层上下文。Agent 每完成一个阶段就自己跑一次验收命令把结果作为观察。这样它能在循环内部自我纠偏而不是等到最后才发现全错。这比事后验证有效得多。5.3 模型自评的正确用法没有可执行验收标准时只能靠模型自评但要用对方法。直接问你做对了吗几乎必然得到做对了。有效的做法是换一个视角、换一个上下文来评把任务目标和最终产物单独拿出来让一个不带历史对话的评审角色来判断并且要求它给出具体的判断依据和反例。更严格一点可以让评审角色扮演挑刺者专门找问题。正向问对不对容易得到肯定反向问哪里可能有问题更容易暴露真实缺陷。我实测下来这种对抗式自评比普通自评能多抓出三成左右的错误。5.4 验证失败的处置验证不通过怎么办不要直接重跑整个任务那样成本太高。正确的做法是把验证失败的具体信息喂回循环让 Agent 针对性地修复。比如测试报错说第 12 行变量未定义就把这个报错给它让它只改这一处。这要求验证输出足够具体所以验收命令要选那些报错信息清晰的。如果连续几轮验证都不过就要考虑是不是任务本身超出了能力范围及时止损比无限重试明智。我会设一个验证失败次数上限超过就标记任务失败并输出当前最佳结果和失败原因交给人来处理。6. 长时运行让 Agent 扛住几小时的连续任务6.1 状态持久化与断点恢复短任务可以全放内存长任务不行。跑两小时的任务中间进程崩一次就全没了这谁受得了。所以长时运行的第一要务是状态持久化每一步的动作、观察、当前上下文、已完成子目标都要落盘。落盘粒度要细最好每步一存这样恢复时最多丢一步。恢复逻辑要设计成幂等的。重启后先读最新状态判断当前处于哪个阶段从断点继续。这里有个坑如果某步动作有副作用比如已经发了请求、已经改了文件恢复时不能盲目重放。所以每个动作要记录是否已提交恢复时跳过已提交的只重做未完成的。6.2 心跳与健康检查长任务需要一套健康检查机制判断 Agent 是在正常工作还是卡死了。简单的做法是记录每步的时间戳如果超过阈值没有新步骤产生就判定为卡住触发干预。干预可以是重启、降级或者告警。更细一点可以监控资源使用CPU 长期 100% 可能是死循环内存持续上涨可能是泄漏网络长时间无活动可能是等待超时。这些信号组合起来能比较准确地判断 Agent 的健康状况。6.3 成本与预算控制长时运行最怕的是成本失控。一个卡住的 Agent 可能一晚上烧掉大量调用费用。所以必须有预算控制给每个任务设 token 上限和调用次数上限接近上限时告警超过就强制终止。同时记录每一步的成本任务结束后能算出总账方便优化。我还会设一个边际收益检查如果连续若干步都没有推进任何子目标说明 Agent 在原地打转这时候即使没到预算上限也应该终止。判断有没有推进可以看已完成子目标数、验证通过项数这些指标有没有变化。6.4 优雅退出与资源回收任务无论成功失败都要优雅退出保存最终状态、关闭沙箱、回收资源、输出结果和日志。特别是沙箱一定要确保销毁否则残留的容器会越积越多。我一般用 try/finally 或者上下文管理器来保证清理逻辑一定执行哪怕中间抛异常。退出时输出的东西要完整最终结果、完整日志路径、失败原因如果失败、消耗的资源统计。这些信息对后续排查和优化至关重要。很多 Harness 退出时只吐一个结果出了问题完全无从下手。7. 把五层串起来一个可落地的最小 Harness 骨架讲了这么多层最后给一个把它们串起来的最小骨架方便你对照自己的实现查漏补缺。核心结构大概是这样class Harness: def run(self, task): sandbox Sandbox.create(task.resources) state StateStore.load_or_init(task.id) try: while not self.should_stop(state): ctx ContextBuilder.build(state) action self.model.decide(ctx) if action.type finish: if self.verify(task, state): return self.finalize(state) else: state.add_feedback(self.verify_detail) continue obs sandbox.execute(action) state.record(action, obs) state.persist() return self.fallback(state) finally: sandbox.destroy() state.persist()这个骨架里should_stop综合了步数、预算、健康检查、边际收益多个条件ContextBuilder负责分层组装和压缩Sandbox负责隔离执行verify负责三层验证StateStore负责持久化和恢复。每一块都可以独立替换和优化互不影响。实际落地时我建议先跑通最小闭环再逐层加固。一开始可以不要沙箱、不要持久化先把循环和验证跑通确认任务能完成。然后加沙箱解决安全问题加持久化解决长任务问题加预算控制解决成本问题。每加一层都跑一批回归样本确认成功率没有下降。这样迭代比一上来就搭全套要稳得多。踩过的坑里最常见的是验证层做得太弱。很多人把精力全花在循环和上下文上验证就随便写个格式检查结果 Agent 表面上跑得欢实际产出全是错的。我的建议是验证层的投入至少要和循环层持平能自动验证的绝不手软。这是把 Demo 变成可用工具的分水岭。另外一个小技巧把每次任务的完整轨迹存下来定期回看失败案例。你会发现失败模式高度集中往往就那么几类。针对这几类做专项优化比泛泛地调提示词有效得多。Harness 工程的进步本质上就是不断把意外失败变成已知问题再变成已解决的过程。

相关新闻

用华为云码道 CodeArts 代码智能体,三天从零做出一个全栈 AI 求职平台(附源码)

用华为云码道 CodeArts 代码智能体,三天从零做出一个全栈 AI 求职平台(附源码)

一键开通华为云码道 CodeArts 代码智能体 项目仓库:https://atomgit.com/gcw_93rlw6ed/careerpilot (公开,MIT 协议) 演示账号:打开登录页自动进入(演示账号 candidatedemo.com 自动登录) 一、…

2026/10/15 5:38:22 阅读更多 →
Vue项目实现Office文档在线预览:DOCX、XLSX、PPT一次搞定

Vue项目实现Office文档在线预览:DOCX、XLSX、PPT一次搞定

做前端这几年,被文档预览折磨的次数真不算少。之前接一个合同管理需求,用户提了个特别朴素的要求:附件里的Word合同不要下载到本地再打开,在网页里直接能看就行。我一开始也心想,这有什么难的?不就是嵌一个…

2026/10/15 5:37:22 阅读更多 →
C00系统PLC梯形图维修指南:钻攻中心信号排查与修改实战

C00系统PLC梯形图维修指南:钻攻中心信号排查与修改实战

简介:面向日本兄弟钻攻中心C00系统的操作与维护人员,这是一份系统讲解PLC(可编程逻辑控制器)应用的官方技术手册,内容由浅入深,特别适合现场工程师和培训学员快速掌握设备控制逻辑。手册从PLC基础概念与系统…

2026/10/15 5:37:22 阅读更多 →

最新新闻

UDP广播实战:从原理到跨平台稳定收发的完整指南

UDP广播实战:从原理到跨平台稳定收发的完整指南

1. 项目概述:为什么一个“UDP广播demo”值得花一整天认真写透UDP广播这个概念,听起来像教科书里被翻旧了的一页纸——很多刚学网络编程的人,第一反应是:“不就是发个包,让局域网里所有机器都收到吗?”但真当…

2026/10/15 6:14:42 阅读更多 →
Spring事件机制实战:用ApplicationEventPublisher实现业务解耦

Spring事件机制实战:用ApplicationEventPublisher实现业务解耦

做后端开发的人应该都有过这种经历:一个下单接口,业务代码越堆越多。一开始只是保存订单,后面要扣库存、发短信、发优惠券、加积分、通知财务……新需求一个接一个,每次都要打开核心 Service 往里面塞代码。改到后面,下…

2026/10/15 6:14:42 阅读更多 →
Java工程师24周转型Agent工程师:从LLM基础到多Agent协作实战

Java工程师24周转型Agent工程师:从LLM基础到多Agent协作实战

1. 为什么Java老手转Agent工程师反而有优势这两年Agent Engineer这个岗位火得有点不讲道理。招聘网站上挂出来的JD,薪资区间普遍比同级别的后端开发高出30%到50%,而且很多岗位明确写着“有后端经验者优先”。我身边不少写了五六年Java的朋友都在问同一个…

2026/10/15 6:14:42 阅读更多 →
IDEA+Maven+Tomcat:从零创建JSP Web项目完整实战指南

IDEA+Maven+Tomcat:从零创建JSP Web项目完整实战指南

1. 项目概述:为什么现在还要学JSP,以及你将从这篇文章里得到什么先别急着划走。我知道很多人一看到JSP这仨字母,第一反应是"这不是上个时代的东西了吗?现在不都是前后端分离、Vue/React一把梭吗?"——这话没…

2026/10/15 6:14:42 阅读更多 →
机房UPS备用电源监控实战:电池巡检与告警配置全解析

机房UPS备用电源监控实战:电池巡检与告警配置全解析

说起来有点丢人,我们这套机房UPS备用电源监控系统,是被一次本可以避免的机房掉电事故逼出来的。那会儿机房规模不大,两台某品牌的200kVA主机做11冗余,带大约60多路机柜,负载不算重,约40%左右。当时我们对UP…

2026/10/15 6:14:42 阅读更多 →
对抗样本攻击方法全解析:从FGSM到物理世界攻击

对抗样本攻击方法全解析:从FGSM到物理世界攻击

1. 对抗样本攻击的底层逻辑与整体分类框架搞机器学习安全这块的人,迟早会碰到对抗样本这个绕不开的坎。我第一次接触这个概念是在做一个图像分类的小项目时,模型在测试集上准确率跑到98%以上,结果把一张熊猫照片加上一层肉眼几乎看不出来的噪…

2026/10/15 6:13:42 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →