尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

openai-agents-python 语音流水线追踪(Voice Tracing)完全指南:配置、敏感数据处理与源码级原理解析

openai-agents-python 语音流水线追踪(Voice Tracing)完全指南:配置、敏感数据处理与源码级原理解析 openai-agents-python 语音流水线追踪Voice Tracing完全指南配置、敏感数据处理与源码级原理解析【免费下载链接】openai-agents-pythonA lightweight, powerful framework for multi-agent workflows项目地址: https://gitcode.com/GitHub_Trending/op/openai-agents-python语音流水线Voice Pipeline是 openai-agents-python 中负责语音输入 → 文本 → Agent 工作流 → 语音输出全链路的核心模块而 tracing追踪则是理解和调试这条链路的关键能力。本文聚焦于语音流水线的专属追踪配置基于 docs/voice/tracing.md 展开结合仓库源码深入讲解VoicePipelineConfig中全部追踪相关字段的语义、默认值与底层实现并剖析 STT/TTS 在追踪中的 span 生成机制帮助你掌握语音应用的观测与调试方法。语音流水线为何需要独立的追踪配置在 openai-agents-python 中Agent 运行时的追踪 是内置且默认开启的SDK 会在一次 Agent 运行期间收集 LLM 生成、工具调用、handoff、guardrail 以及自定义事件等完整记录供你在 Traces 仪表盘上调试、可视化和监控线上工作流。语音流水线VoicePipeline与普通 Agent 运行不同它由三个阶段组成语音转文字STT→ 工作流推理 → 文字转语音TTS。正如 docs/voice/tracing.md 开头所述就像 Agent 会被自动追踪一样语音流水线也会被自动追踪。这意味着你无需额外编写任何打点代码一次pipeline.run()就会自动产生一条完整的 trace。但语音场景有一个普通文本场景没有的特殊问题——音频与转写文本属于高度敏感的数据因此 SDK 专门为语音流水线提供了VoicePipelineConfig这一套独立的追踪开关用于精细控制 trace 中是否包含音频、转写稿等内容。从源码看这一自动追踪并不是魔法而是由 VoicePipeline 内部显式创建的# src/agents/voice/pipeline.py 中的 _run_single_turn / _run_multi_turn with TraceCtxManager( workflow_nameself.config.workflow_name or Voice Agent, trace_idNone, # 自动生成 group_idself.config.group_id, metadataself.config.trace_metadata, tracingself.config.tracing, disabledself.config.tracing_disabled, ):可以看到单轮模式_run_single_turn和多轮流式模式_run_multi_turn都会用TraceCtxManager将整个语音处理的异步生命周期包裹起来形成一个独立的 trace 作用域workflow_name、group_id、metadata、disabled等字段全部取自VoicePipelineConfig。这就是自动追踪的底层实现依据。VoicePipelineConfig 追踪字段全解析VoicePipelineConfig定义在 src/agents/voice/pipeline_config.py是一个dataclass。与追踪直接相关的字段如下字段默认值作用tracing_disabledFalse是否关闭整个语音流水线的追踪默认开启trace_include_sensitive_dataTrue是否在 trace 中包含敏感数据如语音转写文本。只作用于语音流水线本身不影响 Workflow 内部产生的追踪trace_include_sensitive_audio_dataTrue是否在 trace 中包含音频数据base64 编码的 PCMworkflow_nameVoice Agenttrace 的工作流名称group_id自动随机生成gen_group_id()trace 的分组 ID用于把多条 trace 关联到同一会话trace_metadataNone附加到 trace 上的额外元数据字典各字段的语义在 docs/voice/tracing.md 中均有说明这里结合源码逐一深入tracing_disabled一键关闭整条流水线的追踪默认值为False即默认开启追踪。置为True后TraceCtxManager(disabled...)会收到该值整条流水线包括 STT 与 TTS 阶段都不再产生 trace。适用于隐私要求极高、完全不需要观测数据的场景。需要注意的是它与全局追踪开关是正交的全局层面你仍然可以用OPENAI_AGENTS_DISABLE_TRACING1环境变量或set_tracing_disabled(True)见 src/agents/tracing/init.py来关闭所有追踪也可以只为某一次Runner.run()通过RunConfig.tracing_disabled关闭单个运行。语音流水线的tracing_disabled只作用于这一条流水线实例。trace_include_sensitive_data控制转写文本等敏感内容默认值为True。该字段只针对语音流水线本身STT 转写文本、TTS 输入文本等不会影响 Workflow 内部 Agent 运行的敏感数据开关——后者由RunConfig.trace_include_sensitive_data控制。从源码看这个开关被逐层传递到了 STT 与 TTS 的实现中在 VoicePipeline 的_process_audio_input中self.config.trace_include_sensitive_data被作为参数传给 STT 模型的transcribe()在 OpenAISTTModel.transcribe 中只有该开关为True时prompt、language等模型配置才会写入transcription_span的model_config转写结果response.text才会写入 span 的output在 TTS 一侧StreamedAudioResult._stream_audio 中只有该开关为True时speech_span的input要合成的文本与model_config中的instructions才会被记录。这意味着当trace_include_sensitive_dataFalse时trace 中仍然保留发生了 STT/TTS 调用这一结构信息模型名、耗时、配置骨架但不再记录具体的文本内容。trace_include_sensitive_audio_data控制音频数据默认值为True。这是语音场景最独特的开关它控制 trace 中是否包含 base64 编码的 PCM 音频数据STT 输入音频在 OpenAISTTModel.transcribe 中input.to_base64()仅在开关为True时写入transcription_span的input。对于流式会话OpenAISTTTranscriptionSession见 openai_stt.py 的_end_turn每个轮次的音频缓冲self._turn_audio_buffer只有在trace_include_sensitive_audio_data为True且缓冲非空时才会被编码为 base64 写入 span 的input。而_stream_audio中openai_stt.py也只在开关开启时才把音频缓冲保留下来用于回填 span——源码注释明确指出当音频追踪关闭时继续保留缓冲等于白白持有整整一轮 PCM 数据这体现了该开关同时承担着内存优化的作用。TTS 输出音频在 StreamedAudioResult._stream_audio 中只有开关为True时TTS 合成的音频 chunk 才会被累积到full_audio_data并在结束时通过_audio_to_base64写入speech_span的outputresult.py。同样源码注释说明关闭时保留音频数据毫无意义只会占用内存。关闭该开关后trace 中不会出现任何音频负载但 span 结构output_format等依然保留。workflow_name给 trace 一个可读的名字默认值为Voice Agent。它对应通用追踪体系中的workflow_name——一次端到端工作流的逻辑名称。你可以在 Traces 仪表盘中按名称筛选因此建议将其设置为有业务含义的名字例如客服语音助手或订单查询语音机器人。注意 VoicePipeline 中写的是self.config.workflow_name or Voice Agent即如果你显式传入空字符串会回退到默认名。group_id把多条 trace 串成一段会话默认值由gen_group_id()自动生成每次实例化VoicePipelineConfig都会生成一个新的随机 group ID。group_id的作用是关联多条 trace多轮语音对话中每一轮run()都会产生一条独立的 trace但它们共享同一个group_id在仪表盘中就能作为同一段会话被聚合查看。这与通用追踪体系中的group_id语义一致参见 docs/tracing.md 中 Traces 的属性说明可选的分组 ID用于把同一会话的多条 trace 关联起来例如可以使用聊天线程 ID。在语音场景下一个自然的做法是把用户会话 ID如 WebSocket 连接 ID 或呼叫 ID传进来替代默认的随机值从而实现跨轮次、跨重连的会话级聚合。trace_metadata附加自定义元数据默认值为None可传入任意dict[str, Any]这些键值对会随 trace 一起被记录用于标记版本号、环境、业务标签等信息。tracing 字段更细粒度的导出配置VoicePipelineConfig还包含一个tracing: TracingConfig | None字段默认None。TracingConfig定义在 src/agents/tracing/config.py是一个 TypedDict目前支持api_key用于导出 trace 的 API key可选include_task_and_turn_spansRunner 是否创建 task 和 turn span省略时默认为True。在语音流水线中传入该字段可以复用通用的追踪导出配置。语音流水线自动生成的 Span 层级语音流水线的 trace 不是一条平铺的记录而是由多层 span 构成的层级结构。除了通用追踪中已有的 Agent span、generation span、function span、guardrail span、handoff span 等docs/tracing.md 中有完整列表语音场景还引入了几类专属 spantranscription_spanSTT语音转文字阶段每一次语音转文字调用都会被包裹在一个transcription_span中。对应的数据结构是 TranscriptionSpanData其导出格式为{ type: transcription, input: {data: base64 音频或 , format: pcm}, output: 转写文本, model: STT 模型名, model_config: {...}, }从 OpenAISTTModel.transcribe 可以看到单轮语音输入时 span 的input直接来自input.to_base64()受trace_include_sensitive_audio_data控制model_config中包含temperature、language、prompt后两者受trace_include_sensitive_data控制。发生异常时span 会通过SpanError记录错误信息且错误消息本身也会根据trace_include_sensitive_data决定是否保留原始错误文本。流式会话OpenAISTTTranscriptionSession则每个轮次都会开启一个新的transcription_span_start_turn中创建并start()_end_turn中回填数据并finish()参见 openai_stt.py。speech_spanTTS文字转语音阶段每一段文本的语音合成都被包裹在一个speech_span中。数据结构为 SpeechSpanData导出格式{ type: speech, input: 要合成的文本, output: {data: base64 PCM 音频或 , format: pcm}, model: TTS 模型名, model_config: {voice: ..., instructions: ..., speed: ...}, first_content_at: 首字节到达时间 ISO 时间戳, }从 StreamedAudioResult._stream_audio 的实现可以看到几个有价值的细节model_config记录了voice、speed以及受trace_include_sensitive_data控制的instructionsfirst_content_at在收到第一块音频 chunk 时通过time_iso()记录result.py可用于衡量 TTS 的首字节延迟TTFB每段文本的speech_span会以parentself._tracing_span指定父 span挂到 speech_group span 之下。speech_group_spanTTS 轮次分组SDK 会把一轮回复中相关的多个语音 span 聚合在一个speech_group_span之下对应的数据结构是 SpeechGroupSpanDatatype为speech_group。在 StreamedAudioResult._start_turn 中每轮语音输出开始时都会创建一个speech_group_span并start()在轮次结束时_finish_turn把整轮文本写入input后finish()。这形成了清晰的观测层级Voice Agent (trace) └── transcription_span # 用户语音 → 文本 └── speech_group_span # 一轮回复的语音输出 ├── speech_span # 第一句文本合成 ├── speech_span # 第二句文本合成 └── ...实战如何配置一个生产可用的语音追踪下面给出一个完整的配置示例覆盖最常见的生产需求开启追踪、自定义工作流名称、绑定会话 ID、打业务标签并关闭音频数据的记录保护用户隐私。import asyncio from agents.voice import ( AudioInput, VoicePipeline, VoicePipelineConfig, VoiceWorkflowBase, VoiceStreamEvent, ) # 自定义一个最简语音工作流实际项目中通常是多 Agent 协作 class EchoWorkflow(VoiceWorkflowBase): async def run(self, input_text: str): yield f你刚才说的是{input_text} async def main() - None: config VoicePipelineConfig( workflow_name客服语音助手, group_idsession-20260911-0001, # 用真实会话 ID 关联多轮 trace trace_metadata{ env: production, region: cn-north-1, version: v2.3.0, }, trace_include_sensitive_dataTrue, # 保留转写文本便于调试 trace_include_sensitive_audio_dataFalse, # 不记录音频数据控制成本与隐私 # tracing{api_key: sk-..., include_task_and_turn_spans: True}, # 可选 ) pipeline VoicePipeline( workflowEchoWorkflow(), configconfig, ) # 单轮语音输入需替换为真实音频 result await pipeline.run(AudioInput.from_file(user_audio.wav)) async for event in result.stream(): if event.type voice_stream_event_audio: # 播放音频... pass elif event.type voice_stream_event_lifecycle: print(生命周期事件:, event.event) elif event.type voice_stream_event_error: print(出错:, event.error) asyncio.run(main())要点说明workflow_name设置为业务名仪表盘中一眼可辨group_id传入真实会话 ID多轮对话的所有 trace 可在仪表盘聚合为一条会话时间线trace_metadata打上环境、区域、版本等标签便于线上检索与过滤trace_include_sensitive_audio_dataFalse可以显著减小 trace 体积避免整段 PCM 音频的 base64同时保留文本级信息用于调试若需要为语音流水线的导出单独指定 API key 或关闭 task/turn span可传入tracing{api_key: ..., include_task_and_turn_spans: False}其语义与RunConfig(tracing...)一致参见 docs/tracing.md。敏感数据控制的两个层级不要混淆在语音应用中敏感数据控制存在两个独立维度配置时必须分清楚语音流水线层VoicePipelineConfig.trace_include_sensitive_data/trace_include_sensitive_audio_data控制 STT/TTS 产生的音频与转写内容是否进 trace这是语音场景特有的。Workflow/Agent 层RunConfig.trace_include_sensitive_data控制 Workflow 内部 Agent 运行的 LLM 输入输出、函数调用参数等是否进 trace与普通文本 Agent 相同docs/tracing.md 的 Sensitive data 一节有详细说明。正如 docs/voice/tracing.md 明确强调的trace_include_sensitive_data只针对语音流水线不涉及你 Workflow 内部发生的任何事情。所以如果你的语音流水线里嵌入了处理敏感业务数据的 Agent需要在两层都做好配置缺一不可。另外与全局配置的联动方式还包括环境变量OPENAI_AGENTS_DISABLE_TRACING1可全局禁用追踪环境变量OPENAI_AGENTS_TRACE_INCLUDE_SENSITIVE_DATA可设置敏感数据开关的全局默认值true/1或false/0set_tracing_disabled(True)可在代码中全局禁用。以上均来自 docs/tracing.md可作为语音追踪配置的全局兜底。源码视角追踪开关如何穿透整条语音链路最后把整个数据流串起来看一遍能帮你更透彻地理解这些配置项的作用位置入口VoicePipeline.__init__接收configVoicePipelineConfig或其字典形式经coerce_dataclass_config归一化见 pipeline.pytrace 作用域run()内部单轮_run_single_turn/ 多轮_run_multi_turn用TraceCtxManager开启整体 trace字段来自 configpipeline.pySTT 穿透trace_include_sensitive_data与trace_include_sensitive_audio_data传入OpenAISTTModel.transcribe()/create_session()决定transcription_span中是否写入文本与音频openai_stt.pyTTS 穿透StreamedAudioResult持有_voice_pipeline_config在_stream_audio中据其决定speech_span的input、instructions与音频output是否记录并在每轮用speech_group_span聚合result.py导出span 完成后由全局TraceProvider及默认的BatchTraceProcessor批量导出src/agents/tracing/init.py 中的add_trace_processor/set_trace_processors/flush_traces可扩展或替换导出目标。这套设计意味着追踪是默认全开、按需收敛的。你可以在开发阶段保留全部敏感数据含音频便于深度调试在灰度/生产阶段逐步关闭音频、再按业务需要关闭文本而完全不需要改动业务代码——只需要调整VoicePipelineConfig的这几个字段。小结语音流水线追踪是 openai-agents-python 中开箱即用的观测能力与 Agent 追踪共用同一套 trace/span 体系并通过VoicePipelineConfig提供了语音场景专属的精细控制tracing_disabled管开关、workflow_name管命名、group_id管会话关联、trace_metadata管标签、两个trace_include_sensitive_*字段管敏感数据转写文本与 PCM 音频。理解这些字段在 VoicePipeline、OpenAISTTModel 与 StreamedAudioResult 中的实际作用位置你就能为语音应用搭建一套既保护隐私又足够可观测的生产级追踪方案。【免费下载链接】openai-agents-pythonA lightweight, powerful framework for multi-agent workflows项目地址: https://gitcode.com/GitHub_Trending/op/openai-agents-python创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表