跳转到内容

执行结果

当您运行智能体时,您将收到以下其中之一:

两种结果类型都暴露了相同的核心结果面,例如 finalOutputnewItemsinterruptionsstateStreamedRunResult 还增加了流式控制项,例如 completedtoStream()toTextStream()currentAgent

大多数应用只需要少量属性:

如果您需要……使用
展示给用户的最终答案finalOutput
包含完整本地转录、可用于重放的下一轮输入history
仅包含本次运行中新生成、模型形状的条目output
带有智能体/工具/交接元数据的丰富运行条目newItems
通常应处理下一轮用户输入的智能体lastAgentactiveAgent
OpenAI Responses API 基于 previousResponseId 的链式调用lastResponseId
待批准项与可恢复快照interruptionsstate
应用上下文、审批、用量和嵌套智能体工具输入runContext
当前嵌套 Agent.asTool() 调用的元数据,例如在 customOutputExtractoragentToolInvocation
原始模型调用或护栏诊断信息rawResponses 和护栏结果数组

finalOutput 属性包含最后一个已运行智能体的最终输出。该结果可能是:

  • string —— 默认用于未定义 outputType 的任意智能体
  • unknown —— 当智能体将 JSON schema 定义为输出类型时。在这种情况下 JSON 已被解析,但您仍需手动验证其类型。
  • z.infer<outputType> —— 当智能体将 Zod schema 定义为输出类型时。输出会自动按该 schema 解析。
  • undefined —— 当智能体未产出输出时(例如在产出前已停止)

当流式运行仍在进行中,或运行在达到最终输出前因审批中断而暂停时,finalOutput 也会是 undefined

如果您在交接中使用了不同的输出类型,应使用 Agent.create() 方法而不是 new Agent() 构造函数来创建智能体。

这样 SDK 就能推断所有可能交接路径上的输出类型,并为 finalOutput 属性提供联合类型。

例如:

Handoff final output types
import { Agent, run } from '@openai/agents';
import { z } from 'zod';
const refundAgent = new Agent({
name: 'Refund Agent',
instructions:
'You are a refund agent. You are responsible for refunding customers.',
outputType: z.object({
refundApproved: z.boolean(),
}),
});
const orderAgent = new Agent({
name: 'Order Agent',
instructions:
'You are an order agent. You are responsible for processing orders.',
outputType: z.object({
orderId: z.string(),
}),
});
const triageAgent = Agent.create({
name: 'Triage Agent',
instructions:
'You are a triage agent. You are responsible for triaging customer issues.',
handoffs: [refundAgent, orderAgent],
});
const result = await run(triageAgent, 'I need to a refund for my order');
const output = result.finalOutput;
// ^? { refundApproved: boolean } | { orderId: string } | string | undefined

这些属性回答的是不同问题:

属性包含内容最适用途
input本次运行的基础输入。如果交接输入过滤器重写了历史,这里反映的是运行继续时使用的过滤后输入。审计本次运行实际使用了什么输入
output仅包含本次运行中生成的模型形状条目,不含智能体元数据。仅存储或重放新增模型增量
newItems带智能体/工具/交接元数据的丰富 RunItem 包装对象。日志、UI、审计与调试
historyinput + newItems 构建的可重放下一轮输入。手动聊天循环与客户端管理的会话状态

在实践中:

  • 当您在应用中手动维护整段会话时,使用 history
  • 当您已在其他地方存储了历史,只想要本次运行中新生成条目时,使用 output
  • 当您需要智能体关联、工具输出、交接边界或审批条目时,使用 newItems
  • 如果您使用 conversationIdpreviousResponseId,通常不需要把 history 再传回 run()。相反,只传新的用户输入并复用服务器管理的 ID。完整对比请见运行智能体

history 是在类聊天场景中维护完整历史的便捷方式:

History loop
import { Agent, user, run } from '@openai/agents';
import type { AgentInputItem } from '@openai/agents';
const agent = new Agent({
name: 'Assistant',
instructions:
'You are a helpful assistant knowledgeable about recent AGI research.',
});
let history: AgentInputItem[] = [
// initial message
user('Are we there yet?'),
];
for (let i = 0; i < 10; i++) {
// run 10 times
const result = await run(agent, history);
// update the history to the new output
history = result.history;
history.push(user('How about now?'));
}

newItems 为您提供本次运行过程最丰富的视图。常见条目类型有:

当您需要知道某个条目由哪个智能体产出,或它是否标记了工具、工具搜索、交接或审批边界时,请优先选择 newItems 而不是 output。当您使用 toolSearchTool() 时,这些工具搜索条目是检查在常规工具调用发生前加载了哪些延迟工具或命名空间的最简方式。

lastAgent 属性包含最后一个运行的智能体。在交接后,这通常是最适合复用来处理下一轮用户输入的智能体。activeAgent 是同一值的别名。

在流式模式下,currentAgent 可在运行尚未结束时告诉您当前处于活跃状态的智能体。

如果某个工具需要审批,运行会暂停,interruptions 会包含待处理的 RunToolApprovalItem。这可能包括直接工具触发的审批、交接后触达工具触发的审批,或嵌套 agent.asTool() 运行触发的审批。

通过 result.state.approve(...) / result.state.reject(...) 处理审批,然后将同一个 state 传回 run() 以恢复运行。您无需一次性处理所有中断。如果您只处理了部分条目就重新运行,已处理的调用可以继续,未处理的仍会保持待定并再次使运行暂停。

state 属性是结果背后的可序列化快照。可将其用于人机协作、重试流程或任何需要稍后恢复暂停运行的场景。

在使用 OpenAI Responses API 链式调用时,lastResponseId 是下一轮应作为 previousResponseId 传入的值。

如果您已经通过 historysessionconversationId 续接会话,通常不需要 lastResponseId。如果您需要多步骤运行中的每个原始模型响应,请改为查看 rawResponses

agentToolInvocation 用于嵌套 Agent.asTool() 的结果,尤其适用于您位于 customOutputExtractor 内并希望获取当前工具调用元数据时。它不是通用的“整个运行已完成”摘要字段。

在该嵌套上下文中,agentToolInvocation 提供:

  • toolName
  • toolCallId
  • toolArguments

如果您还需要传入该嵌套智能体工具运行的结构化输入,可配合 result.runContext.toolInput 一起使用。

在普通顶层 run() 结果上,这通常为 undefined。该元数据仅存在于运行时,不会被序列化到 RunState。相关模式请参见Agents as tools

StreamedRunResult 继承了上述相同的结果面,但增加了流式专用控制项:

  • toTextStream():仅用于助手文本。
  • toStream()for await ... of stream:用于完整事件流。
  • completed:等待运行及所有后处理回调完成。
  • errorcancelled:检查流式运行的终止状态。
  • currentAgent:在运行中追踪当前活跃智能体。

如果您需要流式运行最终稳定后的状态,请在读取 finalOutputhistoryinterruptions 或其他汇总属性前先等待 completed。如需逐事件处理,请参阅流式传输指南

如果流式运行被取消,completed 仍会在清理后完成,且 cancelled 变为 true,但如 finalOutput 这类轮次结束字段可能仍未设置,因为当前轮次未完成。此时应使用 result.state(以及同一个 session,如果您在用)恢复这个未完成轮次,而不是追加一条新的用户消息。

runContext 属性是结果上受支持的公开运行上下文视图。result.runContext.context 是您的应用上下文,而同一对象也携带 SDK 管理的运行时元数据,例如审批、用量和嵌套 toolInput。完整结构请参见上下文管理

rawResponses 包含运行期间收集到的原始模型响应。多步骤运行可能产生不止一个响应,例如在交接或重复的工具/模型循环中。

inputGuardrailResultsoutputGuardrailResults 属性包含智能体级护栏结果。工具级护栏结果通过 toolInputGuardrailResultstoolOutputGuardrailResults 单独提供。

当您希望记录护栏决策、查看护栏函数返回的额外元数据,或调试某次运行为何被阻止时,请使用这些数组。

Token 用量汇总在 result.state.usage 中,它会跟踪本次运行的请求次数和 token 总量。同一个用量对象也可通过 result.runContext.usage 获取。对于流式运行,这些数据会随着响应到达而更新。

Read usage from RunState
import { Agent, run } from '@openai/agents';
const agent = new Agent({
name: 'Usage Tracker',
instructions: 'Summarize the latest project update in one sentence.',
});
const result = await run(
agent,
'Summarize this: key customer feedback themes and the next product iteration.',
);
const usage = result.state.usage;
console.log({
requests: usage.requests,
inputTokens: usage.inputTokens,
outputTokens: usage.outputTokens,
totalTokens: usage.totalTokens,
});
if (usage.requestUsageEntries) {
for (const entry of usage.requestUsageEntries) {
console.log('request', {
endpoint: entry.endpoint,
inputTokens: entry.inputTokens,
outputTokens: entry.outputTokens,
totalTokens: entry.totalTokens,
});
}
}