这次不聊 ComfyUI也不聊普通的“换个皮套”展示页。我们把一个 Live2D 陪伴型 AI 角色拆开看Live2D 模型负责形象和表情大模型负责对话和记忆TTS 负责语音回复最后全部串在一个网页里。标题里的“陪伴型 AI 兔兔”本质上就是这么一套东西并不玄乎。如果你最近也在搜 Live2D、Live2D Cubism 安装包、Live2D 免费模型、AI 大模型这类关键词说明你可能已经不只是想看看模型长什么样而是想自己搭一个能对话、能开口说话的虚拟角色。这篇文章会从模型资源准备、Web 渲染、AI 对话接入、TTS 语音合成、前后端联调一直写到性能观察和排错整个链路走一遍。先给结论Live2D 展示本身对显卡几乎没要求核显就能跑真正吃硬件的是本地大模型和本地语音合成如果你用云端 API门槛会低很多。需要提前说明的是Live2D 被一些灰色工具拿来搞“一键脱装”之类的低俗玩法这种方向涉及版权侵权和平台违规本文完全不碰也不建议你去碰。下面的内容全部围绕合法的模型展示、AI 陪伴和内容创作展开。1. 核心能力速览围绕“Live2D 陪伴型 AI 兔兔”这个展示项目完整技术方案通常包含下面这些模块能力项说明角色形式Live2D 兔兔虚拟角色以 Web 页面方式展示Live2D 渲染Cubism 模型 Web 端渲染常用 pixi-live2d-display、OhMyLive2D表情与动作通过模型参数控制表情、口型、头部跟随、点击交互AI 对话调用大模型 API或使用 Ollama 本地部署开源模型语音合成云端 TTS 快速验证或本地 GPT-SoVITS / CosyVoice 保留音色硬件门槛Live2D 渲染不挑显卡本地 LLM / 本地 TTS 才需要大显存启动方式静态页面、Node 服务、Python FastAPI 服务均可接口能力可以拆成 /chat 对话接口和 /tts 语音接口批量任务多角色人设回复、多音色 TTS 批量生成都可以脚本化适合场景个人陪伴型角色、直播互动、桌面助手、视频内容展示这张表是围绕该需求给出一套可落地方案。具体到某个开源项目时哪些功能已经实现、哪些需要自己补要以项目 README 和实际环境测试为准。2. 这类项目到底在做什么很多人第一次看到 Live2D 模型展示会以为只是一个动画图片。实际上一个完整的“陪伴型 AI 兔兔”包含四个层第一层是模型资源层。你需要一个 Live2D 模型文件通常由 Live2D Cubism 编辑器制作导出里面包含 moc3 动作文件、textures 贴图、model3.json 配置、physics3 物理效果、expressions 表情配置。标题里那只兔兔的原型就是这一层的产物。没有原模型也没关系可以找官方或作者授权的免费模型也可以在 Cubism 里从零开始捏。第二层是渲染层。模型文件要在网页或应用里动起来需要解析器。Web 端最常用的是 pixi-live2d-display 和 OhMyLive2D它们可以把 model3.json 加载到 Canvas 里自动播放 idle 动画响应鼠标点击和拖拽还要监听表情参数。渲染层是后续所有交互的基础但性能开销并不大。第三层是 AI 对话层。虚拟角色需要有“大脑”一般通过大模型接口实现。简单做法是调云端 OpenAI 兼容接口把角色人设写成 system prompt比如“你是一只陪伴型兔兔语气温柔称呼用户为主人”然后接收用户输入并返回回复。如果不想依赖外部服务可以在本机用 Ollama 跑 Qwen、Llama 这类开源模型再通过 /v1/chat/completions 标准接口接入。第四层是语音层。文字回复不够有陪伴感所以还要把回复文本转成语音。最简单的验证方案是用 Edge-TTS 生成 mp3优点是免费、中文音色好、接入快如果要特定音色并且能离线运行再考虑 GPT-SoVITS 或 CosyVoice 这类本地 TTS 项目。把四层串起来的胶水代码不多前端负责显示 Live2D 和播放音频后端负责对接大模型和 TTS模型负责“皮”大模型负责“脑”TTS 负责“嘴”。这篇文章后面的内容就是一层层教你怎么把这些模块拼起来。3. 适用场景与使用边界这种 Live2D AI 的组合适合几类人第一类是个人开发者想快速做一个网页版 AI 陪伴角色验证模型展示、对话交互、语音播放这套流程。第二类是内容创作者需要生成虚拟角色视频素材或者做直播互动形象。第三类是产品经理或独立开发者想评估 Live2D 在虚拟陪伴、数字人、客服角色等产品里的表现。第四类是纯玩家手里有一个喜欢的模型想搭个网页放在桌面侧边栏。不适合的场景也要说清楚。不要把它当作情感替代工具去长期依赖AIGC 内容需要有明确边界。涉及真人肖像、真人声音克隆时必须获得授权否则很容易侵权。使用的 Live2D 模型也要确认授权范围免费模型通常不能商用商用模型要保留授权文件。合规方面提三点第一API Key 不要写进前端代码否则会被别人抓走刷额度第二如果服务部署到公网要加访问控制和请求频率限制第三不要做低俗、擦边、涉黄方向的角色设定也不要把模型用于绕过平台规则的内容生产。4. Live2D 模型准备与展示资源4.1 模型文件结构一个标准 Live2D 模型在 Cubism 中导出后通常是这样的目录结构rabbit/ ├── rabbit.model3.json ├── rabbit.moc3 ├── physics3.json ├── exp/ │ ├── angry.exp3.json │ └── happy.exp3.json ├── motions/ │ ├── idle.motion3.json │ └── tap_body.motion3.json └── textures/ └── texture_00.pngmodel3.json 是整个模型的入口Web 渲染库通过它找到 moc3、贴图和动作文件。moc3 是模型几何数据textures 是贴图physics3 控制头发、耳朵、尾巴等部位的物理摆动exp3.json 定义表情切换motion3.json 定义待机动画和点击反馈动画。所以准备工作第一步是确认模型目录完整尤其不能缺 model3.json 和贴图。很多 Live2D 模型加载失败不是代码问题而是目录里少了 textures。4.2 怎么获取可用模型标题里的兔兔模型如果是你自己在 Cubism 里做的直接导出即可。如果是从网上下载优先找这些来源Live2D 官网的官方示例模型和免费模型。pixiv 等平台上作者公开配布的免费模型使用时留意是否要求标注来源。购买了商业授权的模型包。搜索“Live2D 免费模型”时要注意有些资源站会把模型和贴图拆开或者提供的是旧版 .model.json 而不是 .model3.json。Web 渲染常用的是 Cubism 3 及以上格式也就是 .model3.json。下载后先检查文件格式避免花时间调试才发现模型版本不对。4.3 兔兔角色的人设与表情参数“陪伴型 AI 兔兔”要让人觉得“活着”光有待机动画不够还需要表情和对话反馈。Cubism 编辑器里常用参数包括ParamAngleX / ParamAngleY头部角度可以实现轻微的头部跟随。ParamEyeLOpen / ParamEyeROpen眼睛睁开程度用于眨眼和惊讶表情。ParamMouthOpenY嘴巴张开程度用于对话口型。ParamBrowLY / ParamBrowRY眉毛位置表达情绪。在网页里点击模型可以触发一个动作例如播放“摸头”动画AI 回复时把嘴巴参数随音频音量变化观感会自然很多。5. Web 端 Live2D 渲染与一键展示5.1 用 pixi-live2d-display 渲染pixi-live2d-display 是 Web 端比较常用的 Live2D 渲染库基于 PixiJS。先安装依赖npm install pixi.js pixi-live2d-display然后在项目入口文件里引入 PixiJS 和 Live2D 模块。由于库内部会访问 window.PIXI一般需要把 PIXI 挂到全局import * as PIXI from pixi.js; import { Live2DModel } from pixi-live2d-display; window.PIXI PIXI;加载模型并添加到舞台核心代码是这样const app new PIXI.Application({ view: document.getElementById(live2d-canvas), autoStart: true, width: 600, height: 800, transparent: true }); const model await Live2DModel.from(/models/rabbit/rabbit.model3.json); app.stage.addChild(model); model.scale.set(0.4); model.anchor.set(0.5, 1); model.x 300; model.y 800;这段代码会把模型放在 Canvas 底部anchor 设置为底部居中方便控制位置。使用Live2DModel.from时会请求 model3.json 以及里面的贴图、动作文件所以模型目录必须放在静态资源目录下并且配置好开发服务器的静态文件服务。5.2 交互事件和动作播放陪伴型角色不能一直站在原地。pixi-live2d-display 支持hit事件点击模型的不同区域可以播放不同动作。比如点击身体时播放tap_body动作model.on(hit, (hitAreas) { if (hitAreas.includes(body)) { model.motion(tap_body); } });“hit 区域”需要在 Cubism 编辑器里提前定义导出后才能在模型里拿到。如果模型没有定义任何 hit 区域hitAreas会是空数组点击事件就不会触发。模型加载成功后可以通过model.expression(happy)切换表情也可以直接设置参数model.internalModel.coreModel.setParameterValueById(ParamMouthOpenY, 0.8);这对后面做“对话时嘴巴在动”非常有用。不过参数设置要放到动画循环里配合音量变化使用否则只会瞬间改变一次。5.3 一个最小可运行页面开发阶段不需要复杂框架一个简单的 HTML 加 Vite 或 Vue 都能跑。如果用 Vite把模型放在public/models/rabbit/目录下然后写一个组件加载模型。先在开发服务器里跑通模型展示再往里面加 AI 对话这是比较稳的顺序。如果你只是临时验证不想搭前端工程也可以用纯 HTML 引入浏览器版本的 pixi-live2d-display但需要确认 CDN 文件路径和版本匹配。更省事的方案是直接找一个已经封装好的 OhMyLive2D 配置模板把模型文件放进去改配置就能看到效果。6. 接入 AI 对话从 API 到本地模型6.1 云端 API 方式先做最容易跑通的方案调用 OpenAI 兼容接口。这样不需要本地 GPU只要申请一个 API Key在代码里配置 base_url 和 model 名称即可。用 Python requests 实现一个简单对话函数import requests API_KEY your-api-key BASE_URL https://api.openai.com/v1 MODEL gpt-4o-mini SYSTEM_PROMPT 你是一只陪伴型AI兔兔名字叫小雪语气温柔会把用户称为主人。 def chat(prompt: str, history: list[dict] | None None): messages [{role: system, content: SYSTEM_PROMPT}] if history: messages.extend(history) messages.append({role: user, content: prompt}) resp requests.post( f{BASE_URL}/chat/completions, headers{Authorization: fBearer {API_KEY}}, json{model: MODEL, messages: messages}, timeout30 ) data resp.json() return data[choices][0][message][content]这里把角色人设写进了 system prompt模型会按照“陪伴型兔兔”的语气回复。需要记住的是API Key 只在后端保存前端不能直接暴露。6.2 本地大模型方式如果不想走云端 API本地可以用 Ollama 部署开源模型比如 Qwen 系列。Ollama 安装后拉模型ollama pull qwen2.5:7b ollama serveOllama 默认提供 OpenAI 兼容接口地址是http://localhost:11434/v1。上面的 Python 代码只需要改 BASE_URL 和 MODELBASE_URL http://localhost:11434/v1 MODEL qwen2.5:7b本地模型的好处是数据不出本机、不依赖外网、没有按 token 计费。缺点是需要显卡。以常见的 7B 量化模型为例通常 6GB 到 8GB 显存左右能跑起来但具体占用要看量化等级、上下文长度和模型版本不能一概而论。如果你的显卡只有 4GB建议用更小规模的模型或者干脆用云端 API。6.3 多轮对话和历史记录陪伴型角色至少要能记住刚才说了什么。最简单的方式是把历史消息拼进 messages 数组。注意历史太长会占用上下文窗口一般只保留最近 10 到 20 条。工程化一点可以把会话记录存在 Redis 或 SQLite 里每次请求带上 session_id。7. 接入 TTS 语音让兔兔开口说话7.1 快速验证用 Edge-TTSEdge-TTS 是微软 Edge 浏览器内置语音服务的一个 Python 封装免费支持多种中文音色生成速度很快。先安装pip install edge-tts生成一段语音edge-tts --voice zh-CN-XiaoyiNeural --text 主人欢迎回来我一直在。 --write-media welcome.mp3Python 里异步调用import asyncio import edge_tts TEXT 主人欢迎回来我一直在。 VOICE zh-CN-XiaoyiNeural async def main(): tts edge_tts.Communicate(TEXT, VOICE) await tts.save(welcome.mp3) asyncio.run(main())Edge-TTS 需要联网依赖微软的服务。如果你部署的服务器没有外网或者要特定音色、离线运行就不能用这个方案。7.2 本地 TTS 方向要离线、可商用、可控音色需要看本地 TTS 项目。GPT-SoVITS 是目前很火的中文语音克隆方案支持少样本音色克隆。你可以用一个小样本集训练或推理生成和参考音频音色相近的语音。缺点是部署复杂度高需要下载模型权重推理时如果用 GPU 会占用显存。CosyVoice 是阿里开源的语音合成框架支持多语言和音色控制也支持流式合成适合做对话场景。无论是 GPT-SoVITS 还是 CosyVoice都需要比较强的硬件环境。实际显存占用和推理速度要以对应版本和参数量为准建议先在官方文档确认。7.3 音频返回给前端TTS 生成 mp3 后最快的方式是把它放到静态目录然后让前端用audio播放。更好的方式是后端提供一个 /tts 接口动态返回音频文件这样不用每次生成都写死文件名。8. 把链路串起来前端交互 后端接口 播放音频8.1 后端接口设计用一个 FastAPI 服务把“对话”和“语音”两个能力串起来。接口设计如下POST /chat接收用户文本返回 AI 回复文本。GET /tts接收文本参数生成并返回 mp3 音频。先安装依赖pip install fastapi uvicorn edge-tts后端代码from fastapi import FastAPI from fastapi.responses import FileResponse from pydantic import BaseModel import asyncio import edge_tts app FastAPI() class ChatRequest(BaseModel): prompt: str history: list[dict] | None [] app.post(/chat) async def chat(req: ChatRequest): # 这里实际调用大模型接口示例直接返回固定文本 reply 主人欢迎回来我一直在。 return {reply: reply} app.get(/tts) async def tts(text: str): tts edge_tts.Communicate(text, zh-CN-XiaoyiNeural) await tts.save(reply.mp3) return FileResponse(reply.mp3, media_typeaudio/mpeg)启动uvicorn main:app --host 0.0.0.0 --port 8000注意这是最小示例省掉了大模型调用和异常处理。实际项目里 /chat 里要把 req.history 和历史记录一起传给大模型返回后再决定是否需要调用 TTS。8.2 前端把文字、语音和 Live2D 串起来前端交互流程是这样的用户在输入框输入文字点击发送fetch 到 /chat 拿到 AI 回复然后在页面里显示文本同时请求 /tts 返回的音频并播放。async function sendMessage(text) { const resp await fetch(/chat, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ prompt: text, history: [] }) }); const data await resp.json(); const audio new Audio(/tts?text encodeURIComponent(data.reply)); audio.play(); }如果想让兔兔说话时嘴巴动可以在音频播放时读取音量并设置 Live2D 的嘴巴参数。最简单的方式是用 Web Audio API 的 AnalyserNodeconst audioCtx new AudioContext(); const source audioCtx.createMediaElementSource(audio); const analyser audioCtx.createAnalyser(); source.connect(analyser); analyser.connect(audioCtx.destination); const data new Uint8Array(analyser.frequencyBinCount); analyser.getByteFrequencyData(data); const volume data.reduce((a, b) a b, 0) / data.length / 255; model.internalModel.coreModel.setParameterValueById(ParamMouthOpenY, volume);用 requestAnimationFrame 在播放期间一直更新嘴巴参数就能实现简单的口型同步。这个方案不是音素级同步但作为陪伴型角色已经够用。8.3 麦克风语音输入进阶想更接近“陪伴”体验可以加语音输入。浏览器里用getUserMedia录音调用后端 ASR 接口转成文字然后走上面的对话链路。不过这一步会明显增加复杂度建议先把文字对话跑通再考虑语音输入。麦克风权限、浏览器兼容性、ASR 接口选择都要单独测试。9. 资源占用与性能观察9.1 各模块开销等级模块部署位置CPU内存显存网络要求Live2D 渲染浏览器低低无要求仅加载模型资源云端大模型云端无无无需要外网本地大模型本机中中高无云端 TTS云端低低无需要外网本地 TTS本机中高中高视项目而定无这里的“高/中/低”是相对概念具体要看模型大小、并发数和上下文长度。如果一个页面同时跑 Live2D 动画、播放音频、再请求推理接口流畅度瓶颈通常不在 Live2D而在音频解码和 JavaScript 频繁设置模型参数这两块。9.2 观察手段Windows 下按Ctrl Shift Esc打开任务管理器看 CPU 和内存占用。有 NVIDIA 显卡的机器在命令行运行nvidia-smi -l 1每 1 秒刷新一次显存使用情况。浏览器按 F12 打开开发者工具在 Network 面板里看模型文件、/chat、/tts 请求的耗时。如果在后端跑本地模型日志里通常会打印每次推理耗时和显存占用。先跑小模型、小音频、短文本观察资源占用再逐步放大这是最稳妥的做法。9.3 怎么降低资源占用Live2D 部分如果模型贴图过大可以压缩贴图尺寸减少同时加载的模型数量把 Canvas 分辨率调低。AI 对话部分本地模型建议用量化版上下文长度不要设置过大。TTS 部分Edge-TTS 本身不占本地算力是最省的方案本地 TTS 则要控制并发避免多个合成任务同时跑导致显存溢出。10. 常见问题与排查方法问题现象可能原因排查方式解决方案模型加载不出来model3.json 路径错误或模型文件缺失看浏览器 Network 面板是否返回 404检查静态资源目录和模型文件名控制台报 CORS 错误前端和后端不在同一个域名/端口检查请求地址和响应头后端开启 CORS 或使用反向代理点击模型没反应模型没有定义 hit 区域在 Cubism 里检查 hit 区域配置重新导出模型或在代码里直接触发 motion/chat 返回超时大模型 API 响应慢或网络不通先单独 curl 测试接口增加超时时间检查 API Key 和网络本地模型推理卡顿显存不足或模型过大nvidia-smi 查看显存占用换小模型、降低上下文长度、启用量化TTS 生成失败Edge-TTS 无法访问外网运行 edge-tts 命令看报错切换到本地 TTS 方案音频播放没有声音浏览器自动播放策略限制打开控制台查看 Audio 报错在用户点击后调用 audio.play()页面刷新后角色丢失模型加载逻辑依赖手动调用检查初始化流程在页面加载完成后自动加载模型口型不明显ParamMouthOpenY 设置值与动画循环冲突打印参数值观察在动画更新循环里持续设置参数接口偶发失败批量任务并发太高查看后端日志加队列、限流和失败重试11. 最佳实践与合规建议如果你准备照着做一套自己的陪伴型 AI 角色有几个习惯值得提前建立。第一模型资源、输入素材、输出结果分目录管理。比如models/anim/放 Live2D 模型audio/input/放参考音频audio/output/放 TTS 结果避免所有文件堆在根目录。第二第一次跑通链路时先验证最小闭环打开页面看到兔兔动起来输入一行字后端返回一句固定文本前端播放一段固定 mp3。最小闭环跑通后再接大模型和真实 TTS排错范围会小很多。第三接口服务如果部署到公网一定要做访问限制。FastAPI 可以加简单 token 校验或者用 Nginx 限制 IP 白名单。不要把 API Key、数据库连接串等敏感信息提交到前端项目或公开仓库。第四批量任务要有日志和重试机制。比如一次生成 100 条 TTS 音频逐条生成时建议记录成功和失败状态失败任务最多重试三次再失败就写入单独的错误列表。第五涉及真人肖像、声音克隆、版权模型时必须先确认授权。免费下载的 Live2D 模型通常不能商用商用时需要保留授权文件。声音克隆更要谨慎真人声音必须获得本人明确授权否则会侵犯人格权和著作权。第六角色人设需要保持尊重和健康。陪伴型 AI 可以温柔、可爱但不要引导用户产生过度情感依赖更不要做低俗、擦边、涉黄方向的内容。12. 总结与下一步整个链路拆开看并不复杂Live2D 负责形象大模型负责对话TTS 负责语音前后端胶水代码负责把三者串起来。最建议你先跑通的验证路径是找一个授权明确的 Live2D 兔兔模型用 pixi-live2d-display 加载到网页再写一个 FastAPI 后端/chat 接口先返回固定文本再接 Edge-TTS 生成 mp3最后把前端音频播放和嘴巴参数同步加上。这条路不需要好显卡一台普通电脑 外网就够了。跑通之后再考虑两件事一是把固定文本换成真实大模型 API二是把云端 TTS 换成本地音色克隆。如果你想要的是多个 AI 角色在同一空间里生活、互动的效果而不是单角色展示可以关注 my_ai_town 这类 AI 角色群组模拟项目方向不太一样但对做虚拟世界和角色生态的开发者很有参考价值。最容易被忽略的坑有三个模型路径和静态资源目录不对、前端暴露 API Key、CORS 配置缺失。先把这三个坑绕开后面的开发就顺了。建议收藏备用等你开始搭属于自己的 Live2D 陪伴角色时照着这份清单一步步验证即可。