添加测试、添加总结、全量、rag(todo)3种历史记录保存方式,流式实现
This commit is contained in:
292
WORLDBOOK_ACTIVATION_LOGIC.md
Normal file
292
WORLDBOOK_ACTIVATION_LOGIC.md
Normal file
@@ -0,0 +1,292 @@
|
||||
# 世界书激活业务逻辑说明
|
||||
|
||||
## 概述
|
||||
|
||||
世界书(WorldBook)系统允许用户创建动态的知识条目,这些条目可以根据特定条件自动激活并注入到对话上下文中。本文档详细说明世界书条目的筛选和分类逻辑。
|
||||
|
||||
## 核心流程
|
||||
|
||||
### 1. 数据收集阶段
|
||||
|
||||
后端从两个来源加载世界书条目:
|
||||
|
||||
1. **全局世界书** (`globalBooks`)
|
||||
- 来自前端传递的全局世界书列表
|
||||
- 所有对话都会检查这些世界书
|
||||
|
||||
2. **角色绑定世界书** (`characterBookId`)
|
||||
- 与当前角色卡绑定的世界书
|
||||
- 仅在该角色的对话中检查
|
||||
|
||||
### 2. 条目筛选阶段
|
||||
|
||||
对每个世界书条目进行以下检查:
|
||||
|
||||
#### 2.1 禁用状态检查
|
||||
```python
|
||||
if entry_data.get("disable", False):
|
||||
continue # 跳过禁用的条目
|
||||
```
|
||||
|
||||
#### 2.2 触发条件检查
|
||||
|
||||
支持四种触发类型:
|
||||
|
||||
##### A. 常驻触发 (constant)
|
||||
- **配置**: `trigger_config.triggers.constant[0] == true`
|
||||
- **行为**: 总是激活,无需任何条件
|
||||
- **适用场景**: 角色基础设定、世界观背景等始终需要的信息
|
||||
|
||||
##### B. 关键词触发 (keyword)
|
||||
- **配置**:
|
||||
```json
|
||||
{
|
||||
"key": ["关键词1", "关键词2"],
|
||||
"caseSensitive": false,
|
||||
"matchWholeWords": false
|
||||
}
|
||||
```
|
||||
- **检查范围**:
|
||||
- 用户当前输入 (`user_message`)
|
||||
- 聊天历史消息 (`chat_history`)
|
||||
- **匹配模式**:
|
||||
- 大小写敏感/不敏感
|
||||
- 全词匹配/部分匹配
|
||||
- **适用场景**: 当对话中提到特定概念时激活相关解释
|
||||
|
||||
##### C. 条件触发 (condition)
|
||||
- **配置**:
|
||||
```json
|
||||
{
|
||||
"conditions": [
|
||||
{"text": "tb.力量 > 10"},
|
||||
{"text": "tb.态度 包括 \"友好\""}
|
||||
]
|
||||
}
|
||||
```
|
||||
- **支持的语法**:
|
||||
- 数值比较: `tb.字段名 >/</>=/<=/==/!= 数值`
|
||||
- 字符串相等: `tb.字段名 = "值"`
|
||||
- 字符串包含: `tb.字段名 包括 "子串"`
|
||||
- **逻辑**: 所有条件必须同时满足 (AND)
|
||||
- **适用场景**: 基于动态表格状态的 conditional 内容
|
||||
|
||||
##### D. RAG触发 (暂未实现)
|
||||
- 预留接口,未来可支持向量检索激活
|
||||
|
||||
### 3. 位置分类阶段
|
||||
|
||||
激活的条目按插入位置进行分类和排序:
|
||||
|
||||
#### 位置编号及含义
|
||||
|
||||
| 位置 | 标签 | 权重 | 说明 |
|
||||
|------|------|------|------|
|
||||
| 0 | 角色定义之后 | 高 | AI读完人设紧接着就读到这里,适合补充角色的详细设定 |
|
||||
| 1 | 角色定义之前 | 中 | 在角色卡内容的最上方,用于定义角色的基础背景 |
|
||||
| 2 | 示例对话之前 | 低 | 在对话示例的最上方 |
|
||||
| 3 | 示例对话之后 | 低 | 用于在对话开始前提供最后的上下文补充 |
|
||||
| 4 | 系统提示/作者注释 | 极高 | AI对最近看到的信息记忆最清晰,适合动态信息 |
|
||||
| 5 | 作为系统消息 | 最高 | 强制作为System Prompt插入,用于强制指令 |
|
||||
| 6 | 深度插入 | - | 预留,待实现 |
|
||||
| 7 | 宏替换 | - | 预留,待实现 |
|
||||
|
||||
#### 排序规则
|
||||
|
||||
```python
|
||||
active_entries.sort(key=lambda x: (x.position or 0, x.order or 0))
|
||||
```
|
||||
|
||||
1. **主排序**: 按 `position` 升序(位置编号小的先插入)
|
||||
2. **次排序**: 同位置内按 `order` 升序(order值小的先插入)
|
||||
|
||||
### 4. 统计与日志
|
||||
|
||||
激活完成后,生成详细的统计信息:
|
||||
|
||||
```
|
||||
[WorldBook] 📊 激活统计:
|
||||
- 总激活条目数: 5
|
||||
- 按位置分布:
|
||||
* 角色定义之后 (pos=0): 2 个
|
||||
* 系统提示/作者注释 (pos=4): 3 个
|
||||
- 按触发类型分布:
|
||||
* constant: 2 个
|
||||
* keyword: 2 个
|
||||
* condition: 1 个
|
||||
```
|
||||
|
||||
## 数据结构
|
||||
|
||||
### 前端发送的数据格式
|
||||
|
||||
```javascript
|
||||
{
|
||||
worldBookData: {
|
||||
globalBooks: [
|
||||
{ id: "...", name: "全局世界书1" },
|
||||
{ id: "...", name: "全局世界书2" }
|
||||
],
|
||||
characterBookId: "角色绑定的世界书ID"
|
||||
},
|
||||
mes: "用户输入的消息",
|
||||
chatHistory: ["历史消息1", "历史消息2"],
|
||||
dynamicTableData: {
|
||||
currentValues: {
|
||||
"力量": 15,
|
||||
"态度": "友好"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 后端返回的激活条目格式
|
||||
|
||||
```python
|
||||
{
|
||||
"type": "worldbook_active",
|
||||
"entries": [
|
||||
{
|
||||
"uid": "uuid-string",
|
||||
"content": "条目内容",
|
||||
"position": 0,
|
||||
"order": 100,
|
||||
"trigger_config": {...},
|
||||
...
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 实现细节
|
||||
|
||||
### 关键方法
|
||||
|
||||
1. **`_collect_and_activate_worldbooks()`**
|
||||
- 主入口方法
|
||||
- 负责加载世界书、检查激活条件、排序和统计
|
||||
|
||||
2. **`_check_entry_activation()`**
|
||||
- 检查单个条目的激活条件
|
||||
- 支持 constant、keyword、condition 三种触发类型
|
||||
|
||||
3. **`_check_keyword_trigger_with_config()`**
|
||||
- 关键词匹配逻辑
|
||||
- 支持大小写敏感和全词匹配选项
|
||||
|
||||
4. **`_parse_table_condition()`**
|
||||
- 解析动态表格条件表达式
|
||||
- 支持数值比较和字符串操作
|
||||
|
||||
5. **`_get_trigger_type()`**
|
||||
- 识别条目的触发类型
|
||||
- 用于日志和统计
|
||||
|
||||
6. **`_get_position_label()`**
|
||||
- 将位置编号转换为中文标签
|
||||
- 用于日志和前端显示
|
||||
|
||||
### 数据类型标准化
|
||||
|
||||
在激活前,对所有条目数据进行标准化处理:
|
||||
|
||||
```python
|
||||
def _normalize_worldbook_entry(entry_data):
|
||||
# content 必须是字符串
|
||||
# uid 必须是字符串
|
||||
# position 必须是整数
|
||||
# group 必须是列表或None
|
||||
```
|
||||
|
||||
## 前端集成
|
||||
|
||||
### WebSocket 消息接收
|
||||
|
||||
前端通过 WebSocket 接收激活条目:
|
||||
|
||||
```javascript
|
||||
// ChatBoxSlice.jsx
|
||||
else if (data.type === 'worldbook_active') {
|
||||
console.log('[WebSocket] 📚 收到世界书激活信息:', data.entries.length, '个条目');
|
||||
import('../../Store/SideBarRight/WorldBookActiveSlice').then(module => {
|
||||
module.default.getState().setActiveEntries(data.entries);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### 显示组件
|
||||
|
||||
`WorldBookActive` 组件按位置分组显示激活的条目:
|
||||
|
||||
```jsx
|
||||
// 按位置分组
|
||||
const groupedEntries = activeEntries.reduce((acc, entry) => {
|
||||
const pos = entry.position || 0;
|
||||
if (!acc[pos]) acc[pos] = [];
|
||||
acc[pos].push(entry);
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
// 渲染每个位置组
|
||||
{Object.keys(groupedEntries).map(pos => (
|
||||
<div key={pos} className="position-group">
|
||||
<div className="position-label">
|
||||
{positionLabels[pos]} ({pos})
|
||||
</div>
|
||||
{/* 渲染该位置的所有条目 */}
|
||||
</div>
|
||||
))}
|
||||
```
|
||||
|
||||
## 扩展方向
|
||||
|
||||
### 短期优化
|
||||
1. 添加概率触发支持 (`probability` 字段)
|
||||
2. 实现RAG检索触发
|
||||
3. 支持逻辑表达式触发 (`logicExpression`)
|
||||
|
||||
### 长期规划
|
||||
1. 实现深度插入 (position=6)
|
||||
2. 实现宏替换 (position=7)
|
||||
3. 添加条目冲突解决机制
|
||||
4. 支持条目依赖关系
|
||||
|
||||
## 调试建议
|
||||
|
||||
### 查看激活日志
|
||||
|
||||
后端会输出详细的激活日志:
|
||||
|
||||
```
|
||||
[WorldBook] 📖 加载全局世界书 '测试世界书',共 10 个条目
|
||||
[WorldBook-Check] 📌 常驻触发 | UID: xxx-xxx-xxx
|
||||
[WorldBook] ✅ 全局世界书 '测试世界书' 条目激活 | UID: xxx | 触发: constant | 位置: 角色定义之后
|
||||
[WorldBook-Check] 🔑 关键词触发(用户输入) | UID: yyy | 匹配关键词: ['魔法']
|
||||
```
|
||||
|
||||
### 常见问题排查
|
||||
|
||||
1. **条目未激活**
|
||||
- 检查 `disable` 字段是否为 `true`
|
||||
- 检查触发条件配置是否正确
|
||||
- 查看日志中的 `[WorldBook-Check]` 输出
|
||||
|
||||
2. **位置不正确**
|
||||
- 确认 `position` 字段是整数类型
|
||||
- 检查 `order` 字段的排序是否符合预期
|
||||
|
||||
3. **关键词不匹配**
|
||||
- 检查 `caseSensitive` 设置
|
||||
- 检查 `matchWholeWords` 设置
|
||||
- 确认关键词拼写正确
|
||||
|
||||
## 总结
|
||||
|
||||
世界书激活系统实现了:
|
||||
- ✅ 多源数据加载(全局 + 角色绑定)
|
||||
- ✅ 多种触发类型(常驻、关键词、条件)
|
||||
- ✅ 智能位置分类(8个插入位置)
|
||||
- ✅ 详细统计分析(按位置和触发类型)
|
||||
- ✅ 完整日志记录(便于调试)
|
||||
|
||||
这为动态上下文管理提供了强大的基础,可以根据对话内容智能地注入相关知识。
|
||||
Reference in New Issue
Block a user