惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cloudbric
Cloudbric
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
量子位
A
About on SuperTechFans
宝玉的分享
宝玉的分享
小众软件
小众软件
T
Tor Project blog
The Hacker News
The Hacker News
WordPress大学
WordPress大学
IT之家
IT之家
L
LINUX DO - 热门话题
大猫的无限游戏
大猫的无限游戏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
酷 壳 – CoolShell
酷 壳 – CoolShell
NISL@THU
NISL@THU
D
Darknet – Hacking Tools, Hacker News & Cyber Security
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Latest news
Latest news
Martin Fowler
Martin Fowler
F
Full Disclosure
爱范儿
爱范儿
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Application and Cybersecurity Blog
Application and Cybersecurity Blog
W
WeLiveSecurity
C
Cisco Blogs
Recorded Future
Recorded Future
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - Franky
美团技术团队
N
Netflix TechBlog - Medium
Know Your Adversary
Know Your Adversary
Hacker News - Newest:
Hacker News - Newest: "LLM"
H
Help Net Security
雷峰网
雷峰网
G
Google Developers Blog
人人都是产品经理
人人都是产品经理
Microsoft Azure Blog
Microsoft Azure Blog
Security Latest
Security Latest
M
MIT News - Artificial intelligence
J
Java Code Geeks
Project Zero
Project Zero
Jina AI
Jina AI
P
Palo Alto Networks Blog
Vercel News
Vercel News
腾讯CDC
N
News | PayPal Newsroom
V
Visual Studio Blog
Cisco Talos Blog
Cisco Talos Blog
V
Vulnerabilities – Threatpost
AWS News Blog
AWS News Blog

博客园_首页

Plist 二进制格式 Milvus 和 PGVector,哪个更好? OpenClaw 已过时?在 VS Code 中运行 Hermes Agent! 第30篇文章:一个大三计科生的自白 Manim如何在数学公式中完美显示中文? Docker 部署 RocketMQ 5 并发编程核心概念辨析 C#事务处理最佳实践:别再让“主表存了、明细丢了”的破事发生 CLI 是什么?为什么大厂突然集体卷命令行? 【从0到1构建一个ClaudeAgent】协作-自主Agent UIImageView 设置图片不生效的原因排查 最小二乘问题详解20:无先验约束下的增量式SFM自由网平差 痞子衡嵌入式:大话双核i.MXRT1180之XIP应用里借助MU实现可靠Flash IAP的方法 AI Chat 封装, SemanticKerne.AiProvider.Unified 已发布 Windows下右键编辑js文件无法打开记事本——在注册表中使用环境变量 在后台服务中使用 Scoped 服务,为什么总是报错? H200 安装驱动并使用sglang启动模型 wireshark 抓包Trap上报告警内容 我用 AI 辅助开发了一系列小工具(2):图片压缩工具 [A Primer On MC and CC] 2.1 Memory Consistency 1 - 指令重排序和 SC 模型 Oracle数据库SCN推进技术详解与实践指南 玩转控件:封装个带图片的Label控件 Claude Code 4.7 真正该升级的不是模型,而是你的工作流 前端小白一句话,AI 帮我做了个颜值拉满的桌面媒体播放器。当代码不再是门槛,一句话编程就是现实。 5. WorkBuddy: 小龙虾的灵魂三件套,让你的小龙虾不只是工具 SQLite 分片方案实战:三种分片策略的深度对比 告别简陋 UI!一款基于 Fluent Design 和基于 WinUI 的开源免费、现代化的 Avalonia UI 控件库 关于二进制排列组合枚举的总结 AI开发-python-LangGraph框架(3-27-LangGraph从零实现大模型智能决策工作流) ElasticSearch主分片和副本分片概念详解 【002】HTTPS 粗解:证书、TLS 握手与对后端配置的影响 Hermes Agent 一周暴涨五万 Star,但我劝你别急着追 明明连接的是Redis的DB0,为什么能查到DB3的数据? 【从0到1构建一个ClaudeAgent】协作-Agent团队 熟悉电子元器件之后,电子小白下一步该怎么走? MAF快速入门(23)通过C#类定义Skills .NET 高级开发 | 手写一个对象映射框架 FastAPI数据库ORM怎么选?我肝了三个Demo后,终于不再纠结了 mysqldump 参数拾遗:在遗忘与铭记之间 C# .NET 周刊|2026年3月5期 Claude code入门 - 陈彦斌 一文学习入门 ThingsBoard 开源物联网平台 GitHub 热门项目 | 2026年04月16日 如何为GIT设置全局勾子,为每次提交追加信息 Number.isFinite和isFinite与isNaN()和Number.isNaN的区别 PortSwigger SQL注入LAB2 推荐一个测试人必备的Skills,从功能到性能全搞定(附详细实操和安装下载方式) 筑基期:掌握Odoo基础核心知识点02(Odoo XML 开发方式详解) GLM模型这么火,咱们用vllm也咧一个呗! 深入理解 AbortController:从底层原理到跨语言设计哲学 字符串学习笔记 多租户系统框架的基础模块设计和分析设计 Apache SeaTunnel Zeta 为什么能做到“又快又稳”? AI开发-python-LangGraph框架(3-26-LangGraph基本概念及第一个简单样例) Vue 3 组件通信,别只会用 Props 和 Emits 了,这几个狠活儿你得看看 ElasticSearch7.X版本配置密码 用Manim实现动态交点计算--从一个动点问题说起 团结引擎+Addressable+Instant Game打包抖音小游戏 function call 实战:让 LLM 自动判断 pod 异常、调用日志工具并完成故障分析 bubseek —— 让 Agent 的足迹,变成团队的洞察 通过 C# 读取并导出 PDF 书签 如何用 GitHub Actions 实现 Steam 自动化发布 【从0到1构建一个ClaudeAgent】并发-后台任务 .NET 高级开发 | 定制 ASP.NET Core 框架 电子小白:什么是运算放大器(运放) zero2Agent:面向大厂面试的 Agent 工程教程,从概念到生产的完整学习路线 堆上的ORW HC32F460 USB CDC通信异常:非对齐访问异常排查 20260413-Hyperbridge 攻击事件:发生在默克尔山上的验证绕过 那些喊着AI 要淘汰你的人,正在靠你的焦虑赚大钱! 深度学习进阶(八)Swin Transformer 最小二乘问题详解19:带先验约束的增量式SFM优化与实现 SnapTranslate 3.0 正式发布:全局划词翻译 + 完整英语学习闭环,一站式搞定查词、记词、复习 工作的意义、工作的困难认知再思考 .NET + AI 进阶实战:基于类的技能开发 - 打造可治理的 Agent 能力模块 【从0到1构建一个ClaudeAgent】规划与协调-技能 上周热点回顾(4.6-4.12) 电子小白的工具三件套:面包板、杜邦线、万能板 单表五亿数据的查询优化 | Mysql、StarRocks 2. WorkBuddy:从“我是谁”到“帮我干活” C# 如何减少代码运行时间:7 个实战技巧 基于HelixToolkit.SharpDX 渲染3D模型 - 笺上知微 从零开始的双臂具身VLA起源及现阶段发展综述 - SkyXZ 记对 xonsh shell 的使用, 脚本编写, 迁移及调优 - pluvium27 受够了Vibe Coding的失控?换个起点,让AI事半功倍 从开始配置漏洞环境到漏洞复现流程 - 難しい 关于10年工作经验的程序员对OpenClaw的实战经验分享以及看法 - 虚无境 Any metadata 的内存布局 C# .NET 周刊|2026年3月2期 - InCerry 我帮你测过了,测试圈排名第二的 Skill 依然很牛逼 Skill Discovery | 无监督技能发现的经典工作总结 - MoonOut 上下文工程是什么?过时了么?一文讲明白! - 一枫说码 开了 TUN 模式还是直连?90% 的人都踩过这个坑 AScript扩展多种脚本语言 - rockey627 AI 学习笔记:Agent 的记忆机制 你能被装进一个文件里吗?——7 万人把同事"蒸馏"成了 AI - 我没有三颗心脏 Claude Code 通关手册(七):给 AI 装上技能包——Skills 完全指南 - 暮色之狐 在浏览器中快速编辑代码:VSCode Web 集成实践 - Newbe36524 蒸馏自己 skill?基于 Deepseek 的蒸馏器,丐版蒸馏方式,简单便捷 - To_Carpe_Diem Spring AI Aliababa和AgentScope,哪个更好? - 苏三说技术
Agent Harness Runtime 架构深度解析:工具循环、状态外置与长程任务调度
AI小老六 · 2026-05-22 · via 博客园_首页

拆解 Agent Harness 如何用工具循环、外置状态和 Hook,让模型真正变成可靠交付系统。
原文链接AI 小老六

导语

评估一个 ​Coding Agent​,很多人会先盯模型:是不是换了更大的权重、推理链是不是更长、上下文窗口是不是更宽。但真实工程里经常出现另一种情况:模型没变,Agent 的表现却像换了一代产品。

原因不在模型参数里,而在模型外面那层运行系统里。它决定模型能看到什么上下文、能调用什么工具、在什么环境里执行命令、失败后如何被纠正、长任务跑偏时谁来把它拉回来。Addy Osmani 把这层系统称为 ​Agent Harness Engineering​。用一句工程化的公式概括就是:

agent = model + harness

这个等式的含义并不抽象。Terminal Bench 2.0 上已经出现过很有说服力的案例:同样的模型、同样的任务和预算,只调整 harness,Coding Agent 的排名可以从 Top 30 拉到 Top 5。换句话说,​Agent 的差距并不总是来自“模型聪不聪明”​,更多时候来自“模型被怎样接入真实工作流”。

本文不把 Harness 当成一个流行词来解释,而是把它拆成一套可落地的运行时架构:​工具循环、状态持久化、执行沙箱、记忆检索、确定性 Hook、长程任务调度​,以及正在形成的 Harness-as-a-Service 趋势。

inline-01-harness-shell.png

图:Harness 像模型外壳,把推理能力接入工具、状态、约束和真实工作流。

Harness Runtime:模型之外的执行外壳

一个 Agent 不是“会说话的模型”,而是“模型被放进一个可以行动的系统”。这个系统最小也要包含三个东西:​目标、工具、循环​。

Simon Willison 对 Agent 有一个极简定义:Agent 是一个为了达成目标而在循环中使用工具的系统。这个定义听起来朴素,却正好把 Harness 的职责说清楚了:模型负责推理下一步,Harness 负责把“下一步”变成可执行、可观测、可纠偏的动作。

可以把 Harness Runtime 看成下面这几层:

mermaid-01.png

图:Harness Runtime 把目标、工具、环境、状态和约束串成可执行闭环。

这张图里,模型只占 Loop 中的推理部分。真正决定 Agent 行为边界的,是外面这些工程组件:

Harness 层级 负责的问题 常见实现
指令层 让模型理解角色、边界、项目规则 System Prompt、AGENTS.mdCLAUDE.md、Skill 描述
工具层 把推理结果接入真实世界 Bash、文件编辑、浏览器、MCP Server、搜索
环境层 让工具调用有安全边界 Sandbox、权限审批、网络隔离、默认 CLI
状态层 让任务跨轮次、跨会话延续 Plan 文件、日志、Git 分支、Memory Store
约束层 把“应该做”变成“必须做” PreToolUse、PostToolUse、Stop Hook、Reviewer Agent
观测层 让失败可复盘、可迭代 Trace、Token/Cost 统计、Session Replay

这也是为什么 “换模型”“改 Harness” 会产生完全不同的工程收益。换模型改变能力上限,改 Harness 改变模型能把上限发挥到什么程度。

失败归因:别急着把锅甩给模型

Agent 一旦翻车,最容易出现的判断是:“模型还是不够强,等下一代吧。”这个判断有时成立,但在工程现场经常过早出现。

HumanLayer 在讨论 Coding Agent 时提出过一个很刺耳的反转:这不是模型问题,而是配置问题。它的意思不是替模型开脱,而是提醒工程师先检查自己能控制的那部分:

  • Tool description 是否让模型知道什么时候该用、什么时候不该用?
  • System Prompt 与项目规则是否互相冲突?
  • 文件系统里的计划、日志和中间产物是否足够清晰?
  • Hook 是否在背后拒绝了工具调用,但错误没有被模型看见?
  • Reviewer 或 Evaluator 是否真的独立于生成者,而不是让 Agent 自己宣布成功?

这类问题都发生在 ​Harness 层​。它们不会因为模型多几个百分点的 benchmark 分数自动消失。

更关键的是,归因方式会改变团队文化。如果团队默认“模型不行”,工程动作就只剩等待。如果团队默认“先查 Harness”,今晚就能动手:重写一个工具描述、把一条项目纪律挪进 Hook、把超长工具输出落盘、给长任务补一个 plan 文件、把自评改成外部 Judge。

Harness Engineering 的价值就在这里:它把不可控的“等模型升级”,拆成一组今天就能改的工程对象。

Ratchet 机制:让每次失败沉淀成约束

好的 Harness 不靠灵感堆配置,而靠失败推动演进。Addy Osmani 对 AGENTS.md 有一个很硬的标准:好的规则文件里,每一行都应该能追溯到一次具体失败。

这句话可以转成一个更可操作的 Ratchet 机制。Ratchet 是棘轮,只允许系统向一个方向积累改进。放到 Agent Harness 里,它有两层含义。

第一层是新增约束。只有真实事故发生后,规则才进入 Harness。比如 Agent 曾经提交过被注释掉的测试,那下一版 Harness 不应该只在文档里提醒一句,而应该至少建立三道防线:

mermaid-02.png

图:一次真实失败会同时沉淀为规则、Hook 和评审标准。

第二层是删除过时约束。模型变强以后,一些旧 scaffolding 可能不再需要。比如早期为了防止模型在上下文剩余 30% 时焦虑收尾,很多 Harness 会写大量提醒;当新模型已经稳定处理这个问题,就应该删掉这些噪音。Harness 不是配置垃圾抽屉,不能只增不减。

所以 Ratchet 不是“规则越多越可靠”,而是“​每条规则都有事故来源​,并且经得起继续存在的测试”。这让 Harness 从提示词收藏夹变成一个会进化的工程系统。

状态外置:Filesystem、Git 与 Memory 的真实职责

很多人会把 Agent 的记忆想象成 Context Window。这个理解只对了一小半。Context 能承载当前轮对话,却不适合作为长任务的状态仓库。

真正可靠的状态通常在模型外面​。

Filesystem 是第一层外置状态。计划文件、调试日志、工具输出快照、子任务交接摘要,都应该写到磁盘上。这样即使上下文被压缩、会话被重启,任务仍然可以从文件恢复。

Git 是第二层外置状态。它提供版本化、分支、回滚和审计。Agent 在独立分支或 worktree 中探索,失败可以回滚,成功可以合并。对长任务来说,Git 不只是代码管理工具,还是 Agent 行为的安全带。

Memory Store 是第三层外置状态。AGENTS.mdCLAUDE.md 适合放静态规则,但不适合放动态事实。客户偏好、历史 bug 修复路径、某个服务的运行经验,更适合进入 KV、向量库或结构化 Markdown 树。它们解决的是“跨会话事实记忆”,而不是“本轮提示词补丁”。

再往外,还需要 Search 和 MCP 处理训练截止日之后的信息。模型知道的是过去,工程任务面对的是今天。把搜索、内部知识库、API 文档查询接进 Harness,是为了避免模型用旧事实回答新问题。

可以把状态外置理解成一条原则:凡是不应该随着 Context 被截断而消失的信息,都不要只放在 Context 里。

inline-02-external-state.png

图:长程任务的关键状态应沉淀到文件系统、Git 和记忆库,而不是只留在 Context 里。

Bash 与 Sandbox:通用能力必须配安全边界

设计工具层时,很多团队会先走向“为每种动作定义一个专用 Tool”。这条路很安全,也很快变得笨重。真实任务里的需求太碎:查日志、改 JSON、跑测试、抓网页、批量替换、临时分析数据。专用工具很难盖住所有场景。

因此,现代 Coding Agent 越来越倾向于给模型一个强通用工具:Bash。

Bash 的价值 不是“让模型执行命令”这么简单,而是让模型可以临时组合工具。rg 查找、jq 解析、curl 请求、语言测试 CLI 验证、headless browser 跑页面,这些动作不用每个都包装成独立 API。很多复杂任务最后都会坍缩成几条设计良好的 CLI 调用。

但 Bash 的风险也同样明显。给 Agent 通用执行能力,就必须同时给它安全边界:

能力开放 对应边界
允许 Shell 执行 危险命令拦截、审批流、命令审计
允许读写文件 项目目录隔离、敏感路径 deny-list
允许联网 默认禁出网,按域名或任务白名单开放
允许安装依赖 临时容器、缓存隔离、依赖来源检查
允许并行任务 worktree 隔离、文件锁、冲突检测

这里有一个重要的产品判断:默认工具链应该由 Harness 准备,而不是让模型临场配置。Git、ripgrep、语言测试工具、jqyq、浏览器自动化、包管理器,这些东西应该在执行环境里预装。模型不应该把时间花在“先装一个 rg”上。

通用工具让 Agent 能干,Sandbox 让它不至于失控​。两者缺一不可。

Hook Runtime:把偏好变成确定性纪律

Prompt 可以表达偏好,但不能保证执行。​Hook 的价值​,是把一部分“请记得”改成“系统会强制”。

在 Agent 生命周期里,Hook 可以插在多个关键点:

mermaid-03.png

图:Hook 在工具调用前后和任务结束前提供确定性校验。

Hook 的设计精神可以概括成一句话:​成功静默,失败喧哗​。

比如 Edit/Write 后自动跑 typecheck。通过时不返回任何信息,避免污染 Context;失败时把错误塞回下一轮,让模型必须修。这样你就不需要在 CLAUDE.md 里反复写“改完代码记得跑类型检查”。这条纪律已经从提示词变成运行时逻辑。

一个典型的 PostToolUse 配置可以长这样:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "cd $CLAUDE_PROJECT_DIR && pnpm tsc --noEmit 2>&1 | head -50"
          }
        ]
      }
    ]
  }
}

PreToolUse 可以拦截危险 Bash 命令,Stop Hook 可以在模型宣布完成前检查 todo、测试、未提交变更和交付物。Hook 的位置越靠近执行链路,规则就越不依赖模型“记性”。

这也是 Harness 和 Prompt 的分界:​能用确定性逻辑约束的,不要只写进提示词​。

Long-Horizon Execution:长任务靠外部状态与独立判定续航

长程任务是 Harness 能力的试金石​。单轮问答可以靠模型聪明,跑几十分钟甚至几小时的任务则会暴露三个问题:

  • Context 装不下完整过程,压缩会损失细节。
  • 模型容易把“当前阶段完成”误判为“整个任务完成”。
  • 子任务之间缺少交接协议,信息在 Agent 间漂移。

解决这些问题,需要同时处理 Context 和调度。

Context 侧有三种常用战术​。

第一是 Compaction,把旧上下文压缩成摘要。但压缩有损耗,连续压缩会让任务慢慢失真。更稳的做法是把关键状态写入 handoff 文件,然后在必要时重启会话,让新 Context 从磁盘恢复。

第二是 Tool-call Offloading。工具输出不应该无脑塞进 Context。几千行日志、完整网页、巨型目录树,都应该落盘;Context 里只保留摘要、路径和可继续查询的线索。模型需要细节时,再用 rgRead 精确取片段。

第三是 Progressive Disclosure。能力不应该全部预置进 System Prompt,而应该按需加载。Skill 体系的核心价值就在这里:启动时只暴露 name 和 description,命中任务后才加载完整说明、脚本和引用材料。

调度侧则要避免“自我宣布胜利”。可以用三种机制兜底:

调度机制 解决的问题 实现方式
Plan-then-Act 防止任务在多轮执行中丢目标 先写 plan 文件,完成一项勾一项,新增依赖及时追加
Ralph Loop 防止模型过早退出 Stop Hook 拦截 exit attempt,用干净 Context 重读状态继续
Planner / Generator / Evaluator 分离 防止生成者自评偏乐观 规划、执行、判定完成由不同角色或不同 Agent 承担

这里最重要的是 ​Evaluator 独立​。写代码的 Agent 往往天然倾向于说“已经好了”。更可靠的方式是在开工前定义 sprint contract:哪些测试必须通过、覆盖哪些边界、交付物长什么样。最后由独立 Judge 对照合同验收。

长任务不只需要更大的 Context,更需要更清晰的外部状态、更硬的退出条件和更独立的完成判定。

inline-03-long-horizon-loop.png

图:长任务要靠计划、执行和独立评估组成闭环,避免 Agent 过早宣布胜利。

Skill 与 Hook:普通工程师最容易动手的两个入口

如果把 Harness 拆到日常可操作层面,普通工程师最值得先抓两类东西:Skill 和 Hook。

Skill 解决“Agent 能做什么”。它把领域能力封装成按需加载的能力包,而不是把所有知识都塞进主提示词。一个好的 Skill,description 比正文更关键,因为它决定触发面:写得太窄,模型永远想不起它;写得太宽,它会在不该出现时污染任务。

Hook 解决“Agent 必须怎么做”。它把类型检查、危险命令拦截、提交前验证、结束前复核这些纪律放进运行链路。模型不需要记住纪律,Harness 会在对应时刻执行纪律。

两者分别对应 Harness 的两个方向:

入口 本质 典型问题
Skill 能力的渐进式披露 这个任务需要哪组领域知识、脚本和流程?
Hook 纪律的确定性执行 哪些规则不能依赖模型自觉?

每新建一个 Skill,都是在告诉 Agent“遇到这类任务时,你可以调用这组外部能力”。每挂一个 Hook,都是在告诉 Agent“到了这个生命周期点,这条规则必须执行”。这两类改动看起来像配置,实际上是在改 Agent 的运行时行为。

Harness-as-a-Service:外壳正在成为工业品

早期做 Agent,团队往往从 LLM completion API 开始,自己搭 loop、写 tool calling、维护上下文、做权限审批、补日志回放。每个团队都在重造同一套底座。

现在趋势变了。Claude Agent SDK、Codex SDK、OpenAI Agents SDK 这类产品,正在把 Harness 的一部分能力服务化:循环、工具注册、上下文管理、子 Agent、审批流、Trace,都逐渐变成可配置的运行时能力。

这就是 Harness-as-a-Service。它卖的不是模型,也不是传统 SaaS,而是一组默认工程决策:

  • Agent Loop 怎么跑?
  • 工具如何注册、过滤和裁剪结果?
  • 子 Agent 如何创建、交接和回收?
  • Context 什么时候压缩,什么时候重启?
  • 权限审批如何进入执行链路?
  • Trace 如何记录,失败如何回放?

HaaS 的价值是把 v0.1 成本摊平。团队不必从零写一个能跑的循环,而是拿到一个已经可用的底座,把精力放到领域 Harness 上:业务工具、项目规则、评测指标、数据权限和组织知识。

但这不意味着 Harness 会消失。模型变强后,旧约束会减少,新的约束会出现。过去我们不信任模型记得跑测试,于是写 Hook;未来我们可能不信任模型能协调多个 Agent 同改一个仓库,于是写 worktree 调度和冲突仲裁。Harness 不会变薄,它只会把边界移动到更高层。

结语

Agent 的能力上限由模型决定,但实际表现往往由 Harness 决定。​模型是发动机,Harness 是传动、刹车、仪表盘、导航和安全笼​。发动机再强,如果外壳不能把动力稳定传到真实任务上,结果依然会失控。

对普通工程师来说,这反而是好消息。模型训练不在多数团队手里,但 Harness 在。你可以今天就改一条工具描述、删掉一条过时规则、把长日志落盘、给任务加 plan 文件、把类型检查搬进 Hook、把领域流程封装成 Skill。

这些动作看起来细碎,却共同决定 Agent 是否能从“会回答”走向“能交付”。所谓 Harness Engineering,就是承认模型之外还有一整套工程系统,并且认真打磨它。

模型由实验室推进,Harness 由工程现场推进。真正能让 Agent 在具体任务里变可靠的,往往正是这层“模型之外的全部”。