模型差距在缩小,但Harness的鸿沟在拉大!Coding Agent 工程化落地的硬核真相 📅 2026/8/5 14:44:54 最近圈子里有个挺有意思的现象,大家都在聊模型有多强,GPT-5、Opus 4.6 这些名字满天飞。但如果你真去用了像 Claude Code 或者 Codex 这种真正的 Coding Agent,你会发现一个很扎心的事实:同样的模型权重,换个壳子,体验简直是云泥之别。Sebastian 之前发了一篇很硬核的文章,把这个问题扒得很透。他没去纠结模型本身的参数大小,而是把目光投向了模型外面那层系统——他管这个叫 Harness。说实话,读完之后我有一种“拨开云雾见青天”的感觉。原来我们以前总觉得 AI 写代码不行,可能是模型笨;现在看清楚了,很多时候是“工位”没配好。今天这篇内容,我想把这套逻辑掰开了、揉碎了讲清楚。这不仅是一篇技术解析,更像是一份给所有想搞 AI 工程化落地的开发者的避坑指南。如果你正打算在团队里推行 Coding Agent,或者自己搞个智能体玩,这篇干货绝对能帮你省下不少头发。先把概念理顺:别把 LLM 和 Agent 混为一谈咱们先做个简单的科普,虽然老生常谈,但很多坑就是因为概念混淆踩进去的。很多人觉得,Coding Agent 就是一个“会写代码的聊天机器人”。大错特错。真实的 Coding Agent,本质上是这三个东西的组合体: 1. 模型(LLM):这是引擎,负责预测下一个 token。 2. 控制循环(Agent Loop):这是大脑的节奏,决定下一步是看代码、跑测试还是改文件。 3. 运行时系统(Harness):这是外部环境,负责给模型提供上下文、工具权限、状态记忆和反馈。你可以把 LLM 想象成一个刚毕业的天才程序员。他代码写得飞快,逻辑也没问题。但是,如果你把他扔到一个没有文档、没有权限、不知道项目结构、也没有测试环境的房间里,让他去修一个复杂的 Bug,他大概率会给你写出一堆看起来很像样、但完全跑不通的代码。这时候,Harness 的作用就出来了。它就像是给这位天才配了一个资深导师、一套完善的 IDE、清晰的代码规范、自动化的测试脚本,以及一个能记录他所有操作日志的系统。所以,为什么 ChatGPT 聊天框里的模型,和 Claude Code 里的模型,体感差距那么大?不是因为聊天框里的模型突然变笨了,而是因为 Claude Code 外面多了一层极其复杂的工程系统。这层系统,就是 Harness。为什么聊天框里的同款模型,没那么能打?咱们来复盘一下真实的软件开发流程。你以为写代码主要是在“生成下一段代码”吗?其实不是。在真实的项目里,工程师 80% 的精力花在这些地方: * 导航仓库结构,找文件; * 搜索文档,理解业务逻辑; * 查找函数定义,看依赖关系; * 应用 Diff,理解变更; * 运行测试,看报错日志; * 维持上下文连续性,别做着做着忘了刚才改了什么。这些事,人类工程师觉得累,是因为它们琐碎、脏、而且容易打断心流。而一个好的 Coding Harness,最大的价值就在于:它把这些脏活累活,自动接过去了。当你在聊天框里问模型时,它只有你发给它的文字。但在 Claude Code 或 Codex 里,模型能直接看到你的目录结构,能直接运行 pytest,能直接读取 AGENTS.md 里的规范。Sebastian 有个推测很有意思:如果把今天最强的开源模型(比如 GLM-5),放进跟 Codex 同等成熟的 Harness 里,最终体验未必会比 GPT-5.4 差太多。这话虽然有点绝对,但方向是对的。这几年,真正的进步往往发生在模型外面的系统层。模型选型固然重要,但 Harness 的工程质量,往往才是决定体感的关键。一个能协作的 Coding Agent,到底长啥样?如果把 Coding Harness 拆开看,它通常由三层叠起来:1. 模型层:提供智力引擎。 2. Agent 循环层:观察(Observe)→ 检查(Inspect)→ 选择(Choose)→ 执行(Act)。 3. 运行时支撑层:提供上下文、工具、状态、权限、反馈。真正拉开差距的,往往不是那个最小的循环,而是循环外面越来越厚的那层工程设施。比如: * 仓库事实怎么收集? * 状态怎么持久化? * 工具怎么卡边界,防止模型乱删文件? * 测试和日志怎么回流给模型? * 长上下文怎么压缩,避免窗口爆满? * 子智能体怎么约束,防止它无限递归?这些细节,才是区分“玩具”和“生产力工具”的分水岭。决定成败的 6 个核心组件为了让大家更直观地理解,我们可以把 Coding Agent 拆成 6 个核心组件。这 6 个组件,每一个都在解决真实工程中的痛点。# 1. Live Repo Context:先拿稳定事实,再开始推理用户说一句“修一下测试”,对模型来说远远不够。它得先知道: * 当前是不是 Git 仓库? * 现在在哪个分支? * 目录结构长什么样? * README 或 AGENTS.md 里有没有特殊规则? * 哪些脚本才是标准入口?核心就一个意思:模型不能两眼一抹黑地开工。如果它能看到 AGENTS.md,就更可能知道应该跑哪条测试命令。如果它知道仓库根目录和文件结构,就更可能去对的地方找代码,而不是瞎猜。这就好比新同事入组第一天,先看项目文档,先摸清目录,先知道团队怎么做事。不是一坐下就开始改文件。一个成熟的 Agent,通常会先把这些稳定事实收集出来,整理成一个工作区摘要,每轮任务都带着它出发。# 2. Prompt Shape & Cache Reuse:稳定的东西要稳定下来Agent 摸清仓库之后,下一个问题是:怎么把这些信息喂给模型。一个不太聪明的做法是,每轮都把整份上下文重新拼一遍,再让模型从头读一遍。这样当然也能跑,但很浪费。因为写代码是一个反复拉扯的过程。在这个过程中: * 系统指令通常不变; * 工具定义通常不变; * 仓库摘要大多数时间也基本不变。真正高频变化的,其实是: * 用户最新请求; * 最近几轮对话; * 刚返回的工具结果; * 短期工作记忆。所以更好的做法,是把提示词拆成两部分: * 稳定前缀:系统指令、工具定义、工作区摘要。 * 动态部分:当前请求、近期历史、短期记忆。这样做有两个现实好处。一是更容易命中缓存,成本更低,速度更稳。二是结构更清楚,长任务里也更不容易漂。# 3. Structured Tools:真正危险的,不是工具少,而是边界不清很多人会把“会不会调工具”理解成模型能力。但工具层的大头其实在 Harness。模型能做的,只是输出一个结构化动作。真正让这个动作安全、可控、能落地的,是外层系统继续做的几件事: * 校验参数; * 检查路径; * 判断是否需要人工批准; * 执行动作; * 把受控结果再喂回循环。流程其实很清楚:模型先输出动作 → Harness 验证 → 必要时请求人工批准 → 执行 → 结果传回系统。所以工具设计里最重要的判断,可能不是“多不多”。而是: * 是不是白名单? * 描述是不是清楚? * 输入是不是可验证? * 出错时能不能明确失败? * 路径和权限有没有边界?最近很多 Agent 实践也在说同一件事:如果工具设计不对,模型选错工具时,你表面上以为是模型笨,实际上常常是工具本身不适合模型来用。一个能在错误方向上高速乱跑的 Agent,通常比一个稍慢一点、但动作受控的 Agent 更危险。# 4. Context Management:长任务的真正难点,很多时候不是推理,是别吃撑这一节讲的不是“更聪明”,而是“别失真”。写代码这种任务,天生会制造大量脏上下文: * 文件很多; * 日志很长; * 工具输出很臭很长; * 同一个文件会被反复读取; * 历史对话会不断累积。如果 Harness 老老实实把这些东西一股脑全塞回去,上下文窗口很快就满了。所以一个好的 Coding Agent,核心能力之一其实是“会忘”。至少有三种常见的压缩动作: * Clipping:超长输出直接截断。 * Transcript reduction / summarization:把完整历史压成更轻的近期摘要。 * Deduplication:早先读过的重复文件别一遍遍喂。这里还有一个原则,也很实用:近的事保留更多细节。远的事压得更狠。因为离当前决策越近,通常越重要。这一段看起来很像脏工程,很少拿来当卖点。但 Sebastian 有句话说得好:很多表面上的“模型质量”,其实是上下文质量。很多系统最终稳不稳,真的就死在这里。# 5. Session Memory:完整记录和工作记忆,不是一回事Coding Agent 至少应该有两层状态: * Full Transcript:完整记录。保存所有用户请求、工具输出和模型回复。目标是可恢复、可审计。 * Working Memory:工作记忆。只保留当下任务最需要的精炼状态。目标是让任务不断线。这个区分很重要。因为很多人会把“压缩后的近期历史”和“工作记忆”混在一起。但两者不是一回事。 * 压缩后的对话,是为了重建提示词。 * 工作记忆,是为了维护任务连续性。前者更像近期上下文的浓缩包。后者更像一份手动维护的小备忘录。里面可能只有这些信息: * 当前最重要的任务是什么? * 哪些文件最关键? * 最近做过什么? * 还有哪些待办没收尾?这层设计,在长任务里特别有用。因为很多时候,模型不是突然变笨了。而是系统没有把“完整历史”和“当前重点”分开。# 6. Delegation & Subagents:子智能体不是越多越好,关键是怎么绑住当 Agent 有了工具,也有了状态,下一步很自然就会想到委托。主智能体正在干主线任务时,常常会冒出来一些适合拆出去的支线问题: * 这个符号在哪个文件定义? * 这个测试为什么挂? * 这个配置到底写了什么?这种时候,子智能体就很有价值。它能把辅助问题剥离出去,减轻主循环负担。也能在理想情况下做并行。但子智能体最危险的地方有两个: * 给它的上下文不够,它出去一趟什么也做不了; * 给它的边界太松,它回来前已经把系统搞乱了。所以真正难的,不是“会不会 spawn subagent”。而是: * 给它多少上下文才够? * 它能不能写文件? * 能不能继续往下再生子智能体? * 它和主智能体是不是会重复劳动? * 它的任务范围是不是足够清楚?还有一个有意思的现实细节。Claude Code 很早就支持子智能体。Codex 是后来补上的。而 Codex 通常也不是一刀切地强制子智能体只读。更多时候,它们会继承主智能体的大部分沙箱和批准设置。也就是说,边界不一定只靠“只读”来做。很多时候更依赖任务范围、上下文大小和深度控制。对照自己的系统,可以先看什么如果顺着一个比较现实的排查顺序往下看,通常可以先看这几件事:1. 模型是不是在零上下文里盲启动? 2. 长期规则和当前请求是不是混在一起? 3. 工具是不是太多、太散、描述太工程师视角? 4. 日志和历史是不是在吞掉注意力? 5. 工作记忆和完整记录是不是混成一坨? 6. 子智能体是不是已经比主智能体还难控?如果这些地方有明显问题,可能不必急着上更多 Agent。先把单 Agent 的协作基础设施补稳,通常更划算。因为单个 Agent 如果连规则、上下文、工具、记忆和验证都还没站稳,多开几个往往不是在提效,更像是把混乱并行化了。不是说多 Agent 没价值。只是很多系统还没到那一步。它和 OpenClaw 像吗?像,但不完全是一类东西Sebastian 在结尾还提了一下 OpenClaw,这个对比挺有意思。大致的看法是: * Coding Harness 更像终端里的专用编码助手。 * OpenClaw 更像本地通用智能体平台,编码只是其中一种工作负载。两者也确实有不少重叠: * 都会利用工作区里的指令文件,比如 AGENTS.md; * 都会保留会话文件; * 都会做记录压缩和状态管理; * 都支持辅助会话或子智能体。