Skip to content

注入的 Emoji URL 中使用 UUID 可能导致某些模型引用表情包时出错 #9

Description

@Cherylight

问题描述

emojiluna 配合 ChatLuna Character 使用时,插件通过 chatlunaIntegration 适配器将表情包列表注入到系统提示中。当前 URL 格式使用 UUID 作为路径参数

// 提示词
"- [U-556晃尾嫌弃](http://...429a71c8f73e)"

这导致 LLM 在思考和输出过程中,可能截断或篡改 UUID 字符串,例如:

// 模型思考
"等下,表情包的URL是http://...429a71c8f73 对吧?对,那个是U-556晃尾嫌弃的。"  # 少了末尾的 'e'

UUID 是 36 字符的随机字符串,对 LLM 而言没有实际意义,token 化后被分割成多个片段,增加了复制出错的概率。

复现步骤

  1. 启用 emojiluna 插件的 injectVariables 功能添加若干表情包
  2. 触发 ChatLuna Character 对话并注入表情包列表到系统提示
  3. 要求 LLM 使用 sticker 标签包裹 URL 发送特定表情包
  4. 观察 LLM 思考和输出的 <sticker> URL,会发现 UUID 经常被截断或篡改
  5. chatluna-character : Error: send_group_msg failed: 下载文件失败: Not Found at sendElements...

环境

  • koishi-plugin-emojiluna: 1.3.3
  • koishi-plugin-chatluna: latest
  • 模型: doubao-seed-2-0-pro-260215(但问题可能在所有 LLM 上均存在)

使用了 emoji.id(UUID),而非 emoji.name

建议修复

chatlunaIntegration.ts 中的 URL 生成从 emoji.id 改为 emoji.name

// 修改前
const emojiUrl = `${baseUrl}/get/${encodeURIComponent(emoji.id)}`;

// 修改后
const emojiUrl = `${baseUrl}/get/${encodeURIComponent(emoji.name)}`;

证据支持

后端路由支持名称查找applyRestApi 中的 /get/:id 路由逻辑为:

const emoji = await ctx.emojiluna.getEmojiById(id) 
           || await ctx.emojiluna.getEmojiByName(id);

getEmojiByName 还会匹配 nametagscategoryid 四个字段,因此使用表情包名称作为 URL 参数完全可以正常工作。

修复效果

修改前(LLM 容易出错):

- [U-556晃尾嫌弃](http://localhost/emojiluna/get/eac1ce43-5bb5-4239-a880-429a71c8f73e)

修改后(LLM 可正确复制有意义的名称):

- [U-556晃尾嫌弃](http://localhost/emojiluna/get/U-556%E6%99%83%E5%B0%BE%E5%AB%8C%E5%BC%83)

优势

  1. LLM 出错率降低U-556晃尾嫌弃 是有意义的自然语言,比 36 字符随机 UUID 更容易被 LLM 正确复制
  2. 链接一致性[] 中的文本与 URL 路径中的名称一致,LLM 可交叉验证
  3. 无破坏性:后端已支持名称查找,无需修改路由逻辑
  4. 完全兼容:现有的 UUID 格式 URL 依然会被 getEmojiById 处理,不会影响已有客户端

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions