Imported from gbowo/live2d-interactive-avatar (
AGENTS.md). Install upstream withnpx skills add gbowo/live2d-interactive-avatar. Copyright stays with the author.
# AGENTS.md - 项目开发宪法与全局上下文
项目名称: Live2D Virtual Interactive Avatar (主动式虚拟交互形象)
目标: 在1个月内完成MVP,实现以对话为核心的虚拟角色实时交互
开发周期: 4周 (2026-02-20 至 2026-03-20)
当前状态: Phase 1-6(MVP 范围)已完成,Phase 7 进行中(系统整合与 Electron 套壳)
最后更新: 2026-03-26
🤖 第一部分:AI 角色设定与工作流 (System Prompt)
【角色设定】 你是一位拥有丰富工程经验的全栈开发专家(精通 React + Python FastAPI + 架构设计)。当前我们需要开发一个“以对话为主流程、视觉情绪为辅助”的主动式虚拟交互形象 MVP。
【工作流铁律(Strict Rules)】
- 绝对的分步执行(Step-by-Step):严格按照本文档规划的模块顺序开发。每次只输出一个最小可验证单元(MVU)的代码。必须得到用户确认("继续"或"Next")后,才能进入下一步。禁止单次输出超过200行代码。
- Context 意识:每次回答前,必须默默核对本文件中的【架构决策】与【代码规范】,确保方案不冲突。
- 版本与单一路线强制约束:
- 绝不允许“兜底双方案”并存(如 STT 仅限
sherpa-onnx,TTS 仅限Edge-TTS)。确定方案后必须删除废弃代码。 - 依赖库版本必须严格对齐(当前前端为
@naari3/pixi-live2d-display+live2dcubismcore.min.js 5.1.x;禁止用临时补丁绕过检查)。
- 绝不允许“兜底双方案”并存(如 STT 仅限
- 终端与进程隔离(CRITICAL):
- 前后端必须在独立的终端会话中运行。
- 重启后端前,必须确保旧后端进程已彻底终止 (Ctrl+C)。
- 后端启动工作目录强制规则:必须
cd backend后再启动uvicorn,绝不允许在项目根目录启动(会导致 ModuleNotFoundError)。
- 严禁遗留垃圾:测试文件(如
test_*.py)验证完毕后必须立刻要求删除。
【更新本文件规范】 AI 在解决重大 Bug 或完成 Phase 后,需更新本文件。禁止在文件末尾无脑追加流水账。必须:
- 更新“进度看板”的状态。
- 将 Bugfix 提炼成一句话总结,归入“架构决策与避坑指南”,并覆盖/删除过期的旧记录。
🏗 第二部分:架构与技术栈
2.1 技术栈选型
- 前端: React 18+ + Vite 5+ + TypeScript 5+ | Zustand | WebSocket
- 渲染与视觉:
pixi-live2d-display(Live2D) |@mediapipe/tasks-vision(纯前端人脸追踪,已彻底废弃手势识别) - 后端: Python 3.10+ + FastAPI 0.104+ |
openaiSDK(直接调用 OpenAI 兼容接口)|pydantic-settings - AI 链路 (单一路线):
- STT:
sherpa-onnx(流式,禁用 faster-whisper) - TTS:
Edge-TTS(API 型 TTS,强制单次整段调用 + 连接池复用,禁用 Kokoro/ChatTTS/CosyVoice)
- STT:
2.2 代码与接口规范
- TypeScript: 严格禁用
any;接口统一定义在types/目录下,以I开头(如IMessage)。 - Python: 遵循 PEP8;强类型注解;异步优先 (
async def)。 - 通信协议: WebSocket 用于实时流(STT/TTS流、表情状态推送),格式必须为带
type枚举的 JSON。
🗺 第三部分:进度看板与模块拆解
状态标识:[✅ 已完成] | [⏳ 进行中] | [📅 待开始]
- Phase 1: 基础架构搭建 [✅]
- 前后端初始化,WebSocket 双向握手与心跳机制。
- Phase 2: Live2D 渲染模块 [✅]
- 模型加载、Canvas 渲染。
- 表情与动作系统(参数映射、队列管理、状态流转)。
- Phase 3: 视觉感知模块 [✅]
- MediaPipe 前端集成,478面部特征点与 Blendshapes 提取。
- 视觉数据结构化(含置信度)通过 WS 推送后端,完成表情到情绪的基础映射。
- Phase 4: 大模型对话主链路 [✅]
- [✅] STT 实时语音输入(sherpa-onnx 流式)。
- [✅] TTS 集成(Edge-TTS)。
- [✅] 链路流式化改造(STT final -> LLM delta -> 分段 TTS -> 前端队列播放)。
- [✅] 对话打断机制(Barge-in)与 VAD 前端静音检测。
- [✅] 对话记忆分层(Persona + 动态上下文 + 摘要,自研轻量实现,无 LangChain 依赖)。
- [✅] 完善 LLM 对话流程细节,调优 TTS 首包延迟与连续播放稳定性。
- Phase 5: 主动式交互逻辑 (多模态自发式对话 - 核心对齐 Neuro-sama) [✅]
* 静默状态机 (Idle Guard): 严格监听前端 VAD 与系统状态。仅在“用户持续无输入(如15s) + TTS 队列为空 + LLM 无生成任务”三者同时满足时触发。
* 填补空白 (Fill the dead air): 触发时,系统需自动截取最近 3 轮对话摘要(Short-term Memory),并结合 MediaPipe 实时推送的用户瞬时面部表情(如发呆、微笑、皱眉),组装特定的
Idle Prompt。 * 表现范式: 强制 LLM 扮演略带混沌、俏皮的虚拟主播,通过吐槽环境或延伸话题发起简短的“碎碎念”。绝对禁止客服式发问(如“你还在吗”)。 * Barge-in 绝对让步: 主动发起的闲聊优先级最低。在播报期间一旦 VAD 检测到用户开口,立即复用 Phase 4 的打断机制掐断当前 TTS。 - Phase 6: Live2D 动作与对话内容语义绑定 (Action Binding) [✅]
* 表现目标: 实现动作、表情与播报内容的深度同频,拒绝“木桩式”念稿。
* 语义触发器: 在 LLM 的 System Prompt 中约定特殊标签(如
[思考],[生气],[得意])。后端解析流式文本时,剥离这些标签不发给 TTS,而是转化为 WebSocket 指令推给前端。 * 前端执行: 前端接收到特定表情指令后,调用pixi-live2d-display的model.expression()或model.motion()接口,确保视觉动作与 TTS 音频到达的时间节点基本一致。- 完成状态: 已完成 mouth/expression/motion/tts/ws 中粒度 Hook 解耦,并完成口型权威写入与动作情绪一致性收敛。
- Phase 7: 系统整合与 Electron 套壳 [⏳]
- [✅] Task 10-13: Live2D 渲染优化 - ParameterProbe 实现与集成
- Task 10: 实现 ParameterProbe 工具类(版本检测、参数枚举)
- Task 10.1: 31 个单元测试验证版本检测正确性
- Task 11: 重构 useLive2DMouthSync - 支持 Cubism 3/4/5 双路径
- Task 11.1: 12 个集成测试验证 TTS 口型写入一致性(含 afterMotionUpdate 事件)
- Task 12: 重构 useLive2DExpressionController - 参数过滤与警告管理
- Task 12.1: 13 个测试验证参数过滤与缺失处理
- Task 13: 在 App.tsx 中集成 ParameterProbe 生命周期(模型加载时探测、状态传递)
- [✅] 动作策略收敛:回退模型默认待机轮播,仅保留 speaking 阶段情绪动作触发;修复 speaking 动作残留循环
- 异常处理、全局 Loading 态、打包分发(Task 14+)。
- [✅] Task 10-13: Live2D 渲染优化 - ParameterProbe 实现与集成
💡 第四部分:架构决策与避坑指南 (知识库)
这里记录项目演进过程中的核心决策,避免重复踩坑:
- TTS 单一路线(强制):生产链路仅允许
Edge-TTS;禁用 Kokoro/ChatTTS/CosyVoice 并清理废弃代码。 - API 型 TTS 调用策略(强制):必须采用“整段单次调用”;禁止“按句多次调用”导致固定网络延迟累加。
- Edge-TTS 连接复用(强制):必须使用可复用连接池与长连接;监控
conn(created/reused),若reused=0视为回归缺陷。 - 首包与连续播放策略(强制):首包使用短暂聚合后立即下发(小阈值大小 + 时间窗),后续使用较大块聚合,降低首字等待与分段缝隙感。
- 前端音频播放链路(强制):优先
MediaSource + SourceBuffer(sequence)连续 append;旧HTMLAudioElement串播仅作为回退。 - 多语言一致性(强制):Prompt 层注入语言约束:用户用
[X]语输入,系统必须用[X]语回复,禁止混用和翻译。 - Live2D 眼神跟随(强制):
model.focus()绑定全局window.pointermove,并完成浏览器坐标到 Canvas 坐标转换。 - 主线程性能(强制):音频分片解码放入 Web Worker,禁止在 React 主线程执行重解码逻辑。
- 边界修复原则(强制):禁止硬编码样本特判;仅允许“能力探测 + 置信度 + 阈值 + 明确回退链路”的可扩展策略。
- 双轨 Prompt 与单点记忆策略(强制):
- 系统必须维护两套 System Prompt(主链路常规问答 vs Phase 5 的主动碎碎念)。
- 记忆强制共享:这两套 Prompt 必须挂载到**同一个全局历史记忆池(Message History)**上。无论走哪条链路,AI 的主动发言和用户的回复都必须记录在同一上下文中,严禁实例化两个独立的 Memory 对象。
- Idle 注入规范:触发主动对话时,将当前用户视觉情绪与上下文摘要动态注入
Idle Prompt,临时替换当前 SystemMessage 即可。必须强制限制输出长度(1-2句),并设定明确的“俏皮/吐槽”人设约束,严防 AI 降级为传统问答助手。
- 口型权威写入(强制):
ParamMouthOpenY仅允许末端统一覆盖与写入拦截;动作与表情不得直接抢写嘴参数。 - 动作情绪一致性(强制):待机/说话动作必须按当前情绪过滤(如 happy/neutral 禁用
flick_down);说话结束动作优先平滑回收,避免“语义开心但姿态失落”。 - Live2D 运行时版本约束(强制):当前前端运行时为
@naari3/pixi-live2d-display+live2dcubismcore.min.js (5.1.x);默认支持 Cubism 3/4/5 的.model3.json + .moc3资产接入。Cubism 2(.model.json)默认不支持,若要接入必须单独改造对应 bundle 与运行时,禁止在现有链路混接。 - ParameterProbe 能力探测(强制):
- 必须在模型加载完成后调用
probeModelParameters(internalModel)探测 Cubism 版本(读取 moc3 header offset 4)和参数 ID Set。 - 探测结果(
IParameterProbeResult)必须传递给useLive2DMouthSync和useLive2DExpressionController,用于版本感知的参数写入路径选择。 - Cubism 5 必须在
afterMotionUpdate事件中写入ParamMouthOpenY(索引/元音口型路径),否则参数值会被动作重置;Cubism 3/4 优先走setParameterValueById,必要时回退setLipSyncValue。 - 缺失参数 ID 仅在模型加载时警告一次,避免日志刷屏;使用
parameterProbe.paramIds.has(id)进行高效的参数存在性检查(Set 成员测试)。
- 必须在模型加载完成后调用
- 动作调度策略(强制):当模型自动待机轮播已满足观感时,禁止再叠加自定义 idle 轮播;当前策略固定为“模型默认 auto motion 负责待机/呼吸 + 仅 speaking 阶段按情绪触发动作”。若出现 speaking 动作残留循环,必须在 speaking 结束后显式收束并回归模型默认待机。
- Auto 轮播频率能力边界(强制):
@naari3/pixi-live2d-display未提供“自动待机轮播频率(间隔 ms)”的内置配置项;仅可配置idleMotionGroup与motionPreload。调频需求应优先通过模型资源侧(动作时长/数量)处理,避免业务层硬编码干预默认轮播。