罗德岛通讯与技术部

Lorebook / World Info — 设计与现状

LOREBOOK

app/prompts/lorebook_common.md ← 系统通用(git管理)

状态:🟡 规划 · 最后核对 2026-08-06

future-directions.md 抽出来独立成篇(2026-08-03)。

原文那份叫「未来方向」的文档里四项 C/D/E/F 全部实施完了,按 docs-reorg-plan 该整篇删掉。但这一节不能删 —— 它是唯一记着这套东西怎么设计的地方, 而且里面三处「设计稿和代码不符」的复核批注,代码里一个字都读不出来

  • ST 兼容是名义上的 —— 酒馆导出的 entries 是对象不是数组,真拿 Chub 的文件调会 422
  • 「导入条目排后面所以优先级更高」是错的 —— 排序纯按 weight,位置只在打平时起作用
  • 「常驻条目不受上限限制」从来没实现过 —— get_active_entries 结尾就是 final[:max_entries]

这三条都是「读设计稿会得出错误结论」的地方。删掉它们,下一个人(或下一个 AI) 会照着设计稿去写代码,然后发现对不上。


E:Lorebook / World Info 关键词触发注入 🟡 部分实施(2026-07-13 上线,2026-07-31 大修)

⚠️ 2026-07-31 更正:本节以下内容是设计稿,有几处和代码长期不符。 已就地标注。读之前先看这段。

上线后两周半里,这个功能实际只有 1/10 在工作。 解析器把正文行 (- 开头且不含冒号)当成"扩展关键词行"丢掉,条目接着因为正文为空被整条 跳过 —— 10 条场景条目只活下来「宿舍」一条,因为它正文里恰好有个全角冒号。 不报错、不打日志。已修(lorebook.py::_strip_bullet 附近有完整说明), 并加了 tests/test_lorebook_parser.py 盯住"条目数量对不对"。

已实施:解析器 / 匹配引擎 / 粘性冷却 / 三级知识 / 角色过滤 / 场景绑定 / 条目级开关(Markdown 侧 2026-08-01 补齐)/ 总闸 lorebook_enabled 未实施:前端面板(一行代码都没有)、ST 格式真兼容(方向已改,见下) 覆盖:普通聊 ✅ 深聊 ✅(2026-08-01 接入)群聊 ✅(关键词触发,不传在场场景)

设计

文件格式

app/prompts/lorebook_common.md               ← 系统通用(git管理)
app/prompts/lorebook/{op}.md                 ← 角色专属(git管理)
data/users/{username}/lorebook_custom.json   ← 用户导入(ST兼容格式)

每条条目:

## 甲板
- 关键词: 甲板, 舰桥, 瞭望哨, 甲板上, 吹风
- 排除: 博士, 你, 我, 他, 她
- 权重: 30
- 冷却: 3
- 罗德岛的甲板开阔而安静。夜风从移动城市的方向吹来,带着干燥的尘土味。围栏边有几个干员留下的折叠椅。

条目字段

字段 说明 默认
场景 (2026-08-01 新增) 绑定到在场系统的场景键(agent_loop.SCENES:deck/dorm/cafeteria/medical/office/corridor/lounge/training)。带这个字段的条目只在干员真的在那儿时注入,且不走关键词——提到一个地方不等于人在那个地方
关键词 精确子串匹配 + 扩展词表 必填
排除 全局排除词——高频通用词不参与匹配 博士,你,我,他,她
权重 0-100,多条命中时按权重排序 50
级别 0=通用 / 1=职业 / 2=个人。L2 覆盖 L0 0
限定 仅 L1/L2。逗号分隔的角色 ID——只有这些角色可见
常驻 是/否。常驻条目永远注入,不需要关键词匹配
粘性 触发后持续注入 N 轮 0
冷却 触发后 N 轮内不再触发 0

三级知识

级别 定义 示例 谁有
L2 个人 亲身经历——在那里生活/战斗/失去过 "他在多索雷斯帮老爹打理生意...全城最大的赌场老板欠他一个人情" Tequila、羽毛笔
L1 职业 工作接触——执行过任务/读过报告 "多索雷斯是玻利瓦尔沿海的独立城邦。罗德岛在那设有办事处。" 陈、凯尔希
L0 通用 世界观常识——泰拉成年人都可能知道 "多索雷斯——玻利瓦尔的赌城,以地下拳赛和烈酒闻名。" 所有人

同一关键词命中时,L2 替换 L0——个人经历覆盖通用百科。

匹配引擎

维度 设计
范围 只匹配用户消息——角色回复不触发,防止循环
方式 精确子串 + 扩展词表。不做 fuzzy
排除 全局排除词(博士,你,我,他,她)不参与匹配
排序 权重降序 → 命中关键词数降序 → 取 top-3
粘性 触发后持续注入 N 轮,期间跳过匹配
冷却 触发后 N 轮内不参与匹配

注入

维度 设计
位置 [World] 第四层——世界与记忆区。氛围块之前
上限 每轮最多 3 条。(常驻 + 粘性 + 匹配命中)合并计算
长度 每条 ≤ 100 字
常驻 常驻条目永远注入,不受上限限制 ⚠️ 和代码不符get_active_entries 结尾是 final[:max_entries]常驻条目一样会被截。设计稿写的是意图,代码从来没实现过。用户级的「世界补充设定」因此没做成常驻条目,而是自成一个注入槽(app/systems/world_note.py),免得和场景氛围抢那 3 个名额

与 ST 对比

ST 有 我们 版本
常驻条目 V1
粘性/冷却 V1
优先级权重 V1
角色过滤器 限定字段 V1
多级知识 ✅ L0/L1/L2 V1
条目级开关 🟡 只有一半
导入自定义世界书 🟡 名义上
递归扫描 V2
包含组 V2
AND/OR/NOT V2

条目级开关 🟡 只有一半

2026-07-31 复核LorebookEntry.enabled 字段存在,匹配时也真的会跳过 (lorebook.pyif not entry.enabled: continue),但 Markdown 解析器的字段正则里没有 启用 —— 2026-08-01 已补。 但前端仍然没有任何面板frontend/ 里搜 lorebook 是零命中: 用户能开关的只有 设置 → 世界 里那个总闸,不能逐条控制。

另外原文说"不需要全局关掉世界书"——这条判断已经被推翻了。解析器修好之后 注入量从"基本为零"变成"每轮 0-3 条",对老用户是可感知的突变,必须有个 不用部署就能关的总闸。已加:runtime_configlorebook_enabled (全局默认 + 每用户覆盖,默认开),前端在 设置 → 世界 里。

每个条目有 启用: 是/否 字段。前端 Lorebook 面板——用户可逐条开关。

ST 的做法:绿色=常驻、黄色=条件、红色=禁用。我们简化为——启用/禁用。

导入自定义世界书

格式兼容 ST 的 World Info JSON:

{
  "entries": [
    {
      "key": ["甲板", "舰桥"],
      "content": "罗德岛的甲板开阔而安静...",
      "constant": false,
      "enabled": true
    }
  ]
}

前端加导入按钮 → 选 .json 文件 → 后端解析 → 追加到用户专属 lorebook 文件(data/users/{username}/lorebook_custom.json)。不覆盖系统默认条目——用户导入的条目排后面,天然优先级更高。

2026-07-31 复核,上面这段有三处和代码不符:

  1. 「前端加导入按钮」没做。 POST /api/lorebook/import 在线上,但前端 没有任何入口——一个没人知道的门。
  2. 「排后面天然优先级更高」是错的。 排序是纯按 weight 降序 (sorted(candidates, key=lambda x: (x[0].weight, x[1]), reverse=True)), 在列表里的位置只在权重打平时才起作用。而且导入条目的 level 恒为 0, 撞上系统的 L2 条目时永远输。
  3. ST 兼容是名义上的。 酒馆最常见的 World Info 导出里 entries对象(键为 "0" "1"),我们的 parse_st_json 和接口的 list[dict] 都只认数组 —— 真拿 Chub 下的文件去调会 422 被拒。 字段名也对不上:酒馆用 disable: true(反的),我们读 enabledkeysecondary / selectiveLogic(二级关键词 AND/NOT)完全没有。

方向已改(2026-07-31 与用户讨论后定案):不做"导入世界书",改做 让用户决定世界观——一段 300 字的自由文本,自成注入槽。理由见 app/systems/world_note.py 的模块注释:world_lore.json 已有 795 条世界观 条目并建了 ChromaDB 索引,再塞一套外部真相进来填的不是空白、是矛盾源。 导入接口保留但不接前端。

为什么不做系统级世界书开关:条目级开关已够用。关掉某个条目不会让角色变蠢——只会减少一条场景描写。不是关掉整个系统。

首批内容

10 个场景:甲板、宿舍、食堂、训练室、办公室、医疗部、温室、图书馆、酒吧、工程部

10 个角色/NPC:凯尔希、阿米娅、能天使、德克萨斯、拉普兰德、年、陈、W、莫斯提马、普瑞赛斯

实施

阶段 内容
1 文件格式定义 + 解析器
2 匹配引擎——遍历关键词 + 排序 + 粘性/冷却状态追踪
3 注入逻辑——[World] 层追加,常驻永远注
4 10 个场景条目编写
5 10 个角色条目编写

投入:设计 1 天 + 实现 2 天 + 内容 1 天。