# SPEC: 三元知识域架构 (Tri-Domain Knowledge Architecture) > **版本**: v1.0 > **前置依赖**: [SPEC_deepview_metadata_scoping_v3.md](./SPEC_deepview_metadata_scoping_v3.md) (Prosumer-First 沙箱隔离) > **设计哲学**: [DESIGN_PHILOSOPHY_AI_NATIVE.md](./DESIGN_PHILOSOPHY_AI_NATIVE.md) (AI-Native 产品心法) > **状态**: 草案 (Proposal) --- ## 1. 问题陈述 V3 SPEC 成功地将用户数据(客户档案、录音、个人风格)锁死在 `storage/users/{userId}/` 的物理沙箱内。但当前的 `storage/wiki/` 仍然是一个**无主的全局公域**——任何经过认证的用户上传的知识库文件,都会落入这个公有池,并被所有用户的 Agent 无差别读取。 在单机构运营阶段,这不构成安全问题。但本产品作为一款轻量级 SaaS 工具,**将很快遇到多家医疗机构同时使用的场景**。届时: | 风险 | 场景 | |------|------| | **知识污染** | A 机构的"报价策略.md"被 B 机构医生的 Agent 读取,导致 AI 输出了竞争对手的定价策略 | | **方法论冲突** | A 机构上传的"保守型话术规范"与 B 机构的"激进型破冰话术"同在一个池中,Agent 无法判断听谁的 | | **逆向泄密** | 医生在对话中追问"知识库里有什么内容",Agent 如实汇报,变相暴露了其他机构的核心商业资产 | **结论**:`wiki/` 需要从"一个桶"裂变为"三元域",否则沙箱隔离只做了一半。 --- ## 2. 三元域模型 (Tri-Domain Model) ### 2.1 架构总览 ``` storage/ ├── platform/ ← 🌐 Domain 1: 平台域 (Platform) │ └── wiki/ │ ├── system_instructions.md # 系统级行为约束 │ └── medical_ethics_baseline.md # 医疗合规底线 │ ├── orgs/ ← 🏢 Domain 2: 机构域 (Organization) │ ├── {orgId_A}/ │ │ └── wiki/ │ │ ├── rfm_rules.md # A机构的 RFM 客群规则 │ │ ├── pricing_2026.md # A机构的报价表 │ │ └── talk_track_v3.md # A机构的话术规范 │ │ │ └── {orgId_B}/ │ └── wiki/ │ └── ... # B机构的独立知识库 │ └── users/ ← 👤 Domain 3: 个人域 (User) └── {userId}/ ├── clients/ # 私有客户档案 (V3 已实现) ├── inbox/ # 未归档录音 (V3 已实现) └── doctor_profile.md # 个人风格画像 (V3 已实现) ``` ### 2.2 三元域的职责定义 | 域 | 物理路径 | 写入权限 | 读取权限 | 内容特征 | |----|---------|---------|---------|---------| | **平台域** `platform/wiki/` | 仅运维/开发者 | 所有用户(只读) | 通用底线:医疗合规、AI 行为红线、系统级兜底 Prompt | | **机构域** `orgs/{orgId}/wiki/` | 机构管理员 | 该机构下所有用户 | 企业差异化资产:RFM 规则、定价表、话术方法论、培训心法 | | **个人域** `users/{userId}/` | 用户本人 | 仅用户本人 | 私有工作数据:客户、录音、个人风格、Inbox | ### 2.3 上下文注入优先级 当 Agent 构建 System Prompt 时,三元域按**由近及远**的优先级叠加注入: ``` [优先级 1] 个人域 → doctor_profile.md, 当前客户 profile.md [优先级 2] 机构域 → orgs/{orgId}/wiki/* [优先级 3] 平台域 → platform/wiki/* ``` **冲突解决原则**:近域覆盖远域。如果个人域的 `doctor_profile.md` 声明了"我不使用激进话术",即使机构域的 `talk_track_v3.md` 中含有激进话术范例,Agent 应优先遵从个人偏好。 --- ## 3. 用户与机构的关系模型 ### 3.1 Prosumer 生命周期 ``` ┌──────────────────────────────────────────────────────────────┐ │ Phase 1: 自由人 (Freelancer) │ │ ─ 注册即可用,无需任何机构归属 │ │ ─ Agent 读取: platform/wiki/* + users/{userId}/* │ │ ─ orgs 层级对该用户透明(不存在) │ ├──────────────────────────────────────────────────────────────┤ │ Phase 2: 受邀加入机构 (Org Member) │ │ ─ 机构管理员发出邀请码,用户确认加入后绑定 orgId │ │ ─ Agent 读取: platform/* + orgs/{orgId}/* + users/{userId}/* │ │ ─ 个人域数据对机构管理员不可见(除非显式授权移交) │ ├──────────────────────────────────────────────────────────────┤ │ Phase 3: 授权联邦 (Federation) [远期预留] │ │ ─ 医生主动授权特定客户档案向机构汇报系统开放 │ │ ─ 机构管理层获得聚合视图(只读),不触碰个人原始录音 │ └──────────────────────────────────────────────────────────────┘ ``` ### 3.2 数据流向的不可逆栅栏 - **上行不可逆**:个人域数据只有经用户显式确认后,才可拷贝(非移动)至机构域的聚合报告。机构管理员永远不可直接遍历 `users/{userId}/` 目录。 - **下行只读注入**:机构域和平台域对个人域的影响仅限于"知识注入"(Agent Prompt 中追加上下文)。任何域都不能向个人域写入文件。 - **跨机构绝对隔离**:`orgs/{orgId_A}/` 与 `orgs/{orgId_B}/` 之间零交集。一个用户同时隶属两家机构时,Agent 只加载当前活跃会话所选的机构上下文。 --- ## 4. 现有 `wiki/` 的迁移路径 当前 `storage/wiki/gemini_rfm_rules.md` 实质上是某一家机构的商业方法论,不应继续驻留在全局公域。 ### 4.1 迁移策略(渐进式) | 阶段 | 动作 | 影响 | |------|------|------| | **Phase 0 (当前)** | `storage/wiki/` 保持原址不动 | 继续服务单机构运营,无破坏性 | | **Phase 1 (首次多机构)** | 引入 `storage/platform/wiki/` 存放通用底线;将 `storage/wiki/` 整体 rename 为 `storage/orgs/{首个orgId}/wiki/` | 一次性 rename,后端路径切换 | | **Phase 2 (稳态)** | 新机构入驻时,由运维在 `storage/orgs/{newOrgId}/wiki/` 下初始化空目录 | 零干扰,增量部署 | ### 4.2 后端改动影响面预估 需改动的位置与 V3 沙箱重构完全同构,核心变量仅从 `storageDir + "/wiki"` 变为 `storageDir + "/orgs/" + orgId + "/wiki"`: | 文件 | 函数 | 变更内容 | |------|------|---------| | `deepview_sse.py` | `_handleChat` | Prompt 中 wiki 路径追加 orgId | | `deepview_sse.py` | `_handleReportGenerate` | 同上 | | `deepview_materials.py` | `process_uploaded_material_oss` | `wiki:` 上下文路由至 `orgs/{orgId}/wiki/` | | `deepview_sse.py` | `_handleMaterialsList` | 列表查询时过滤至当前用户 orgId | ### 4.3 前端改动 - 零改动(与 V3 一致)。orgId 通过 JWT Token 中的 claim(如 `org` 字段)透传,前端感知不到域的存在。 --- ## 5. 安全边界与防御策略 ### 5.1 物理隔离防线 ```python # 防路径穿越攻击:所有用户可控的 path 片段必须经过白名单校验 def _sanitizePath(segment: str) -> str: """只允许字母数字下划线连字符,严禁 .. / \\ 等""" import re if not re.match(r'^[a-zA-Z0-9_\-]+$', segment): raise ValueError(f"Invalid path segment: {segment}") return segment ``` ### 5.2 Agent 工具权限矩阵 | Agent 工具 | 平台域 | 机构域 (本org) | 机构域 (他org) | 个人域 (本人) | 个人域 (他人) | |-----------|--------|--------------|--------------|-------------|-------------| | `file_read` | ✅ | ✅ | ❌ | ✅ | ❌ | | `file_write` | ❌ | ❌ | ❌ | ✅ | ❌ | | `file_list` | ✅ | ✅ | ❌ | ✅ | ❌ | ### 5.3 审计日志(远期) 对 `orgs/{orgId}/wiki/` 目录的任何写入操作,应记录 `(timestamp, userId, action, filePath)` 至审计表,支持机构管理员追溯"谁在什么时候传了什么"。 --- ## 6. 与 V3 SPEC 的关系 本 SPEC 是 V3 的**正统延伸**,不是替代。二者的关系为: - **V3 SPEC** 解决了"个人域"的物理隔离问题(`users/{userId}/`) - **本 SPEC** 在 V3 之上,向外延伸了"机构域"(`orgs/{orgId}/`)和"平台域"(`platform/`),形成完整的三元安全边界 三者合并后的**完整隔离模型**: ``` ┌─────────────────────────────────────────────┐ │ Platform Domain (只读注入, 运维独占写) │ │ ┌─────────────────────────────────────────┐ │ │ │ Org Domain (机构管理员写, 成员只读) │ │ │ │ ┌─────────────────────────────────────┐ │ │ │ │ │ User Domain (用户独占读写) │ │ │ │ │ │ ┌──────────────────────┐ │ │ │ │ │ │ │ Client Data (归档后) │ │ │ │ │ │ │ └──────────────────────┘ │ │ │ │ │ │ ┌──────────────────────┐ │ │ │ │ │ │ │ Inbox (裸推演态) │ │ │ │ │ │ │ └──────────────────────┘ │ │ │ │ │ └─────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────┘ │ └─────────────────────────────────────────────┘ ``` --- > *本规范为深维医生助理三元知识域架构草案,经审阅确认后,将指导后续的机构域隔离实现。*