自己从头搭一套实时语音 AI 的开发体验通常是这样的:找个 STT 服务,找个 LLM,找个 TTS,然后花大量时间处理它们之间的数据格式、延迟对齐、打断逻辑,每换一个模型提供商就得重新适配一遍。
TEN Framework 能帮你快速解决这个问题。它是声网开源的实时多模态对话 AI 框架,核心思路是把语音 AI 的各个环节抽象成可插拔的 Extension,开发者通过 Graph(有向图)定义它们之间的数据流,不同的 Extension 可以并发运行(项目地址:github.com/TEN-framework/ten-framework,6月25日有更新)。

一. 核心概念:Extension + Graph
TEN 的基本单元是 Extension。每个 Extension 是一个自包含的模块,负责处理某个具体能力:STT、LLM、TTS、VAD、Turn Detection,或者你自己写的任何逻辑。
Extension 之间通过消息传递通信,不直接调用彼此。把多个 Extension 连起来,就构成一个 Graph。
Graph 描述数据怎么从麦克风流入,经过哪些处理节点,最终变成音频输出。TEN 的运行时会按照 Graph 定义并发调度这些 Extension,而不是串行等待。
这个设计的好处是你想换掉其中某个 Extension(比如把 OpenAI 换成 DeepSeek),只需要改 Graph 配置,其他部分不受影响。
二. 内置的语音 AI 核心模块
TEN VAD
专为企业级实时对话设计的语音活动检测模块。它做帧级别的语音判断,计算量比 Silero VAD 低,内存占用更小,关键是延迟更短。
VAD 的响应速度直接影响整个对话系统的感知延迟,这里省下来的时间是实实在在的。
TEN Turn Detection
这是 TEN 里比较有意思的部分。传统的 turn detection 靠静音时长判断”用户说完了没有”,容易在用户停顿、思考时误触发。
TEN 的 Turn Detection 底层跑了一个 Qwen2.5-7B,做语义层面的分析,判断说话人是不是真的表达完整了,而不是单纯看停顿。目前支持中英文,可以直接作为 Extension 插进去用。
这两个模块都可以单独使用,也可以作为 TEN Framework 里的 Extension 集成,接口是统一的。
三. 支持的传输协议和集成
TEN 的传输层支持三种协议:RTC、WebSocket、SIP,内置自动降级和拥塞控制。实际上手时,最常见的配置是用声网 RTC 作为音视频传输层。在 .env 里配上 AGORA_APP_ID 和 AGORA_APP_CERTIFICATE,就能把实时音频流接进来。
模型侧已有的集成包括:
- LLM:OpenAI、DeepSeek、Gemini Live、Claude(通过扩展)
- STT:Deepgram(默认)、Azure Speech、Whisper
- TTS:ElevenLabs、Azure TTS、OpenAI TTS
- 协议:原生支持 MCP 服务器,可以把外部工具直接接给 Agent 用
支持的编程语言:C/C++、Go、Python、JavaScript、TypeScript,六种都能写 Extension。实际上大部分开发者用 Python,因为生态最丰富,调试也方便。Go 和 C++ 适合对延迟有极致要求的场景。
四. 快速跑起来
4.1 开始之前:需要准备哪些东西
API Keys
默认配置依赖四个外部服务,每个都需要提前拿到 Key:
- Agora App ID + App Certificate:负责音视频传输。在 Agora 控制台创建项目就能拿到,每月有免费额度,个人测试够用。
- Deepgram API Key:默认 STT 服务,负责把你说的话转成文字。注册后有免费额度。
- ElevenLabs API Key:默认 TTS 服务,负责把 LLM 的回复转成语音。免费账号每月 1 万字符。
- OpenAI API Key:默认 LLM,负责理解你说的话并生成回复。
本地环境
- Docker + Docker Compose
- Node.js LTS v18
- CPU ≥ 2 核,内存 ≥ 4 GB
用 Apple Silicon Mac 的需要注意一点:打开 Docker Desktop 设置,把 “Use Rosetta for x86/amd64 emulation” 这个选项取消勾选。勾上之后本地构建会出问题。取消之后在 ARM 上构建会稍慢,但实际部署到 x64 服务器时性能正常。
4.2 把环境跑起来
第 1 步:克隆仓库
git clone https://github.com/TEN-framework/TEN-Agent.git
cd TEN-Agent
第 2 步:创建配置文件
cp ./.env.example ./.env
第 3 步:填入 API Keys
用编辑器打开 .env,把刚才准备好的 Key 填进去:
# Agora - 音频传输
AGORA_APP_ID=
AGORA_APP_CERTIFICATE=
# Deepgram - 语音识别(STT)
DEEPGRAM_API_KEY=
# ElevenLabs - 语音合成(TTS)
ELEVENLABS_TTS_KEY=
OpenAI Key 后面在 Playground 界面里填也行,不一定要写进 .env。
第 4 步:启动容器
docker compose up -d
这一步会拉取镜像并在后台启动 ten_agent_dev 容器,第一次跑时间会长一些,取决于网速。
第 5 步:进入容器
docker exec -it ten_agent_dev bash
后续的构建命令都在容器内执行。
第 6 步:构建 Agent
task use
这一步加载 Graph 配置、编译所需的 Extension,把整个 Agent 构建出来。如果你后面改了 Extension 的源码,需要重新跑这步。
第 7 步:启动 Web 服务器
task run
启动后台的 Golang Web 服务器,负责接收前端请求、启动/停止 Agent 进程,并把 graph_name 等参数传给 Agent App。
第 8 步:打开 Playground
浏览器访问 localhost:3000,就能看到 Playground 界面了。
4.3 Playground 里能做什么
Playground 是配置和测试 Agent 的界面,不需要改代码。进去之后主要做三件事:
- 选 Graph 类型:比如”语音 Agent”或”实时对话 Agent”,决定整体的数据流结构
- 选模块:每种 Graph 类型下有对应的模块配置
- 配置 Extension 的 API Key:如果没在
.env里预填,可以在这里逐个 Extension 填入
配置完点开始,就能直接在浏览器里跟 Agent 说话了。这套界面同时也是 TMAN Designer 的入口——想可视化地调整 Graph 连线,访问 localhost:49483。
4.4 数据从麦克风到声音,经过了哪几步
整个系统由三个主要组件构成:
- TEN Agent App:核心进程,负责加载 Graph、协调各 Extension 之间的数据流
- Web 服务器(Golang):处理前端的 HTTP 请求,负责启动和停止 Agent 进程
- 前端 UI:Playground 界面,用于配置和实时对话
一次完整的语音交互是这样走的:
麦克风采集音频
↓
Agora RTC 传输(UDP,避免 TCP 的队头阻塞)
↓
Deepgram STT(语音 → 文字)
↓
OpenAI LLM(理解 + 生成回复)
↓
ElevenLabs TTS(文字 → 语音)
↓
Agora RTC 回传
↓
你听到 Agent 的回复
每个环节都是独立的 Extension,通过 TEN Framework 的消息系统串起来。
最快的路径是从 TEN Agent 的 Demo 开始。它已经预装了一套基础 Graph(VAD → STT → LLM → TTS),可以直接接 Agora RTC 的音频流。
git clone https://github.com/TEN-framework/TEN-Agent
cd TEN-Agent
cp .env.example .env
.env 里需要填的核心字段:
AGORA_APP_ID=你的AppID
AGORA_APP_CERTIFICATE=你的Certificate
OPENAI_API_KEY=sk-...
DEEPGRAM_API_KEY=... # 默认STT
ELEVENLABS_API_KEY=... # 默认TTS
然后:
docker compose up
跑起来之后,浏览器打开 Demo 页面,就能跟 Agent 说话了。整个流程在环境干净的机器上大概20分钟能跑通。
4.5 想换掉某个模块怎么做
TEN Agent 里每个服务层都可以替换。常见的替换选项:
- STT:Deepgram(默认)、Azure Speech、Whisper、AssemblyAI
- TTS:ElevenLabs(默认)、Azure TTS、OpenAI TTS、Cartesia
- LLM:OpenAI(默认)、DeepSeek、Gemini Live、Claude
替换的方式有两种:
- 一是直接在 Playground 界面里切换——选不同的模块时,会自动切换对应的 Extension 组合,填入新的 Key 就行。
- 二是手动改 Graph 配置文件(
property.json)——把对应 Extension 的name改成目标服务的 Extension 名,填入凭证,重新跑task use生效。改完一个 Extension,其他部分不受影响。
五. 和其他框架比有什么不同
横向比较一下几个常见框架:
- TEN:最大的差异化是原生多模态并发和 RTC/SIP 双栈支持。如果你的场景需要同时处理音频+视频流,或者需要对接电话系统(SIP),TEN 的架构更合适。另外 TEN Turn Detection 的语义级打断检测,在 Pipecat 和 LiveKit 里需要自己实现。
- Pipecat:流水线模型,各处理节点串行,调试工具链(Whisker、Tail)很成熟,60+ 服务集成开箱即用。适合快速搭出生产可用的方案,灵活性高。
- LiveKit Agents:深度绑定 LiveKit 的 WebRTC 基础设施,如果你已经在用 LiveKit,接入体验很顺滑。
三个框架解决的核心问题有重叠,但在多模态并发和电话接入上 TEN 目前的完成度更高。
六. 适合用 TEN 的场景
- 需要同时处理音频和视频的 Agent(比如视觉+语音的实时助手)
- 需要对接传统电话系统(SIP 协议)的企业客服场景
- 想用中文语义做更准确打断检测的项目
- 已经在用声网 RTC,想在上面搭对话 AI 能力
七. TEN 里的打断检测:比静音判断更准一件事
把 Agent 跑起来之后,你可能会注意到它对”用户是否说完”的判断比一般语音助手更准,中间停顿时不会急着打断你,说到一半改口也能识别出来这是同一句话。
这背后用的是 TEN Turn Detection,逻辑上和普通的 VAD(Voice Activity Detection)不是一回事。VAD 靠检测音频信号判断”有没有声音”,Turn Detection 用一个微调过的 LLM 做语义判断,把每段转录文字分成三种状态:finished(说完了,可以回复)、unfinished(说到一半,继续听)、wait(不确定,短暂等待)。
Turn Detection 的架构、三种状态的判断逻辑、延迟数据,以及什么时候应该用 VAD 而不是 Turn Detection,将放在下一篇里展开。
