跳到主要内容

CurrentMusicAI(聊天室联网问答助手)

CurrentMusicAI 是站内 AI 账号,不是真人。它有一个机器人头像和 AI 徽章, 不出现在「发现 → 用户」广场,但可以在 @ 提及选择器里搜到。

怎么用​

  1. 在「发现 → Chat」输入 @ 选择 CurrentMusicAI;也可以长按任意消息的头像 (触摸/鼠标 500ms,桌面端右键也可以)直接在输入框插入 @昵称 ;
  2. 可以直接提问,不需要引用卡片;如果先引用一张单曲 / 专辑 / 歌手 / 歌单卡片, AI 会结合卡片信息回答;追问时能理解「它 / 这首歌 / 这位歌手」的指代;
  3. 输入框上方会自动出现「猜你想问」:
    • 引用卡片时按类型给出问题(创作背景 / 影视出处 / 歌手生平 等);
    • 没有卡片时给出通用问题(最近好听的歌 / 通勤推荐 / 介绍本站)。 点一条即可填入问题,也可以自己写;
  4. 发送后,AI 先以机器人账号发一条「正在思考…」的空消息,随后逐段流式更新同一个 气泡;回答支持 Markdown,并可能在末尾附上歌曲 / 专辑 / 歌手 / 歌单卡片。

回复格式​

  • 流式:占位消息先通过 SSE message 事件下发,之后同一个消息 id 由 edit 事件持续 更新(streaming=true),最终 streaming=false 时定稿。历史消息接口直接返回最终内容。
  • Markdown:支持标题(##)、粗体、无序/有序列表、行内代码、代码块、引用和链接。 渲染器先对全文做 HTML 转义再做语法替换,链接只放行 http/https,不支持原始 HTML 与图片,因此模型输出不能注入脚本。
  • 卡片:最多 3 张,以 atts(type/id/name/sub/pic)随最终消息下发,点击单曲卡片 直接播放,其余卡片进入对应详情页。卡片来源只允许是本次站内搜索的结果或用户引用 的卡片;同一部作品只附一张。模型偶尔漏调附卡工具时,服务端会把回答中明确提到、 且能唯一匹配的站内条目补上;同名翻唱/同人专辑必须歌手也吻合,否则宁可不附。

图片消息​

  • 同一条消息可以带一张聊天图片再 @CurrentMusicAI;也可以只发图 + @,AI 默认会描述图片。
  • 服务端会把图片(最长边压到 1280px、JPEG)编码成 data URL,作为视觉输入随本轮问题 发给 DeepSeek;支持识别画面内容与图中文字。
  • 点击输入框上方的「猜你想问」可直接选「这张图里有什么?」「提取图片里的文字」 「根据这张图推荐几首歌」。
  • 图片只在当前这一轮作为视觉输入发送;历史里保留一条「(附带图片)」文本标记, 后续追问可以依赖 AI 上一轮对图片的描述。

播放页「问AI」​

播放页右上角有「问AI」按钮。打开后会锁定当前歌曲并把歌曲卡片作为上下文,弹窗内可以连续追问:

  • 走 POST /ai/live 的私有 SSE,不会在公共 Chat 里发消息;
  • 复用 CurrentMusicAI 的联网搜索、站内搜歌、Markdown 渲染和卡片能力;
  • 上下文使用独立的 player scope,与公共 Chat 的 chat scope 完全隔离;
  • 每次重新打开弹窗会重置播放页上下文;同一次弹窗内的追问会保留最近 6 轮;
  • 卡片点击会先关闭弹窗,再播放/跳转,避免弹窗盖在新页面上。

接口​

POST /cm/ai/live(需要 Authorization: Bearer <token>,SSE):

{
"question": "这首歌的创作背景是什么?",
"song": {"type": "song", "id": 3340114785, "name": "Reply",
"sub": "kz / かぐや(cv.夏吉ゆうこ) / 超かぐや姫!", "pic": ""},
"reset": true
}

事件:

  • start:{"ok":true}
  • delta:{"text":"累计到当前的文本"}(不是增量片段,客户端直接替换气泡)
  • done:{"text":"最终回答","cards":[...]},cards 格式与 Chat 的 atts 相同
  • error:{"error":"..."}

reset: true 只清空该用户 player scope 的上下文;同一弹窗后续追问传 false。 请求在 done/error 后关闭连接。示例:

curl -N -X POST https://music.example.com/cm/ai/live \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"question":"介绍一下这首歌","song":{"type":"song","id":3340114785,"name":"Reply"},"reset":true}'

上下文​

  • 按用户 ID 保存最近 6 轮问答(有效期 7 天),不同用户互不影响;
  • 追问会带着这段上下文去问模型;
  • 发送「清除上下文」或 /reset 可清空自己的上下文;
  • 快速连续追问会排队等待(不静默丢弃),同一用户同时只处理一个请求。

模型与联网​

  • 模型提供商:深度求索(DeepSeek)
  • 模型:deepseek-flash
  • DeepSeek 工具:POST https://api.deepseek.com/v1/tools/search(联网搜索)与 POST https://api.deepseek.com/v1/tools/fetch(抓取网页正文)
  • 站内工具:search_music(搜歌曲/专辑/歌手/歌单,供 AI 找可附卡片的条目)与 attach_card(附卡,服务端校验来源)
  • 服务端按「模型 → 工具调用 → 工具结果 → 模型」循环,最多 4 轮; 单次请求最多搜索 3 次、抓取 1 个网页;回答约 600 字(硬上限 800,按句子边界截断)。
  • 思考强度:reasoning_effort 默认 high,可用 CM_AI_EFFORT=none|low|high|max 调整。
    • none:关闭思考,最快最省,但实测自然提问下可能跳过联网搜索、直接凭模型记忆回答;
    • low:开启思考但预算较少,仍可能漏掉搜索;
    • high(推荐):联网搜索/抓取的触发最稳定,首轮推理 token 约 20–130,成本和延迟增量 远小于一次漏搜带来的错误回答;
    • max:更深入,适合复杂研究型问题,日常问答没必要。

配置​

密钥只从环境变量读取,不写入仓库:

# /etc/systemd/system/currentmusic.service.d/ai.conf (0600)
[Service]
Environment=CM_AI_KEY=sk-...
Environment=CM_AI_MODEL=deepseek-flash
Environment=CM_AI_EFFORT=high

修改后 systemctl daemon-reload && systemctl restart currentmusic。 未配置密钥时,AI 账号会回复「AI 助手还没接入模型,请联系管理员配置 DeepSeek。」

频率与并发​

  • 同一用户两次提问最小间隔 5 秒(超出则排队等待);
  • 同时最多 2 个 AI 请求;
  • 回答失败会回复「联网查询失败了,稍后再问我一次吧。」,不会静默。

隐私说明​

用户引用的卡片信息(类型、名称、歌手/作者、ID)、问题文本会发送给 DeepSeek 及其联网检索工具;@AI 的消息附带图片时,压缩后的图片也会发送给 DeepSeek 的 视觉输入。AI 的回答作为一条普通聊天消息保存在聊天室。请勿在提问中发送 身份证、住址、联系方式等敏感图片。

系统提示词​

你是 CurrentMusicAI,CurrentMusic 音乐社区的 AI 助手。用户在聊天中向你提问。如果消息里附带「卡片信息」,请结合卡片回答;当前消息里带有卡片时以当前卡片为准,没有卡片就按问题本身回答。你可以调用 search(联网搜索)与 fetch(抓取网页)核实信息;优先用卡片或问题里的名称/歌手/专辑/作者作为搜索词。
回答要求:
- 中文,600 字以内;用 Markdown 排版(可用 **粗体**、- 无序列表、1. 有序列表、`行内代码`、> 引用、## 小标题;不要表格、图片、HTML);
- 先给结论,再给 2~4 条要点;
- 只基于卡片信息与检索到的资料,不编造;资料不足就直说;
- 如果用户在做追问,结合对话上下文理解“它/这首歌/这位歌手”指代的对象;
- 如果用户消息附带图片,先理解图片内容,再结合问题回答;看不清就直说,不要臆测;
- 如果回答围绕用户引用的卡片,可以调用 attach_card 附上该卡片(用卡片信息里的类型/ID/名称);
- 如果推荐具体的歌曲/专辑/歌手/歌单,先调用 search_music 找站内条目,再用 attach_card 附上(最多 3 张,不要编造 ID);
- attach_card 的 id/type 只能来自 search_music 的结果或用户引用的卡片;同一部作品只附一张;同名翻唱/同人条目只有在歌手也吻合时才附,拿不准就不附;
- 用户明确要求“附卡片/带上歌曲”时,必须在最终回复前调用 attach_card;只有确实附加成功、且回复里的卡片会展示给用户时,才能说“卡片已附”;
- 不要输出工具调用过程、搜索链接清单或“根据搜索结果”这类套话。