~/reviews · Open-LLM-VTuber · 2026-06-05

cat README.md

Open-LLM-VTuber

一个让你可以免提语音跟任何大模型聊天、随时打断它、还能看着 Live2D 角色对你做表情的开源 AI 伴侣。全链路离线可跑,不挑平台。

Python Live2D ASR+TTS MIT 9.6k Stars v2.0 WIP

// 目录

▶ 概览 ▶ 这是什么 ▶ 架构拆解 ▶ 打断机制 ▶ 装饰器链 ▶ 竞品对比 ▶ 能力雷达 ▶ 我的看法 ▶ 部署指南 ▶ 参考链接

// 概览

★ Stars
9,587
今日 +581,近万星开源 AI VTuber 项目,GitHub AI 伴侣赛道头部
⑂ Forks / Issues
1.2k / 89
社区活跃,38 个 PR 待合并,v2.0 重写规划中暂不接受新功能
⇧ Commits
913
19 个 Release,最新 v1.0.0 (2026-02),高频迭代但版本号跳跃大
⏰ Releases
v1.2.1
2025-08-26 发布,v1.0.0 有 Breaking Changes,v2.0 重写中
⚙ Language
Python 96.6%
FastAPI + asyncio 全异步架构,前端 TypeScript(独立子模块)
📜 License
MIT
后端 MIT 开源可商用,Live2D 示例模型需单独授权,前端 v1.2.0 起独立协议

每天跑 GitHub 日报,看的 AI Agent 项目少说也有几十个了。但今天这个,怎么说呢——它是那种"一看 README 就知道作者是认真搞过工程"的项目。

Open-LLM-VTuber,说白了就是一个"能跟你语音聊天、能被打断、还有个 Live2D 虚拟形象的 AI 伴侣"。但你千万别被"伴侣"这俩字带偏了——它的工程含金量,比很多正儿八经的 "AI Agent 框架" 高出一个量级。

项目的初始动机特别简单:有个叫 Neuro-sama 的闭源 AI VTuber 在海外火得不行,但它锁死在 Windows 上。作者(Yi-Ting Chiu、Ethan Lee 和 t41372 等人)想的是——用开源方案在 Mac/Linux 上复刻一套,结果越做越深,从"能对话"一路做到"你能在 AI 说话的中途直接打断它,它还能无缝接上"。这就不是玩具了。

核心能力一句话

把你的麦克风插上,选一个 Live2D 角色,接一个 LLM(可以是本地 Ollama,也可以是云端 Claude),然后跟它聊天。AI 会通过 Live2D 表情和 TTS 语音回应你。你说着说着突然插嘴,它能立刻停下——不会机械地说完上一句,而是像真人对话一样被打断后重新组织回应。

这听起来好像没什么,但做过实时语音管线的都懂:"能在 AI 说话时被打断"这一条,就够你喝一壶的。

技术底子

跟那些"装个 LangChain 然后调 API"的项目不一样,Open-LLM-VTuber 的代码里有一套非常扎实的实时管线设计:VAD 状态机做端点检测、asyncio.Task 做打断链、装饰器链做输出流转换、WebSocket 做前后端通信。这些东西加一起,是一个真正的 全双工实时语音 Agent 参考实现

支持的后端更是管饱:LLM 能接 Ollama / OpenAI / Claude / Gemini / DeepSeek / 智谱 / vLLM / LM Studio 等;ASR 有 sherpa-onnx / FunASR / Whisper 全系列;TTS 有 CosyVoice / GPTSoVITS / MeloTTS / Bark / Edge TTS 等 19 种实现。你想完全离线跑,整套 Ollama + sherpa-onnx + CosyVoice 就搞定。


// 架构拆解:五段管线 + 打断通道

先说整体架构。把这个项目的核心数据流画出来,是五段串行管线加一条"竖向红线"打断链路:

🎙
Mic + VADSilero VAD
三态状态机
🗣
ASR 识别sherpa-onnx
Whisper 系列
🧠
LLM 推理流式 AsyncIterator
装饰器链转换
🔊
TTS 合成19 种引擎
TTSTaskManager
🎭
Live2D 渲染表情映射
唇形同步
↑ 打断信号:VAD 检测到用户开口 → asyncio.Task.cancel() → 整条管线立即终止,开始新会话

打断机制的工程含金量

这条"竖向红线"才是这个项目最值钱的部分。我们拆开看:

第一步:VAD 端点检测。用的是 Silero VAD,参数调得非常激进——语音概率阈值 0.4、连续 3 帧(约 96ms)才确认"用户开始说话"、连续 24 帧(约 768ms)才确认"用户说完了"。这个设计让系统既能快速响应插嘴,又不会被短暂停顿误判。

还有一个很实用的细节:db_threshold=60required_misses=24 两个参数,保证 AI 自己 TTS 的声音从扬声器回灌麦克风时不会被误判成"用户在说话"。这就是 README 里说的"免提语音打断不需要耳机"——不是魔法,是工程参数调出来的。

# VAD 状态机 — 三态转换 class State(Enum): IDLE = 1 # 等待说话 ACTIVE = 2 # 正在说话 INACTIVE = 3 # 已停口 # IDLE → ACTIVE:连续 3 帧语音 (96ms) # ACTIVE → INACTIVE:连续 24 帧静默 (768ms) # INACTIVE + 新语音 → 触发 interrupt

第二步:asyncio.Task.cancel() 取消链。这是全双工管线的核心。代码只有一行:

self.current_conversation_tasks[client_uid].cancel()

但这行代码背后藏着三个关键设计:

(1) 每个 WebSocket 连接有独立的任务注册表,用 client_uid 做 key——单聊群聊完全对称处理。

(2) 取消会沿着 await 边界自动冒泡——正在等 LLM token 的子协程、正在合成 TTS 的子协程、正在排队播放的音频,全部同时停掉。

(3) 取消后不是简单丢弃上下文,而是把 LLM 已通过装饰器链处理的部分(heard_response)存进对话历史,写一条 [Interrupted by user] 记录。这样下一个会话的上下文是连续的——AI 知道自己被打了什么岔

做过实时语音管线的同学应该能看出来:要做到"安全取消 + 上下文连续 + TTS 截断无缝衔接"这三件事同时成立,需要非常细致的任务生命周期管理。这也是为什么很多大厂的全双工语音方案还在"按住说话"——不是模型不行,是管线没做对。


// 装饰器链:最 Pythonic 的设计

如果说打断机制是"硬工程",那装饰器链就是项目里最有审美的地方。

LLM 输出的原始 token 流,要变成能驱动 TTS 的文本 + 能驱动 Live2D 的表情指令,这中间需要四步转换。作者没有写一个巨大的 Pipeline 类,而是用 Python 装饰器优雅地叠了四层:

@actions_extractor(live2d_model) # (4) 抽出 [joy] [sadness] 情绪标签 @display_processor() # (3) 解析 display_text → 内心独白 @tts_filter(tts_preprocessor_config) # (2) 过滤 TTS 不能念的字符 @sentence_divider(faster_first_response=True) # (1) 切成完整句子 async def chat(memory, user_input): ... return llm_stream # 纯流式 LLM 调用

装饰器从下往上执行:先把 token 切成完整句子(pysbd 分句 + 首句优先模式),然后过滤掉 TTS 读不出的符号,再解析内心独白文本,最后提取情绪标签映射到 Live2D 表情。

有意思的是表情驱动的设计思路——不是在代码里硬编码关键词匹配("如果 LLM 输出包含'哈哈'就切到 joy 表情"),而是把表情标签列表注入 System Prompt,让 LLM 自己输出 [joy] [sadness] [surprise] 等标签。然后 actions_extractor 正则提取,后端映射到 Live2D 表情参数,WebSocket 推给前端渲染。换模型、换角色人设,都不影响表情系统。 这个设计非常干净。

整个 Agent 模块也是接口化的——AgentInterface(ABC) 定义三个方法(chat / handle_interrupt / close),目前有 BasicMemoryAgent(默认滚动窗口记忆)、LettaAgent(长期记忆)、Mem0LLM、HumeAI 四种实现。项目不绑死任何一个 Agent 框架,你爱用哪个用哪个。


// 竞品对比

AI VTuber / AI 伴侣这个赛道看起来热闹,但真能做到"全双工语音 + Live2D + 打断 + 完全离线"的,一只手数得过来。

项目 Stars 定位 核心差异化 短板
Open-LLM-VTuber 9.6k 语音 AI 伴侣 + Live2D 全双工打断、装饰器链、3层后端可插拔、完全离线 v2.0 重构期不稳定、Live2D 商用需额外授权
Amica 1.5k 3D VRM 虚拟角色 3D 模型代替 Live2D、Tauri 桌面端、情绪引擎 Stars 差距大(社区小)、VRM 生态不如 Live2D
LLM-Live2D-Desktop 181 Open-LLM-VTuber Fork 桌面宠物模式、屏幕感知、语音唤醒、唱歌功能 Fork 模式、即将合并回上游、社区极小
Neuro-sama N/A 闭源 AI VTuber 产品成熟度最高、直播级稳定性 闭源、仅 Windows、不开源无法定制
VTube Studio N/A Live2D 面部追踪 行业标准、iPhone ARKit 追踪精度极高 无 AI 能力、仅面部追踪、需额外 AI 管线

核心判断:Open-LLM-VTuber 是目前唯一把"实时语音打断"做成工程一等公民的开源项目。 Amica 走 3D 路线但社区体量差了一个数量级,LLM-Live2D-Desktop 方向不错但本质是 Fork 即将合并回上游。至于 Neuro-sama——它是这个赛道的精神原点,但闭源这件事就注定了它只能是一个"看别人做"的东西。


// 能力雷达

没有公开的量化 Benchmark 数据(ASR 字错率、TTS MOS 分、端到端延迟都没有),下面是我根据代码和架构做的定性评估:

实时打断
9.5 / 10
后端可插拔
9.2 / 10
离线完整性
9.0 / 10
架构整洁度
8.8 / 10
跨平台覆盖
8.5 / 10
社区生态
7.5 / 10
文档质量
7.0 / 10
流式延迟
7.2 / 10

TTS 目前多数还不是流式的——需要等整句话合成完才发给前端,这是最大的延迟瓶颈(v1.3 计划上流式 TTS)。打断响应在"亚秒级",但整条管线的延迟受 LLM 推理速度影响最大——用云端 API 会快很多,纯本地取决于你 GPU 够不够。


// 我的看法

verdict
8.6
综合评分
实时语音 Agent 赛道的工程参考实现
✔ 全双工打断是真正的工程资产——不是"调 API 能对话"的玩具,而是一套完整的 VAD 状态机 + asyncio.Task 取消链 + 上下文连续恢复。所有做实时语音 Agent 的人都应该读一遍它的 Conversation Handler 代码。
✔ 后端可插拔设计极度克制又实用——三层工厂模式(LLM/ASR/TTS),19 种 TTS 实现、10+ 种 ASR、8+ 种 LLM,但接口干净不臃肿。想纯离线跑一套完整方案,配 Ollama + sherpa-onnx + CosyVoice 就能搞定。
✔ 装饰器链是最 Pythonic 的设计——四层装饰器把原始 token 流逐步转换成 (文本, 表情, 动作) 结构化输出,每一层职责单一、可独立替换。这个设计模式值得抄到任何"流式 LLM 输出需要后端处理"的场景里。
✔ 跨平台真正做到了 macOS/Linux/Windows 全覆盖——不是"理论支持"那种,而是 Web 版 + Electron 桌面端 + 桌面宠物模式三道菜一起上。
✘ v2.0 重构期的不确定性——项目目前处于"v1.x 只修 bug 不接受新功能 + v2.0 早期规划"的状态。这对想贡献代码的人是个障碍——你不知道自己的 PR 会不会被 v2.0 直接废弃。
✘ TTS 非流式是性能硬伤——首句延迟 = LLM 首 token + 整句 TTS 合成,这个延迟在本地推理时很可观。v1.3 承诺的流式 TTS 还没出来。
✘ 没有量化 Benchmark——ASR 字错率、TTS MOS 分、端到端延迟、打断响应时间,一个公开数据都没有。这在严肃工程评估里是减分项。
✘ Live2D 商用授权是隐藏成本——项目本身 MIT,但 Live2D 示例模型用的是 Free Material License,中大型企业商业使用需要额外授权。而且 v1.2.0 起前端仓库也改成了独立协议(Open-LLM-VTuber License 1.0),不再 MIT。
✘ 89 Issues / 38 PRs 积压——对 9.6k 星的项目来说不算严重,但考虑到 v2.0 开发期的"准冻结"状态,这些 PR 和 Issue 的响应速度会进一步放缓。

// 十分钟跑起来

部署其实不复杂,四条命令的事:

# 1. 克隆(带 frontend 子模块) git clone --recurse-submodules https://github.com/Open-LLM-VTuber/Open-LLM-VTuber.git cd Open-LLM-VTuber # 2. 安装 uv(项目推荐) # macOS: brew install uv # Windows: pip install uv # 3. 同步依赖 uv sync # 4. 启动服务器 uv run run_server.py

然后浏览器打开 http://localhost:8000,首次启动从 config_templates/ 复制 conf.yaml 并按需配置 LLM/ASR/TTS 后端。

几个踩坑提醒:

(1) 如果要从另一台设备访问,需要配置 HTTPS 反向代理——浏览器麦克风 API 只在 localhost 或 HTTPS 下可用。

(2) 推荐纯本地方案:LLM 用 Ollama + Qwen2.5,ASR 用 sherpa-onnx + SenseVoiceSmall,TTS 用 CosyVoice。这三件套可以做到完全断网运行。

(3) 桌面宠物模式需要额外下载 Electron 桌面端(在 Release 页面找 open-llm-vtuber-electron 开头的文件)。宠物模式支持透明背景、全局置顶、鼠标穿透——可以拖到屏幕任意位置。


GitHub 仓库

官方文档 · 快速开始

版本发布博客

GitHub Pages 文档

Discord 社区

技术深度解析 · txtmix

DeepWiki · 架构文档