通用 Agent Harness 架构设计:从 LLM 的四个缺陷到三十六个功能补全
目录文章目录目录通用 Agent Harness 架构设计从 Model 的四个做不到到三十六个功能模块4-5 页10~15 分钟一、Agent Model Harness二、Model 的本质与四个做不到2.1 前提一Model 是一个无状态的文本函数2.2 前提二Agent 的目标是可靠地完成一个真实任务2.3 结论Harness 需要解决 Model 的四个做不到三、从需求到职责四、八个职责域与三十六个功能模块4.1 上下文域4.2 行动域4.3 状态域4.4 动作管控域4.5 验证域4.6 接入域4.7 策略与扩展域4.8 观测域五、功能模块总览图六、软件架构示意图六、怎么把这套框架用到垂类场景6.1 任务场景五维坐标6.2 五维分别决定哪些模块加厚6.3 编码 Agent 与生产运维 Agent 站在对角线两端参考引用通用 Agent Harness 架构设计从 Model 的四个做不到到三十六个功能模块4-5 页10~15 分钟一、Agent Model HarnessChatGPT 出现之后的第一年模型的用法基本只有一种即人在对话框里提问、模型给出一段文本、人自己去执行。到 2024 年起Coding Agent 与 Deep Research 这类产品把同一个模型放进了另一种用法即人只给出一个目标然后模型自己读文件、自己执行命令、自己检查结果一轮不够就再来一轮。模型本身没有变变的是模型外面那一层而这一层就是 Harness。业界较为认可的 Harness 定义来自 LangChain 团队它用一个公式把 Harness、Model、Agent 三者之前的关系表达了出来Agent Model Harness这条公式可以通过下面 2 点来进行解读它们分别对Harness 进行了定性与定量Harness 的内涵就是补足 Model 的短板。Model 的本质是一个 “无状态的文本函数”输入文本、概率分布采样、输出文本。所以 Model 本身没有 “手脚”没法干活因此一切帮助补全 Model 短板的内容都可以归纳为 Harness Engineering 的一部分。这是定性的部分。Agent 的目标决定了需要补哪些短板需要补多厚。不同应用场景中的 Agent 要干的活不一样所以它们要补的短板也不一样。同一处短板在不同场景下要做 “厚些或薄些” 也相差很大。这是定量的部分。本文的目的是提出一种通用 Agent Harness 架构的架构设计它是一个最小功能集只包含最核心的部分并且要能被各垂类做定制化扩展。它的抽象来源是四家主流编程 Agent 的 Harness 设计即 OpenAI Codex1、DeepSeek dsh2、Claude Code3与 AWS Kiro4。二、Model 的本质与四个做不到2.1 前提一Model 是一个无状态的文本函数把 Model 剥到不可再分它就是这样一个东西一次调用接受一段有长度上限的文本作为输入从一个概率分布中采样产出一段有长度上限的文本作为输出并且这次调用与任何其他调用相互独立。2.2 前提二Agent 的目标是可靠地完成一个真实任务值得注意的是模型的短板似乎有很多但本文使用 Agent 的目标来定义边界。Agent 的目标是可靠地完成一个真实任务而一个任务就是一条受约束的状态轨迹即从当前状态出发、经过一系列动作后到达目标状态并满足约束因此 Agent 需要 “感知、行动、连续、正确” 这四个充分必要条件。注ReAct 感知、推理、行动中的 “推理” 由 Model 完成所以此处不列举。感知知道当前状态与相关事实。行动能够对外部环境施加改变。连续多步之间的进展不丢失。正确动作与结果符合目标与约束。下面对上述的充分必要性进行论证。必要性是逐条可验的即去掉任何一条任务都不可完成例如没有感知则无从下手没有行动则只能空谈没有连续则每一步都从零开始因而轨迹不成立没有正确则到不了目标、或者到了但违规。满足必要性。充分性来自任务的定义本身。任务被定义为一条受约束的状态轨迹而把这条轨迹拆开之后包含的方面只有四个且每一个方面正好就是上面四条中的一条。也就是说这四个方面是从 “任务” 的定义里拆出来的因此四条齐备时任务已经可以完成满足充分性。轨迹的起点及其所处的环境对应的是感知。相邻两点之间的状态迁移对应的是行动。迁移与迁移之间的连贯对应的是连续。整条轨迹与目标及约束的符合对应的是正确。2.3 结论Harness 需要解决 Model 的四个做不到Harness 要补全的短板就是 Agent 所要求的条件减去 Model 所能提供的条件就得到 Model 的 4 个做不到它们是 Harness 的需求来源5。它不知道输入之外的任何事对应感知短板。Model 只能拿到用户输入的提示词因此最新事实、私有数据、系统的当前状态乃至它自己还剩多少额度都不在其中。并且输入的长度有上限所以既装不下全部也分不清装进去的哪一部分可信。它不能行动对应行动短板。Model 的输出是一段文本而不是动作必须由外部把它解释成动作后才会真的发生。并且输出的长度也有上限因此一次产出的成果有限长任务就需要分多步完成。它不记得上一次调用对应连续短板。因为 Model 的本次输出只由本次输入决定因此上一次的结论、上一次的产出、以及上一次已经获得的授权都不会自动延续过来。它不保证 100% 正确且对此不自知对应正确短板。因为 Model 给出的答案不一定是我们想要的那个而它的输出里也不会包含关于事实差距的可靠声明因此它会自信地把错的说得像真的也会被输入里 “夹带” 的内容操纵。三、从需求到职责前面我们得到了 Harness 的需求下面再讲这些需求怎么转换为 Harness 所需要完成的职责与能力。下表左列是 Agent 的需求中列是满足需求的方法右列 Harness 的职责。Agent 的需求或问题解决方法Harness 的职责它不知道输入之外的任何事每次调用 Model 前把外部事实写进输入提示词由于输入有上限所以必须设计上下文空间利用由于输入又分不清可信度所以必须标明每段的来处。上下文构造它不能行动由外部程序把 Model 输出里的意图解释成动作并真的执行而输出也有上限所以一次做不完还要能反复发起下一次调用。行动工具循环它不记得上一次调用把下一次仍需生效的事实存到 Model 之外的会话中下一次调用时重新写进输入存的时候采用只追加而不改写的方式否则原始记录不可恢复。状态会话、任务进展等它不保证正确动作发生前动作一旦发生外部环境就已经被改变了所以动作之前要按规则判定该不该做给出允许、拒绝或者上交审批。动作管控行动前它不保证正确动作发生后动作做完了 Model 也不知道对不对所以动作之后要按检查器判定做对没有给出重试、回退或者上交审批。验证行动后用户界面接入网关唯一的对外通路承载入站请求、出站响应与上交审批。接入应用场景扩展与泛化把策略与规则配置文件、权限控制、扩展插件、MCP、Skill、系统提示词、钩子挂载点声明成运行时可读的数据并分层装载因此改行为不必改代码策略与扩展观测审计与评估优化各处只写地记录 Agent 的运行过程、命中规则、Token 用量、判定依据等作为后续审计、评估、优化的依据。观测表里需要特别说明的是把 “不保证正确” 的解决分为了 2 个阶段因为动作把时间轴切成了两段动作之前问的是该不该做、判据是规则动作之后问的是做对没有、判据是检查器两段合不了。四、八个职责域与三十六个功能模块职责回答的是要做什么而域回答的是由谁来做和怎么做也就是说域就是职责的落地单元因此上一章那八项职责一一落到下面这八个域上。职责域功能模块上下文域上下文构造模块、用户引用解析模块、项目规则装载模块、上下文窗口配额模块、上下文压缩模块行动域主循环模块、工具路由模块、模型路由模块、错误分类模块、子 Agent 调度模块状态域会话记录模块、会话管理模块、记录检索模块、Checkpoint 模块、任务清单模块、记忆模块动作管控域动作拦截模块、权限规则与判定模块、工具可见性模块、人工审批模块、沙箱隔离模块、凭证托管模块验证域验收标准模块、检查器接入模块、失败处置模块接入域接入网关模块、反向请求模块策略与扩展域分层配置装载模块、扩展装载模块、钩子装载模块观测域审计记录模块、用量计量模块、观测数据导出模块、过程回放模块、评估模块、优化模块八个域并不构成自上而下的堆叠关系。其中 ”上下文、行动、动作管控、验证、接入“ 这五个域落在一次请求调用的数据路径上而 ”状态、策略与扩展、观测“ 这三个域不在路径上。域与域之间的数据路径的顺序是接入域收下请求行动域开启新的一轮并冻结本轮的工具集、权限规则与模型选择上下文域装配输入行动域调用模型并拿到行动意图动作动作管控域在动作之前进行权限等和约束等判定行动域执行实际动作验证域在动作之后判定效果最后回到行动域推进下一步或者收尾。冻结之所以排在装配之前是因为被冻结的这三样正是装配的输入参数即工具集决定装配时写进哪些工具定义、权限规则决定工具可见性怎么过滤、模型选择决定窗口多大因而决定配额与压缩怎么算。若放到装配之后再冻结那装配本身就是对着一个可能正在变的配置做的。另外要区分的是这里冻结的是本轮的规则与能力集而不是装配好的那份输入后者是步骤级的快照用途是重试能复现同样的输入。注意行动域被动作管控域切成了两段。因为动作管控域判定的对象正是行动域产出的那个动作意图因此判定只能落在模型调用之后、真实动作执行之前。另有一处也要点明即动作管控域还有一个模块在装配输入时就已经生效也就是工具可见性模块决定模型这一轮能看到哪些工具、路径与字段。因此动作管控不止是动作之前那一次判定它还管模型的可见面。还要说明验证的时机。图 6 里第 07 步画的是动作级的验证即每一轮在执行动作之后立刻判一次判据是这一步做对没有由检查器接入模块承担例如命令有没有报错、这次工具调用的结果健不健康。这一判定落在回环之内每走一遍就跑一次。但任务级的验证是另一个时机即整条轨迹到没到目标、达不达标判据是任务完成没有由验收标准模块承担它不在每一轮跑而是循环的退出条件。图 6 里那条回到上下文域的回环箭头它的另一面正是达标才收尾因此任务级验证被折叠进了这条回环而没有单独画成一步。也就是说验证域内部有两个不同时机的模块即每轮一次的检查器接入模块与收尾一次的验收标准模块二者不可混为一次判定。4.1 上下文域这一层补的是 “不知道聊天窗口外” 的短板。LLM 只认聊天窗口之内的内容窗口之外的一切等同于不存在所以要做两件事把该看的信息送进去同时把聊天窗口本身管住抑制上下文腐烂。功能模块作用与例子上下文构造模块模型只认这一次输入里的文字所以要把散落在文件、检索结果与历史里的事实拼成这一次的输入并记下每一段的来处出问题时才知道是哪一段误导了它。例如Codex 会把输入拆成约四十三段分别管理。用户引用解析模块用户写下 某个文件 时把这个指向变成真实内容送进输入。例如Claude Code 的文件引用语法与 Kiro 的上下文引用语法。项目规则装载模块把项目规范与角色设定自动带进每一次输入用户不必每轮重申一遍本项目缩进用四个空格。例如Claude Code 的 CLAUDE.md 文件。上下文窗口配额模块输入窗口既大小有限又花钱它盯住每一段占了多少、还剩多少压缩靠窗口配额来做决定因为必须留一块给压缩本身。例如Claude Code 按块显示窗口占用并单独标出为自动压缩预留的缓冲。上下文压缩模块快装不下时把旧历史压成摘要后继续执行下一轮让长任务不必中断。例如Claude Code 快到上限时自动压缩。其中的核心是上下文构建模块典型技术就是 RAG 检索先从知识库中捞出相关内容再拼入上下文同时把任务目标、扮演角色、验收标准一并交代清楚。同时还需要 “管住聊天窗口” 的大小因为上下文并非越多越好。LLM 的 “注意力预算” 有限每多一个 token 便耗费一分而且关键信息一旦落在长聊天窗口的中段被有效召回的概率会明显下降。常用的手段有渐进式披露先给一份目录LLM 需要哪一块再去拉取哪一块接近聊天窗口上限时做压缩把已有历史就地总结为摘要后再续跑把中间产物写入文件外置存放需要时再读回。常用于企业知识与智能服务助手智能体依赖企业内部知识与实时状态就必须把知识库与实时数据接进来。4.2 行动域这一层补的是 “不能行动” 这处短板。以 “Kubernetes app 某服务为何返回 502” 为例如果缺少这一层时LLM 只能凭记忆回答一句 “502 通常是网关问题”便无以为继具备这一层后它会先执行 kubectl get pods 查看状态发现某个 Pod 处于 CrashLoopBackOff再用 kubectl logs 读取日志看到一行 connection refused: redis:6379进而顺着这条线索去排查 redis。每一步的真实输出都回灌给 LLM它便从 “背诵知识” 转为 “勘察现场”。功能模块作用与例子主循环模块Agent 与 ChatBot 的分界就在这里调模型、执行它要的工具、把结果回灌、再调下一次直到做完或者推不动。它还要在每轮开始把本轮的工具集、权限规则与模型选择固定住这三样都由策略与扩展域供给。否则一轮进行到一半有人改了配置这一轮前半段按旧规则、后半段按新规则跑事后没人解释得清它凭什么允许改动只在下一轮生效。工具路由模块模型只会说我要调 X 工具、参数是 Y该模块登记了全部可用的工具。例如Claude Code 把内置、MCP、客户端三类工具统一编址模型看不出区别。模型路由模块决定这一次调哪个模型以及主模型超载或者不可用时退到哪个避免一次抖动就让整个任务失败。例如Claude Agent SDK 的 model 与 fallback_model 两个参数。错误分类模块是一张失败类型和处置方式的映射表例如超时与限流可重试权限不足要人批文件写坏了要回退配额耗尽只能停等。例如Claude Code 把成功与失败拆成两个钩子事件即 PostToolUse 与 PostToolUseFailure。子 Agent 调度模块把可并行执行的子任务派给独立子 Agent各自带一份干净上下文主线程的窗口不被占满权限和被调用者一样防止子 Agent 拿到比调用者更大的权限。例如Claude Code 的子 Agent。该域中最关键的模块是 “主循环模块”最基础的技术有 2 项ReAct2022 年提出它让 LLM 在推理Reason与行动Act之间交替先想一步、再动一步、观察结果、再想下一步这正是主循环的思想雏形。Function Calling函数调用OpenAI 于 2023 年推出它让 LLM 能以结构化格式吐出 “调用哪个工具、传什么参数” 的结果从而与确定性代码稳定对接。这是整个 Harness 唯一不可再分的内核无论往下如何拆解最终都会回到它。今天几乎所有 Agent 的主循环本质上都是这两者的延续与工程化。4.3 状态域这一层补的是 “不记得上一次” 的短板。Agent 是一个 “有状态” 应用程序其中会话、记忆、任务进展等需要被持久化的数据。功能模块作用与例子会话记录模块把每一步发生的事按顺序追加成一条记录只写不改所以进程崩溃后还可以回到断点事后也能查清当时究竟发生了什么。例如Codex 以 JSONL 文件来进行持久化的会话保存。会话管理模块会话是一次任务的容器负责它的建立、恢复、派生与中断人关掉终端第二天还能接着上次继续。例如Claude Agent SDK 的 resume 与 fork_session。记录检索模块会话记录是流水账只能从头读。为了快速检索相关内容例如按文件路径挑、按成败挑、按待办牵连的历史挑就需要该模块为会话记录建一个搜索渠道。使用环境包括装配输入前挑历史记录、恢复会话时用于定位断点。例如Codex 用 SQLite 来进行索引检索。Checkpoint 模块动作之前留一份快照用于失败后的整体还原这是敢让 Agent 动手的前提。例如Kiro 把 Checkpoint 存在一个影子仓库里有需要就用于还原同时也不会污染目标项目的 git。任务清单模块长任务要跨很多轮甚至很多天清单让每一轮接手时都知道做到哪、还剩什么不必从头重推一遍。例如Claude Code 的待办清单工具Kiro 规格里的任务文件。记忆模块跨会话保留的结论与用户偏好和会话记录分开存放。有长短期记忆、情景记忆、语义记等类型。其中最核心的功能模块就是会话模块任务需要跨越多轮、多个会话以及中断后能续跑但是模型本身并不记录任何状态信息这会导致同一个任务分成多轮对话、多天推进或进程中途崩溃后重启再次接手时模型对此前发生过什么一无所知。Anthropic 有一个贴切的比喻这就像一个轮班作业的项目每一班到岗的工程师都不清楚上一班做了什么。此外任务模块也非常重要具体的做法是把当前任务的进展状态持久化保存以此来支持断点续跑将 “进行到哪一步、哪些结论已确认、哪些教训已积累” 一一记下来。具体实现举例Claude Code以一次 git commit 作为断点另配一个进度文件充当临时工作台另外还会在长程任务实践中把上百条待办拆成 JSON 记录、逐条推进。其中用 JSON 而非随手写的 Markdown是因为 LLM 不易擅自改动 JSON 的结构DeepSeek dsh把整个会话记为一份只追加的事件日志一旦崩溃便重放日志恢复。4.4 动作管控域这一层补的是 “不确定 100% 正确” 的短板。让一个 Agent 从 “demo 能跑” 到 “敢于上线” 的关键在这一层它约束了 “哪些动作不允许做事前挡住”。功能模块作用与例子动作拦截模块作用于模型返回工具调用后、实际真的执行这次工具前。每一次工具的实际执行都必须从这里进拦截和判定。并且此处是代码级别的硬判定而不是提示词的软判定。例如Claude Code 的 permissions 规则在每次工具执行前都会生效。权限规则与判定模块包含分层规则例如Claude Code 的 settings 分四层其中的企业层规则具有最高优先级。在动作拦截器中拿这次的动作去比对权限规则得到允许、拒绝或者人工审批等结论。工具可见性模块根据权限规则决定了这一轮对话中模型能看到哪些工具。看不见的工具模型根本不会去试比事后拒绝更省事也更安全。例如Claude Code 把禁用的工具直接从输入里移除而不是留着再拒绝。人工审批模块不可回退的动作先出方案、人工审批过了之后才执行。而且批准必须带范围与有效期、超时按拒绝闭合否则一次授权会被无限复用。例如Claude Code 的权限征询带作用范围以及 Kiro 的信任模式。沙箱隔离模块把文件、网络与进程限制在一个沙箱的可控范围内让故障域仅限于沙箱。沙箱起不来就直接拒绝执行而不是降级放行。例如Codex 的沙箱策略与 Claude Agent SDK 的 sandbox 参数。凭证托管模块密钥只在工具真的执行的那一刻才被取出并且永不写进模型输入模型泄露不了它从未看过的东西。核心模块是 “动作拦截模块” 和 “权限规则与判定模块”把危险动作挡在发生之前。 按拦截强度通常叠三道权限分级工具分成只读、可写、可执行三档默认只授予完成任务所需的最小权限两阶段提交面向生产、对外发送、涉及费用等不可回退的动作禁止一步到位而是先产出一份 “拟执行方案”经人工或合规校验通过后第二步才真正落地规则硬约束把架构规范与安全红线写成机器可强制的 lint例如规定依赖只能自上而下单向流动即按 Types、Config、Repo、Service、Runtime、UI 逐层向下、不许反向越界即报错并把 “应如何改” 回传给 LLM这比在提示词里反复叮嘱可靠得多。这三道之外还有一条始终生效的底线外部内容零信任。凡从公网、邮件、外部文档读入的内容都视为不可信重点防范其中夹带 “忽略此前指令、你现在是另一个 Agent” 这类提示词注入工具。同样LLM 对外的输出也应默认视作不可信的生产数据必须经过脱敏与合规校验才可释放。这一层要投入到什么力度几乎完全由风险决定动作越不可回退、合规要求越高就越要在这一层重点投入。纯只读的问答智能体无须太重而运维改动生产、办公对外发信、金融执行交易都必须把这一层做到最重典型措施包括只读定位与授权写严格分离、环境绑定不可变、关键写操作强制人工审批以及全链路审计。4.5 验证域这一层补的也是 “不确定 100% 正确” 的短板但属于 “事后” 逻辑。功能模块作用与例子验收标准模块先声明目标描述和验收标准否则检查器无从下手模型也只能自己宣布做完了。Kiro 的规格文件会把验收标准单独说明。检查器接入模块第三方检查器接入采用对抗检查。例如编程智能体中的编译、测试、静态检查、业务校验、裁判模型等做完后由第三方证明而不是模型自己。失败处置模块验证不通过时决定重试、回退到 Checkpoint 还是交给人并限定重试次数防止在同一处反复打转。首先回答两个问题验什么谁来验。验的是任务到底有没有真正完成、产出到底对不对。因此该域也是 Loop Engineering 的重点。谁来验是绝不能让执行任务的那个 LLM 自己当裁判避免 LLM 自己说 “我做完了”。因为 LLM 极不擅长评判自己实测中让它为自己的产出打分它往往一味自夸哪怕成果在旁人看来只是平平。因此必须引入一个独立于执行者之外的验证者让 “完成” 成为被第三方证明出来的结论而非由执行者自行宣布。关键的 “验收标准模块” 和 “检查器接入模块”有 3 个关键验证方面确定性程序计算性验证测试、编译、探活、对账客观且快但判不了业务是否合理。另一个专门当裁判的 LLM推理性验证能读懂语义与体验代价是较慢、不稳定、有额外成本。必要时的人工复核无论用哪一种都有两条经验值得记住把 “生产” 与 “验收” 拆成两个角色并刻意把验收者调得更为多疑实践表明让一个独立评估者变挑剔远比让生成者对自己下狠手来得容易验证要 “带环境” 进行不是读一遍结论、看一眼截图就打分而是像真实用户、真实系统那样实际走一遍包括点开应用、调用接口、核对数据库状态与监控。另外“失败处置模块” 是为了让系统出错后能自己恢复。 同样是 3 个方面有限自愈某一步失败时把错误信息回灌给 LLM 令其自行修正但必须限定重试次数以免它在同一处反复打转崩溃恢复进程意外中断后能凭日志重放回到断点而不是从头再来收尾归位任务结束时不论成败都要清理临时资源、释放锁并明确 “提交或回滚”不给下一个任务留下脏状态。4.6 接入域功能模块作用与例子接入网关模块使用同一的 endpoint 对接多种客户端类型收请求/发响应换客户端不必动 Agent 的内核。而且触发源不限于人告警、定时与外部事件都从这里进来一旦是无人值守的会话审批超时就必须按拒绝闭合。例如Kiro 用 ACP 加自有 WebSocket 支撑 4 种不同的客户端openclaw 的请求来自 WhatsApp、Telegram、Slack 等消息通道。反向请求模块这个通道专用于 Agent 主动向人联系比如请求授权。例如Claude Agent SDK 的三个反向请求。4.7 策略与扩展域承担第一章那条定量结论即同一份 Harness 要服务不同垂类因此凡是随垂类而变的东西都必须外置成声明而不能写在内核代码里。据此可以推断一条判定归属的方法即凡是换一个垂类就要改一次的东西都属这一域而凡是换垂类也不变的东西都不属。功能模块作用与例子分层配置装载模块支持自定义指定配置包括权限规则、扩展、钩子等。例如Kiro 的企业配置只可收紧且校验失败就拒绝启动。扩展装载模块第三方代码的加载点Skills、MCP、Plugin 都从这里进。例如Claude Code 提供了 Plugin、MCP 与 Skilks 三类装载。钩子装载模块这个模块负责把事件送到挂上去的钩子然后执行第三方代码。例如Claude Code 的钩子事件覆盖了会话、提示词、工具调用、权限、子 Agent、上下文压缩等多类时机。动态装载的内容恰有 3 类策略与规则换的是允不允许做即同一批工具、不同的放行边界。扩展换的是能做什么即插件、MCP 服务器、工具与子 Agent 定义。钩子挂点换的是什么时候插一脚即在生命周期的某一处插入垂类自己的流程。值得注意的是三类里只有前一类的机制不那么直观因为扩展与钩子本来就是软件程序而策略听起来像一句文档规定所以下面单独展开。策略与规则的载体是一张可求值的匹配表而不是一段代码。它的形状如下所示即每一条是工具名加参数模式按结果分组。{permissions:{deny:[Bash(rm -rf *),Read(./.env)],ask:[Bash(git push:*)],allow:[Bash(git status),Read(./src/**)]}}权限规则与判定模块是一个纯函数其输入是这次动作与这张表输出是允许、拒绝或上行且拒绝优先。也就是说内核里没有任何一句写着不许删库那句话完全活在数据里因此换掉这张表就换掉了放行边界。声明单位可以再抬高一层。Kiro 的规则匹配的不是工具名而是能力标签例如文件写入与命令执行工具各自挂标签。这样新增一个工具只要挂上标签就自动落进既有规则的覆盖面而规则文件一个字都不用改。反过来若以工具名为声明单位则每新增一个工具都要新增一条规则且用户此前写下的规则对新工具一律不生效。装载有三个时机其中第三个才是真正运行时动态的。进程启动时按层装载并合并其中企业层的拒绝项不可被下层覆盖。轮次开始时重新读一遍并冻结在本轮因此改了规则文件不必重启下一轮即生效。运行中追加审批通过时往表里追加一条带范围与有效期的临时规则例如本次会话内允许推送。这一条就是图中人工审批模块与权限规则与判定模块之间那条线的实质内容。最后一条纪律是解析失败时一律视为 “拒绝”它最容易做反因为忽略并继续是解析失败时最省事的处理而它在策略场景下的语义恰恰是把限制全部取消。4.8 观测域功能模块作用与例子审计记录模块只写地记下每一次判定凭的是哪条规则、审批的范围是什么事后要回答当时凭什么允许它做就靠它。例如Codex 把判定依据写进同一条事件流与对话记录同处一处。用量计量模块只写地记下 token、耗时与成本既是账单依据也回传给上下文窗口配额模块做预算。例如Claude Code 的成本与用量统计。观测数据导出模块把记录按标准格式送到外部日志、监控与审计系统并导出成功率、步数、成本、人工介入次数这类字段供离线评估直接消费否则这些数据只躺在本地机器上。例如Claude Code 支持按 OpenTelemetry 导出指标与事件。过程回放模块把那条记录还原成人能读的过程排障与复盘时能一步步看当时发生了什么而不是只看到一个最终结果。例如Claude Code 可以恢复历史会话并逐条回看。评估模块按统一指标给一批运行打分例如成功率、平均步数、单任务成本与人工介入率这样一次改动到底是变好还是变坏才有依据而不是靠感觉。优化模块拿评估结果回头调可调的部分例如提示词与项目规则、上下文预算与压缩触发线、工具描述、模型选择与重试次数让改进成为一个闭环。这一域的六个模块分成两组。前四个只管把记录攒下来并呈现出去即审计记录、用量计量、观测数据导出与过程回放它们的共同点是只写不读理由是排障、审计与评估这三件事目的不同要的却是同一批记录即每一次判定凭什么、每一次调用花了多少排障问的是刚才为什么这样审计问的是当时凭什么允许评估问的是哪一处最贵最慢。后两个才动这批记录即评估模块按统一指标打分优化模块拿分数回头调可调的部分。只写是一条硬约束而不是实现建议。一旦某个域把观测记录读回去用于判定观测就从只写变成了控制依赖追溯随之失去可信度因为被审计者开始依赖审计记录。这条约束针对的是环内判定而评估与优化是在环外读不参与任何一次动作放行与否的判断因此不构成控制依赖。值得注意的是评估与优化虽然进了这一域却只能给到接口与契约因为指标怎么定、优化往哪个方向调完全取决于场景通用架构给不出实现。而规划器仍然不在 Harness 之内这条边界不变。五、功能模块总览图图 7 给出的是这八个域的全景布局但要注意的是这三十六个模块并非所有场景都要建全。一个编码 Agent 与一个生产运维 Agent 在验证域与动作管控域上的投入天差地别。六、软件架构示意图六、怎么把这套框架用到垂类场景6.1 任务场景五维坐标判断一个垂类场景的实现重心五个维度就够。可验证性一个结果的对错能否被低成本、客观、快速地判定编码的可验证性极高编译器与测试就是最诚实的裁判而这条故障定位结论对不对、这份周报写得好不好则很难由机器当场裁定。可回退性动作一旦做错能否撤销、回退到出错之前改一行代码是可回退的而重启一个生产集群、删除一批数据、对外发出一封通知则大多无法回退。环境确定性运行环境是否稳定、是否可复现同一份代码在沙箱里今天跑与明天跑结果一致而线上有几十个集群与多个机房同一条命令此刻安全、下一刻可能致命。自主性任务是一次性的问答还是需要连续数小时、跨越多个会话的长程任务任务越长程对记住进展、不迷失目标的要求就越高。合规性这个场景是否受监管、是否需要审计、是否必须为结果担责编码在实验分支上几乎没有合规压力而金融、医疗与生产运维的每一个动作都可能要留痕、要复核、要能回溯根因。维度核心问题要求严格时工程实践的重心可验证性对错能否低成本、客观地判定可验证性低从自动验证转向独立评审 人工把关可回退性做错能否撤销、回退可回退性低事前约束、权限分级、两阶段审批环境确定性世界是否稳定可复现确定性低强化异常处理并在真实环境中反复验证自主性单轮还是长程任务自主性高状态持久化、记忆、断点续跑合规性是否受监管、需审计合规性高动作管控、审计、数据隔离、可追溯值得注意的是可验证性这一维可以再拆一次依据就是 4.5 那两类期望因为可枚举的期望与不可枚举的期望验证成本相差很大。编码就是典型即编译与测试对可枚举的期望近乎免费然而这次重构没有破坏任何既有不变量这句话依然很贵。不拆的话编码 Agent 的可验证性被记为高就会掩盖它真正贵的那一半。6.2 五维分别决定哪些模块加厚这一节是本章的落点即把每一维的打分直接翻译成模块清单。维度取值要加厚的模块可验证性低验证域三个模块全部要建且检查器接入模块须接人工评审通道失败处置模块须支持升交给人可回退性低动作管控域的人工审批模块做成两阶段提交并带范围与有效期权限规则与判定模块启用不可覆盖键同时 Checkpoint 模块在此类场景里会退化因此判定必须前移环境确定性低上下文域的用户引用解析模块要能接实时状态行动域的错误分类模块要分得细验证域要带真实环境走一遍自主性高状态域的会话记录模块、记录检索模块、任务清单模块与记忆模块全部要建上下文域的上下文压缩模块要能长跑合规性高观测域的审计记录模块记录粒度加细动作管控域的人工审批模块与权限规则与判定模块加厚而无人值守的会话必须把审批超时按拒绝闭合要强调的是五维打分动的只是各模块的厚薄与取舍并不改变第四章那八个域与三十六个模块的结构。也就是说五维坐标不改变架构只改变投入。6.3 编码 Agent 与生产运维 Agent 站在对角线两端值得注意的是Harness 这套工程最早诞生、发展并成熟于编程场景。Claude Code起初只是 Anthropic 内部的一个命令行编码工具因在工程师之间口口相传、使用量迅速攀升才于 2025 年初对外发布。正是在反复打磨它、以及一系列长程编码实践的过程中Anthropic 团队逐渐意识到真正决定好不好用的往往不是模型本身而是模型外面那圈 “循环 工具 上下文管理 护栏” 的工程体系并在工程博客中正式用 harness 一词来指代它。OpenAI Codex把 harness 工程推向了大规模真实代码库。为了让 Agent 在庞大工程中稳定协作Codex 团队把资深工程师的架构判断固化成机器可强制的 Lint 规则又用一份精简的 AGENTS.md 充当 “导航地图”这些都是典型的 harness 手段。DeepSeek dsh一套开源的 Agent Harness 运行时框架。它索性把上下文、工具、编排、安全等一切能力都做成可插拔的插件并以事件溯源作为底座代表了把 harness 本身彻底框架化的思路。三者出身不同、路径各异却共同指向同一个事实几乎所有成熟的 Harness 概念与实践都是先在编码 Agent 上被打磨出来的。所以这些经验也就与编码场景强关联反之编码场景也是 Harness 工程最友好的场景因为它同时具备三个得天独厚的条件低成本的验证一段代码正确与否无须主观判断编译一次、运行测试、执行一遍 Lint机器会立刻给出客观结论。动作可回滚改错了代码git revert 即可撤销沙箱重置即可还原世界随之回到出错之前的状态。环境确定且可复现同一份代码、同一套依赖今天运行与明天运行的结果基本一致。正是这三个条件使得编码 Agent 可以采取一种 “先动手、再验证” 的策略大胆修改一旦出错事后的验证环节会予以拦截拦截之后回滚重来即可。换言之编码场景允许把工程重心放在事后的验证上而事前的约束反而可以相对宽松。然而问题也正出在这里。垂类生产场景的这三个基础条件往往与上述情形恰好相反验证并不免费、动作难以回滚、环境也不确定。将一套 “为最友好场景调校” 的 Harness直接套用到一个基础条件完全相反的场景上出问题几乎是必然的。两者在五维上几乎完全反向因此为编码场景设计的 Harness 不能照搬到垂类场景。这也解释了第四章那张表里的五处空缺即四家编程 Agent 恰好在可验证性与可回退性上都拿了高分所以它们不需要验证域也不需要凭证托管模块而评估与优化则被它们留给了线下的人工判断。可验证且可回退的场景例如编码重心可以落在事后验证上事前从简。低可验证、不可回退、高合规的场景例如生产运维、金融与办公重心必须放到事前在动作发生之前就把风险拦住同时把事后的审计与追溯做扎实。用一个朴素的类比收束这一章。编码 Agent 像是在草稿纸上工作写错了划掉重写代价只是几张纸因此鼓励它多写多试关口设在终点。生产运维 Agent 则像是在做手术每一刀都作用在真实的病人身上且无法撤销因此真正的功夫全在动手之前反复确认、分级授权、关键步骤必须有人复核关口设在每一个动作的起点事后还要留下完整的手术记录以备追溯。参考引用https://blog.csdn.net/Jmilk/article/details/163748849https://github.com/openai/codexhttps://github.com/deepseek-ai/deepseek-harnesshttps://docs.claude.com/en/docs/claude-code/overviewhttps://kiro.dev/docs/how-kiro-works/https://github.com/openai/codex ↩︎https://github.com/deepseek-ai/deepseek-harness ↩︎https://docs.claude.com/en/docs/claude-code/overview ↩︎https://kiro.dev/docs/how-kiro-works/ ↩︎https://blog.csdn.net/Jmilk/article/details/163748849 ↩︎