7.0 KiB
07 · LLM 对话
本节讲怎么接 LLM、两条协议(OpenAI 兼容 / Anthropic)的差别、常见错误码、长什么样。
1. 配置文件在哪里
存在 ~/.live2D/live2d.conf.json 里,但改完必须重启(见 §5.1)。
{
"llm_provider": "openai", // "openai" 或 "anthropic"
"llm_model": "gpt-4o-mini",
"llm_api_key": "sk-...",
"llm_base_url": "https://api.openai.com"
}
修改入口:桌宠 → 工具栏 ⚙ → 配置中心 → 「🤖 LLM 对话设置」区。
2. 两条协议对照
| 项 | OpenAI 兼容 | Anthropic |
|---|---|---|
| 端点 | POST {base_url}/v1/chat/completions |
POST {base_url}/v1/messages |
| 鉴权 Header | Authorization: Bearer <key> |
x-api-key: <key> + anthropic-version: 2023-06-01 |
| system 消息位置 | messages: [{role:"system", content:...}] |
提到顶层 system: "..." 字段 |
| messages[0] 限制 | 无 | 必须是 user(后端有兜底,强制补一条) |
| max_tokens | 可选(默认 1024) | 必填(默认 1024) |
| 响应 | choices[0].message.content |
content[*].text(按 type 过滤) |
| 多模态 | content: [{type:"text"}, {type:"image_url", image_url:{url:"data:..."}}] |
content: [{type:"text"}, {type:"image", source:{type:"base64", media_type, data}}] |
| 请求超时 | 180 秒 | 180 秒 |
| 代理 | no_proxy()(不走 HTTP_PROXY) |
no_proxy()(不走 HTTP_PROXY) |
💡 OpenAI 兼容 = 任何实现同一协议的服务:OpenAI 官方、Azure OpenAI、OpenRouter、DeepSeek、Moonshot、智谱 GLM(兼容端点)、自部署 vLLM / Ollama(
/v1端点)、LM Studio 等。
3. 常用 Base URL + Model 速查
| 服务 | Provider 选项 | Base URL | 常用 Model |
|---|---|---|---|
| OpenAI 官方 | openai |
https://api.openai.com |
gpt-4o-mini, gpt-4o, o1-mini |
| Anthropic Claude | anthropic |
https://api.anthropic.com |
claude-3-5-sonnet-20241022, claude-3-5-haiku-20241022 |
| DeepSeek | openai |
https://api.deepseek.com/v1 |
deepseek-chat |
| Moonshot | openai |
https://api.moonshot.cn/v1 |
moonshot-v1-8k, moonshot-v1-32k |
| 智谱 GLM | openai |
https://open.bigmodel.cn/api/paas/v4 |
glm-4-flash, glm-4 |
| Ollama(本地) | openai |
http://localhost:11434/v1 |
任何已 pull 的模型 |
| LM Studio(本地) | openai |
http://localhost:1234/v1 |
加载的模型 |
| 自部署 vLLM | openai |
你的 URL | 部署时定的名字 |
⚠️ 如果你在走代理(clash-verge / sing-box 等),且 LLM 端点是内网 / Tailscale IP,注意
no_proxy()已在代码里强制加上,但你自己的系统环境变量如果有错可能让请求出问题。详细见 09-常见问题FAQ.md。
4. 错误码
LLM 返回非 2xx 时,会在气泡里显示一条 system 错误,格式:[<状态码>] <友好前缀>: <API 原始消息>。
4.1 OpenAI 兼容
| 状态码 | 含义 |
|---|---|
| 401 | API key 无效或未授权 |
| 403 | API key 权限不足 |
| 404 | API 端点或模型不存在(检查 base_url 和 model 名) |
| 429 | 请求频率超限或余额不足 |
| 5xx | API 服务异常 |
| 60s | "请求超时"(注意:实际超时是 180s,错误文案是历史遗留) |
| connect | "无法连接到 API 服务" |
4.2 Anthropic
| 状态码 | 含义 |
|---|---|
| 401 | API key 无效或未授权 |
| 403 | API key 权限不足 |
| 404 | 模型不存在 |
| 429 | 请求频率超限 |
| 529 | 服务过载(Overloaded) |
| 5xx | 服务异常 |
5. 关键限制
5.1 改完配置必须重启 ⚠️
LLM 客户端(OpenAiProvider / AnthropicProvider)在 main() 里一次性创建:
let llm_provider: Arc<dyn LLMProvider> = match provider_kind.as_str() {
"anthropic" => Arc::new(AnthropicProvider::new(...)),
_ => Arc::new(OpenAiProvider::new(...)),
};
这个 Arc 整个进程生命周期里都是同一个对象。get_llm_status 读到的是磁盘最新配置,但实际请求的还是启动时的 provider。
所以:
- 改了 provider / model / api_key / base_url 任何一项 → 重启软件
- 在配置中心保存时按钮会变绿显示「✅ 已保存」,但状态点变色和实际能用是两回事
5.2 流式输出不支持 ❌
当前是整段返回:等 LLM 全推完才一次性显示。
- 小模型(< 3B)体验还行
- 大模型(7B+、Claude Sonnet 等)会有一段"静默"等待期
- 输入框会一直 disabled,底部出现"桌宠正在思考…"
5.3 max_tokens 硬编码 = 1024
对话回复超过 1024 token 会被截断。当前版本没有 UI 让你改这个。
5.4 多模态(图片)支持
- 支持:发截图给 LLM 看 → 见 04-桌宠窗口使用.md §4
- JPEG 预览优先(不是 PNG 原图,节省 10× 体积)
- 只支持 image_url 形式(OpenAI)/ image base64 形式(Anthropic),不支持音频/视频
5.5 思考块(DeepSeek / QwQ / o1)
LLM 回复里含 <think>...</think> 时自动折叠为可点开的小标签。详细见 05-聊天功能.md §3.2。
5.6 动作标签([MOTION: xxx])
当前版本不再注入动作标签指令进 system prompt。
- 历史:2026-06-12 曾经让 LLM 在回复末尾附
[MOTION: idle]等 - 当前:脑里不再加这个 prompt,LLM 不会主动回动作标签
- 情绪仍然通过事件注入(interact / praise 等)驱动模型动作
5.7 RAG 记忆的真相
- 架构上有 RAG(SQLite + 向量索引)
- 实际 embedder 是
DummyEmbedder(基于 hash 的伪 384 维向量)— 不是真实语义嵌入 - 所以"长期记忆"功能当前没意义:检索结果随机性强,不实用
- 状态:架构已就位,等接入真实 embedder 才能用
💡 如果你接的是 OpenAI 兼容服务,可以让你的 LLM 端点自带 embedding 能力(如支持
/v1/embeddings),把dummy换成真实调用即可——但这是改源码的事,本手册不展开。
5.8 base_url 末尾 /v1 处理
- OpenAI 兼容:自动剥末尾的
/和/v1,请求时统一拼{base}/v1/chat/completions - Anthropic:只剥末尾
/ - 举例:填
https://api.deepseek.com/v1和https://api.deepseek.com都对
6. 多模态请求超时 = 180 秒
- 普通对话:理论几秒-几十秒
- 多模态(截图)请求:图片 base64 上传 + 视觉编码 + 文本生成,实测 30-90 秒很常见
- 如果 LLM 端点很慢,可以把图片压得更小(04-桌宠窗口使用.md §4.3),但不能改超时
7. 自部署网关的兼容性提示
某些自部署 OpenAI 兼容网关严格校验 detail 字段。代码已主动不传 detail 字段(默认行为是 OpenAI 官方默认 auto),所以兼容性好。
如果你的网关还报 invalid image detail: auto (2013),前端清缓存(关掉重开),确认版本是 2026-06-14 之后。
下一步:08-数据存储与备份.md。