Lorebook / World Info — 设计与现状
LOREBOOK
状态:🟡 规划 · 最后核对 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.py里if not entry.enabled: continue),但Markdown 解析器的字段正则里没有—— 2026-08-01 已补。 但前端仍然没有任何面板,启用frontend/里搜lorebook是零命中: 用户能开关的只有 设置 → 世界 里那个总闸,不能逐条控制。另外原文说"不需要全局关掉世界书"——这条判断已经被推翻了。解析器修好之后 注入量从"基本为零"变成"每轮 0-3 条",对老用户是可感知的突变,必须有个 不用部署就能关的总闸。已加:
runtime_config的lorebook_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 复核,上面这段有三处和代码不符:
- 「前端加导入按钮」没做。
POST /api/lorebook/import在线上,但前端 没有任何入口——一个没人知道的门。- 「排后面天然优先级更高」是错的。 排序是纯按
weight降序 (sorted(candidates, key=lambda x: (x[0].weight, x[1]), reverse=True)), 在列表里的位置只在权重打平时才起作用。而且导入条目的level恒为 0, 撞上系统的 L2 条目时永远输。- ST 兼容是名义上的。 酒馆最常见的 World Info 导出里
entries是 对象(键为"0""1"),我们的parse_st_json和接口的list[dict]都只认数组 —— 真拿 Chub 下的文件去调会 422 被拒。 字段名也对不上:酒馆用disable: true(反的),我们读enabled;keysecondary/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 天。