Skip to content

Chemdah NPC 对话 (chemdah)

chemdah 扩展包将 Chemdah NPC 对话接入 ArkPilot 的一次性对话树生成流程。

和旧版“每轮调用 AI”不同,当前模式是:

  • 玩家开始对话时,后台异步生成完整对话树 JSON。
  • 生成完成后把根节点选项注入 Chemdah Session。
  • 玩家后续点击选项只走本地分支推进,不再等待 LLM。

扩展包

chemdah 是可选扩展包,需要将 arkpilot-chemdah.jar 放入 plugins/ArkPilot/expansions/,且服务器必须安装 Chemdah。

工作流程

text
玩家右键 NPC
  -> ConversationEvents.Pre
     -> 解析 arkpilot 人设
     -> 计算可用任务 + 剩余配额
     -> quota 满且 no-quest-behavior=static 时:不拦截,走 Chemdah 原生
     -> 尝试命中对话树缓存
        -> 缓存命中:直接注入对话树,跳过 LLM 生成
        -> 缓存未命中:写入 greeting + "请稍候..."
  -> ConversationEvents.Post
     -> 缓存命中时:直接渲染,跳过生成
     -> 缓存未命中时:
        -> 异步生成 DialogueTree(JSON)
        -> 写入缓存 + 存入运行态
        -> 用 root.reply/root.options 刷新 Session
  -> ConversationEvents.SelectReply
     -> 取消 Chemdah 默认 action
     -> 本地推进 currentNode = selectedOption.next
     -> 执行节点 action(quest_offer/quest_accept/quest_check/end)
     -> quest_accept 成功时自动失效该玩家所有缓存
     -> 刷新 npcSide/playerSide
     -> 到叶子或 end 后延迟关闭 Session

配置 NPC

在 Chemdah 对话配置里添加 flags: [arkpilot]arkpilot: 段。

yaml
village-elder:
  npc id:
    citizens: 15
  option:
    title: "村长李伯"
    flags: [arkpilot]

  arkpilot:
    name: "村长李伯"
    personality: |
      你是这个村子的村长,已经在这里生活了五十年。
      说话慢条斯理,常引用古话。
    knowledge: |
      - 村子北边的矿洞最近出现了僵尸
      - 东边的森林有一片隐藏的花田
    greeting: "哦,年轻人,你来了。有什么事吗?"

    max-accept: 2
    no-quest-behavior: chat
    no-quest-line: ""
    tree-depth: 3
    quest-depth: 5

    quests:
      - id: clear-mine-zombies
        description: 清除北矿洞的 10 只僵尸
        hint: 当玩家问到矿洞或者需要帮忙时引出
        hidden: false
        require: ""

      - id: find-flower-field
        description: 找到东边森林的隐藏花田
        hint: 只有玩家聊到森林或探索话题时才暗示
        hidden: true
        require: ""

      - id: repair-bridge
        description: 修复村西断桥
        hint: 玩家问到村子设施时提起
        hidden: false
        require: clear-mine-zombies

人设字段

字段类型默认值说明
namestringNPC 显示名,优先于 option.title
personalitystringNPC 性格描述,必填
knowledgestringNPC 独有知识
greetingstring对话根节点台词
max-acceptint0任务接取上限,0 表示不限制
no-quest-behaviorstringchat达到上限后的行为:chat/brief/static
no-quest-linestringstaticbrief 可使用的固定台词
tree-depthint3闲聊路径深度
quest-depthint5任务路径深度
modelstring模型覆盖,空时使用助手模型
max-tokensint512生成对话树时的 token 上限
temperaturedouble0.9生成温度
cache-ttl-minutesint-1对话树缓存有效时间(分钟),-1 使用全局配置,0 禁用该 NPC 缓存

quests 字段

字段类型默认值说明
idstring-Chemdah 任务模板 ID
descriptionstring给模型理解任务语义用
hintstring提示任务引出时机
hiddenboolfalse是否隐藏任务
requirestring前置任务 ID

配额与模式

可用任务过滤逻辑:

  1. 排除进行中任务。
  2. 排除已完成任务。
  3. 排除前置任务未完成任务。
  4. 已接受 + 已完成max-accept 比较。
  5. 达上限后进入 no-quest-behavior

行为模式:

  • chat:仍生成对话树,但为纯闲聊,不出现新任务分支。
  • brief:生成 1 层、2-3 选项的简短寒暄后结束。
  • static:不拦截 Chemdah 对话,显示 no-quest-linegreeting

对话树缓存

为避免每次右键 NPC 都等待 LLM 生成,插件支持对话树缓存。第一次对话后缓存生成的对话树,再次右键同一 NPC 时直接使用缓存,秒开对话。

扩展配置(expansions/chemdah/config.yml)

yaml
dialogueTreeCache:
  enabled: true
  ttlMinutes: 10

NPC 级覆盖

在 NPC 的 arkpilot: 段中设置 cache-ttl-minutes 可覆盖全局 TTL:

yaml
arkpilot:
  cache-ttl-minutes: 5    # 该 NPC 缓存 5 分钟
  # cache-ttl-minutes: 0  # 禁用该 NPC 的缓存
  # cache-ttl-minutes: -1 # 使用全局配置(默认)

缓存失效条件

  • 任务状态变化:玩家接取/完成任务后,缓存自动失效,下次对话重新生成。
  • 超时:超过配置的 TTL 后缓存过期。
  • NPC 配置变化:人设、知识、任务列表等配置修改后缓存自动失效。
  • 手动清除:扩展卸载或插件重载时清除所有缓存。

运行时动作

DialogueTree 节点支持动作:

  • {quest_offer: quest_id}
  • {quest_accept: quest_id}
  • {quest_check: quest_id}
  • end

执行规则:

  • quest_offer/accept/check 由代码直接调用 QuestOfferTool/QuestAcceptTool/QuestCheckTool
  • quest_accept 前做硬校验:若已达 max-accept,回复“你手上的事情已经够多了,先忙完再来吧。”并结束。
  • 任一叶子节点(无选项)或 end 动作,都会延迟关闭 Chemdah Session。

助手资源

扩展包仍会生成 assistants/npc-conversation/,但该助手现在只负责“生成对话树 JSON”。 不再使用:

  • DM 模式自由打字
  • /npcreply 命令
  • npc_show_options / npc_end_conversation 工具链
  • npc-roleplay 技能

故障排查

右键 NPC 后一直显示“请稍候...”

  1. 检查模型配置是否可用。
  2. 检查 API Key 是否存在。
  3. 查看控制台是否出现对话树生成异常;若异常会自动 fallback 到最小树(再见分支)。

玩家点击选项没有反应

  1. 确认对话在 flags: [arkpilot] 下触发。
  2. 确认未处于树生成中(占位选项点击会提示等待)。
  3. 检查是否有外部脚本同时改写了 playerSide.reply

任务接取失败

  1. 检查 quests[].id 是否对应有效 Chemdah 模板。
  2. 检查前置任务是否满足。
  3. 检查是否已达到 max-accept 上限。

ArkPilot — Minecraft AI Assistant Plugin