Self-Harness:让Agent控制框架自动进化,告别人肉调优

发布时间:2026/9/17 4:02:52
Self-Harness:让Agent控制框架自动进化,告别人肉调优 1. 重新认识 Agent Harness不是“绳子”是“驾驶舱”1.1 从“裸奔的 Agent”说起为什么需要 Harness先说一个我自己的切身体会。最早做 Agent 原型的时候我的想法特别单纯把大模型的 API 接上丢给它几个工具函数让它自己去完成任务。跑通 demo 的那一瞬间确实爽但进了真实业务场景就发现根本不是那么回事。模型经常会在某个分支里反复横跳工具调用顺序乱套提示词里明明写了“先查数据库再调接口”Agent 偏要反着来甚至有时候它会把同一个工具连续调用七八次像是在原地打转。后来我才意识到问题不出在模型本身而是出在“约束”上。大模型本质上是一个概率系统你给它再强的推理能力它也需要一个明确的行为边界、执行规则和纠错机制。这个边界和机制就是行业里常说的Agent Harness。Harness 这个英文词本意是“马具”或者“安全带”。放到 Agent 开发里它指的是包围在 Agent 核心逻辑外面的那一层“控制系统”。这层系统负责管理提示词、工具列表、执行流程、上下文窗口、重试策略、权限边界以及 Agent 每一步动作的范围。你可以把 Agent 当成驾驶员Harness 就是驾驶舱——驾驶员技术再好仪表盘、油门刹车、导航路线也得靠驾驶舱来定义和约束。我见过不少团队一上来就追求 Agent“聪明”把精力全花在调模型提示词上却忽略了 Harness 的存在。结果就是项目越做越脆换一个场景就得重写一套逻辑。真正稳定可用的 Agent 项目Harness 占据了半壁江山。1.2 Harness 和 Agent 到底有什么区别刚接触这个领域的人经常把 Agent 和 Harness 混为一谈包括我自己早期也走过这个弯路。一句话区分Agent 是“做什么”的决策者Harness 是“怎么做、能做什么、不能做什么”的执行框架。展开一点说Agent 的核心能力是拆解任务、选择工具、调用工具、汇总结果。它靠的是大模型的推理能力和指令遵循能力。而 Harness 更接近传统软件工程里的“运行时框架”它定义了Agent 的输入输出协议比如消息格式、工具调用格式工具注册表哪些工具可见、哪些工具在当前步骤被禁用执行循环的控制逻辑比如最大步数、最大 token 限制、超时时间提示词的组装策略系统提示词如何拼接、历史消息如何压缩、工具文档如何注入错误处理与自愈机制比如工具调用失败后是否重试、是否需要换一种写法可观测性每一步决策的日志、token 消耗、成本统计都要能追溯到拿一个实际例子说明。假设我要做一个“自动巡检服务器并生成报告”的 Agent。Agent 要做的事是理解“巡检”目标、决定调用哪些检测命令、分析输出结果、生成报告。而 Harness 要做的事更底层规定这个 Agent 只能访问白名单内的检测命令不允许访问生产环境的删除接口规定每次巡检最多执行 15 步超过就强制停止规定每一条命令执行前都要登记日志耗时超过 30 秒的命令自动中断还规定报告必须按照固定模板输出。这些规则如果只写在提示词里模型偶尔就会“忘记”写在 Harness 里就成了强制约束模型根本没有机会绕过。所以在实际项目里我的建议是把 Harness 当作一种“基础设施”来建设。它的价值不在于让 Agent 在某一次任务里表现更好而在于让 Agent 的行为变得可预测、可控制、可审计、可持续改进。1.3 为什么 Harness 必须“自我改进”传统 Harness 的问题也很明显它是静态的。你写好了规则它就一成不变地执行Agent 表现不好只能靠人肉去翻日志、调提示词、改工具列表然后再发一版。一次两次还行Agent 应用一旦进入生产环境场景复杂度上来之后人工调优根本跟不上。举个我自己踩过的坑。我做过一个面向内部客服场景的 Agent工具列表里挂了 20 多个接口。一开始我精心设计了工具描述和路由提示词但上线后发现客服问题稍微绕一点比如“用户说订单被扣款但没出票”Agent 就不知道该先查订单状态还是先查支付流水。我连续调了三版提示词效果还是很随机。后来我换了个思路不再手动调提示词而是让 Harness 收集这类失败案例自动总结规律把“遇到扣款未出票类问题优先查询支付流水表”的规则自动写入 Harness 的约束文件并在下一次运行时强制启用。这就是Self-Harness 的基本雏形——让控制框架本身具备感知、分析、自我调整的能力。这个方向的工程价值非常大。它把“Agent 调优”从一种依赖个人经验的手艺活变成了一套可以自动化、可量化的工程流程。说白了我们缺的从来不是一个更聪明的模型而是一个能不断学习、不断收紧行为边界的支架。Self-Harness 要解决的就是这个问题。1.4 Self-Harness 的适用人群与场景根据我自己的实践下面这几类团队最适合在这个方向投入正在做 Agent 应用落地的团队尤其是 Agent 已经进入测试或生产阶段单靠人肉调优已经力不从心的时候。Self-Harness 的价值体现得最直接。做 Agent 平台或框架开发的工程师需要为上层业务提供可插拔、可自驱动的 Harness 能力让业务方不用每次重复造轮子。运维自动化、客服自动化、代码生成等高频重复场景这些场景天然会积累大量历史运行数据恰好是 Self-Harness 自我改进的“燃料”。研究提示词工程或 Agent 行为优化的同学Self-Harness 本质上就是把提示词优化、工具路由、失败修复这些工作用一种系统性的方式串起来。不需要有很深的算法背景核心开发工作还是软件工程为主关键是理解“反馈闭环”的设计思路以及怎么把日志和评估结果转换成可执行的框架更新。2. Self-Harness 的核心设计让框架自己“写作业”2.1 一句话理解 Self-Harness如果让我用一句话概括 Self-Harness我会说它是这样一套系统——Agent 每运行一次Harness 都会把运行结果喂给一个“评估器”评估器找出失败模式和低效模式再由“改进器”生成补丁更新 Harness 自身的提示词、工具配置或流程配置让下一次运行能少犯同样的错。这听起来有点像 AutoML也有点像强化学习里的策略迭代但工程实现上更简单、更透明。Self-Harness 不追求修改模型权重它只修改模型外部的“控制配置”。因为不碰权重所以不需要训练资源不需要算力集群一套普通的后处理流程就能跑起来。打个比方传统 Harness 是一本写好的规章手册Agent 照着执行Self-Harness 相当于给规章手册配了一个“编辑委员会”每次执行完毕委员会会根据事故报告修订手册再把新版手册发给所有 Agent。2.2 自我改进的三类反馈信号来源不先把反馈信号设计清楚后面所有工作都是空中楼阁。我自己在实践中最看重三类信号第一类任务结果信号。这个最直观。Agent 执行一个任务最后给出的答案是对是错用户可以点“有帮助”或“无帮助”。在代码生成场景里就是生成的代码能不能通过测试用例在运维场景里就是执行完命令后目标状态是否达到预期。这类信号信噪比最高也最容易采集。第二类过程效率信号。即使最终任务成功运行过程也可能很糟糕。比如某个操作走了 20 步才完成正常只需 5 步比如同一个工具被反复调用参数几乎一样比如中间连续出现了 3 次工具执行错误靠重试才蒙混过关。这些信号代表了“隐性失败”在真实业务里往往会累积成高延迟和高成本。第三类约束冲突信号。当 Agent 的行为偏离了 Harness 里定义的规则例如调用了被禁止的工具、输出的格式不符合规范、在某个环节超出步数限制这类信号说明 Harness 的规则没有被模型充分理解或者规则本身就不合理。这类信号的价值在于它能告诉我们“约束文件哪里写得不清楚”。在具体实现时我会把这三类信号全部归一化成一条一条的“事件”带上时间戳、Agent 会话 ID、具体错误信息和上下文截断摘要再落入统一的存储里。后续的评估器、改进器都从这份事件流里取数。2.3 改进器Improver与编译流程改进器是 Self-Harness 的核心组件。它读取评估器产出的“问题清单”针对每一个问题生成相应的 Harness 配置补丁。补丁分成三类Prompt 补丁往系统提示词或 Hint 文件里追加一条规则例如“在处理退款争议时必须先查询支付流水表”Tool 补丁调整工具的可见性、参数描述、调用前置条件或者把某些低效工具从主流程里降级Workflow 补丁修改执行流程比如增加一个前置路由节点或者对一个容易出错的步骤设置重试策略补丁生成之后不能直接生效必须先经过一次“编译验证”。这里的编译不是传统意义的代码编译而是把补丁合并进 Harness 的基础配置跑一遍配置校验、在测试集上回放一遍历史日志确认新的配置不会让原本正常的场景崩溃。通过验证之后补丁才能进入新的 Harness 版本。我自己的实现里会把每个补丁都存成带编号的 diff 文件和 Git 的提交记录一一对应。这样任何一个改坏了都能快速回滚到上一个稳定版本。这套机制不复杂但在生产环境里极其重要。2.4 为什么选这套设计而不是直接调模型可能有朋友要问既然要自我改进为什么不直接用强化学习微调模型或者用更高级的自动化推理框架我的回答是成本和透明度。微调一个好模型动辄需要大量高质量数据和几百张显卡一个团队如果只是为了优化工具路由规则这种投入完全不划算。而且模型微调是不可解释的出了问题很难定位。Self-Harness 把改进对象限制在模型外部的“配置文件”上这带来三个直接好处。第一改造成本低一套 Python 脚本加配置文件就能跑起来第二可解释性强每一版 Harness 改动都能明确对应到某几条新增规则出了问题改回去就行第三和模型解耦今天用 GPT、明天换开源模型Harness 照常工作规则和提示词的调整经验还能积累复用。这套设计思路的本质是把“模型能力”和“业务约束”分开治理。模型负责泛化智能Harness 负责沉淀那些具体的、场景化的、不断累积的经验。两者各司其职系统才会越来越稳。3. 落地实操构建 Self-Harness 的五个核心模块3.1 Hint 配置把经验写进上下文的“便签条”我最早尝试自我改进时第一个想到的落地对象就是 Hint 配置。所谓 Hint就是系统提示词里一段独立维护的规则列表它独立于模型主提示词专门用来注入“最近总结出的新经验”。举个例子。假设我维护一个代码评审 Agent工具列表里有“读取文件”“搜索代码”“提交评论”三个工具。一开始提示词里关于“提交评论”只要求“格式化为 Markdown”。跑了几轮之后评估器发现评论经常遗漏对测试用例的建议。改进器就会生成一条 Hint在提交评论时始终坚持以下顺序 1. 指出代码风格问题 2. 指出潜在逻辑缺陷 3. 明确建议增加/更新的测试用例 4. 给出可执行的重构建议这条 Hint 会被追加到系统提示词的固定区域每次 Agent 加载时自动带上。实现上非常简单就是维护一份 Markdown 或 YAML 文件在构建提示词时拼接到 System Prompt 的尾部。关键在于Hint 文件必须支持追加和回滚并且每一条 Hint 都要带上触发场景标签避免所有场景都堆同一堆规则。我在实际项目里会为 Hint 设计一个简单的 schema包括id、trigger触发条件描述、content规则内容、source哪一轮改进产生的、created_at等字段。这样即使规则积累到了几百条也能通过检索只注入与当前任务相关的部分不会把上下文撑爆。3.2 Tool 配置工具列表的“增删改查”工具配置是另一个非常适合自我改进的模块。Agent 的工具列表不是越多越好。工具太多模型的选择压力大容易选错工具描述写得不好模型会误解用途。Self-Harness 可以持续优化工具列表的“可见性”和“描述准确性”。我的做法是给每个工具加一个enabled_by_default标记和一组routing_tags路由标签。改进器发现某个工具长期不被调用或者调用后频繁报错就会自动把它的默认可见性改成“隐藏”如果发现某个问题场景下应该先调 A 工具却总去调 B 工具就会在 A 工具的描述里追加一条“当遇到 X 类问题时优先选择本工具”的说明。这里有一个重要细节隐藏工具不等于删除工具。Agent 在极少数情况下仍然可以通过明确的“意图表达”唤起隐藏工具。我把这个机制叫做“工具降级而非工具禁用”它既减少了模型的选择噪声又保留了兜底能力。工具配置的自我改进同样需要版本管理。我会把每个工具的注册信息写成独立的 YAML 片段改进器生成修改建议人工确认后合并到主配置。之所以保留人工确认环节是因为工具配置直接影响生产系统的安全边界不能完全放手给模型去改。3.3 工作流与路由配置让执行路径自适应比工具配置更上一层的是工作流和路由配置。这里解决的是“多步骤 Agent 任务”的编排问题。一个复杂的业务任务通常不是一步完成的而是拆成路由节点、处理节点、验证节点、输出节点。Self-Harness 就是用来持续修正这个链条的。一个我在客服 Agent 里做过的优化最初的流程是“用户提问 - 直接调用工具 - 生成回答”。结果发现涉及退款流程的问题直接调“生成回答”往往答非所问。改进器分析日志后建议在流程中加入一个前置路由节点专门用于识别“退款/支付/订单状态”类问题然后把请求引导到对应的处理子流程。在代码层面我会把工作流定义成 JSON 配置节点类型包括router路由、tool_call工具调用、llm_step大模型处理、condition条件判断等。每次改进器更新工作流本质上就是增删节点或调整节点间的连接关系。这里我非常推荐把工作流也纳入版本管理并且每次改动后都自动跑一遍历史黄金用例集防止改动引发回归。自适应的路由配置是 Self-Harness 最出彩的地方因为它直接影响 Agent 的执行路径优化效果立竿见影。但它的风险也最大改错了可能导致一大类任务整体失败。所以工作流补丁我一般都会设置一个“灰度生效期”先在 10% 的流量上测试稳定后再全量。3.4 评估与追踪先有“眼睛”才有“手术刀”前面几个模块改进再多如果没有可靠的评估机制Self-Harness 就是盲人摸象。评估模块要回答三个问题这次运行成功还是失败失败在哪个环节和上一次相比是变好了还是变差了我的评估模块分两层。第一层是规则评估器它用一套可编程的规则检查运行结果。比如代码生成任务就检查测试用例通过率、编译是否成功、代码规范扫描是否通过客服任务就检查答案中是否包含关键实体订单号、退款金额、语气是否合规。第二层是模型评估器用一个专门负责打分的评估模型对结果进行多维打分包括准确性、完整性和格式规范性。追踪系统则负责把每次运行的全过程记录下来。我会为每次 Agent 运行生成一个 trace_id然后把以下信息全部关联到这条 trace 上用户输入原文Agent 每一步的思考摘要工具调用请求与响应上下文截断事件最终输出结果耗时、token 消耗、成本用户反馈或评估器打分这些数据积累到一定量级后评估器就能用统计方法找出高频失败模式。比如“有 30% 的失败案例都发生在用户意图涉及‘退款’时”那改进器就有明确方向了。没有这套追踪系统所谓的自我改进就是空谈。3.5 改进器触发与版本回滚机制最后是改进器的触发逻辑和回滚机制。改进器不能随时乱跑必须按节奏触发。我的做法是设置一个“改进流水线”当评估模块累计了 N 个失败样本或者每隔固定周期比如每天凌晨自动启动一次改进流程。改进流程先对失败样本做聚类找出 top 失败模式然后为每个模式生成一个补丁草案。补丁草案生成之后先在测试集上做回放验证计算“补丁收益”——即补丁上线后理论上能挽回多少失败样本。收益低于阈值的补丁直接丢弃收益达标但风险较高的补丁进入人工审核队列只有低风险高收益的补丁才自动上线。版本回滚我强烈建议做成“一键式”。因为即使做了回放验证真实环境里仍然可能出现意料之外的情况。我的方案是用 Git 管理所有 Harness 配置每次自动更新就产生一次带 tag 的提交。回滚命令就一句话git revert commit_id reload。我还会把每次自动更新的 diff 摘要、评估指标、影响范围全部写进一个更新日志文件方便排查。4. 完整改进循环拆解从“踩坑”到“修复”4.1 一个具体场景Agent 重构代码时老把测试改丢为了让整个流程更直观我拿一个我自己长期维护的“代码重构 Agent”来举例。这个 Agent 的任务简单说就是读取一个源码文件按需重构跑测试提交结果。工具列表包括read_file、write_file、run_test、search_symbols、submit_patch。一开始我用的 Harness 配置非常朴素没有 Hint工具描述也写得很简短流程就是“读取 → 重构 → 测试 → 提交”。上线跑了两周评估器统计出一个非常刺眼的失败模式有约 25% 的重构任务Agent 提交的补丁会把原有的测试用例删掉或者改得面目全非。测试覆盖率明显下降但 Agent 自己提交时还认为“测试全部通过”。如果靠人工调优我大概会去改提示词在系统提示词里长篇大论地写一堆“不要删除测试”“不要修改测试逻辑”。但 Self-Harness 的做法完全不同它把这个失败模式转化成了一条结构性规则。4.2 一次完整的 Self-Harness 改进流程分步骤下面就是这个流程在 Self-Harness 里的实际运作过程第一步失败样本聚类。评估器从日志库中捞出失败案例发现共同特征是输出补丁中的delete行占比异常高且删除的内容集中在test_前缀的代码块。聚类结果被标记为“高风险——重构过程中破坏测试代码”。第二步改进器生成补丁草案。改进器分析这些样本后生成了一个 Hint 补丁内容如下id: hint-20250614-001 trigger: 重构场景涉及测试文件和被测文件 content: | 重构时务必遵守以下规则 1. 测试文件中的所有测试函数禁止删除或改名 2. 若重构导致测试失败优先调整被测代码而不是修改测试断言 3. 若确有测试本身存在问题必须在补丁说明中明确列出原因。 source: 自动改进——失败模式聚类 #42同时改进器还给write_file工具生成了一条增强描述“当写入目标为测试文件时需要额外校验修改是否导致测试函数数量减少。”第三步回放验证。补丁草案在历史 500 条样本上回放结果是原本失败的 120 个案例中理论上可修复 82 个修复率约 68%同时不会影响原本成功的样本。收益达标风险低自动上线。第四步灰度生效。新 Harness 版本在 20% 流量上生效运行 3 天失败率从 25% 降到 14%。随后扩大至 100%失败率稳定在 11% 左右。第五步生成更新日志。系统自动生成提交记录标题是“hint-20250614-001防止重构Agent删除测试代码”附上指标对比。4.3 这次改进带来的启示整个流程里最让我吃惊的不是失败率下降而是改进的“可迁移性”。因为新增规则被写进了通用 Hint 文件当我把同一个 Harness 用到另一个“自动化补丁生成”任务上时这条防删除规则同样生效。也就是说Self-Harness 积累的不仅仅是某一个任务的补丁而是一套跨任务、跨场景的工程经验库。当然不是每次改进都有这么好的效果。我跑过的另外一轮改进想通过修改路由节点让 Agent 更频繁地调用搜索工具结果回放时发现会拖慢整体执行速度最后被收益阈值直接拦下。这说明评估器和改进器配合工作的节奏很重要宁可保守一点也不要为了“改进”而改进。4.4 改进循环的工程节奏与人工介入点关于改进的节奏我的经验是不要贪多每次只解决一个最重要的失败模式。一次性塞进去十条规定模型根本记不住反而可能把原本正常的行为搞乱。我一般会让改进器按“失败样本数量 × 影响严重程度”给模式打分每次只处理得分最高的一个。人工介入点也很关键。我保留了三个人工审核场景涉及工具启用或禁用、涉及工作流节点增删、以及影响范围超过 20% 流量的改动。在这三类改动上即使自动评估收益很高我也会要求有经验的工程师过目一遍。毕竟 Harness 最终要管的还是生产环境安全比效率重要。5. 常见问题与踩坑实录5.1 四个高频问题与排查表这个方向看着不复杂真正实操时坑不少。我整理了四个自己或团队踩过的高频问题问题现象根本原因排查方向解决方案改进器不断生成重复规则Hint 文件快速膨胀失败样本聚类粒度过粗多条规则本质是同一件事检查评估器的聚类结果看是否有大量重复主题在改进器里增加“与已有 Hint 相似度”过滤相似度超阈值直接合并或丢弃新规则上线后原本正常的场景开始失败回放验证的样本集覆盖不足缺少某些边界样本检查回放集是否包含足够多不同业务场景的样本扩充黄金样本集覆盖每个工具、每个流程节点的正反案例Agent 完全不理会新增 Hint规则形同虚设Hint 注入位置不对或者模型上下文太长被截断检查实际发送给模型的 System Prompt 里 Hint 是否完整出现把 Hint 提到更高优先级的位置并压缩历史消息释放上下文空间自我改进在测试环境有效生产环境失效生产环境数据分布和测试集差异过大对比生产和测试环境的样本特征特别是输入长度、工具调用模式增加生产环境灰度验证阶段先用小流量测试再全量这四类问题里最隐蔽的是第二条。我之前踩过一次坑改了一版 Hint 以为很完美结果某个冷门场景直接崩了。原因就是回放集太“正面”全是从历史成功样本里抽的没覆盖真实的边界情况。从那以后我把黄金样本集改成了“正向集 负向集 边界集”三份每次回放必须三份全过才能上线。5.2 三个独家避坑心得第一Hint 规则要带“场景标签”不要写“万能规则”。没有场景标签的规则积累多了会对无关任务产生干扰。比如“涉及退款先查支付流水”这条规则如果所有任务都注入一个写文案的 Agent 也会莫名收到退款信息。正确做法是让规则带上trigger字段启动时只注入与当前任务意图匹配的部分。第二评估器要能识别“假成功”。Agent 的标准里“成功”和业务上的“成功”经常不一样。代码重构 Agent 认为测试通过就算成功但业务上还要求覆盖率不下降客服 Agent 认为回复了用户就算成功但业务上还要求解答正确。所以评估器里除了规则评估一定要引入业务维度指标否则 Self-Harness 会不断优化一个错误的目标。第三给改进器设置“耐心值”。一条规则刚上线时短期效果可能不明显甚至因为模型随机性出现回退。我遇到过因为一两天数据波动就把一条本来正确的规则回滚掉的情况。现在我会让改进器观察至少 50 个新样本后再下结论避免被随机性误导。5.3 硬件与成本建议最后说一点大家可能关心的事。Self-Harness 不需要专门的训练硬件它跑的是数据分析和轻量级模型推理普通的 CPU 机器加少量 GPU 就能跑起来。我自己的实践里改进器用的就是一个中等规模的开源模型7B 到 14B 级别主要负责生成补丁草案单次成本很低。真正的大头反而是评估器——它需要对每一次 Agent 运行都做打分如果流量大可以选择先采样评估而不是全量评估。日志存储也要提前规划。每次运行的完整 trace 数据量不小我会在采集时就做摘要压缩保留完整工具调用记录的样本只占一小部分大部分样本只保留关键事件和最终结果。这样既能满足聚类分析的需求又不会让存储成本失控。根据我个人经验构建 Self-Harness 最重要的是先跑通一条最小闭环哪怕只是让系统学会往 Hint 文件里追加一条规则、然后验证这条规则有效这个闭环本身就是最大的门槛。配套设施比如评估器、灰度发布、版本回滚都是在闭环跑通之后逐步加厚的。不要等项目设计得无比完美再动手先从一个小场景开始让它自己“长大”。