news 2026/9/24 13:55:41

TEN Framework 中 StepFun 多模态实时语音 Agent 扩展 stepfun_mllm_python 接入指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
TEN Framework 中 StepFun 多模态实时语音 Agent 扩展 stepfun_mllm_python 接入指南
  • 人工智能
  • AI Agent
  • 多模态
  • 语音
  • AI 应用

【免费下载链接】ten-framework

Open-source framework for conversational voice AI agents

项目地址:https://gitcode.com/TEN-framework/ten-framework
点击查看免费下载

本篇技术指南围绕 TEN Framework 开源仓库中的stepfun_mllm_python扩展展开,讲解如何将 StepFun(阶跃星辰)新一代多模态实时模型(默认step-1o-audio)以 WebSocket Realtime 协议的方式接入语音 Agent 应用,实现"语音进、语音出"(voice-to-voice)与文本处理的端到端能力。读完本文,你将掌握该扩展的完整配置项语义、manifest 属性契约、数据/命令接口、底层消息协议与源码实现路径,并能够参照仓库中的 stepfun-demo 示例搭建可运行的多模态语音助手。

扩展概览:一个与 OpenAI Realtime 协议对齐的多模态语音扩展

stepfun_mllm_python位于 ai_agents/agents/ten_packages/extension/stepfun_mllm_python 目录,是一个标准的 TEN Framework Python 扩展(extension),版本号为0.2.2。从 extension.py 的类定义可以看到,它继承自AsyncMLLMBaseExtension,并在注释中明确说明其设计目标:

StepFun realtime provider, API-compatible with OpenAIRealtime2Extension: same public methods, same server event mapping → send_server_* APIs

这意味着该扩展在 TEN 生态中扮演的是 MLLM(多模态大模型)Provider 的角色,对外暴露与 OpenAI Realtime 扩展一致的公共方法与服务端事件映射,凡是遵循ten_ai_basemllm-interface约定的上游节点(如转写模块、主控逻辑),都可以无差别地对接 StepFun。

核心特性

按照 README.md 的说明,该扩展提供三大特性:

  • StepFun 多模态集成:支持将 StepFun 多模态模型用于语音到语音(voice to voice)以及文本处理;
  • 高度可配置:可通过属性灵活定制 API Key、模型、提示词、temperature 等参数;
  • 异步队列处理:基于 asyncio 的实时消息处理,支持任务取消与优先级调度(配合服务端 VAD 实现打断/优先响应)。

API 契约:manifest 属性定义与默认值

该扩展的 API 定义在 manifest.json 的api.property.properties中,默认值则在 property.json 中给出。下表汇总了两者的完整对应关系:

PropertyType默认值Description
api_keystring${env:STEPFUN_API_KEY}用于向 StepFun 认证的 API Key
temperaturefloat0.9采样温度,值越高随机性越强
modelstringstep-1o-audio模型标识符
max_tokensint2048生成的最大 token 数
system_messagestring(未在 property.json 中设置,见prompt发送给模型的默认系统消息
voicestringlinjiajiejieStepFun 模型说话的语音(如alloyechoshimmer等)
server_vadbooltrue是否启用 StepFun 服务端 VAD
languagestringen模型回复使用的语言(如en-USzh-CN等)
dumpboolfalse是否启用音频 dump 用于调试

需要注意,README 中的属性表描述的是接口语义,而 manifest.json 中的 schema 是 TEN 运行时实际校验与注入的依据,两者存在轻微差异(如system_message在 schema 中以prompt字段出现)。实际生效的完整配置集合,以源码中StepFunRealtimeConfig数据类为准,详见下文"配置解析"一节。

数据接口(Data Out)

扩展向图(graph)下游节点输出的数据消息:

NamePropertyTypeDescription
text_datatextstring输出的文本数据

命令接口(Command Out)

NameDescription
flush刷新当前状态后给出响应

音频帧接口(Audio Frame In / Out)

NameDirectionDescription
pcm_frameIn语音处理的音频帧输入(用户语音)
pcm_frameOut语音处理后的音频帧输出(模型语音)

配置解析:从 property.json 到 StepFunRealtimeConfig

扩展在on_init阶段通过ten_env.get_property_to_json(None)读取全部属性,并用 Pydantic 的model_validate_json校验生成StepFunRealtimeConfig。完整配置字段及其默认值定义在 extension.py:

@dataclass class StepFunRealtimeConfig(BaseModel): base_url: str = "wss://api.stepfun.com" api_key: str = "" path: str = "/v1/realtime" model: str = "step-1o-audio" language: str = "en" prompt: str = "" temperature: float = 0.5 max_tokens: int = 1024 voice: str = "linjiajiejie" server_vad: bool = True audio_out: bool = True sample_rate: int = 24000 # VAD tuning vad_type: Literal["server_vad", "semantic_vad"] = "server_vad" vad_eagerness: Literal["low", "medium", "high", "auto"] = "auto" vad_threshold: float = 0.5 vad_prefix_padding_ms: int = 300 vad_silence_duration_ms: int = 500 dump: bool = False dump_path: str = ""

各字段核心语义:

  • base_url+path:WebSocket 服务地址,默认拼接为wss://api.stepfun.com/v1/realtime,模型名通过查询参数?model=...附加(见 connection.py);
  • sample_rate:输入输出音频采样率,默认 24000 Hz,扩展的input_audio_sample_rate()synthesize_audio_sample_rate()均直接返回该值(extension.py),即整个图链路统一按 24 kHz PCM 处理;
  • vad_type/vad_eagerness/vad_threshold/vad_prefix_padding_ms/vad_silence_duration_ms:VAD 调优参数。服务端 VAD 模式(server_vad)下,阈值、语音前填充(默认 300ms)与静音判定时长(默认 500ms)会被组装进session.update请求(extension.py);
  • audio_out:是否输出音频模态。为falsesession.update会设置modalities = ["text"],实现纯文本对话模式(extension.py);
  • prompt:即 README 中system_message对应的实际实现字段,作为 session 的instructions下发(extension.py);
  • language:通过InputAudioTranscription(language=...)注入输入音频转写的目标语言(extension.py)。

api_key为空,扩展会在on_init阶段直接抛出ValueError("api_key is required")拒绝启动(extension.py),因此部署时必须提供有效的 StepFun API Key。

依赖与运行环境

manifest.json 声明了两个系统依赖:

  • ten_runtime_python(版本0.11):TEN 运行时 Python 绑定;
  • ten_ai_base(版本0.7):提供AsyncMLLMBaseExtension基类与MLLMClientMessageItemMLLMServerFunctionCallMLLMServerInputTranscript等结构化消息类型。

Python 侧依赖见 requirements.txt 与 pyproject.toml:要求 Python >= 3.10,依赖aiohttp>=3.14.1(WebSocket 客户端)、pydantic>=2.13.4(配置校验)与pydub==0.25.1

运行机制:WebSocket Realtime 协议与事件循环

扩展的运行核心是 extension.py 中的start_connection()客户端事件循环,整体链路可概括为:

  1. 建立连接RealtimeApiConnectionaiohttp.ClientSession.ws_connect连接base_url + path + ?model=...,并在请求头携带Authorization: Bearer <api_key>(connection.py);
  2. 会话建立:收到session.created后标记connected=True、缓存session_id,随后发送session.update(注入 prompt、tools、VAD 参数、语音与转写语言),并在session.updated到达后向上游广播mllm_server_session_ready
  3. 用户语音上行send_audio()将收到的AudioFrame二进制按 PCM16 编码为 Base64,封装为input_audio_buffer.append事件发送(connection.py);
  4. 服务端事件分发listen()异步迭代 WebSocket 消息,经parse_server_messagetype字段反序列化为 30 余种 dataclass 事件(struct.py),再交由match message:模式匹配分发处理;
  5. 输出事件上抛
    • 文本流:response.text.delta/response.audio_transcript.delta累积为response_transcript,通过send_server_output_text输出mllm_server_output_transcript(final=False),结束事件则补发 final=True;
    • 音频流:response.audio.delta中的 Base64 数据解码后经send_server_output_audio_data以 PCM 帧形式输出(extension.py);
  6. 打断与 VAD:收到input_audio_buffer.speech_startedserver_vad=true时,发送mllm_server_interrupted中断当前生成,并为未完成的转写追加[interrupted]标记后以 final=True 收尾(extension.py);
  7. 断线重连:事件循环异常退出后调用_handle_reconnect(),以 1 秒退避延时重新start_connection()(extension.py)。

客户端 → 服务端消息类型

struct.py 定义了完整的客户端上行消息集合,均由ClientToServerMessage派生并自动生成event_id(UUID):

  • input_audio_buffer.append/commit/clear:音频缓冲区操作;
  • conversation.item.create:创建用户/助手/函数调用输出消息项;
  • response.create:触发模型生成(含cancel_previous取消上一轮生成);
  • session.update:更新会话参数;
  • conversation.item.truncate/delete:截断或删除对话项。

服务端 → 客户端事件分类

下行事件在 struct.py 中按EventType枚举组织,主要分为:

  • 会话生命周期session.createdsession.updatederror
  • 输入语音转写conversation.item.input_audio_transcription.delta / completed / failed
  • 响应流response.created / doneresponse.text.delta / doneresponse.audio_transcript.delta / doneresponse.audio.delta / done
  • VAD / 轮流input_audio_buffer.speech_started / speech_stoppedinput_audio_buffer.committed / cleared
  • 工具调用response.function_call_arguments.delta / done
  • 其他response.output_item.added / donerate_limits.updated

序列化时to_json会剔除值为None的字段,保证上行报文精简(struct.py)。

工具集成:将外部工具接入 StepFun 多模态模型

该扩展完整实现了 MLLM 工具调用链路,README 中注释掉的 Tool Support 特性在源码中已有落地:

  1. 工具注册:上游节点通过send_client_register_tool()注册LLMToolMetadata,工具被缓存到available_tools并触发session.update(extension.py);
  2. 会话工具清单_update_session()将工具元数据转换为{"type": "function", "name", "description", "parameters"}结构,并根据是否存在工具设置tool_choice"auto""none"(extension.py);
  3. 工具调用回传:收到response.function_call_arguments.done后,通过send_server_function_call向上游广播mllm_server_function_call(含 call_id、函数名与 JSON 参数);
  4. 结果回填:上游执行完成后调用send_client_function_call_output(),将结果封装为conversation.item.createfunction_call_output类型)回传模型(extension.py)。

以仓库中的 stepfun-demo 为例(property.json),weatherapi_tool_python通过tool_register命令向main_control注册天气工具,main_control再将mllm_server_function_call等消息与 v2v(即 stepfun_mllm_python)相连,形成"模型发起工具调用 → 主控路由 → 工具执行 → 结果回填模型"的闭环。

端到端实战:基于 stepfun-demo 的图编排示例

仓库在 ai_agents/agents/examples/stepfun-demo 提供了完整可运行的示例,其 tenapp/property.json 定义了名为voice_assistant_realtime的预置图(predefined graph)。核心节点与连接如下:

  • 音频输入输出agora_rtc(声网 RTC 负责采集/播放),通过pcm_frame音频帧与扩展互通;
  • 流 ID 适配streamid_adapter在 RTC 与扩展之间做流标识转换;
  • 主控main_control消费mllm_server_input_transcriptmllm_server_output_transcriptmllm_server_session_readymllm_server_interruptedmllm_server_function_call等数据消息;
  • MLLM 核心v2v节点即stepfun_mllm_python扩展,配置如下(与扩展默认 property.json 完全一致):
{ "api_key": "${env:STEPFUN_API_KEY}", "temperature": 0.9, "model": "step-1o-audio", "max_tokens": 2048, "voice": "linjiajiejie", "language": "en", "server_vad": true, "history": 10, "enable_storage": false, "base_url": "wss://api.stepfun.com" }

图中的音频帧连接(property.json)形成两条关键通路:

  • 上行agora_rtcstreamid_adapterv2v(用户语音送入 StepFun 模型);
  • 下行v2vagora_rtc(模型合成语音回放给用户)。

配置中使用${env:STEPFUN_API_KEY}形式从环境变量注入密钥,这是 TEN 生态推荐的密钥管理方式——密钥不出现在配置文件中,且支持${env:VAR|default}的默认值语法。

调试建议

  • 开启 verbose 日志RealtimeApiConnectionverbose参数开启后,会在日志中打印双向 WebSocket 消息;smart_str会将delta/audio长字段截断到 128 字符,避免日志被音频数据刷屏(connection.py);
  • 音频 dump:设置dump: truedump_path可将输入输出音频落盘,用于排查采集/回放问题;
  • 观察会话事件:日志中Session createdSession updatedResp createdResp done(含 usage token 统计)等关键节点均打点输出,可作为运行状态的风向标;
  • 转写失败排查conversation.item.input_audio_transcription.failed事件会携带错误详情并以log_warn记录,可据此确认language参数是否与服务端支持的语言一致。

小结

stepfun_mllm_python是一个与 OpenAI Realtime 协议对齐的异步多模态扩展:通过 manifest.json 声明属性契约、property.json 提供默认值、extension.py 承载事件循环与 TEN 消息桥接、realtime/connection.py 与 realtime/struct.py 实现 WebSocket 协议编解码。将其作为图中的一个v2v节点,配合音频帧通路与mllm_server_*数据消息,即可快速构建基于 StepFun 多模态模型的实时语音 Agent,并复用 TEN 生态中现成的 RTC、工具与主控组件。

  • 人工智能
  • AI Agent
  • 多模态
  • 语音
  • AI 应用

【免费下载链接】ten-framework

Open-source framework for conversational voice AI agents

项目地址:https://gitcode.com/TEN-framework/ten-framework
点击查看免费下载
上一篇:如何用OpenCore Legacy Patcher让老Mac焕发新生:终极兼容性优化指南
下一篇:OpenFGA SDK全攻略:Java、Node.js、Go、Python、.NET五语言快速上手指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 13:55:18

树莓派DIY智能灌溉控制器:MQTT+继电器HAT+土壤湿度传感器实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/24 13:53:23

arrylist怎么让他变得不可修改

在Java中&#xff0c;要将一个 ArrayList变得不可修改&#xff0c;你可以使用以下几种方法&#xff1a;###1. 使用 Collections.unmodifiableListJava 提供了 Collections.unmodifiableList 方法&#xff0c;可以生成一个不可修改的视图。这种方式返回的列表将不允许添加、删除…

作者头像 李华
网站建设 2026/9/24 13:53:14

【Dv2Admin】Django配置线上ws反向代理

在 Web 应用程序的部署过程中,安全性、稳定性和实时通信是开发者们普遍关注的重点。Django 是一个非常流行的 Web 框架,常与 Nginx 配合使用,以便实现反向代理、负载均衡以及 SSL 加密等功能。除此之外,实时功能(如 WebSocket)也是现代应用中经常使用的技术。 在项目中实…

作者头像 李华
网站建设 2026/9/24 13:52:32

gsd-core 中 bracket 阶段 ID 约定的统一显示与配置校验解析

【免费下载链接】gsd-core Git. Ship. Done - Core 项目地址&#xff1a; https://gitcode.com/gh_mirrors/ge/gsd-core 点击查看 免费下载 本文围绕 gsd-core 的 ADR-612「bracket 阶段 ID 约定」显示面落地&#xff08;issue #3638 / PR 4111&#xff09;展开&#xff1a;当…

作者头像 李华
网站建设 2026/9/24 13:47:54

【Coze】【视频】踏马爽文工作流

今天给大家演示一个 踏马爽文视频 Coze 工作流。该工作流结合了大语言模型、批处理、语音合成和剪映小助手等功能节点,能够从输入的爽文主题出发,自动生成符合爽文文风的文案,再将文案转化为音频、字幕并组合到视频草稿中,最终实现一键生成爽文短视频的效果。通过这个工作流…

作者头像 李华