ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

AI Agent稳定性实战:Harness工程中的上下文管理与任务调度

AI Agent稳定性实战:Harness工程中的上下文管理与任务调度 1. 从能跑到跑得稳AI Agent 的稳定性到底卡在哪很多人第一次搭 AI Agent 的时候都会经历一个非常相似的曲线Demo 阶段惊艳接入真实任务之后开始翻车。你让它查个资料、调个接口、写段代码单轮对话看起来都挺聪明可一旦任务链条拉长到十几步它就开始丢上下文、重复劳动、忘记目标甚至自己把自己绕进死循环。这不是模型不够聪明的问题而是驾驭层Harness没做好的问题。我先把话说在前面Agent 的能力上限由模型决定但 Agent 的稳定性上限由 Harness 决定。这句话是我踩了无数坑之后总结出来的。所谓 Harness直译是马具、挽具你可以把它理解成套在模型外面的一整套操作系统——它负责给模型喂什么上下文、允许模型调用哪些工具、每一步的输出怎么校验、失败了怎么回退、整个任务的状态存在哪里。模型是发动机Harness 是变速箱加底盘加刹车。发动机再猛底盘散了照样翻车。这篇内容适合三类人看一是正在从零搭 Agent、被各种玄学 bug 折磨的开发者二是已经有一个能跑的 Agent但想把它做成生产可用的工程师三是对 Agent 架构感兴趣、想搞清楚Harness 和 Agent 到底啥区别的学习者。我会围绕上下文管理、任务调度、工具编排、状态持久化、失败恢复这几个核心机制展开把我在实际项目里验证过的做法、踩过的坑、以及那些文档里不会写的经验尽量讲透。先厘清一个高频困惑Harness 和 Agent 不是一回事。Agent 是一个会自主决策、调用工具、完成目标的智能体这个概念本身Harness 是让这个智能体稳定运行的那套工程框架。打个比方Agent 是司机Harness 是车。司机再老练车没有方向盘助力、没有 ABS、没有仪表盘跑长途一样出事。很多开源项目号称Agent 框架其实里面一大半代码都在做 Harness 的活——上下文裁剪、重试、工具路由、状态机管理。搞清楚这个分层你后面设计系统的时候脑子会清楚很多。2. 上下文管理Agent 稳定性的第一命门2.1 为什么上下文不是塞得越多越好新手最容易犯的错就是把所有历史消息一股脑全塞进 prompt觉得信息越全模型越聪明。实测下来恰恰相反上下文越长模型的注意力越稀释关键信息越容易被淹没。这就像你给一个员工布置任务把过去三天的所有聊天记录、邮件、会议纪要全甩给他他反而抓不住重点。上下文管理的核心目标不是保留全部信息而是在有限的 token 预算内保留对当前决策最有价值的信息。这里有个关键概念叫token 预算——模型的上下文窗口是有上限的你必须在历史对话工具返回结果系统指令当前任务状态之间做分配。我的经验是给这几类内容划一个大致比例比如系统指令占 10%、任务状态占 20%、近期对话占 40%、工具结果占 30%具体比例按任务类型调。2.2 三层上下文裁剪策略我在项目里用的是一套分层裁剪策略从粗到细三层第一层硬截断。超过窗口上限的部分直接丢弃但丢弃的是最老的对话不是最新的。这一层是兜底防止程序崩溃。第二层摘要压缩。把较早的对话用模型自己总结成一段历史摘要保留关键决策和结论丢掉过程性废话。这一步很关键因为很多 Agent 的记忆其实就是靠摘要撑起来的。第三层相关性筛选。对当前任务用向量检索或关键词匹配把最相关的历史片段捞回来而不是按时间顺序全带上。这三层配合起来效果比单纯截断好太多。我做过对比测试同样一个多步任务纯截断方案在第 8 步左右就开始丢目标三层策略能撑到 20 步以上还保持连贯。2.3 工具返回结果的瘦身处理还有一个特别容易被忽略的点工具返回的结果往往又长又脏。你调一个搜索接口返回一大坨 JSON里面 90% 的字段 Agent 根本用不上。如果原样塞进上下文几轮下来 token 就爆了。我的做法是在工具层做一次结果预处理只提取 Agent 真正需要的字段长文本做截断加省略号结构化数据转成紧凑格式。比如搜索返回 20 条结果我只保留前 5 条的标题和摘要其余丢弃。这一步能省下大量 token而且不影响决策质量。提示上下文裁剪一定要有日志。每次裁剪前后都记录 token 数和保留内容出问题的时候你才知道是哪一步把关键信息裁掉了。我吃过这个亏排查了整整一个下午。3. 任务调度让 Agent 知道现在该干什么3.1 从自由发挥到状态机驱动早期我做 Agent 的时候是让它完全自由发挥——给个目标它自己决定下一步。结果就是它经常跑偏做着做着就忘了原始目标或者在一个子任务上反复打转。后来我改成了状态机驱动的思路把任务拆成明确的阶段每个阶段有清晰的进入条件、退出条件和允许的动作。这不是要限制 Agent 的智能而是给它一个轨道。就像火车可以在轨道上高速行驶但脱轨就完蛋。状态机就是那条轨道。常见的阶段划分比如理解目标 → 收集信息 → 制定计划 → 执行步骤 → 校验结果 → 输出。每个阶段 Agent 只能做该阶段允许的事做完自动流转到下一阶段。3.2 任务分解的粒度控制任务分解太粗Agent 一步做不完分解太细调度开销爆炸。我的经验是单个子任务的执行步数控制在 3 到 7 步之间。超过 7 步说明这个子任务还能再拆少于 3 步说明拆得太碎合并一下。这里有个实操技巧让 Agent 在制定计划时对每个子任务预估一个复杂度分数1 到 5分数高的自动触发二次分解。这个机制能有效防止 Agent 一头扎进一个巨大的任务里出不来。3.3 调度中的防打转机制Agent 打转是最常见的稳定性问题之一。表现就是它在两个状态之间来回跳或者反复调用同一个工具。我的防打转机制有三道步数上限整个任务设一个最大步数比如 50 步超了强制终止并输出当前进展。重复检测记录最近 N 步的动作签名工具名加参数哈希如果连续出现相同签名触发警告并强制换策略。进展评估每隔几步让 Agent 自评一次距离目标还有多远如果评估结果连续不变说明卡住了需要人工介入或换方案。这三道防线配合起来能挡掉绝大多数打转情况。我印象最深的一次Agent 在一个 API 调用上反复重试了 30 多次就是因为没做重复检测白白烧了一堆 token。4. 工具编排Agent 的手脚怎么接才不出事4.1 工具描述的质量决定调用准确率很多人抱怨 Agent 调错工具其实问题往往出在工具描述写得烂。模型选工具靠的就是描述文本你描述写得含糊它当然选错。好的工具描述应该包含这个工具干什么、什么情况下用、输入参数的含义和格式、返回什么、有什么限制。我见过一个反面案例一个工具描述只写了查询数据结果 Agent 在需要查用户信息、查订单、查日志的时候全调它因为它看起来啥都能查。后来把描述改成根据用户 ID 查询用户的基本资料包括昵称、注册时间、等级不包含订单信息调用准确率立刻上去了。4.2 工具调用的参数校验与容错Agent 生成的工具参数经常有格式问题——该传数字传了字符串该传数组传了单个值必填字段漏了。如果直接透传给后端轻则报错重则写坏数据。所以工具层必须做参数校验而且要给出清晰的错误信息让 Agent 能自我修正。我的做法是在工具入口加一层 schema 校验校验失败时返回结构化的错误提示比如参数 user_id 必须是整数你传的是字符串 123请修正后重试。Agent 拿到这种提示通常下一轮就能改对。如果只返回一个参数错误它大概率会瞎猜。4.3 危险操作的人工确认闸门有些工具是写操作——发消息、改数据、删文件。这类操作绝对不能让它自动执行必须加人工确认闸门。我的做法是给工具打上危险等级标签高危工具调用前暂停把 Agent 的意图和参数展示给用户确认后才执行。注意这个闸门不是限制 Agent 能力而是保护你自己。我见过 Agent 因为理解偏差把测试数据写进了生产库那酸爽至今难忘。5. 状态持久化与失败恢复Agent 的存档读档5.1 为什么 Agent 必须能断点续跑长任务跑到一半程序崩了、网络断了、token 用完了如果没有状态持久化一切从头再来。这在生产环境是不可接受的。Agent 的状态必须能存能读就像游戏存档一样。我用的方案是把 Agent 的完整状态序列化后存到外部存储——包括当前阶段、已完成步骤、上下文摘要、工具调用记录、中间结果。每次状态变更就存一次重启时从最近的存档恢复。这样即使中途挂了也能接着跑。5.2 失败分类与差异化恢复策略不是所有失败都一样恢复策略也得区别对待失败类型典型场景恢复策略瞬时失败网络抖动、接口超时指数退避重试最多 3 次参数失败工具参数格式错返回错误给 Agent让它自我修正逻辑失败Agent 走错方向回退到上一个检查点换策略重试致命失败权限不足、资源耗尽终止任务输出诊断信息人工介入这张表是我踩坑踩出来的。早期我对所有失败都无脑重试结果逻辑失败越重试越糟白白浪费资源。分类之后恢复效率高了一大截。5.3 检查点的设置时机检查点不能设太密开销大也不能太稀回退代价高。我的经验是在每个阶段切换时设检查点加上关键工具调用成功后设一个。这样回退粒度适中既不会丢太多进度也不会频繁写存储。6. 那些文档不会告诉你的实战心得6.1 日志要记决策依据不只是执行结果大部分人的日志只记了调用了什么工具、返回了什么但排查问题时真正有用的是Agent 为什么这么决策。所以我在每步都记录 Agent 的推理摘要——它当时看到了什么、考虑了哪些选项、为什么选了这个。有了这个出问题时你能快速定位是信息不足导致决策错还是信息够了但推理错。6.2 给 Agent 设预算防止失控token 是有成本的时间也是有成本的。我给每个任务设了双重预算token 预算和时间预算。超预算就强制收尾输出当前最好的结果。这个机制能防止 Agent 在无解的问题上无限烧钱。6.3 小步快跑别追求一次做完美我见过太多人想一步到位设计一个完美 Harness结果复杂度爆炸自己都维护不动。正确的做法是先跑通最小闭环再逐步加机制。先有基本的上下文管理和工具调用跑起来再加状态机再加持久化再加防打转。每加一层都验证效果别一次性堆上去。6.4 测试要用对抗性用例正常用例谁都能过真正考验 Harness 的是对抗性用例——故意给模糊的目标、故意让工具返回错误、故意制造网络中断。我专门维护了一个捣乱测试集每次改完 Harness 都跑一遍。这个习惯帮我提前发现了无数线上才会暴露的问题。7. 关于 Harness 工程的一点个人体会做 Agent 这件事越往后越会发现难点从来不在模型而在工程。模型能力每年都在涨但 Harness 的活儿是实打实要一行行写、一个个坑填的。我现在的判断是一个团队能不能把 Agent 做成产品看的不是它用了多强的模型而是它的 Harness 工程做得多扎实。上下文管理决定了 Agent 能记多久任务调度决定了它能走多远工具编排决定了它能做多准状态持久化决定了它能不能扛住意外。这四块拼起来才是一个稳定的 Agent。至于那些花哨的架构名词说到底都是为这四件事服务的。最后分享一个我一直在用的判断标准如果一个 Agent 在连续 20 步的复杂任务里还能保持目标不漂移、工具不乱调、失败能自愈那它的 Harness 就算及格了。你可以拿这个标准去测自己的项目大概率会发现问题比想象中多。但别慌一个个补就是了——Harness 工程本来就是个不断打磨的活儿没有终点只有更稳。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进