13 KiB
13 KiB
灵台插件化运行时
状态:重写目标态(rewrite/1.0 基线) 职责:定义灵台认知运行时的结构——极小硬核 Kernel、插件体系、事件溯源会话、上下文投影、提示词与记忆注入管线、压缩、并发与命台控制。 设计理念参考 deepseek-harness 的"一切皆插件"与 pi 的会话/压缩模型,均只借设计不引依赖。
1. 设计理念与硬核例外
运行时遵循三条理念:
- 一切皆插件:模型适配、工具、记忆、人格调节、压缩、世界认知……全部以插件装配,无特权核心,可从配置替换。
- 事件溯源:Run 的一切输入输出进入 append-only 事件日志(一炁),模型可见上下文从事件日志投影派生;铁律 "模型可见即可重建"——到达模型的任何输入必须能从日志重建,运行时以断言强制。
- 监听器可否决:关键节点(请求前、工具执行前、结果接纳前)是瀑布事件,插件监听器可改写或否决;注入、审计、安全都在事件层做,不改循环骨架。
硬核例外(不可插拔):Kernel 固化以下内容,任何插件不可卸载、降权或绕过——
- 镜树不变量:重新生成不覆盖旧候答、未归真旁枝不自动入忆、归真不因切换候答回滚、编辑已发送内容必分叉;
- 命台不变量:同一人物同一时刻只有一条前台意识流,多分支前台请求排队;
- 司命禁域裁决点:高风险能力、数据、后果、情境四维裁决中标记为禁域的规则在请求前强制执行;
- 事件日志写入:状态变更与事件一致提交(事务内或 Outbox)。
这套例外的依据是产品宪章"禁域不能被 Prompt、人物、模型、扩展、管理员或普通部署配置关闭"。插件体系的自由度止步于禁域。
2. 分层结构
flowchart TD
subgraph Kernel[极小硬核 Kernel · 不可插拔]
INV[不变量裁决器]
SEAT[命台并发控制]
LOG[事件日志读写]
LOOP[Run 循环骨架]
end
subgraph Bus[事件总线 · 瀑布节点]
N1[run.requested]
N2[turn.started]
N3[llm.pre_request]
N4[tool.pre_execute]
N5[result.pre_accept]
N6[turn.finished]
end
subgraph Plugins[插件层 · Profile 装配]
P1[灵核 · 人格调节]
P2[太一 · 目标]
P3[司命 · 常驻裁决]
P4[烛照 · 观察反思]
P5[河图 · 世界认知]
P6[洛书 · 计划]
P7[息壤 · 记忆]
P8[百工 · 能力注册]
P9[天工阁 · 功能 Agent]
end
LOOP --> Bus
Plugins --> Bus
Kernel --> Plugins
3. 事件溯源会话
3.1 事件模型
Run 是一次人物认知运行(一次前台回答、一次后台受托任务、一次应感)。Run 事件序列是一炁事件流的一个分区:
flowchart LR
E1[run.started] --> E2[turn.started]
E2 --> E3[context.projected<br/>投影快照引用]
E3 --> E4[llm.requested]
E4 --> E5[llm.delta ...]
E5 --> E6[llm.completed]
E6 --> E7{工具调用?}
E7 -- 是 --> E8[tool.pre_execute]
E8 --> E9[tool.executed]
E9 --> E4
E7 -- 否 --> E10[turn.finished]
E10 --> E11[result.pre_accept]
E11 --> E12[run.finished]
- 事件带单调序号、
run_id、character_id、trace_id与时间戳;事件类型与取值以契约词典为单一事实源。 - SSE 输出是事件流的可发布投影:
visibility=public的事件可推送前端,internal/audit不出灵台。 - 中断(取消、网络失败、超时)写入
run.interrupted,芽体封存为残答,不伪装完成。
3.2 上下文投影
derive_context() 从事件日志 + 镜树状态 + 记忆状态投影出本次模型可见上下文,来源只有三类(镜树 PRD 不变量 6):
- 祖先路径:当前工作入口的问节-候答祖先链;
- 获准长期记忆:经息壤检索且通过敏感与权限过滤的明忆/重忆;
- 显式引文:用户建立的引文锚及其快照。
未采用旁枝默认不进入投影。投影结果写入 context.projected 事件(引用而非全文,可从日志重建),这是"模型可见即可重建"的落点。
4. 插件体系
4.1 插件契约
class Plugin(Protocol):
name: str # 稳定标识,登记于契约词典 pivot 枚举
version: str
def register(self, bus: EventBus, profile: Profile) -> None: ...
- 插件通过订阅瀑布节点与提供能力(工具、检索器、调节器、压缩器)参与运行。
- 插件之间不直接调用,只经事件总线与能力注册表交互。
- 插件加载顺序由 Profile 决定;同节点多个监听器按注册序执行,任一否决即中断并记录。
4.2 Profile(运行档案)
Profile 是一次 Run 的插件装配清单与参数包,来源于配置层叠:
flowchart LR
A[平台硬边界<br/>禁域与全局上限] --> E[最终 Profile]
B[平台目录<br/>默认插件与参数] --> E
C[用户偏好 / BYOK] --> E
D[人物覆写<br/>道体·人格·能力授契] --> E
F[镜树临时选择<br/>模型·火候·指引] --> E
层叠顺序与产品 PRD"神识配置继承"一致;镜树临时选择只作用于该节点及用户明确继承的后继。Profile 本身写入事件日志,保证可审计、可回放。
4.3 九枢落位
| 枢 | 插件职责 | 关键机制 |
|---|---|---|
| 灵核 | 人格调节:道体锚点 + 调节层参数注入 | 道体不可运行时覆盖;调节层按证据渐进演进,重大变化走铸魂流程 |
| 太一 | 目标:人物长期目标的维护与冲突检测 | 目标层级与状态见契约词典 |
| 司命 | 安全裁决:能力/数据/后果/情境四维 | 自省/循律/请命/禁域四级自主性;禁域挂载点在 Kernel |
| 烛照 | 观察与反思:对工具观察、用户反馈做理解候选 | 产出心痕候选与正影建议,不直接写状态 |
| 河图 | 世界认知:世界实体、世谱(Lorebook)激活 | 世谱激活管线见 §6.1 |
| 洛书 | 计划:多步任务的计划生成与跟踪 | 计划状态机见契约词典 |
| 息壤 | 记忆:三级记忆的写入候选、检索、注入 | 管线见 §6.2 |
| 百工 | 能力注册:工具/MCP/Skill/感官的唯一目录 | 每个 Run 只暴露最小获准 Schema |
| 天工阁 | 功能 Agent 编排:受托任务分解与并行 | 功能 Agent 无魂籍与身份;不构成第二意识 |
5. 提示词组装管线
采纳 SillyTavern PromptManager 的"实体化提示词 + 审计覆盖"模式:
- 每个注入片段是实体:
identifier / role / source / position / depth / order / forbid_override; source区分:系统契约、道体、人格调节、世界认知(河图)、记忆(息壤)、引文、用户指令、镜树对话;position:相对排序或绝对深度(atDepth 注入对话流内),depth从消息尾部计数;- 组装结果与每个片段的来源一起写入
context.projected事件,前端"可解释轨迹"直接读该事件; forbid_override=true的片段(系统契约、禁域声明)不可被人物层与镜树层覆盖,只可被平台更新替换。
6. 记忆注入与检索
6.1 微痕激活(借世界信息激活管线)
微痕与会谱条目共用激活管线:
- 时序效果:
sticky(激活后置顶 N 轮)、cooldown(冷却轮数)、delay(延迟轮数); - 关键词扫描:对最近 N 条消息做关键词/正则匹配(全字边界、大小写选项);
- 次级键逻辑:AND ANY / NOT ALL / NOT ANY / AND ALL;
- 递归扫描:已激活条目内容回流再扫描,限最大步数;
- 预算控制:激活条目按
order排序,超出 token 预算(上下文的百分比上限)从尾部淘汰; - 向量补充:预算内对未命中关键词的微痕做相似度召回。
激活结果作为 source=trace 的提示词实体进入组装管线。
6.2 长期记忆检索(明忆/重忆)
- 双路召回:pgvector 向量 + PG 全文检索,RRF 融合;
- 过滤:敏感等级、界域(境界记忆不进真界上下文)、撤回与删除状态、授权范围;
- 时间衰减与优先级加权:活力值
2^(−Δdays/半衰期),命中强化,重忆优先展示来源与版本; - 召回预算:条数与字符上限;
- 每次召回写入轻量审计(召回了什么、用于哪个 Run),支撑"召回透明"。
6.3 写入管线(归真后提取)
只有带 canonical_scope 的归真结果触发长期记忆提取(异步任务):
- 提取:单次 LLM 调用完成情境切分 + 记忆候选抽取;三原则:宁缺毋滥(滤闲聊与一次性指令)、独立完整(脱离对话仍成立)、归纳合并;输出
{content, type, priority, confidence, sensitive, source_message_ids}; - 双源标记:
user_explicit(用户明说)与self_inferred(人物推断); - 分级落位:白名单内低敏 → 明忆候选(自动生效 + 撤销窗);敏感或高影响 → 重忆候选(必须用户确认);类型含心痕(
relationship_view,主观非事实); - 去重合并:向量召回统一候选池 → 批量判定 store/skip/update/merge(跨类型合并、时间戳并集);
- 版本链:更新产生新版本指向旧版本,旧版停止普通召回(正影语义);
- 删除:墓碑只证明删除行为发生,不承载原文;主存储、索引、上下文、主动对话同步停止使用。
7. 压缩管线
长对话压缩是可插拔能力(息壤插件的子模块),非循环骨架:
- 触发:投影 token 超过窗口减预留阈值;
- 切点规则(pi 模型):从尾部保留近段消息累计到保留额度,向前寻找合法切点;工具结果永不作切点,工具调用与结果必须配对保留或一同进入压缩区;
- 分区摘要:旧摘要 + 新消息增量续写,分区为背景/事实/关系/未决事项/关键决定;
- 内容路由(headroom 思想):工具结果按内容类型分治——JSON/结构化裁剪、代码保关键段、纯文本摘要;对话历史走摘要压缩;
- 缓存友好:注入片段位置固定(固定 depth 注入点),前缀字节稳定,避免打爆 Provider KV 缓存;
- 可逆引用:被压缩掉的原文保留在事件日志,人物可经"回溯"能力按引用取回;
- 压缩边界事件(start/end)入日志,崩溃可检测(孤儿压缩标记)。
8. 并发与命台控制
sequenceDiagram
participant U1 as 设备 A
participant U2 as 设备 B
participant K as Kernel 命台控制
participant R as Run
U1->>K: 前台生成请求(树 1)
K->>R: 获得前台槽位,Run 启动
U2->>K: 前台生成请求(树 2)
K-->>U2: 排队(返回队列位置)
U1->>K: steer(运行中插话)
K->>R: 注入 steering 消息队列(下一 turn 生效)
U1->>K: 取消
K->>R: 取消 → 芽体封存残答 → run.interrupted
K->>R: 出队树 2 请求
- 前台槽位以人物为粒度,Redis 持锁(轻量档进程内锁),带租约与心跳;崩溃后租约到期自动释放,进行中的芽体标记中断。
- 后台受托 Run(天工阁)可并发,标记为功能任务,不进入前台槽位。
- steering 消息进入队列并在事件日志留痕,插话不静默(下一 turn 前端可见"已插话")。
9. 工具执行(百工 ↔ 乾坤)
tool.pre_execute:司命按四维裁决;请命级暂停等待用户确认(confirmations 表,超时即拒绝执行);- 获准后由执行器分派:HTTP 工具、MCP(博闻等)、乾坤沙箱(本地/代码执行)、内置工具;
tool.executed:结果先净化(敏感词/隐私脱敏)与标证(来源、时间、许可),作为观察写入事件日志;- 观察被接纳(
result.pre_accept)后才有资格形成记忆候选;任何插件不得把工具结果直接写成事实或人物答复。
10. 目录与代码组织
backend/app/
kernel/ # 极小硬核:不变量、命台、事件日志接口、循环骨架
runtime/ # 事件总线、Profile、插件加载、投影、压缩调度
pivots/ # 九枢插件实现(每枢一个包)
domains/ # 六域领域层(镜生/缘契/三界/形仪/灵台域/天宰)
infra/ # 复用基础设施:auth/RBAC/审计/事件存储/幂等/SSE
shenshi_client/ # 神识客户端边界(唯一模型出口)
api/ # v1 路由与 DTO
11. 测试策略
- 不变量测试:Kernel 不变量逐条有失败用例(重生成覆盖、旁枝入忆、归真回滚、并行前台、禁域绕过——全部必须被拒绝并留痕);
- 回放测试:随机抽样历史 Run,从事件日志重放投影,与当时
context.projected比对一致("模型可见即可重建"的验证); - 插件契约测试:每个插件用统一 harness 验证注册、订阅、否决语义;
- 管线性质测试:世谱激活(时序/递归/预算)、记忆提取(三原则)、压缩(切点配对、缓存前缀稳定)各有单元与性质测试;
- 端到端:创建→首聊→分叉→归真→记忆候选→确认→召回 的完整链路走 BFF 入口验证。