Harness和LLM的动态博弈

一个月前我在《别让 LLM 当 JSON 搬运工》的结论是别让昂贵的神经网络去倒腾细碎的 JSON,让模型写出程序,扔进受控沙箱批量编排工具。

但技术的推进速度往往比预期更快。刚过去的一个月里,前沿模型在真实工程环境里跑出了新表现,把这套刚建立起来的认知推到了新的分叉口。

一个月后的新碰撞

在 OpenCode 2 的开发中,作者 Dax 遇上了一个具体的工程冲突。

OpenCode 2 实现了一套规范的 CodeMode 机制,通过解释器拦截代码内部的工具调用。模型要读写文件或搜索代码,必须调用暴露出来的工具函数,宿主系统因此可以逐项拦截权限,把执行进展实时投影到界面上。

但在接入 GPT-6 Astra 后,这套流程被打破了。模型开始绕过暴露出来的工具体系,直接自己写一整段原生 Python,引入标准库、操作路径、启动系统进程去完成任务。

如果模型就是想直接运行原生 Python,Harness 还要不要强行拦着它,逼它去用一套定制的解释层?

工具编排的第四代演进

回头看 Agent 探索环境和使用工具的历史,可以划分出四个代际。

第一代是经典的 Function Calling。所有工具定义全量灌进上下文,模型逐轮输出 JSON 参数。模型充当了按 token 计费的数据搬运工,既浪费上下文窗口,又在多步串联时容易中断。

第二代是 Tool Search 与 Dynamic Tools。Harness 开始引入工具检索和渐进式披露,模型按需索取接口定义。这缓解了上下文空间的挤压,但整个任务的推进依然由模型单步轮询驱动,多步调用的往返延迟依然存在。

第三代是 Harness 层的 Code Mode。Harness 为模型提供一套定制的 DSL 或者受控脚本语言,模型通过写程序来编排工具,中间过程在沙箱中一次性跑完,只把最终的聚合结果交给模型。

第四代是 Model-native Code Execution。模型在预训练与 RL 中已经把通用编程能力内化成了自己的默认行动策略。面对复合任务,模型天然偏向直接输出一段原生 Python 或 Shell 脚本,把运行环境本身当成了最顶层的万能工具。

工具编排这件事从 Harness 赋予的能力内化成了模型自身的能力。

顺着模型还是逆着模型

为什么新模型会自发偏向原生代码。

我倾向于用训练分布解释这件事。在复杂任务的轨迹训练里,需求常常是遍历几十个文件、正则提取特定函数、按依赖拓扑决定修改顺序。调用十次外部工具去完成,成功率和效率多半比不过直接写一段带 Pathlib 和循环的脚本。一次执行,搜索、过滤、批量修改全部跑完。模型在海量代码语料与反馈中,早已把 Code 视作最高效的工具。

模型已经演化出更高级的行动策略,外部 Harness 如果还执意在中间加一层受限的解释层,强迫模型调用封装好的工具,就是逆着模型内化的策略做事。

想拦住这种原生能力的框架,眼下面临的第一个问题就是模型不往定制的路子上走,交回来的还是它想写的代码。顺应模型已经学到的行动模式,成了更现实的架构选择。

变薄的编排与变厚的控制

这种转变带来一个直接的问题。既然模型自己能写代码干完所有事,外部 Harness 会不会很快变薄直至消失。

变薄确实在发生,只是薄的和厚的根本不在同一层。

变薄的是编排。过去我们在 Harness 里投入了大量精力去设计细碎的工具描述、严格的参数格式规范、复杂的单步引导提示词。随着模型理解力与自编排能力的增强,这一层正在被迅速剥离。Harness 正在放弃教模型怎么调工具。

变厚的是执行层与控制平面。当模型的行动方式换成原生代码之后,外部系统必须承担起一系列更严肃的稳定性挑战。

  • 第一个问题是权限拦截。模型直接写出一段文件删除或外部请求代码,谁来决定这段代码能碰哪些目录、能不能访问生产内网。这种审查不可能交给模型自我批准。外部系统必须在操作系统层、沙箱层或 Server 层设防。
  • 第二个问题是可观测性。在过去离散的工具调用下,界面可以渲染出每一步的语义意图。一旦变成黑盒代码执行,用户看到的可能只是一个长条执行。怎么把黑盒里跑出来的东西映射回界面上成了新问题。
  • 状态管理与错误恢复更加复杂。如果一段几十行的写操作脚本执行到一半抛出异常,工作区处于脏状态,系统怎么回滚,怎么把精准的错误上下文喂给下一 Turn,这些都要外部环境来兜底。

架构思路因此发生了位移,从在前端解释器里模拟一套受控语言,移到了后端 Runtime 注入拦截器、探针与沙箱隔离。

为什么 Harness 很难自进化

既然大模型在持续进化,能不能把 Harness 本身的设计也交给模型自我迭代完成?这触及了当前强化学习的边界。

在 Coding 的强化学习里,评判标准清晰。模型写完一段算法题后进行自动化测试,几毫秒内就能拿到明确的对错信号。

但 Harness 的评估完全不同。如果模型提议把一套微型工具集改造成单一的脚本执行环境,要判断这个决策是优是劣,无法依靠单点测试。系统必须把这个方案部署进真实的 Agent 循环,跑完数十个端到端的大型工程任务。每一个任务都要经历长达十几分钟的长程交互,消耗数亿 token,触发数以百计的外部环境变动。效率极低,算力开销也巨大。

更关键的瓶颈在于缺乏客观标准。五次工具调用消耗三万 token,和十次调用消耗一万五 token,究竟哪一个更优秀。一次不出错但等待极久,和自我修正了两次但响应敏捷,到底哪一个更符合需求。这些多维度的权衡夹杂着用户体验、延迟、安全边界和成本等各种噪音,无法收敛成一个简单的标量奖励,导致大量实践靠经验和感觉。

正因为缺乏廉价的反馈机制,现阶段的模型无法靠纯粹的自博弈推演出优雅的系统架构。高质量的 Harness 架构,仍依赖人类工程师根据工程能力去探索。

动态滑动的工程分工

大模型与 Harness 之间的关系是一场长期的动态博弈。

模型的每一次能力升级,都会把一部分过去属于 Harness 的能力吸收进去,内化为自身的行动策略,例如最近 Astra 比以前的 GPT 模型更会用 Subagent。如果 Harness 缺乏敏锐度,依然试图用旧时代的工具规范来框住新模型,Harness 就会沦为模型的阻碍。

优秀的 Harness 设计必须保持动态滑动的边界。模型已经内化的操作逻辑,果断让渡出去,不再做多余的封装。模型力所不及的权限控制、Sandbox、状态机和界面交互,继续进一步完善。

写在最后

回到开头 Dax 的问题。他的想法是两边都要,CodeMode 保留,但渲染和权限提示做进了代码执行的链路里,模型交过来一坨代码也能弹权限、出界面。这个答案对 Astra 够不够用,下一代模型出来后还有没有效果均是未知数。

博弈还在继续。

添加评论
点赞收藏
点踩分享查看原文
评论
?
参与讨论