@kmeanskaran: https://x.com/kmeanskaran/status/2071160257943052683

X AI KOLs Timeline 新闻

摘要

一个关于为多智能体LLM系统构建生产级Agent框架的详细指南,涵盖编排器、子代理、技能、后端状态管理和上下文工程等组件。

https://t.co/8bdau2a2as
查看原文
查看缓存全文

缓存时间: 2026/06/28 16:11

将您的 Agent Harness 投入生产环境的指南

让一次 LLM 调用正常工作很容易。让五个 agent 在生产环境中可靠地协同工作则完全是另一个问题。真实用户会破坏系统。真实成本会迅速累积。真实故障会以本地环境从未展示过的方式级联。

区别就在于 harness。

本指南涵盖了完整的工程图景:Agent Harness 是什么,它由哪些组件构成,如何设计支持它的后端,以及如何优化,从而将一个可工作的系统转变为生产级系统。

第一部分:Agent Harness

它是什么

Agent Harness 是一个基础设施层,它将语言模型包装成一个有用的系统。它不是模型本身。它不是提示词。它是回答模型自身无法回答的所有问题的脚手架:

  • 工作产物在 agent 步骤之间存放在哪里?
  • 每个 agent 能看到什么上下文,明确排除什么?
  • agent 如何在不互相干扰上下文窗口的情况下协调?
  • 当 agent 产生错误输出或调用失败时会发生什么?
  • 成本如何追踪、限制和控制?

LLM 是一个推理引擎。harness 是让它变得有用的系统。每一个严肃的 agent 部署都建立在一个明确设计或偶然积累的 harness 之上。明确设计的那一个更快、更便宜、更容易调试。

五个组件

一个设计良好的 harness 由五个概念组成。每个概念都是针对在生产环境中运行 agent 时出现的特定故障模式的解决方案。

Agent Harness:五大组件

Agent Harness:五大组件

这五个组件是:

  • Orchestrator(协调器): 读取简报,按顺序委派任务,验证完成,报告完成
  • Subagents(子代理): 隔离的执行上下文,每个子代理只有一个任务和一份输出工件
  • Skills(技能): 每个 agent 的知识文档,定义了角色、输出格式和规则
  • Backend(后端): 共享的虚拟文件系统,agent 在步骤之间传递工作产物
  • Context Engineering(上下文工程): 控制每个 agent 看到什么、何时看到以及以什么顺序看到的规则

理解每个组件为什么存在比记忆 API 更有用。源自于理解为什么的设计决策才能规模化。

第二部分:后端

后端是 harness 的状态管理层。它回答了每个多 agent 系统都必须回答的问题:工作产物存放在哪里?

消息传递状态的缺陷

最 naive 的方法是通过对话消息传递 agent 输出。Agent A 产生结构化见解并返回它们。Orchestrator 存储响应并将其作为消息内容传递给 Agent B。

这会产生三个叠加强化的问题。

  • 上下文膨胀。 Orchestrator 线程中的每一条消息在后续每次调用中都会消耗 tokens。在四个 agent 运行并回传输出后,Orchestrator 携带了数千 tokens 的内容,而这些内容只有下一个 agent 才需要。在执行结束之前,每次调用你都要为此付费。
  • 没有检查面。 如果不解析 Orchestrator 的对话历史,就无法读取 Agent A 产生了什么。调试意味着要费力翻看推理痕迹。
  • 耦合。 Agent B 的行为依赖于 Agent A 响应在对话中出现的精确格式。A 输出模式中的格式变化会破坏 B。这种耦合在失败之前是不可见的。

虚拟文件系统

StateBackend 通过为每个任务提供一个虚拟文件系统解决了所有三个问题——这是一个在运行期间作用域的内存工作区。

Agent 之间不通过消息传递内容。它们将文件写入工作区并从中读取。

Agent 使用 skills.md 进行编排

Agent 使用 skills.md 进行编排

一个典型的五 agent 管道的工作区如下所示:在任务开始时植入一个 brief.md(唯一的输入),然后每个 agent 写入一个文件(提取的见解)、每个平台的草稿,以及最终的审核意见文件。当 extractor 完成时,它会写入其输出文件并在一句话中确认。Orchestrator 在其线程中只存储一行内容,而不是实际内容。下一个 agent 在运行时直接从文件中读取。

这一简单的更改将五 agent 管道中 Orchestrator 累积的上下文减少了大约 85%。它使得每个中间输出都可检查。并且它解耦了 agent:每个 agent 通过路径读取文件,而不是通过位置读取消息。

植入和结果组装

工作区一开始是空的。在 Orchestrator 运行之前,植入管道所需的一切:技能文件、共享上下文文档以及每个任务的简报。植入将文件系统设置与 agent 运行时分离,因此在第一次 LLM 调用之前工作区就已完全定义。

当管道完成时,读取工作区以组装结构化结果。这是调用代码唯一读取文件内容的地方。

最佳实践: 在管道运行期间,永远不要从 Orchestrator 代码中读取工作区内容。Orchestrator 通过文件存在性推断进度——哪些文件出现了,而不是文件内容。内容只读取一次,在结束时。

从工作区推断进度

基于文件的工作区有一个被低估的特性:你可以通过哪些文件存在来推断管道进度。在 agent 代码中不需要显式的进度回调。工作区状态就是进度状态。

第三部分:Skills

技能是什么

每个 agent 都有特定的工作。工作描述包括要产生什么、采用什么格式、遵循什么规则——这些都存在于技能文件中。技能是 markdown 文档,随系统提示一起加载到 agent 的上下文中。

关键的设计决策是渐进式披露:每个 agent 只加载它需要的技能。

Naive 的方法是包含所有 agent 的所有技能。这是错误的,原因有两个。

Token 成本。 技能是每次调用都加载的静态上下文。一个 X 文案撰写者加载 LinkedIn 格式说明,每次运行时都要为这些 tokens 付费,且对输出毫无贡献。

聚焦退化。 模型有时会从错误的上下文中应用指令。一个携带不必要指令的 agent 会以某些非零概率产生受这些指令影响的输出。agent 携带的无关上下文越多,这个问题就越严重。

每个 agent 声明它精确加载哪些技能。技能解析器只加载匹配的文件。五个 agent,五个技能。每个 agent 只看到自己的。

工具作用域遵循相同原则

工具是技能概念的扩展。和技能一样,它们增加 tokens(工具定义计入输入)并增加行为表面积。

只给 agent 它们实际能使用的工具。审核 agent 获得一个事实核查工具,只有它能验证外部声明。其他 agent 都不获得。一个不能调用外部 API 的 writer 没有工具。一个它用不了的工具就是开销:付出的 tokens、承担的行为风险,没有收益。

最佳实践: 一个 agent 的技能和工具集应该是完成其特定工作所需的最小集合。只有在特定任务要求时才扩展范围。

第四部分:Subagents 和隔离上下文

为什么共享上下文窗口会失败

当你在一个单一对话线程中运行多 agent 管道时,每个 agent 都会累积完整的历史记录。到审核 agent 运行时,它携带了 orchestrator 的规划推理、每个 writer 的输出确认,以及来自更正的任何来回交互。你要为每一个 tokens 付费。质量下降,因为审核 agent 在一个充满与其工作无关的上下文中进行推理。

Subagent 在隔离中运行

每个 subagent 得到一个全新的对话:自己的系统提示、自己的技能,以及它明确从工作区读取的内容。

agent 的共享线程 vs 隔离上下文(Subagents)

agent 的共享线程 vs 隔离上下文(Subagents)

Orchestrator 维护一个 agent 描述的扁平列表。当它决定委派时,通过描述进行选择。Subagent 在自己的上下文中运行,完成工作,写入工作区,完成后其上下文被垃圾回收。

成本差异显著。一个完全在单一共享线程中运行的五 agent 管道,在最后一步累积了 15,000–30,000 tokens 的历史记录。使用隔离 subagent 的相同管道,每个 agent 的上下文保持在 2,000–5,000 tokens。Orchestrator 的线程保持精简,因为它累积的是文件路径和一句话确认,而不是内容。

最佳实践: 设计 subagent,使其在工作区中正好有一个输出工件。一个任务,一个文件。这使得进度跟踪变得简单,输出可检查。

第五部分:上下文工程

上下文工程是控制什么进入 agent 上下文窗口、何时进入以及以什么顺序进入的规则。它对成本和质量的影响比其他任何工程决策都大。

静态先于动态规则

这是基础规则。必须无条件遵循。

静态内容 是在许多请求中相同的任何内容:系统提示、技能文件、工具定义、共享上下文文档。动态内容 是每个请求变化的内容:任务 ID、用户输入、时间戳、每个任务的参数。

正确的顺序是:工具定义最先(最稳定),然后是系统提示,接着是技能文件,然后是对话历史,最后是当前用户消息(完全动态,从不缓存)。

支持 provider 的提示缓存会存储前缀直到第一个动态内容的计算张量表示。缓存读取成本为正常输入价格的 10%。缓存未命中成本为 100%。

每次违反静态先于动态的规则都会破坏缓存前缀。常见的违反方式:在系统提示中放入任务 ID 或时间戳,在技能文件路径中嵌入用户特定数据,在系统消息中包含环境特定标志,或在请求之间更改工具定义。修复方法总是相同的:将动态值移到用户回合消息中。

持久记忆 vs. 每个任务的上下文

并非所有上下文都以相同方式老化。

持久记忆 在每个任务中都是稳定的:项目约定、行为指南、agent 应如何处理边缘情况。这些存在于一个共享文档中,在图构建时作为记忆加载。它在每个工作进程中计算并缓存一次。

每个任务的上下文 是特定于任务的:用户的 README、请求的平台、语气。这些属于在任务开始时植入工作区的简报文档——这是管道的唯一动态输入。

判断一段上下文属于哪个类别的测试:它在 1,000 个不同的任务中会相同吗?如果是,它是持久记忆。如果每个任务都变化,它属于简报,且永远不应出现在系统提示中。

线程压缩

对于长期运行的管道,对话线程会增长。较早的回合不如最近的回合相关,但在后续每次调用中仍消耗 tokens。

线程摘要中间件会自动处理这个问题。当线程超过可配置的 token 阈值时,较早的回合会被压缩成一个摘要段落。最后 N 条消息保持原样——最近的上下文最相关。

最佳实践: 不要将摘要阈值设置得太低。在上下文容量的 80% 处进行摘要,给 agent 留出工作空间,而无需不断压缩。在 40% 处进行摘要则会浪费 tokens 在摘要开销上。

第六部分:Orchestrator

协调,而非执行

Orchestrator 的角色只有一件事:读取简报,按顺序委派,验证完成,报告完成。

它明确不产生内容。这是一个严格的架构约束,而非指南。

Orchestrator 在系统中拥有最广泛的上下文。如果它开始推理领域特定任务(如撰写内容、做出事实判断、格式化输出),它将产生尚可的结果,但代价是:其上下文窗口被长推理轨迹填满、其协调角色与刚假定的领域角色之间的混淆,以及绕过 subagent 实现的质量控制。任何 orchestrator 想要产生领域特定输出的迹象,都意味着设计中缺少了一个 subagent。

构建一次,永远复用

Orchestrator 的构建成本很高:从磁盘加载技能文件、初始化模型客户端、编译图。在进程级别缓存它。每个工作进程构建一次,在每个任务中复用。

一个每小时处理 40 个任务的工作进程,构建图一次并复用 40 次。模块级单例是 Python 这里最简单、最可靠的模式。

在提示中强制执行管道不变量

Orchestrator 的系统提示是编码管道规则的地方:只生成简报中列出的平台,始终最后运行验证,将任务 ID 显式传递给每个 subagent,永远不要直接编写草稿文件,在报告完成前确认文件存在。

这些是协调规则,不是提示。使它们明确直接。Orchestrator 的提示应该读起来像技术运行手册,而不是创意简报。

第七部分:缓存栈

在 agent 系统中,缓存比传统应用有更大的杠杆作用,因为你可以避免多个层面的工作。每个层面有不同的成本节省、不同的命中率和不同的实现复杂性。

3 层缓存

3 层缓存

第 1 层:Provider 提示缓存

Anthropic 的提示缓存存储稳定提示前缀的计算 KV 张量表示。后续请求具有相同前缀时,以正常输入 token 价格的 10% 从缓存读取。

前提条件是严格遵循静态先于动态的顺序。缓存控制透明地应用于每个系统消息——调用点不会改变。

工程师常忽略的关键约束:最小 token 阈值为 1,024 tokens。低于此内容会静默缓存失败;没有错误,没有警告,只是缓存未命中且按全价计费。工具定义更改会使整个缓存层级失效。每个请求最多有四个缓存断点。

第 2 层:Redis LLM 响应缓存

提示缓存降低了 token 成本,但没有消除 API 延迟——你仍然要发出 HTTP 调用并等待响应。Redis 响应缓存在 API 之上运行:缓存命中意味着没有 HTTP 调用、没有延迟、零成本。

系统中的每个 LLM 调用——orchestrator 和所有 subagents——在发出任何 API 调用之前自动检查 Redis。缓存键是完整序列化消息列表与模型配置的哈希组合。将模型配置包含在键中意味着模型升级会自动创建新键。

在提示更改时对键进行版本控制。 没有版本控制,一个有问题的提示会被缓存并服务数小时。部署时进行版本升级会清空整个缓存,而无需直接操作 Redis。

按环境的 TTL: 开发环境 5 分钟(提示编辑立即可见),预发布环境 1 小时(足够稳定以捕获回归),生产环境 24 小时(最大化成本节省)。

第 3 层:内容身份缓存

对于同一源材料反复出现的情况(流行开源仓库被不同用户提交、文档被多次处理),内容身份缓存可以消除管道中最昂贵的步骤。

对原始源内容进行哈希。同一文档即使有不同用户指定的参数,由于源内容相同,会哈希到同一键。此缓存基于内容身份,而非提示身份。命中时完全绕过 LLM:没有 API 调用、没有 tokens、没有延迟。TTL 可以更长——对于大多数内容,七天是合理的。

第八部分:Token 优化

相似文章

@Potatoloogs: https://x.com/Potatoloogs/status/2057391224592667051

X AI KOLs Timeline

本文深度拆解了Agent Harness的概念,即包裹在LLM外部的工程基础设施,包括编排循环、工具调用、记忆系统、上下文管理等12个组件。文章引用Anthropic、OpenAI、LangChain等公司的实践,论证了harness对生产级AI Agent的关键作用。

@janehu07: https://x.com/janehu07/status/2058359677843599494

X AI KOLs Timeline

本学习笔记介绍了智能体基础设施层的概念,将其定义为围绕LLM的基础设施层,提出了ETCLOVG分类法(执行、工具、上下文、生命周期、可观测性、验证、治理),并通过编码智能体案例研究展示了其应用。

最好的智能代理工具会这样做……

Reddit r/AI_Agents

作者分享了构建高效智能代理工具的见解:最好的工具最大限度地减少对大语言模型(LLM)在琐碎任务上的依赖,将其保留用于复杂推理,从而将真正的代理工具与简单的包装器区分开来。