Build Hour: AgentKit




摘要

本次 Build Hour 介绍了 AgentKit,这是一个用于构建、部署和优化代理工作流 (agentic workflows) 的综合工具包。来自 OpenAI 产品和工程团队的演讲者演示了如何使用 Agent Builder 可视化地设计多步骤、调用工具的代理,如何使用 ChatKit 嵌入可定制的用户界面,以及如何使用新的 Evals 功能确保规模化应用时的可靠性,同时还展示了真实的案例。

目录

  • 简介

  • Agent Builder

  • ChatKit

  • Evals

  • 真实案例


简介

Tasia: 大家好,欢迎来到 OpenAI Build Hours。我是 Tasia,平台团队的产品营销经理。很高兴为大家介绍今天的演讲者:首先是我自己开场,然后是来自我们应用 AI 团队初创企业方向的 Samarth,以及负责平台团队产品的 Henry。

提醒一下,Build Hours 的目标是为各位构建者提供最佳实践、工具和 AI 专业知识,帮助大家利用 OpenAI 的 API 和模型来扩展你们的公司、产品和愿景。你可以在下面的链接 openai.com/buildours 查看日程安排。

我们今天的议程是:我会先快速介绍一下几周前在 Devday 上发布的 AgentKit。接着交给 Samarth 进行 AgentKit 的演示。然后 Henry 会带我们了解 Evals,这个功能能真正让代理焕发生机,并让我们能够大规模地信任它们。

如果有时间,我们会看几个真实案例,最后当然会留出时间进行问答。所以请在观看过程中随时添加你们的问题。

我们先来快速回顾一下过去几个月甚至一年里构建代理 (agents) 是什么样子的。过去,这非常复杂。

编排 (orchestration) 很困难,你必须用代码来编写一切。如果你想更新版本,有时会引入破坏性的变更。如果你想安全地连接工具,你必须编写自定义代码来实现。

而运行评估 (evals) 则需要你手动从一个系统提取数据到另一个独立的评估平台,把所有这些独立的系统串联起来,才能确保你能够大规模地信任那些代理。

提示词优化 (prompt optimization) 既缓慢又需要手动操作。最重要的是,你还必须构建 UI 来让这些代理真正可用,这又需要额外几周甚至几个月的时间。

所以,这个领域急需一次重大升级,这正是我们现在在做的事情。

我们希望 AgentKit 能在构建代理的方式上带来一些显著的改进。现在,工作流可以通过一个可视化的工作流构建器 (visual workflow builder) 来直观地构建,并且它是有版本的,所以不会引入破坏性的变更。

我们有一个管理中心,叫做连接器注册表 (connector registry),你可以在这里安全地连接数据和工具。我们还在平台中内置了 Evals 功能,甚至支持第三方模型。

待会 Samarth 会向我们展示,还有一个自动化的提示词优化工具,这使得自动完善提示词变得非常容易,而不再需要你自己手动反复试验。

最后,我们还有 ChatKit,这是一个可定制的 UI。

总结一下,这就是 AgentKit 的技术栈。底层是 Agent Builder,你可以在这里选择用哪些模型来部署代理、连接工具、编写和自动优化提示词、添加防护栏 (guardrails),以确保代理在收到意外查询时也能按预期执行。

然后你可以将其部署到 ChatKit,你可以自己托管,也可以使用 OpenAI 托管。最后,通过我们的 Evals 平台,观察和优化它们在真实世界数据和真实用户交互中的表现,从而在实际应用中大规模地优化这些代理。

我们已经看到大量初创公司和财富 500 强企业在使用代理来构建各种用例。其中比较流行的包括:客户支持代理,用于分类和回答基于聊天的客户支持工单;销售助手,类似于我们今天将要演示的那个。

还有内部生产力工具,就像我们在 OpenAI 内部使用的那样,帮助各个团队更智能、更快速地工作,减少重复劳动。

此外还有知识助手,甚至用于研究,比如文档研究或一般性研究。右边的截图只是 Agent Builder 中的几个模板,展示了我们已经在支持的一些主要用例。

好,让我们通过一个真实的例子来把这一切变为现实。

企业面临的一个共同挑战是推动和增加收入。假设你的销售团队忙于拓展潜在客户、建立关系和会见客户,我们希望构建一个市场推广 (go-to-market) 助手,以帮助销售节省时间并增加收入。接下来,我把时间交给 Samarth,他会向我们展示如何做到这一点。

Samarth: 我们在 OpenAI 收到最多的问题之一就是:OpenAI 内部是如何使用 OpenAI 的?

希望这能稍微揭开一点帷幕,让大家一窥我们实际上是如何构建一些市场推广助手的。我们今天将涵盖几个不同的话题,比如能够进行数据分析、潜在客户资格预审以及出站邮件生成的代理。

我现在切换过来共享一下屏幕。


Agent Builder

Samarth: 好的,我们现在在我们的 Atlas 浏览器上。大家可以下载试试,过去几周我用得非常开心。我觉得它有时帮我节省了几个小时甚至几天的时间,我非常喜欢它。

好,我们开始吧。当我们进入 Agent Builder 平台时,首先看到的是一个开始节点 (start node) 和一个代理节点 (agent node)。

你可以把代理想象成你构建的工作流中的原子单位。其背后是 Agents SDK,它实际上驱动着整个 Agent Builder。

当我们构建这些 Agent Builder 工作流时,它不必非得运行在 OpenAI 平台上。你可以复制这些代码,自己托管。你甚至可能想把它用在传统的聊天应用之外,比如通过 webhooks 来触发它们。

在今天的例子中,我们打算构建三个代理:一个用于数据分析,我们会从 Databricks 拉取数据;一个用于潜在客户资格预审,我们会抓取互联网上的额外信息;还有一个用于出站邮件生成,我们可能想用产品或营销活动的信息来限定邮件内容。

听起来不错吧?

Tasia: 听起来很棒,我准备好了。

Samarth: 好的,我们来构建第一个代理。由于我们实际要构建的东西有三种不同类型的用例,我们想使用一个非常传统的架构模式:使用一个分流代理 (triage agent)。

我们的想法是,代理非常擅长执行特定任务。因此,如果我们把问题分解到正确的子代理 (sub agent),我们可能会得到更好的响应。

我们把第一个代理称为“问题分类器 (question classifier)”。

打字真难。我复制一下我们准备好的提示词,快速看一下内容。我们在这里做的,实际上是要求模型将一个问题分类为“资格预审 (qualification)”、“数据 (data)”或“邮件 (email)”类型。

这样做的目的是,我们接下来就可以根据模型选择的输出类型,将这个查询路由到不同的路径。我们不希望它输出传统的文本,而是想强制模型按照我们能识别和在工作流其余部分使用的格式 (schema) 来输出。

我们把模型输出的这个变量叫做 category (类别),并选择类型为 enum (枚举)。这意味着模型只会从我们这里提供的列表中输出一个选项。在我的提示词里,有邮件代理、数据代理和资格预审代理。

Tasia: 稍等,你是怎么写这个提示词的?完全是你自己写的吗?我知道提示词对于引导代理非常重要,你是怎么构思的?

Samarth: 我认为写提示词是我们要做的最麻烦的事情之一。在构思最初的提示词时,我们经常在到底什么才是真正重要的事情上兜圈子。我自己写提示词最关键的方法之一,就是使用 ChatGPT 和 GPT-5 来创建我的 V0 版本提示词。

在 Agent Builder 内部,你实际上可以从头开始编辑或创建提示词,作为你未来在代理工作流中迭代的基础。目前,我们先用粘贴进来的这个。但在工作流的后续部分,我们会看一看实际使用那个功能是什么样子。

好,现在我们得到了输出。Agent Builder 允许我们让这个过程变得非常有状态 (stateful)。比如,我这里有一个“设置状态 (set state)”图标。抱歉,拖放操作有时也挺难的。

我们要做的是,获取前一个阶段的输出值,并将其赋给一个新变量,以便工作流的其余部分能够引用它。我们还是叫它 category,暂时不设置默认值。

利用这个值,我现在可以进行条件分支,要么转到数据分析代理,要么转到工作流的其余部分,去处理在执行邮件或客户资格预审用例之前,我可能想做的其他步骤。

我们把这个代理拖进来,设置这里的条件语句为:如果状态 category 等于 data。哦,看来我拼错了。调试一下。

很好,如你所见,这里有很有用的提示,我们能看到具体哪里出了错,并且能很快回去修正它。在这个例子中,我们要检查如果它是数据代理,就路由到那个单独的代理。

如果不是,我们可能会用额外的逻辑去互联网上搜索那些我们想要预审的入站线索,或者写一封邮件。我们先来看看数据分析代理,以及在 Agent Builder 和 Agents SDK 中连接到外部数据源是什么样子的。

我想做的是,指示模型如何使用 Databricks 并创建它可以使用的查询,与一个 MCP (Model-driven Computation Platform) 服务器协同工作。我们在这里做的是,为模型添加了一个工具,让它能够去访问这个 MCP 服务器并按需查询 Databricks。

如果我的查询非常复杂,可能需要连接 (joins),Databricks 和 GPT-5 能够协同工作,创建一个简洁的查询。

由于我现在已经构建了自己的服务器,我把它添加进来。我先添加我的 URL,把它叫做“Databricks MCP 服务器”。

我在这里要选择认证模式。你也可以选择无认证,但对于受保护的资源或位于需要认证的平台内部的资源,你可能想使用像个人访问令牌 (personal access token) 这样的东西来完成最后一步的联邦认证。在这个例子中,我使用我在 Databricks 实例中创建的个人访问令牌,然后点击创建。

等它加载一下工具,我们可以看到这里提交了一个 fetch (获取) 工具。这允许我们选择 MCP 服务器实际允许的函数的一个子集,以确保模型不会被它能采取的潜在行动选项所淹没。我把那个工具添加进去。

我退一步,刚才可能漏掉了一件事,就是设置模型。我希望这个反应非常快,所以我可以选择一个非推理 (non-reasoning) 模型。但对于这个节点,我希望模型能够迭代这些查询,并根据模型(或者说代理)感知到的模型结果做出反应。

好,我们来做一个快速测试查询,确保管道是通的。也许我会说:“显示排名前 10 的客户”。

我们可以看到模型实际上正在逐步执行工作流的各个阶段。在开始,你可以看到它把这个问题分类为数据问题,保存了状态,然后进行了路由。

当它到达那个代理并决定使用那个工具时,它实际上会请求我们的同意才会去执行那个操作。你可以在前端配置这个逻辑,来处理如何向用户显示:“嘿,模型想执行一个操作”。

使用 MCP,你既可以执行读操作,也可以执行写操作。我们有一些开箱即用的 MCP 服务器,比如 Gmail。我们还有更多开箱即用的连接,比如 SharePoint。

所以在这里我们可以看到,模型实际上在思考如何构建那个查询,然后我们看到了一个响应。我们没有要求模型为我们格式化这个结果,但我们可以通过这个代理非常快地做到这一点,只需要告诉模型:“我希望结果是自然语言”。

通过在 Agent Builder 内部点击“生成 (generate)”按钮,你就能够根据实时看到的结果进行这些即时更改。

接下来我想做的,是创建另一个代理,来做一些我们之前提到的研究工作。这对于生成邮件或预审一个线索可能很有用。我们称之为“信息收集代理 (information gathering agent)”。

看起来它卡住了,我可能需要刷新一下。平台有点小问题。

好,我们现在在这个信息收集代理。我们想告诉模型如何去互联网上搜索我们想要的线索。具体来说,我们想查找一个公司可能公开的信息子集,比如公司的法定名称、员工数量、公司描述,也许还有年收入以及地理位置。

我们在这里同样想使用结构化输出 (structured output),来定义当模型去互联网上搜索时,我们希望的输出应该是什么样子。这给了我们一个很好的映射,模型自己也知道在编写查询时要查找什么。然后我们就能在模型搜索互联网的方式上对其进行指导。

我们还想更改输出格式,以匹配我们想要输入的 schema。也许我们想把刚才展示的那些字段放到一个结构化输出格式中。你也可以在属性中添加描述,但现在我们先把它们留空。

很好,现在当模型进入这个信息收集代理时,它会触发这个代理,搜索互联网,并按照我们寻找的格式输出。

由于我们在开始时保存了查询路由的状态,我们可以在后面再次引用它。比如当我们要再次通过邮件或潜在客户生成与增强代理进行路由时。

我们把这里设置为等于 email (邮件),否则就把它路由到另一个代理。

Tasia: 对,这种子代理架构很棒,因为它意味着你能更快地获得比使用单一通用代理更高质量的结果。

Samarth: 这对于产生实际影响、帮助销售团队提高效率很有帮助。

我们在这里为这个邮件代理粘贴一个提示词。但这个邮件代理的亮点在于,我们希望生成的邮件不仅是来自查询或互联网的信息,我们还想上传文件,这些文件可能对应着我们构建营销活动邮件的整体思路。

所以在这种情况下,你可能会有包含活动信息的 PDF,也许还有其他包含如何撰写邮件信息的 PDF。所有这些对于模型来说都是非常有用的信息,可以用来详细规划那封邮件到底应该是什么样子。

我们在这里添加一个工具,去搜索这些文件。你可以把你已有的向量存储 (vector stores) 附加到工作流中,并开箱即用。你也可以通过 API 添加它们。

但现在,我们就拖入几个已有的文件。我们有一个关于如何撰写邮件的标准操作流程 (SOP),还有一个关于这家示例公司潜在促销活动的文件。我们所做的就是允许模型进入并搜索这个向量存储,获取这类信息,以便实际生成那封邮件。

至于潜在客户增强代理,我们不自己写了,假装我们有一个市场的通用细分,我们想把不同的客户主管分配过去。在这种情况下,我们想做的是,根据从互联网上收集到的信息,能够输出一个关于我们将如何进行分配过程的快速示意图。Agent Builder 能够在不编写提示词的情况下,输出整个提示词的一个版本,作为一个起点。

在我离开 Agent Builder 并展示端到端工作流之前,我想展示一下 Agent Builder 不仅支持文本和结构化输出格式,我们还支持非常丰富的微件 (widgets)。

在实践中,这意味着我们不仅可以输出文本或 JSON,还可以上传一个微件。我稍后会向你展示创建和使用微件是什么样子,但我们实际上可以上传一个微件文件本身。

我把这个拖进来。

很好,我们可以看到这个微件的快速预览。我们不只是输出文本,也许不像传统的 ChatGPT 那样输出 Markdown 格式的结果,我们可能想渲染一些更丰富的东西。这样,如果你在自己的网站上托管它,你也能拥有那种多模态的组件。

我们在这里创建这个组件。现在如果我说:“起草一封邮件给 OpenAI”。

很好,我们可以看到它进入了信息收集代理。因为我们给了它访问网页搜索工具的权限。我确认一下我是否真的给了。我可能跳过了那一步。

Tasia: 我很喜欢你可以在这里实时测试工作流并进行调试,就像我们现在这样,然后再发布到生产环境。

Samarth: 没错。最棒的是,当你在这个工作流中运行问题时,我们会保存模型执行各种查询的确切追踪 (traces),更宏观地说,是工作流的编排方式。

这在你持续迭代工作流时是非常丰富的信息。Henry 会详细讲到这一点,但这种真正揭开帷幕、查看模型是如何思考并分配评分者 (graders) 的能力,确实让你能够规模化地推广评估过程。

好,看起来它在搜索 LumaFleet。我们让它运行一会儿,看看最后会发生什么。

好吧,看起来可能需要一点时间。我们稍后再回来看端到端的结果。

我们在这里构建的,本质上是一个允许你做三件不同事情的代理。第一,它允许你查询 Databricks,以便拉取那些可能存在于某种信息墙后面的信息,并将其拉入代理工作流。

第二,能够预审和撰写邮件。

第三,预审你可能从客户那里获得的入站线索。

所有这些都存在于一个工作流中,你可以把它托管在 ChatKit(我们稍后会讲到)里,或者你可以把它拿出来,用在你自己的代码库中,处理那些聊天工作流。

Tasia: 我有个问题,从左侧边栏拖一个工具作为一个节点,和把那个工具添加到代理节点内部,这两者有什么区别?

Samarth: 好问题。当我把搜索工具添加到信息收集代理时,我是允许模型来决定是否应该使用那个工具。但有时候,我希望工具在代理获取信息之前总是运行。这时我就可以添加一个这样的节点(指工具节点),来确保模型在代理接收信息之前,确实执行了这个操作。

Tasia: 非常合理。所以 AgentKit 感觉是确定性结果和非确定性结果的一个很好结合。

Samarth: 对。我想切换一下话题。我们构建了这个很棒的工作流,现在我们想去部署它。

我认为我们在最近的 Devday 上发布的最棒的功能之一,就是能够托管你构建的这些工作流。通过使用我们构建的工作流 ID,我们能够驱动这些聊天界面。而这些界面如果自己构建,可能需要大量的工程工作来支持推理模型,以及支持复杂的代理架构和你可能想向用户展示的切换过程。


ChatKit

Samarth: 在生产环境中,这意味着你能够让你构建的聊天界面完全匹配你的品牌指南。我们会看一些真实客户如今是如何使用它的。

但我想强调的是,你完全可以自定义这一切,包括配色方案、字体,以及你的用户可能会用到的启动提示词 (starter prompts)。

举个例子,假设我们有一个查看水电费账单的工作流。我们可能希望它连接到 MCP 服务器,拉取你的账单历史,分析那些过去的账单,然后向用户展示一个非常丰富的微件。这整个过程,以及用户所见内容的定制,完全可以通过 ChatKit 来配置。

所以在这里,对于“我的能源使用情况如何?”这个问题,我们不只是显示传统的文本回复,而是看到了一个非常丰富的图表,让你能够可视化地看到输出。

Tasia: 这太酷了。我想就我们的用例再补充一点,我们有一个可用的微件,也许你稍后会展示,就是电子邮件微件。所以如果你想让代理起草一封给 OpenAI 的邮件——我猜它还在研究相关信息,因为关于 OpenAI 的公开信息太多了——然后销售人员就可以点击一个按钮,把那封邮件发送给客户。

Samarth: 没错。我们来看几个那样的微件。我们发布了一个展示廊 (gallery),你可以看一些我们认为很酷的微件。你也可以点击进去,查看构建这些微件的代码。但我认为真正酷的是,能够通过自然语言来生成它们。

比如,如果我想要一个电子邮件组件或微件,我想模拟出它包含特定的品牌指南,或者以一种符合我品牌风格的方式来格式化那个微件,我完全可以通过自然语言来做到。

然后你可以把它导出到 Agent Builder,当 Agent Builder 在 ChatKit 中调用那个微件时,就可以显示那个 UI。

在交给 Henry 之前,我想展示一个现实生活中的例子。我们这里有一个网站,渲染了一个地球的图片。我们想做的是,通过自然语言来控制这个地球仪。Tasia,我们今天想去哪儿?

Tasia: 我想我们下一个 Devday Exchange 是在班加罗尔,所以我想说印度。我们去印度吧。

Samarth: 我们在这里看到的,是另一个由 Agent Builder 驱动的工作流。但我们可以看到,不仅右侧弹出了一个微件,我们实际上还能够控制网站上渲染的 JavaScript。

所以,能够拥有这种可定制性,并将其移植到你每天使用的网站和浏览器中,这是我们在 ChatKit 中发现的非常吸引人的一点。

Tasia: 这是我去印度最快的一次。

Samarth: 没错。

我们介绍了构建方面,以及部署到 ChatKit 方面。但真正最重要的部分,也是构建代理过程中最困难的部分,是评估 (evaluate) 部分。

Tasia: 没错,这关乎我们如何能信任这些代理在生产环境的真实场景中、在面对所有那些“光荣”又怪异的边缘情况下,能够规模化地工作。

接下来,我想把时间交给我们在英国的朋友 Henry,他会给我们做一个 Evals 的演示。


Evals

Henry: 非常感谢 Tasha 和 Samarth。大家好,我是 Henry,我是参与开发 AgentKit 的产品经理之一。

今天我想谈谈,当你构建了那个代理、有了那个工作流,并在可视化构建器中定义了它之后,你该如何测试它。

我想先谈谈你如何测试一个单独的节点,并确信那个特定的代理或节点会按照你的预期执行。因为归根结底,你的代理的质量取决于它最薄弱的环节。你需要每一个组件都调整到位,并按照你希望的方式执行。

当你对每个节点的表现都满意之后,你就需要评估端到端的性能。为此,你可以查看追踪 (traces),但追踪很难解读。所以现在我们也有了追踪评分 (trace grading) 体验,允许你获取那些追踪并规模化地评估它们。

让我打开我的屏幕,开始给你们演示一下我们是如何做到这一点的。

大家在这里可以看到我构建的一个代理。这是基于我们一个金融服务客户的真实案例。它接收一个公司名称作为输入,评估这是一个上市公司还是私营公司,然后对该公司进行一系列分析,最后为该公司的专业投资者撰写一份报告以供审阅。

正如我提到的,这里有一大堆代理,每一个代理都需要表现良好,并按你的预期执行。那么,你如何对它的性能建立信心?你如何获得可见性和透明度,来了解它将如何执行?

当你定义这个代理并查看其中一个节点时,你可以看到右下角有一个“评估 (Evaluate)”按钮。我们点击它,它会把那个代理节点——它有提示词、有工具、有分配的模型——在一个数据集中打开。

在这里你可以看到这个数据集 (datasets) UI,它允许你直观地构建一个简单的评估。我现在要给这个评估附加几行数据。你可以看到公司名称,以及一些真实 (ground truth) 的收入和利润数据。

我把数据导入到这个数据集中,这能让我们运行这个评估。

在这里你可以看到从可视化构建器传递过来的所有东西:模型、网页搜索工具、系统提示词 (system prompt) 和我们指定的用户消息 (user message)。

此外,你还可以看到我上传的数据。这里只有三行,几个公司名称,然后是我们的网页搜索工具应该为这些公司返回的收入和利润的真实值。

我现在可以运行生成 (generation)。这显然是任何评估的第一阶段。完成了生成之后,再完成评估阶段。

在生成运行的同时,我想展示一下我们如何附加列 (columns)。在这里我们可以为“评分 (ratings)”添加新列,我们可以附加一个“赞”或“踩”的评分。然后我们再为“自由文本反馈 (free text feedback)”添加列。我可以在这里附加一个自由文本的标注。

也许我对某项感到满意,也许我想对那条数据附加一些更长的反馈。

现在你可以看到,输出正在显现。如果我点进去,我可以在这些已完成的生成结果中切换查看。你可以看到,这里要求我完成对亚马逊、苹果的分析,Meta 的还在运行中。我可以滚动查看已完成的生成结果。

接下来我就可以附加我刚才创建的这些自由文本标签或标注。我可以说这个“好”,那个“差”,这个“好”,然后我还可以附加反馈,比如,这个“太长了”。

完成这些标注后,我还可以添加评分者 (graders)。我在这里添加一个评分者,创建一个简单的评分者,用来评估一份金融分析报告。它会要求这份金融分析包含看涨和看跌的论点,考虑了竞争对手,并以“买入”、“卖出”或“持有”的评级结束。

我保存并运行它。这现在会运行,完成那些评分者的评级。这需要一点时间来运行,因为我们有很多数据。

我切换到一个我之前创建的数据集,在这里你可以看到评分者已经完成了。如果我点进去,我可以看到理由 (rationale),看到为什么评分者给出了那样的结果。

比如这里,你可以看到这个评分者失败了,因为没有明确的建议,也没有竞争对手的比较。

在这一点上我们能做什么?我们先回顾一下现状:我们已经完成了生成,有了所有的标注,还有了所有这些评分者的输出。在这一点上,你该如何让你的代理变得更好?

一种方法是做一些手动的提示词工程,试着在数据中找到规律,然后重写你的提示词。这显然需要很长时间,需要你找到那些规律,并花大量时间去解决它们。

我们认为一个更好的解决方案是自动提示词优化 (automated prompt optimization)。你可以看到这里有一个新的“优化 (Optimize)”按钮。如果我点击它,它会打开这个数据集里的一个新提示词标签页。在那里我们将自动重写提示词。这就是你如何省去每次都得手动做提示词工程的方法。

我们在这里所做的,是利用那些标注、评分者输出和提示词本身,来建议一个新的提示词。这同样需要一到两分钟来运行。我切换到一个我之前做好的。你可以看到这里重写的提示词,它完成了一份基本的金融分析,但比我最初那个非常粗糙的提示词要详尽和完整得多。

以上就是关于如何从 Agent Builder 中提取单个节点,并稳健地评估该单个代理的概览。

但我们在这里构建的不是单个代理,这是一个多代理系统 (multi-agent system)。我们想单独测试每一个节点,但最终我们关心的是端到端的性能。我们如何对此建立信心?如何测试它?

正如 Samarth 提到的,这些代理会发出追踪 (traces)。在这里你可以看到我之前运行这个代理时的一些示例追踪。

点击查看,我能看到每一个跨度 (span),我可以点进每一个跨度,开始识别这个代理运行时发生了什么。

在我点击查看的过程中,我可能会开始注意到问题。比如,你可以看到网页搜索工具拉取了一堆来源,比如 CNBC 和 Barrons。也许我们不希望引用这些第三方来源,也许我们只想要第一方的权威来源。所以我们应该说:“网页搜索来源应该只包含第一方”。

我们用 GPT-5 和 Nano 来运行它,这样会很快。

然后,当我点击查看更多追踪时,我可能会发现其他问题。假设我们发现了另一个规律:最终结果不包含“买入/卖出/持有”的评级。所以我们说:“最终结果需要包含清晰的买入/卖出评级”。

我不断地建立这些需求 (requirements),然后我可以在特定的追踪上运行它们。现在,你可以把这套需求看作是一个评分者标准 (grader rubric)。这个标准由一系列定义“好代理”的标准构成。

一旦我建立了这套标准,并在几个追踪上测试过它,我就可以点击顶部的“全部评分 (Grade All)”按钮。这会导出我限定范围内的追踪集合——在这个例子中就是这五个追踪——并且会采用我在右侧定义的评分者集合,在一个新的评估 (eval) 中打开它。

这允许你大规模地评估大量的追踪。因为点击查看每一个追踪并试图找到问题,效率并不高,它需要大量时间,无法规模化。

相反,你可以在大量的追踪上运行这些追踪评分者,这会帮助你只识别那些有问题的跨度,和那些你想要深入研究的追踪。

以上就是关于我们如何将这种嵌入式的评估体验与 Agent Builder 紧密结合的概览。

我还想快速展示一些我们从大量客户那里学到的最佳实践和经验教训。

首先,保持简单,不要过度复杂化,但要尽早开始。在项目一开始就定义好少量的输入和一个简单的评分者,而不是把评估留到最后一刻,像“我马上要发布这个东西了,我最好做点测试”。我知道有些人会这么做。

更好的做法是尽早开始,嵌入评估,进行“评估驱动开发 (eval-driven development)”。你严格地测试你的原型,在原型中发现问题,然后在你针对评估进行爬坡优化时,定量地衡量你的改进。这是构建产品的更好方式,也可能带来更高的性能。

其次,使用人类数据。仅仅靠想出假设性的输入、用大语言模型 (LLM) 生成合成输入是很难的。如果你能从真实终端用户那里获得真实的用户数据和输入,你可能会得到更好的性能,因为这捕捉到了真实世界中的许多混乱情况。

最后,确保你投入大量时间来标注生成结果,并校准 (aligning) 你的大语言模型评分者。这是你确保你的专业领域知识真正被编码到系统中的方式,这样你的评分者才能真正代表你希望产品做到的事情。

这就是我们产品的一个高层概览。这一切都已正式发布 (GA),我们非常希望大家能去试用一下,并请告诉我们任何反馈。

接下来我把时间交还给 Tasha 和 Samarth。


真实案例

Tasia: 谢谢 Henry,我觉得我们完全可以就 Evals 做一个小时的专场。

在你下线之前,我有一个快速问题。聊天区有人问:你推荐多大的评估数据集?是 100 条、1000 条还是 10 条?你怎么知道多大的数据集规模才能得到你想要的结果?

Henry: 最好的做法是尽早开始。所以即便是 10 到 20 个例子也大有裨益。在你的应用中加入那套数据来进行测试,是非常有帮助的。

所以,即便是 10 个、20 个,几十行数据都是有帮助的。当然,当你接近生产环境时,显然是越多越好。但我不会把它仅仅看作是一个有多少行数据的问题,因为这里有一个“质量乘以数量”的乘数效应需要考虑。

拥有 50 行高质量的输入,它们能很好地代表大量用户问题,并且有与你期望行为高度一致的评分者,这可能会表现得非常好。相反,如果你用大语言模型生成 1000 行合成输入,那帮助可能并不大。

所以我想说,质量几乎比数量更重要。

Tasia: 非常有道理。

Samarth: 是的,补充一点。我们经常被问到的一个问题是:我们如何创建一个多样化的数据集来运行评估?特别是当你还没有把很多这类工具投入生产时。

当我们在构建市场推广助手时,支持这些工作流的工程团队会和我们的市场推广团队坐在一起,了解领域专家真正在问什么或好奇什么。这让我们能够构建一个良好且多样化的问题集。这样在每一次迭代优化时,我们都能捕捉到人们真正在交互时的细微差别和真实查询。

Tasia: 太酷了。

好的,谢谢 Henry。接下来,我想介绍几个真实世界的案例,然后我们会在最后留出时间进行问答。

首先是一个简短的视频,是 RAMP 构建的一个采购代理。他们使用 ChatKit 来向请求软件的人可视化这个 UI,使用 Agent Builder 在后端编排代理流程,并使用 Evals 来确保它能在生产环境中规模化地工作。虽然这个功能还没有在他们的平台上正式上线,但我们希望在不久的将来能看到它。这就是他们构建内容和原型的快速演示。

RAMP 使用 AgentKit 技术栈,能够将构建这个原型的速度提高 70%,我觉得这非常惊人。这相当于两个工程冲刺 (sprints) 的时间,而不是两个季度。

Ripling,我记得你参与了这个项目,能分享一下他们构建了什么以及进展如何吗?

Samarth: 当然。我们最初在考虑如何通过 Agents SDK 来规划这个项目。其中一个很大的挑战是,如何在领域专家和构建逻辑上合理的工作流的能力之间达成一致。所以我们真的和他们坐在一起,了解他们真实的市场推广用例,并以此为基础反向工作。和他们团队的交流非常愉快,使用像 Agent Builder 这样的工具,我们得到了大量关于我们希望推出的下一版本的非常好的反馈。

Tasia: 太棒了。

同样,HubSpot 在 AI 领域也做了很多出色的工作。他们使用 ChatKit 来增强他们的 Breeze AI 助手。他们节省了数周的前端时间。正如我们一开始提到的,从头到尾构建代理非常耗时,因为涉及的每一步都很复杂。因此,即便是我们能在众多步骤中的一个环节——在这个案例中是 UI 方面——提供帮助,也是一个有用的提升。

最后是 Carlile 和 Bane,这是我们两个非常出色的 Evals 客户。他们能够在评估数据集中看到 25% 的效率提升,这非常棒。

在我们进入问答环节之前,总结一下:当我们推出 AgentKit 时,这些是早期在产品上构建的客户。你可以看到 AgentKit 目前正在为初创公司、财富 500 强以及介于两者之间的各种公司的技术栈提供支持。

这些是不同类型的代理,用例范围非常广泛,从工作助手到采购代理、政策代理。大型零售商 Albertson's 有一个商品智能代理。Bane 在做代码现代化。很高兴看到如此广泛的用例。

接下来,我们进入聊天区的问答环节。

好的,第一个问题:“我如何添加 for 循环?”

Samarth: 好问题。我们没有 for 循环,但在 Agent Builder 中有一个 while 循环。你能够根据一个完成标准是否被满足,来有条件地、持续地运行不同的代理工作流。

当然,使用 Agents SDK,你可以把它拿到代码库中,然后自己编排。也许把我们的实现当作 V0 版本。但我们支持 while 循环,这样你就能够在整个工作流中迭代,直到满足那个结束标准。希望这有帮助。

下一个问题:“AgentKit 和 Agents SDK 相比如何?”

我想说,AgentKit 是我们尝试提炼出的一套产品套件,包含了我们 OpenAI 在日常构建代理时认为最有用的工具。Agents SDK 驱动着整个 AgentKit,你在 AgentKit 中能做的大部分事情,在 Agents SDK 中也能做到,或者通过 API 可用。

目前,我们正在持续推出大量变更,使两者更加一致。但我们设想,未来 AgentKit 还会包含一些功能,让你能扩展在云上托管这些工作流的能力。这样,你不仅可以使用传统的 ChatKit 实现,还可以通过 API 来触发这些工作流。这本质上允许你在云上托管 Agents SDK。

Tasia: 是的,Agent Builder 在功能上就像是 Agents SDK,但它是基于画布的可视化方式来编排代理,而 Agents SDK 更像是直接跳进代码里去编写。

下一个问题:“如何使用开箱即用的 MCP 服务器,与构建自己的 MCP 服务器相比有何不同?”

Samarth: 我们有一些 MCP 服务器,支持远程 MCP 服务器。这意味着 MCP 服务器必须托管在云上,或者在某种程度上托管在公共互联网上。

当我们在构建自己的 MCP 服务器时,很多关于认证的考量要求我们必须这样做。话虽如此,你每天使用的很多提供商,比如 Gmail、你的日历等,它们都有开箱即用的连接,你可能只需要粘贴一个 API 密钥,就可以开始使用我们支持的所有工具了。

但我想,其中一些我们还没有完全的写入能力。比如,如果你想通过 Gmail API 写邮件,我相信目前还不支持,所以你可能想自己搭建一个 MCP 服务器。

我真正喜欢 MCP 的一点是,它允许进行认证,并将流程黑盒化。所以,无论你是想带上你自己的个人访问令牌,还是通过 OOTH 这样的流程,然后把你拿到的最终令牌传递给 MCP 服务器,这两种都是对安全来源进行认证的绝佳选择。

Tasia: 还有问题吗?有的。

“你推荐什么时候使用分类器代理 (classifier agent) 和分支逻辑来分配到不同的代理?”

Samarth: 我认为这是一个很好的问题,我们经常被问到。因为当你向一个模型添加越来越多的工具和指令时,我们看到性能通常会下降。

想象一个世界,你有 100 个工具。让模型从 100 个工具中选择一个,会变得越来越困难。更现实的情况是,你可能没有 100 个工具,但你可能有 20 个。而每个代理或每个用例,可能会以完全不同的方式使用这些工具。

我思考代理的一种方式是,我喜欢对这个代理的核心能力、我希望它使用的工具集以及它使用这些工具的特定方式,进行逻辑分层。

当模型开始混淆如何调用这些工具、如何结合工具的上下文来解释指令时,我就倾向于分支到一个不同的代理。

就像我们之前的例子,我们有三个不同的市场推广用例。也许我们构建的那个输出微件的邮件代理,并不是同时做潜在客户资格预审的最佳选择。

所以在那些用例中,也许你用的是相同的工具,但你想以不同的方式来结构化输出,你想让模型以不同的方式来解释输出,这时最好就分支到不同的代理。

Tasia: 好的。“我们能将 AgentKit 用于多模态用例吗?特别是分析图像和文件。”

Samarth: 当然。这对 AgentKit 来说是一个很好的用例。我们在之前谈到的预览部分支持文件输入。你甚至可以在 Playground 中试着上传文件。

我发现真正有趣的是,我们将这种行为也推广到了 ChatKit。或者说 ChatKit 也将这种行为推广到了 Agent Builder。当你在 ChatKit 中上传文件时,它也会被传递到托管的 Agent Builder 后端。

Tasia: 太酷了。

好,我们的时间快到了。如果你有兴趣探索更多,我们想留给你一些资源。

AgentKit 文档,是开始的好地方。我们前几周还发布了一本 Cookbook,它会带你过一遍和我们今天展示的非常相似的用例,甚至更详细。Chat Studio,如果你想试玩 ChatKit,看看如何定制它。

最后,要了解更多即将举行的 Build Hours 和过去的内容,可以访问 GitHub 上的 Build Hour repo。

我们还有两场即将举行的 Build Hours。一场是关于 Agent RFT,基于我们今天讨论的内容,你如何为工具调用和自定义评分者来定制模型。那是在 11 月 5 日。所以我们非常期待在下一次会议上继续今天的话题。然后在 12 月 3 日,是关于代理记忆模式 (agent memory patterns)。

希望在这两场活动中都能看到大家。你可以通过这个链接获取更多注册信息。

好的,非常感谢你准备了这么棒的演示,非常有趣。也感谢大家的观看,希望你们在构建代理时玩得开心。


AI 前线

Sam Altman 最新给 AI 时代创始人的七堂课 | 附原访谈全文+视频

2025-12-23 15:17:26

AI 前线

与 Sam 和 Jony 的对话

2025-12-23 15:17:32

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索