追踪
Agents SDK 内置了追踪功能,会在一次智能体运行期间收集全面的事件记录:LLM 生成、工具调用、交接、护栏,甚至是发生的自定义事件。通过 Traces 仪表盘,你可以在开发与生产环境中调试、可视化并监控工作流。
导出循环生命周期
Section titled “导出循环生命周期”在大多数环境中,追踪会以固定间隔自动导出。在浏览器或 Cloudflare Workers 中,此功能默认禁用。追踪在排队过多时仍会导出,但不会按固定间隔导出。此时应使用 getGlobalTraceProvider().forceFlush() 将追踪导出纳入代码生命周期进行手动控制。
例如,在 Cloudflare Worker 中,你应将代码包裹在 try/catch/finally 中,并结合 waitUntil 使用强制刷新,以确保在 worker 退出前导出追踪。
import { getGlobalTraceProvider } from '@openai/agents';
export default { async fetch(request, env, ctx): Promise<Response> { try { // your agent code here return new Response(`success`); } catch (error) { console.error(error); return new Response(String(error), { status: 500 }); } finally { // make sure to flush any remaining traces before exiting ctx.waitUntil(getGlobalTraceProvider().forceFlush()); } },};- Traces(跟踪) 表示一次“工作流”的端到端操作。它由多个 Spans 组成。Trace 具有以下属性:
workflow_name:逻辑上的工作流或应用。例如 “Code generation” 或 “Customer service”。trace_id:该 Trace 的唯一 ID。若不传则自动生成。格式必须为trace_<32_alphanumeric>。group_id:可选的分组 ID,用于关联同一会话中的多个 Trace。例如,你可以使用聊天线程 ID。disabled:若为 True,则不会记录该 Trace。metadata:Trace 的可选元数据。
- Spans(跨度) 表示有开始与结束时间的操作。Span 包含:
started_at与ended_at时间戳。trace_id,表示其所属的 Traceparent_id,指向其父 Span(若有)span_data,关于该 Span 的信息。例如,AgentSpanData包含关于智能体的信息,GenerationSpanData包含关于 LLM 生成的信息,等等。
默认情况下,SDK 会追踪以下内容:
- 整个
run()或Runner.run()被包装在一个Trace中。 - 每次智能体运行都会被包装在
AgentSpan中 - LLM 生成被包装在
GenerationSpan中 - 函数工具调用各自被包装在
FunctionSpan中 - 护栏被包装在
GuardrailSpan中 - 交接被包装在
HandoffSpan中
默认的 Trace 名称为 “Agent workflow”。你可以使用 withTrace 设置该名称,或者通过 RunConfig.workflowName 配置名称及其他属性。
此外,你可以设置自定义追踪处理器,将追踪推送到其他目的地(作为替代或次要目的地)。
语音智能体跟踪
Section titled “语音智能体跟踪”如果你在使用 RealtimeAgent 和 RealtimeSession 搭配默认的 OpenAI Realtime API,追踪将自动在 Realtime API 侧进行,除非你在 RealtimeSession 上通过 tracingDisabled: true 或设置环境变量 OPENAI_AGENTS_DISABLE_TRACING 来禁用它。
查看语音智能体概述了解更多详情。
更高层级的跟踪
Section titled “更高层级的跟踪”有时,你可能希望多次调用 run() 属于同一个 Trace。你可以将整段代码包裹在 withTrace() 中实现。
import { Agent, run, withTrace } from '@openai/agents';
const agent = new Agent({ name: 'Joke generator', instructions: 'Tell funny jokes.',});
await withTrace('Joke workflow', async () => { const result = await run(agent, 'Tell me a joke'); const secondResult = await run( agent, `Rate this joke: ${result.finalOutput}`, ); console.log(`Joke: ${result.finalOutput}`); console.log(`Rating: ${secondResult.finalOutput}`);});- 由于两次对
run的调用都被withTrace()包裹,这些单次运行将归入同一个整体 Trace,而不是创建两个 Trace。
你可以使用 withTrace() 函数来创建一个 Trace。或者,你也可以使用 getGlobalTraceProvider().createTrace() 手动创建一个新的 Trace,并将其传入 withTrace()。
当前 Trace 通过 Node.js AsyncLocalStorage 或相应环境的 polyfill 进行跟踪。这意味着它能自动与并发协同工作。
你可以使用各类 create*Span()(如 createGenerationSpan()、createFunctionSpan() 等)方法来创建 Span。通常无需手动创建 Span。提供了一个 createCustomSpan() 函数用于跟踪自定义 Span 信息。
Span 会自动归入当前 Trace,并嵌套在最近的当前 Span 下方,该 Span 通过 Node.js AsyncLocalStorage 或相应环境的 polyfill 进行跟踪。
某些 Span 可能会捕获潜在的敏感数据。
createGenerationSpan() 会存储 LLM 生成的输入/输出,而 createFunctionSpan() 会存储函数调用的输入/输出。这些可能包含敏感数据,因此你可以通过 RunConfig.traceIncludeSensitiveData 禁用对这些数据的捕获。
自定义跟踪处理器
Section titled “自定义跟踪处理器”追踪的高层架构如下:
- 在初始化时,我们创建一个全局的
TraceProvider,负责创建 Trace,并可通过getGlobalTraceProvider()访问。 - 我们为
TraceProvider配置了一个BatchTraceProcessor,它将追踪/跨度批量发送到OpenAITracingExporter,后者会将跨度和追踪批量导出到 OpenAI 后端。
若要自定义该默认设置,将追踪发送到替代或附加的后端,或修改导出器行为,你有两种选择:
addTraceProcessor()允许你添加一个额外的追踪处理器,它会在追踪和跨度就绪时接收它们。这样你可以在将追踪发送到 OpenAI 后端之外,进行你自己的处理。setTraceProcessors()允许你替换默认处理器为你自己的追踪处理器。这意味着除非你包含一个将追踪发送到 OpenAI 后端的TracingProcessor,否则追踪将不会发送到 OpenAI 后端。