Harness解读

59 阅读23分钟

Agent 里的 Harness 到底是什么?从“大模型 + 工具”讲到 Loop Engineering

摘要:讲清 Agent Harness 的内循环控制,并进一步解释长期任务为什么需要 Loop Engineering。

很多人聊 Agent 时,喜欢用一个公式:

Agent = 大模型 + 工具

这个说法不能算错,但少了一块最关键的东西:Harness。

如果说大模型是“会思考的大脑”,工具是“能触达外部世界的手脚”,那 Harness 就是把大脑、手脚、规则、记忆、检查、日志都串起来的“工作系统”。没有 Harness,模型再强,也只是一次次生成文本;有了 Harness,它才可能持续、安全、可控地把任务做完。

这篇文章不想只解释定义。我们会从一个更工程化的问题出发:

为什么模型能力已经很强了,真正落地 Agent 时还是离不开 Harness?

再往深一点,还会补上一个容易被忽略的问题:

Harness 能管好单个 Agent 的一次次行动,但如果任务长到要跨多轮、多阶段、多 Agent 协作,又该由谁来管?

1. 先把话说清楚:这里的 Harness 不是 CI/CD 产品

本文里的 Harness,指的是 Agent Harness / AI Harness,不是 Harness.io 那个 DevOps 平台。

在 Agent 语境下,Harness 可以理解为:

围绕大模型搭建的一套运行机制,负责上下文构建、工具编排、状态记忆、循环控制、安全审批、流式输出、日志追踪和结果校验。

更直观一点:

image.png

大模型负责“想”,Harness 负责“让这个想法变成可靠行动”。

这也是为什么你图里写的那句很关键:agent = 大模型 + Harness。大模型本身只会预测下一个 token,它不会天然知道哪些工具能用、哪些动作不能做、什么时候该停、做错了怎么恢复、日志该怎么记、成本该怎么控。

这些都不是模型参数里的魔法,而是 Harness 的工程职责。

2. 为什么模型很强,仍然不能直接等于 Agent?

先看一个简单例子。

用户说:

“帮我查一下最近三篇关于 GraphRAG 的论文,整理核心贡献,并生成一份 Markdown 笔记。”

如果只有大模型,它可以凭已有知识写一段内容。但它会遇到几个现实问题:

问题只有模型会怎样Harness 要做什么
信息是否最新模型可能凭旧知识回答决定是否搜索、检索、读文件
工具怎么调用模型只能“说要查”把模型意图转成真实工具调用
中间结果放哪一轮上下文里容易丢保存消息、状态、资料和进度
查错了怎么办可能继续胡编捕获错误、重试、改策略
什么时候停可能一直搜索或提前结束设置完成条件、轮数、预算
是否安全可能调用危险操作做权限、审批、白名单和脱敏
结果怎么验证答案看着像真的做格式校验、事实检查、评测

这就是 Harness 的意义:它不是提高模型智商,而是让模型的能力进入一个能工作的系统。

模型能力越强,Harness 反而越重要。因为模型越能“自己决定”,它越可能触发真实世界的副作用,比如发邮件、改数据库、删除文件、调用付费 API。没有 Harness,Agent 的能力边界会很模糊。

3. 前置知识:Agent 的一次 turn 里发生了什么?

普通 LLM 调用通常是:

用户输入 → 模型生成 → 返回文本。

Agent 的一次 turn 更像这样:

image.png

可以拆成 8 步:

  1. 接收用户请求或外部触发器。
  2. 加载系统规则、用户上下文、会话历史、检索资料。
  3. 构造模型输入,也就是这一轮真正发给模型的上下文。
  4. 模型判断:直接回答,还是请求调用工具。
  5. Harness 校验工具调用是否合法、是否需要审批。
  6. 执行工具,拿到观察结果或错误。
  7. 更新消息、记忆、任务状态和进度。
  8. 判断继续循环、输出结果、暂停审批,还是交给人工。

你会发现,模型只在第 4 步真正“出场”。其余步骤都属于 Harness。

所以,Harness 的核心不是“再包一层 SDK”,而是回答一个更底层的问题:模型每说一句话之后,系统到底该怎么接?

4. Harness 到底管哪些模块?

一个成熟 Harness 通常会管 7 类事情。

4.1 指令与规则:告诉 Agent 什么能做、什么不能做

规则不是简单写一句“你是一个有帮助的助手”。工程里的规则至少包括:

  • 任务目标:最终要交付什么。
  • 行为边界:哪些事情不能做。
  • 工具边界:哪些工具能用,哪些不能用。
  • 输出要求:返回 Markdown、JSON、表格还是结构化对象。
  • 停止条件:达到什么状态就结束。
  • 风险策略:遇到高风险动作是否需要人工确认。

很多 Agent 跑偏,不是模型不聪明,而是 Harness 没把规则写成可执行约束。

比如“不能访问生产库”这句话,不能只放在 Prompt 里祈祷模型遵守。更可靠的做法是:工具层压根不给生产写权限;即使模型想调用,也会被 Harness 拦住。

4.2 上下文构建:不要把所有东西一股脑塞给模型

上下文构建是 Harness 的第一道大活。

模型每一轮看到什么,会直接决定它下一步做什么。Harness 要决定:

  • 哪些历史消息要保留。
  • 哪些历史可以摘要。
  • 哪些知识要从 RAG 中检索。
  • 哪些状态必须显式放进去。
  • 哪些敏感信息不能进入上下文。

这里有个常见误区:上下文越多越好。

实际不是。上下文太多会带来三个问题:

问题后果
噪声变多模型注意力被无关信息分散
成本变高每轮 token 消耗上升
风险变大敏感信息更容易被带入输出或工具参数

好的 Harness 会像一个懂取舍的助理:只把当前任务真正需要的资料递给模型。

4.3 工具编排:把“我想查一下”变成真实动作

工具调用是 Agent 的手脚,但 Harness 是神经系统。

模型可能输出:

  • 调用搜索工具。
  • 查询数据库。
  • 读取文件。
  • 写入文档。
  • 调用内部 API。
  • 请求人工审批。

Harness 需要负责:

职责说明
工具描述告诉模型每个工具能做什么、参数是什么
参数校验检查参数类型、范围、必填项
权限控制判断当前用户和 Agent 是否有权调用
审批流程对发邮件、写库、删除文件等动作加确认
超时重试工具失败时决定是否重试或换方案
结果回填把工具返回结果重新交给模型继续推理

很多人以为 Tool Calling 就等于 Agent,其实 Tool Calling 只是 Harness 的一个子模块。真正难的是:工具调用之后系统怎么继续。

4.4 记忆与状态:别让 Agent 忘记自己做到哪一步

记忆可以分两类:

类型保存什么例子
会话状态当前任务进度、工具结果、待办事项“已完成论文检索,下一步写对比表”
长期记忆用户偏好、稳定事实、可复用资料“用户喜欢中文技术博客风格”

很多 Agent 项目失败,不是因为没有向量库,而是因为没有明确状态。

比如一个研究型 Agent 做到一半重启了。它需要知道:已经查过哪些资料、哪些结论已验证、哪些工具失败过、最终文件保存在哪里。这个“做到哪一步”的信息,比泛泛的长期记忆更重要。

所以别把 Memory 理解成“什么都存”。更准确的说法是:

Harness 要保存那些会影响下一步决策的信息。

4.5 控制循环:决定继续、重试、暂停还是结束

Agent 最容易出问题的地方,就是循环。

它可能一直搜索,一直调用同一个工具,一直说“我再确认一下”,然后成本一点点烧掉。

Harness 需要设置刹车:

  • 最多执行多少轮。
  • 最长运行多久。
  • 最多花多少 token 或多少钱。
  • 连续失败几次就停止。
  • 哪些状态必须转人工。
  • 哪些输出算任务完成。

OpenAI Agents SDK 的 Runner 循环、Cloudflare 对 harness loop 的描述,背后都在讲同一件事:Agent 不是一次调用,而是一个会反复调用模型和工具的控制过程。

4.6 安全护栏:不要把“相信模型”当权限系统

安全护栏可以分三层。

护栏位置检查什么例子
输入护栏用户请求是否越权、恶意、无关“帮我导出所有用户手机号”
工具护栏工具调用是否合法、是否需要审批删除文件、发邮件、改订单状态
输出护栏最终结果是否泄露、违规、格式错误泄露密钥、输出未脱敏数据

真正靠谱的 Harness 不会只靠 Prompt 写“请遵守安全规范”。它会把安全变成代码、权限、审批和日志。

一个基本原则是:高风险动作必须默认不自动执行。

4.7 可观测与评测:Agent 不能只看最终答案

普通接口出错,你看日志就能定位。Agent 出错,如果没有轨迹,就很难知道问题在哪。

你需要记录:

  • 每一轮模型输入。
  • 每一轮模型输出。
  • 工具调用名称和参数。
  • 工具返回结果。
  • 审批是否通过。
  • 每轮 token、耗时、成本。
  • 最终输出是否通过校验。

Cloudflare 的 tracing 文档里也强调,Agent trace 应该能看到每一轮模型调用、工具运行和审批请求。这个能力非常关键,因为 Agent 的问题通常不是“最后一句话错了”,而是“中间某一步悄悄错了”。

5. Harness 的四种常见形态

不同项目需要的 Harness 不一样。不要一上来就做最复杂的自主 Agent。 image.png

5.1 单次调用型 Harness

这是最轻量的形态。

它通常只做:输入清洗、Prompt 拼接、模型调用、输出格式校验。

维度说明
原理把一次模型调用包装得更稳定
优点简单、便宜、延迟低、容易上线
缺点不适合多步任务,不会动态调用工具
适合摘要、分类、改写、信息抽取、结构化输出

如果你的任务本来就是“一问一答”,这个就够了。不要为了“像 Agent”而制造复杂性。

5.2 工具调用型 Harness

这类 Harness 会支持少量工具调用,比如搜索、查库、读文件、调用业务 API。

维度说明
原理模型选择工具,Harness 校验并执行,结果再回到模型
优点能连接外部世界,适合短链路任务
缺点工具多了之后,路由和权限会变复杂
适合RAG 问答、客服查单、知识库助手、内部工具助手

这也是很多团队最先落地的 Agent 形态。它不追求完全自治,而是让模型在有限工具集合里做判断。

5.3 工作流型 Harness

当任务流程比较明确,但某些节点需要模型判断时,工作流型 Harness 更合适。

比如:

  1. 接收用户问题。
  2. 判断意图。
  3. 路由到知识库或业务 API。
  4. 生成答案。
  5. 做安全检查。
  6. 必要时转人工。
维度说明
原理用状态机或工作流显式编排节点,LLM 只负责部分判断
优点可控、可观测、可测试、适合生产
缺点灵活性比自主 Agent 弱,前期设计成本更高
适合客服、审批、工单、企业内部流程、RAG 生产系统

Anthropic 在 Agent 实践文章里也提到:能用简单方案就先用简单方案;当流程明确时,workflow 往往比完全 autonomous agent 更稳定。

5.4 自主 Agent Harness

这类 Harness 更接近大家想象中的 Agent:给一个目标,它自己拆任务、选工具、观察结果、继续推进。

维度说明
原理模型动态决定流程和工具使用,Harness 负责边界与循环
优点适合开放式、多步骤、探索型任务
缺点成本、延迟、稳定性和安全风险都更高
适合深度调研、代码迁移、复杂数据分析、自动化原型

这种形态最有“智能感”,但也最容易失控。落地时一定要有最大步数、预算上限、工具白名单、人工确认和完整 trace。

5.5 平台型 Harness

平台型 Harness 会把 Agent 运行时、工具、记忆、审批、日志、评测、权限、团队协作都做成一套平台能力。

比如 Microsoft Agent Framework 的 Harness、Cloudflare Agents 的 harness/runtime 分层、OpenAI Agents SDK 的 Runner/Guardrails/Tracing 等,都在往这个方向走。

维度说明
原理把 Agent 运行机制产品化、平台化、可治理化
优点更适合团队协作、生产部署和统一治理
缺点平台依赖更强,定制成本和学习成本更高
适合企业级 Agent 平台、多团队复用、长周期运营

6. 深一点看:Harness 的本质是管理“不确定性”

如果只说 Harness 是“模型外壳”,还是浅了。

更深入地看,Harness 是在管理三种不确定性。

6.1 信息不确定性

模型不知道哪些信息最新、哪些资料可信、哪些上下文相关。

Harness 要通过检索、记忆、上下文压缩、来源标注来降低信息不确定性。

6.2 行动不确定性

模型可能选择错误工具、传错参数、重复调用、触发危险动作。

Harness 要通过工具 schema、参数校验、权限控制、审批机制、幂等设计来降低行动不确定性。

6.3 过程不确定性

多步任务会出现偏航、循环、超预算、上下文膨胀、工具失败。

Harness 要通过状态机、最大轮数、重试策略、日志追踪、评测集来降低过程不确定性。

所以 Harness 的价值,不是让 Agent 看起来更复杂,而是让不确定性有边界。

7. 再往深一层:Harness 管内循环,Loop 管外循环

到这里,我们已经能说清楚 Harness 的价值:它让单个 Agent 能安全、可控地完成一步步行动。

但这还不是 Agent 系统的终点。

更准确地说:Agent 解决一次具体执行,Loop 支撑整件事持续推进。 这句话点出了 Harness 的边界。

7.1 什么叫“内循环”?

Harness 更像一个 Agent 的内循环控制器。

它关心的是:

  • 这一轮上下文怎么构建。
  • 这一步要不要调用工具。
  • 工具参数是否合法。
  • 工具结果怎么喂回模型。
  • 这一步是否要重试。
  • 这一轮是否应该停止。

换句话说,Harness 主要解决:

这一步行动到底有没有做对?

比如一个代码 Agent 写完代码后跑测试,测试失败就读取报错、修改代码、再跑测试。这就是典型内循环:模型思考,工具执行,观察结果,再修正。

7.2 什么叫“外循环”?

外循环,也就是现在很多人开始提的 Loop Engineering,关心的是另一层问题:

  • 大目标怎么拆成多个子任务。
  • 子任务之间有什么依赖。
  • 哪些任务可以并行。
  • 哪个 Agent 负责哪一块。
  • 当前进度走到哪了。
  • 某个子任务失败后怎么恢复。
  • 什么时候应该重新规划。
  • 什么标准才算整件事真正完成。

它解决的是:

这件大事到底有没有走完?

所以你可以这样区分:

层级关注点典型问题
LLM能不能推理和生成这句话怎么答?下一步候选动作是什么?
Harness单个 Agent 能不能行动这一步要不要调工具?结果是否要重试?
Agent能不能完成一个具体任务这个研究/编码/分析任务能否做完?
Loop长期目标能不能持续推进子任务怎么排?失败怎么恢复?多 Agent 怎么调度?
Runtime / Platform能不能稳定上线权限、审计、成本、扩缩容、监控怎么做?

这张图可以把关系看得更清楚:

image.png

7.3 为什么 Harness 解决不了所有长任务?

假设你让 Agent 做一份完整的行业研究报告。

它不只是“搜一下资料然后写一段话”,而是要经历:

  1. 明确研究目标。
  2. 拆分研究问题。
  3. 搜集资料。
  4. 读取网页和论文。
  5. 提取关键数据。
  6. 交叉验证来源。
  7. 分析竞争格局。
  8. 写初稿。
  9. 自检和修改。
  10. 生成最终报告。

这里面每一步都可以由 Harness 管好,但“整件事怎么排兵布阵”,不是 Harness 一层就能优雅解决的。

如果没有外层 Loop,系统很容易出现这些问题:

问题表现
进度失忆不知道哪些子任务已经完成
依赖混乱数据还没验证就开始写结论
重复劳动多个 Agent 查同一批资料
失败不可恢复某一步失败后整条链路中断
完成标准模糊Agent 自己说“做完了”就算结束

所以更成熟的系统通常会变成:

目标 → Loop 拆任务和调度 → Agent 执行 → Harness 控制行动 → 工具调用 → 结果校验 → Loop 判断下一步

这里的 Loop 不是普通 Workflow 的改名。

传统 Workflow 往往是提前写死路径:A 完成后走 B,B 完成后走 C。Loop 更强调根据执行状态动态决定下一步:这一步失败了要不要重试?要不要换 Agent?要不要重新规划?要不要暂停给人审批?

不过,Loop 灵活不等于放养。真正能上生产的 Loop,仍然要有状态机、轮数上限、超时机制、成本预算、检查点、权限控制和人工介入。

7.4 别只数 Agent 数量,要看 Loop 质量

很多团队做 Agent 项目,效果不好就想“再加几个 Agent 分工”。

但多个 Agent 摆在一起,不等于系统更强。没有调度、状态、依赖、校验和恢复,多 Agent 只是多开了几个聊天窗口。

真正该看的指标是:

指标为什么重要
端到端任务完成率不是单步成功,而是整件事成功
平均恢复次数失败后能不能自己补救
人工介入率哪些节点仍然需要人兜底
工具失败率工具层是不是系统短板
平均任务耗时长任务是否能在可接受时间内完成
Token / 成本消耗自主循环是否过度调用模型
Trace 可回放性出问题后能不能复盘整条路径

一句话:

Harness 决定单个 Agent 能不能干活,Loop 决定一组 Agent 能不能把复杂任务持续做完。

8. 一个最小 Harness 应该怎么写?

下面是一个教学版伪代码。它不是某个框架的源码,而是帮助你理解 Harness 的基本骨架。

class SimpleAgentHarness:
    # 初始化 Harness,把模型、工具、记忆和策略装配在一起
    def __init__(self, model, tools, memory, policy):
        # model 负责理解输入并生成下一步决策
        self.model = model
        # tools 是工具白名单,只允许模型调用这里注册过的工具
        self.tools = tools
        # memory 保存会话历史、任务状态和可复用资料
        self.memory = memory
        # policy 保存最大轮数、审批规则、预算上限等控制策略
        self.policy = policy

    # run 方法负责完整执行一次用户任务
    def run(self, user_input):
        # 初始化本次任务状态,避免多轮执行时丢失进度
        state = {
            "user_input": user_input,
            "history": [],
            "finished": False,
        }

        # max_turns 是 Harness 的刹车,防止 Agent 无限循环
        for turn in range(self.policy.max_turns):
            # 构建上下文:规则、历史、记忆和用户输入都会进入模型视野
            context = self.build_context(state)

            # 调用模型,让模型决定是回答、调用工具还是请求人工确认
            decision = self.model.decide(context)

            # 如果模型已经给出最终答案,先做输出校验,再返回结果
            if decision.type == "final_answer":
                return self.validate_output(decision.content)

            # 如果模型请求工具调用,先检查工具是否存在于白名单
            if decision.type == "tool_call":
                tool = self.tools.get(decision.tool_name)
                if tool is None:
                    # 工具不存在时记录错误,让下一轮模型修正计划
                    state["history"].append({"error": "tool_not_found"})
                    continue

                # 高风险工具必须先经过审批,不能让模型直接执行
                if self.policy.need_approval(decision.tool_name, decision.args):
                    return self.pause_for_approval(decision)

                # 执行工具,并把外部世界的返回值作为观察结果
                observation = tool.run(decision.args)

                # 保存工具调用轨迹,方便后续调试和审计
                state["history"].append({
                    "turn": turn,
                    "decision": decision,
                    "observation": observation,
                })

                # 把重要观察写入记忆,避免下一轮重复查询
                self.memory.save(observation)

        # 超过最大轮数仍未完成时,返回可控失败,而不是继续烧成本
        return "任务没有在限定轮数内完成,建议人工接管或调整任务范围。"

这段伪代码里,真正“智能”的只有 model.decide()。但真正让系统可用的是周围这些工程控制:白名单、审批、记忆、状态、校验、最大轮数。

这就是 Harness 的味道。

9. 设计 Harness 时,先问这 8 个问题

做 Agent 不要先选框架,先问问题。

问题为什么重要
任务是不是多步的?单步任务不一定需要 Agent
流程是否固定?固定流程更适合 workflow
需要哪些工具?工具决定能力边界和风险边界
工具有没有副作用?写操作、删除、发布都需要审批
状态需要保存多久?决定用内存、数据库还是长期记忆
任务是否跨多阶段?如果要长期推进,就需要外层 Loop 管理进度
如何判断完成?没有完成条件就容易无限循环
如何观测和评测?没有 trace 和 eval,线上问题很难定位

一个很实用的选型顺序是:

  1. 能单次调用解决,就别上 Agent。
  2. 能固定流程解决,就用 workflow。
  3. 只有当步骤需要动态调整时,再用工具调用型 Harness。
  4. 只有当目标开放、路径未知、工具反馈会改变计划时,再考虑自主 Agent Harness。
  5. 如果任务跨多阶段、多 Agent 或长时间运行,就补上外层 Loop。
  6. 只要涉及生产系统,就补齐权限、审批、日志、评测和回滚。

10. 工程落地:Harness 的模块清单

如果你要在项目里真正搭一个 Harness,可以按下面这份清单拆。

模块必做能力进阶能力
Prompt / 指令系统规则、输出格式、工具说明动态指令、角色切换、策略注入
Context历史消息、任务状态RAG、摘要压缩、上下文预算控制
Tool Runtime工具注册、参数校验幂等、超时、重试、熔断、审批
Memory会话状态、关键结果用户偏好、跨任务经验、记忆清理
Loop Control最大轮数、停止条件自反思、重规划、恢复运行
Outer Loop任务拆解、进度记录多 Agent 调度、检查点、失败恢复
Guardrails输入/输出/工具校验数据脱敏、策略引擎、风险分级
Observability日志、trace、token 统计回放、评测集、告警、成本分析
Human-in-the-loop人工确认审批队列、权限分层、SLA

这里面最容易被忽视的是 Observability。很多团队前期只关注“Agent 能不能跑起来”,等线上出问题才发现没有记录中间步骤,根本不知道它为什么做出那个决定。

11. 常见误区

误区一:Harness 就是 Prompt 模板

Prompt 是 Harness 的一部分,但 Harness 远不止 Prompt。

Prompt 负责告诉模型怎么做;Harness 负责当模型真的要做时,系统如何执行、检查、保存和恢复。

误区二:工具越多,Agent 越强

工具越多,模型越容易选错,权限越难管,日志越难查。

更好的做法是:先给少量高质量工具,每个工具有清晰描述、明确参数和可控副作用。

误区三:Memory 什么都应该存

Memory 不是垃圾桶。写入太多低质量内容,会让后续检索变脏。

应该存的是稳定、验证过、会影响未来决策的信息。

误区四:自主 Agent 比工作流高级

不是。

工作流可预测、可测试、好治理;自主 Agent 灵活,但不确定性更高。生产环境里,经常是“工作流为主,Agent 节点为辅”。

误区五:只要最终答案对,中间过程不重要

Agent 的中间过程非常重要。

如果它通过错误资料得到了一个看似正确的答案,下一次可能就会翻车。工程上不能只看结果,还要能回放路径。

误区六:多加几个 Agent,系统就会自动变强

多个 Agent 没有调度、状态、依赖管理和结果验证,只是多个模型实例并排跑。

真正让多 Agent 有生产力的不是“数量”,而是外层 Loop 能不能把任务拆清楚、派清楚、验清楚、恢复清楚。

12. 相关知识点

知识点和 Harness 的关系
ReActHarness 常见控制循环:思考、行动、观察、继续
Loop Engineering管长期目标、任务规划、多 Agent 调度和失败恢复
Plan-and-ExecuteHarness 可以先规划任务,再逐步执行
ReflectionHarness 可在关键节点加入自检和修正
Tool CallingHarness 把模型工具请求变成真实函数调用
MCP为工具提供标准化协议,方便 Harness 接入外部能力
RAGHarness 构建上下文的重要方式
GuardrailsHarness 的安全与合规模块
State Machine工作流型 Harness 常用的控制方式
Checkpoint长任务恢复的关键机制,避免失败后从头再来
TracingHarness 可观测性的核心能力
Evals用任务集检验 Harness 是否真的稳定

13. 总结

如果只记一句话:

Harness 是让大模型从“会说”走向“会做,并且可控地做”的关键工程层;Loop 则让多个行动围绕长期目标持续推进。

它不神秘,也不是某个固定模块清单。它会随着业务场景变化:简单任务可能只需要 Prompt 和输出校验;复杂任务需要工具编排、状态管理、安全审批、长程恢复、trace 和评测;再复杂一点,就要让外层 Loop 负责目标分解、进度记录、多 Agent 调度和失败恢复。

模型越来越强之后,大家真正要拼的不是“谁会调 API”,而是谁能把模型放进可靠的工作系统里。Harness 就是这个系统的骨架。

所以,下一次再聊 Agent,不妨把公式写完整一点:

Agent = 大模型 + Harness;复杂 Agent 系统 = Agent + Loop + Runtime。

参考资料