oh-my-muse/design-docs/架构-03-关键决策与原则(ADR).md
zizi 33aad93bef 提交全维度文档review后的22项架构决策落地
基于产品/架构/流程/前端/后端五维度并行review,澄清并落地22项关键决策:

架构层:Governance按消费者归属拆散、MetaSchema独立模块、
Source传播改为事件驱动自治、去掉Candidate Decision Envelope
和needs_recheck中间状态、Neo4j决策为依赖RAGFlow GraphRAG

后端层:Entitlement统一为可变表+审计日志、API版本策略采用
X-API-Version Header、知识实体唯一键加scope字段

前端层:SSE实时通信(AI stream独立+事件统一)、正文持久化
IndexedDB安全网、Block粒度为场景/小节级

产品层:范围不变UX解决复杂度、知识确认默认自动+冲突时人工
2026-05-24 04:28:52 +08:00

191 lines
20 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 架构-03:关键决策与原则(架构决策记录(ADR))
- 版本:v8
- 更新日期:2026-05-24
- 目标读者:架构/前端/后端/产品
- 阅读时间:30-45 分钟
- 边界说明:这里只收敛架构原则和 ADR;工程结构、表结构、接口、状态机分别归属 `后端-02`、`后端-04`、`后端-05` 和 `架构-04`。本文件描述目标架构决策,不代表当前代码都已实现。
## 1. 架构原则(可执行)
### 1.1 模块化单体优先,边界先于服务拆分
- 默认采用模块化单体:清晰边界、本地事务、低部署成本、可调试。
- 只有当痛点真实且可量化时才拆服务,例如 AI 能力独立扩展、团队边界稳定或外部依赖需要隔离。
- 即使拆外部服务,Muse 的业务事实源和用户确认边界仍必须回到 Muse。
### 1.2 管理员控制系统能力,普通用户控制作品事实
- 管理员(Admin)通过管理员控制台(Admin Console)治理系统模板、Prompt、Agent、全局知识和权限。
- 普通用户(User)通过用户工作区(User Workspace)写作、规划、确认知识和查看用量。
- 管理员不替用户做单个作品的创作取舍;普通用户不直接操作系统后台配置。
### 1.3 数据主权:待审层(Shadow)先行,规范数据(Canonical)后置
- 人工智能(AI)只产出待审层(Shadow),用户决定是否进入规范数据(Canonical)。
- 系统可以提示风险、冲突和参考来源,但不能替用户做不可逆决定。
- 来源快照(Source Snapshot)、归档层(Archive)和审计记录是用户可撤销、可追溯的基础。
### 1.4 数据结构优先,不按 UI 面板造模型
- 先定义模型边界、不变式和状态机,再设计页面流程。
- 作品规划台(Planning Desk)是产品入口,不是每个面板一张表。
- 规划能力应复用管理员治理的元结构定义(MetaSchema)、世界状态(World State)、叙事状态(Narrative State)、作品(Work)、章节(Chapter)和文本块(Block)边界。
## 2. ADR 索引
每条 架构决策记录(ADR)都必须包含:上下文(Context) / 决策(Decision) / 替代方案(Alternatives) / 后果(Consequences)。这里只保留决策要点,细节不要复制到各处。
### ADR-001:模块化单体 vs 微服务
- 上下文(Context):早期阶段、团队小、边界仍在探索,部署与调试成本必须低。
- 决策(Decision):采用模块化单体,内部通过模块边界、接口隔离和事件解耦维护职责。
- 替代方案(Alternatives):直接微服务化会放大部署、事务、观测和跨服务调试成本。
- 后果(Consequences):开发和事务更简单;代价是必须持续维护边界,不能把模块化单体写成大泥球。
- 参考落地:`后端-02-工程结构与模块职责.md`
### ADR-002:AI 能力通过外部 Agent 服务提供
- 上下文(Context):文本生成、实体提取、知识校验、规划和检索等能力需要快速演进,完全放在 Java 内部会限制生态和迭代速度。
- 决策(Decision):AI 能力通过受信任的外部 Agent 服务提供。Muse 后端负责权限、上下文组装、Agent 调用、结果消费和待审层(Shadow)写入。
- 替代方案(Alternatives):全部写入 Muse Java 进程会降低灵活性;让 Agent 服务直接写数据库会破坏事实源和权限边界。
- 后果(Consequences):AI 能力可独立演进;代价是新增服务信任边界,Agent 服务必须遵守同等安全和审计要求。
- 参考落地:`后端-03-关键流程实现与接口契约.md`
### ADR-003:动态属性采用 JSONB,而不是 EAV
- 上下文(Context):实体属性高度动态,但查询、变更追溯和投影仍必须可用。
- 决策(Decision):用 二进制 JSON(JSONB) 当前快照 + 属性级变更日志表达动态属性。
- 替代方案(Alternatives):实体属性值模型(EAV)会让查询和约束复杂度失控。
- 后果(Consequences):查询与演进成本更低;代价是更依赖数据库能力和索引策略。
- 参考落地:`后端-04-统一数据库Schema-v1.md`
### ADR-004:富文本编辑器选择以 Block 级自定义能力优先
- 上下文(Context):Muse 需要段落级文本块(Block),并携带 id、revision、状态、实体高亮和标注。
- 决策(Decision):选择支持结构定义(Schema)和节点扩展能力强的编辑器体系。
- 替代方案(Alternatives):纯 Markdown 或普通富文本编辑器难以承载块级冲突、候选合并和知识标注。
- 后果(Consequences):可实现强结构与扩展;代价是基础复杂度和学习成本更高。
- 参考落地:`前端-02-编辑器与影子层交互.md`
### ADR-005:向量检索采用 RAGFlow,替代 pgvector
- 上下文(Context):上下文组装需要文档管理、分块策略、混合检索和语义检索能力,简单向量相似度不足。
- 决策(Decision):使用 检索引擎(RAGFlow)作为语义检索基座,PostgreSQL 不保存 embedding 作为主检索方案。
- 替代方案(Alternatives):pgvector 方案部署简单,但检索能力不足;完全自建检索引擎成本过高。
- 后果(Consequences):检索质量与灵活性提升;代价是新增外部依赖,必须有降级和重建投影路径。
- 参考落地:`doc/dev/03-S1-RAGFlow集成与知识检索基座.md`
### ADR-006:图查询依赖 RAGFlow GraphRAG,不自建图存储(已决策)
- 上下文(Context):需要判断 RAGFlow GraphRAG 是否足以覆盖时间线、因果链、实体演变等查询。
- 决策(Decision):依赖 RAGFlow GraphRAG 提供图查询能力,不自建 Neo4j 或其他独立图存储。
- 替代方案(Alternatives):引入 Neo4j 会增加运维和同步复杂度;完全放弃图查询会削弱长篇一致性检查。
- 后果(Consequences):减少运维复杂度和外部依赖;代价是图查询能力受限于 RAGFlow GraphRAG 的演进节奏。如未来 RAGFlow GraphRAG 能力不足,可重新评估独立图存储方案。
- 参考落地:`doc/dev/03-S1-RAGFlow集成与知识检索基座.md`
### ADR-007:Block 使用 UUID
- 上下文(Context):文本块(Block)需要为离线、多端、复制粘贴、候选合并和未来协作预留空间。
- 决策(Decision):使用 唯一标识(UUID)作为 Block 的全局标识。
- 替代方案(Alternatives):自增 ID 更省空间,但客户端生成和离线合并能力更弱。
- 后果(Consequences):同步与合并更简单;代价是索引和存储上不如自增友好。
- 参考落地:`架构-02-核心数据结构与双轨模型.md`
### ADR-008:管理员控制台是独立系统入口
- 上下文(Context):新产品形态明确拆分管理员(Admin)和普通用户(User)。管理员负责系统能力治理,普通用户负责作品创作。
- 决策(Decision):管理员控制台(Admin Console)作为独立上层入口存在,承载模板、Prompt、Agent、全局知识库、访问策略、New-API 同步、任务治理、质量评估、用户与审计。
- 替代方案(Alternatives):把这些能力塞进普通用户作品工作台会暴露后台概念,破坏低认知负担,也会让权限边界难以验证。
- 后果(Consequences):前端信息架构、权限模型、审计视图必须分角色;管理员配置影响普通用户生成链路时必须通过可追溯配置快照生效。
- 参考落地:`架构-01-系统全貌与边界上下文.md`、`流程-02A-管理员系统处理流程(系统视角).md`、`流程-02B-普通用户系统处理流程(系统视角).md`
### ADR-009:模型网关 New-API 职责边界
- 上下文(Context):New-API 已负责模型供应商、模型路由、用户分组限流、成本策略和模型消耗日志。Muse 需要和自身用户、作品、授权和配额联动。
- 决策(Decision):New-API 继续负责模型供应商、路由、分组、限流、成本和消耗日志;Muse 只负责用户生命周期相关同步,以及必要的分组、配额、套餐和绑定状态调整入口。
- 替代方案(Alternatives):Muse 重复实现模型网关会扩大系统复杂度;完全不记录同步状态会让失败不可恢复。
- 后果(Consequences):New-API 同步必须幂等、可重试、可审计;Muse 的普通用户用量反馈和管理员审计可以引用同步结果,但不把 New-API 成本日志复制成新的权威来源。
- 参考落地:`流程-02A-管理员系统处理流程(系统视角).md`、`流程-02B-普通用户系统处理流程(系统视角).md`、`架构-04-状态机与约束清单.md`
### ADR-010:全局知识库与局域知识库分层
- 上下文(Context):管理员维护的写作方法、体裁规则、平台规范和公共资料,与单个作品沉淀的人物、关系、事件和叙事状态不是同一类资产。
- 决策(Decision):全局知识库(Global Knowledge Base)归管理员维护和授权;局域知识库(Local Knowledge Base)归单个作品自动维护。普通用户看到的是用户可见投影(User-visible Projection),不是系统内部完整知识。
- 替代方案(Alternatives):混成一个知识库会导致普通用户误改系统资料,也会让全局资料未经授权进入作品生成或检索。
- 后果(Consequences):生成、检索、导出和一致性检查必须标明来源;全局资料不自动进入作品正式知识,局域知识不跨作品共享正式事实。
- 参考落地:`架构-01-系统全貌与边界上下文.md`、`架构-02-核心数据结构与双轨模型.md`
### ADR-011:作品规划台复用已有模型边界
- 上下文(Context):作品规划台需要支持作品方向、作品结构、世界实体、事件时间线、角色弧光、剧情结构、章节叙事规划、张力节奏、叙事策略、文风与质量检查。
- 决策(Decision):这些规划维度映射到元结构定义(MetaSchema)、世界状态(World State)、叙事状态(Narrative State)、作品(Work)、章节(Chapter)和文本块(Block),不为每个 UI 面板新建孤立模型。
- 替代方案(Alternatives):按 UI 面板建模会形成重复事实源,导致规划、正文、知识和生成上下文互相打架。
- 后果(Consequences):前端可以按创作语言组织入口,但后端和架构文档必须保持模型归属;新增规划维度先判断落点,而不是先建表。
- 参考落地:`架构-02-核心数据结构与双轨模型.md`
### ADR-012:小说场景(Scene)暂不作为独立一级模型
- 上下文(Context):产品可以使用情节节拍、场景推进、章节目标等作者语言,但当前正式模型更稳定的骨架是作品、章节、文本块、世界状态和叙事状态。
- 决策(Decision):当前阶段不引入小说场景(Scene)作为独立一级模型,也不采用 `Outline / Scene` 作为并列一级模型。近程叙事控制归入章节叙事规划,并由 Chapter、Block 上下文和 Narrative State(chapter)承载。
- 替代方案(Alternatives):直接引入 Scene 会带来章节顺序、文本块归属、解析确认、导出和知识追溯的连锁改造;继续使用章节叙事规划可以先满足产品语言和生成约束。
- 后果(Consequences):所有文档可以写“情节节拍 / 场景推进”,但不能假定已有 Scene 表、Scene API 或 Scene 状态机。未来若需要独立模型,必须新增 ADR 并同步后端、前端和状态机。
- 参考落地:`架构-02-核心数据结构与双轨模型.md`
### ADR-013:Sa-Token 作为认证授权基座
- 上下文(Context):管理员控制台需要稳定的登录认证、角色权限、接口鉴权、会话与 Token 生命周期、当前用户上下文和基础审计上下文。现有自研 Bearer Token 能力已经能支撑局部 current user,但继续扩展会导致认证、权限和当前用户解析散落在多处。
- 决策(Decision):引入 Sa-Token 作为 Muse 的认证授权基座;现有自研 Bearer Token 能力逐步收敛为 Sa-Token 适配层。Sa-Token 负责 Authentication(登录认证)、RBAC(角色权限)、接口鉴权、会话、Token 生命周期、管理员接口保护、当前用户上下文和基础审计上下文。
- 替代方案(Alternatives):继续扩展自研 Token 会重复造轮子;引入 Yudao / RuoYi 完整后台系统会把通用平台能力带进 Muse,扩大边界并冲击现有产品架构。
- 后果(Consequences):Muse 需要补最小 RBAC 数据模型、默认超级管理员初始化、登录/登出/刷新/me API、前端登录状态管理和权限测试;但 Sa-Token 不决定作品正文、知识草稿或 AI 候选是否进入 Canonical(规范数据),这些仍由 Muse 的 Shadow -> Canonical 业务规则控制。系统任务必须用明确服务身份,不复用普通用户权限绕过确认。
- 更新说明(Update):阶段 7 已选择 yudao-cloud fork 作为后端工程基座时,关于“不引入 Yudao / RuoYi 完整后台系统”的实现取舍由 ADR-014 supersede;本 ADR 保留为认证授权边界的历史背景和 Sa-Token 约束。
- 参考落地:`后端-04-统一数据库Schema-v1.md`、`后端-05-统一API契约-v1.md`、`前端-01-工程结构与核心依赖.md`
### ADR-014:阶段 7 后端基座采用 yudao-cloud fork,但 Muse 领域 owner 不跟随 Yudao 模块
- 上下文(Context):阶段 7 需要承接后台工程结构、权限基座、代码生成、审计、任务和通用管理能力。yudao-cloud fork 可以降低基础设施成本,但其通用后台模块不等于 Muse 的产品领域边界。
- 决策(Decision):允许以 yudao-cloud fork 作为工程基座和过渡物理模块来源;Muse 的逻辑 owner、facade、状态机和写入边界仍以 `架构-01/02/04` 定义的 BC 为准。物理表或代码暂落 `yudao-module-ai`、`yudao-module-system`、Content 旧模块时,必须写明过渡映射,不能改变 MetaSchema、Agent、Handoff、Parse Job、Source / Authorization 的 authority。
- 替代方案(Alternatives):完全不用 yudao-cloud 会增加基础能力建设成本;反向让 Yudao/RuoYi 通用后台模型接管 Muse 领域,会制造普通后台表 owner 与 Muse 创作领域 owner 的冲突。
- 后果(Consequences):后端文档必须区分”物理模块落点”和”逻辑 owner”。MetaSchema 独立为 MetaSchema BC(见 ADR-016);Agent、Tool Grant、Runtime Permission Envelope 仍由 Agent authority 与 Security facade 控制;AI runtime 不得自授权;Market 只发起来源侧 handoff;Parse Job / Chapter Parse Result 归 AI Orchestration;Knowledge Draft 只在章节审阅确认后由 Knowledge 创建。
- Supersedes:仅 supersede ADR-013 中“避免引入 Yudao / RuoYi full backend”的工程基座取舍,不 supersede Sa-Token、Shadow -> Canonical 和系统任务服务身份约束。
### ADR-015:逻辑 owner 优先于物理表、代码模块和页面入口
- 上下文(Context):阶段 7 以后同一对象可能因为 yudao-cloud fork、旧模块兼容或读模型性能,被临时放在非目标模块;页面也会跨多个 BC 组合能力。
- 决策(Decision):Muse 以逻辑 owner 作为唯一写入 authority。物理表、代码包、worker、页面入口和读模型只能承载、投影或消费 owner 数据,不能反向获得写入权。
- 替代方案(Alternatives):按物理表所在模块决定 owner 会让 Content 接管 MetaSchema、AI runtime 自批 Tool Grant、Market 持有目标 Precheck、Personal Center 反写资产事实,最终形成多事实源。
- 后果(Consequences):所有跨 BC 写入必须走 owner facade。Source / Authorization 必须通过事件、快照和传播状态连接各 BC;来源状态变化不得自动改写 Canonical。后端阶段如采用过渡模块,必须在 Schema/API 文档中标注逻辑 owner、写入 facade、消费方和迁移路径。
### ADR-016:Governance 拆散——按消费者归属拆散,不保留 Governance 聚合模块
- 上下文(Context):原 Admin/Governance BC 聚合了 MetaSchema、保护节点、质量策略、市场治理等多种职责,消费者分散在不同模块。聚合导致模块边界模糊,变更影响面过大。
- 决策(Decision):按消费者归属拆散原 Governance 聚合模块:MetaSchema 独立为 MetaSchema BC;Protection Node 和 Quality Policy 归入 AI Orchestration BC(grant 包);市场治理(下架/召回/申诉)归入 Marketplace/Asset BC(admin 包)。Admin/Governance 只保留系统功能链路、开放槽位和系统 Prompt 等纯系统配置职责。
- 替代方案(Alternatives):保留 Governance 聚合模块会让不同消费者的变更耦合在一起,增加协调成本;完全打散到各消费者模块会丢失系统配置的统一治理入口。
- 后果(Consequences):MetaSchema 有独立演进节奏,admin 写入全局定义,用户可在作品级覆盖扩展字段,业务模块通过 facade-api 只读消费。AI 模块通过包级隔离(grant 包 + ArchUnit)管理 Protection Node 和 Quality Policy,grant 包只暴露给 admin-api 调用链路,runtime 包只读。市场治理由 Marketplace/Asset 的 admin 包承载,与市场资产生命周期紧密关联。
### ADR-017:Source 传播模式——事件驱动各模块自治,预留集中式演进
- 上下文(Context):来源状态变化(撤权、下架、召回、版本变化等)需要传播到候选、草稿、绑定、安装、运行任务、导出和个人中心等多个消费方。需要选择传播架构。
- 决策(Decision):采用事件驱动 + 各模块自治模式。来源 owner 发出 Source Status Event,各消费模块监听事件并自行处理反应逻辑(标记 disabled、作废未确认对象、失效凭证等)。不需要独立 source 模块。预留集中式 worker 演进路径。
- 替代方案(Alternatives):集中式 worker 统一处理所有传播目标,优点是传播逻辑集中可观测,缺点是 worker 需要了解所有消费方的业务语义,形成上帝模块。独立 source 模块会增加模块间调用复杂度。
- 后果(Consequences):各模块对来源变化的响应逻辑内聚在自身边界内,降低耦合。Source Snapshot 存储在独立 `source_snapshot` 表,各模块分散写入,DDL 放 infra 层统一管理。来源变化时各模块直接决策 active 或 disabled,不使用中间 needs_recheck 状态。未来如传播可观测性不足或一致性要求提高,可演进为集中式 worker + 事件溯源。
### ADR-018:Candidate Envelope 简化——去掉独立 Envelope 概念
- 上下文(Context):原设计中 Candidate Decision Envelope 封装了来源、权限、合规、质量和风险路由结果的决策快照,作为候选接受的硬闸门。实践中 Envelope 增加了概念复杂度和实现成本。
- 决策(Decision):去掉独立 Candidate Decision Envelope 概念。候选表直接记录创建时的来源版本(source version、authorization snapshot),接受时实时对比当前来源状态即可。质量门控、输出合规、静态检查等校验在接受时同步执行,不需要预先封装为独立 Envelope 对象。
- 替代方案(Alternatives):保留 Envelope 可以缓存决策结果避免重复计算,但增加了过期管理、版本匹配和重算逻辑的复杂度。
- 后果(Consequences):候选接受流程简化为:校验候选存在且未过期 -> 实时对比来源版本与当前状态 -> 执行质量/合规/静态检查 -> 写入正文。减少一个中间概念和对应的状态管理。代价是每次接受都需要实时校验,不能复用缓存的决策结果。
## 3. 本次是否需要新增 ADR 的结论
需要。双角色入口、New-API 职责边界、全局/局域知识库分层、作品规划台模型复用、小说场景(Scene)暂不升一级模型、Sa-Token 认证授权基座、yudao-cloud fork 工程基座、逻辑 owner 优先原则,都会影响跨文档边界和后续实现,因此已补 ADR-008 到 ADR-015。Governance 拆散、Source 传播模式选择、Candidate Envelope 简化和图查询依赖 RAGFlow GraphRAG 的决策已补 ADR-016 到 ADR-018 并更新 ADR-006。
## 4. 关联阅读
- 系统边界与 BC:`架构-01-系统全貌与边界上下文.md`
- 数据结构与模型规则:`架构-02-核心数据结构与双轨模型.md`
- 状态机与约束:`架构-04-状态机与约束清单.md`
- 管理员系统处理流程:`流程-02A-管理员系统处理流程(系统视角).md`
- 普通用户系统处理流程:`流程-02B-普通用户系统处理流程(系统视角).md`