docs: add architecture, workflow and delivery documents
This commit is contained in:
+780
@@ -0,0 +1,780 @@
|
||||
# 雅文内容创造工作台 · 核心逻辑设计文档 v6
|
||||
|
||||
> 文档日期:2026-08-26
|
||||
> 关联文档:[设计文档 v5](./设计文档v5-系统设计.md)、[设计文档 v6:用户端、管理端与云化设计](./设计文档v6-用户端管理端云化与计费设计.md)
|
||||
> 从零落地:[核心逻辑设计文档 v6:从 0 到 1](./核心逻辑设计文档v6-从0到1.md)
|
||||
> 文档用途:说明系统如何运行、数据如何流转、权限如何隔离,以及 v6 多用户云化能力如何接入现有 Runtime
|
||||
> 说明:本文件是逻辑设计文档;其中“当前实现”对应现有源码,“v6 目标”对应 v6 设计,不能把规划功能当作已上线功能
|
||||
|
||||
## 0. 一句话理解系统
|
||||
|
||||
雅文内容创造工作台是一个以 **任务为中心、Agent 为执行单元、知识库为事实来源、记忆库为经验来源、模型目录为受控能力、Trace 为审计链路** 的内容生产系统。
|
||||
|
||||
完整逻辑可以概括为:
|
||||
|
||||
```text
|
||||
用户请求
|
||||
→ 权限和配额校验
|
||||
→ 冻结任务配置
|
||||
→ Agent 画布拓扑调度
|
||||
→ 只检索允许使用的知识与记忆
|
||||
→ Agent Runtime 生成内容
|
||||
→ QC 质检
|
||||
→ 人工审查
|
||||
→ 组合 Agent 统一成稿
|
||||
→ 云存储交付
|
||||
→ 用量计量、账单和 Trace 归档
|
||||
```
|
||||
|
||||
## 1. 核心原则
|
||||
|
||||
### 1.1 数据归属优先
|
||||
|
||||
任何资源都先确定归属,再决定谁能看、谁能用、谁能改:
|
||||
|
||||
```text
|
||||
organization_id
|
||||
→ owner_user_id
|
||||
→ resource_type + resource_id
|
||||
→ visibility / grant / permission
|
||||
```
|
||||
|
||||
用户、Agent、任务、知识库、记忆、模型选择、Trace、产物和账单都必须绑定组织与用户。没有归属键的数据不能进入生产链路。
|
||||
|
||||
### 1.2 配置先冻结,运行后复现
|
||||
|
||||
任务开始前冻结:
|
||||
|
||||
- 画布节点和连线。
|
||||
- Agent 规则、规则版本和规则哈希。
|
||||
- Agent 挂接的技能、知识库和记忆。
|
||||
- Provider、模型、模型能力标签和费率版本。
|
||||
- 内容段、上游锚点和任务参数。
|
||||
|
||||
任务运行过程中修改管理端配置,只影响后续新任务;当前任务始终使用自己的快照。
|
||||
|
||||
### 1.3 知识与记忆不能越权
|
||||
|
||||
检索服务必须先计算用户可访问的资源集合,再执行向量检索:
|
||||
|
||||
```text
|
||||
allowed_kb_ids
|
||||
= owned_kb_ids
|
||||
∪ granted_kb_ids
|
||||
∪ global_kb_ids
|
||||
|
||||
allowed_memory_ids
|
||||
= owned_memory_ids
|
||||
∪ granted_memory_ids
|
||||
∪ global_memory_ids
|
||||
```
|
||||
|
||||
不能先搜索全库再由前端过滤。Agent 只能使用任务快照中允许的知识库和记忆。
|
||||
|
||||
### 1.4 事实必须可追溯
|
||||
|
||||
每个知识片段、模型调用、工具调用、质检结果和最终产物,都要能回溯到:
|
||||
|
||||
```text
|
||||
组织 → 用户 → 任务 → Run → Trace → Segment / Agent → 资源或模型
|
||||
```
|
||||
|
||||
没有来源的事实不能标记为已验证内容;没有 Trace 的模型调用不能计入已完成任务。
|
||||
|
||||
### 1.5 失败必须显式化
|
||||
|
||||
失败不等于空结果,等待不等于成功,Provider 返回 200 也不等于内容有效。系统必须区分:
|
||||
|
||||
- Provider 错误、网关拦截、模型拒绝、超时、限流。
|
||||
- RAG 无命中、索引损坏、文件解析失败。
|
||||
- Agent 输出为空、格式错误、护栏失败。
|
||||
- QC FAIL、人工打回、组合总检失败。
|
||||
- 云对象上传失败、导出失败、账单计量失败。
|
||||
|
||||
## 2. 参与者和职责
|
||||
|
||||
| 参与者 | 核心职责 | 不负责的事情 |
|
||||
| --- | --- | --- |
|
||||
| 用户端 | 创建任务、选择已开放模型、使用自己的资源和获授权资源 | 不能接 Provider、不能改费率、不能越权读私有资源 |
|
||||
| 管理端 | 管理用户、Provider、模型目录、知识库授权、记忆授权、配额、计费和导出 | 不绕过审计直接改历史账单 |
|
||||
| Coordinator Agent | 把导图拆成可执行内容段、分配标签和时间范围 | 不直接生成最终长稿 |
|
||||
| Production Agent | 根据任务段、规则、技能、知识和记忆生成内容 | 不使用未挂接资源,不补写无来源事实 |
|
||||
| QC Agent | 按固定检查项审查结构、内容、风格和跨段一致性 | 不替用户默默修改并伪装为通过 |
|
||||
| Composer Agent | 组合已人工通过的段落,执行全文一致性检查 | 不组合未通过或被跳过的段落 |
|
||||
| Agent Runtime | 维护会话、工具、审批、护栏、恢复和 Trace | 不替业务层决定资源权限 |
|
||||
| RAG 服务 | 解析、分块、向量化、检索、引用和消费锁定 | 不决定用户是否有权访问库 |
|
||||
| 计量服务 | 记录 LLM、Embedding、OCR、存储和导出用量 | 不修改原始调用事实 |
|
||||
|
||||
## 3. 核心对象关系
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
ORGANIZATION ||--o{ USER_ACCOUNT : contains
|
||||
USER_ACCOUNT ||--o{ AGENT : owns
|
||||
USER_ACCOUNT ||--o{ KNOWLEDGE_BASE : owns
|
||||
USER_ACCOUNT ||--o{ MEMORY : owns
|
||||
KNOWLEDGE_BASE ||--o{ KNOWLEDGE_FILE : contains
|
||||
KNOWLEDGE_BASE ||--o{ KNOWLEDGE_BASE_GRANT : shares
|
||||
MEMORY ||--o{ MEMORY_GRANT : shares
|
||||
MODEL_PROVIDER ||--o{ MODEL_CATALOG : exposes
|
||||
MODEL_CATALOG ||--o{ MODEL_ORGANIZATION_GRANT : opens
|
||||
AGENT ||--o{ AGENT_SKILL_BINDING : uses
|
||||
AGENT ||--o{ AGENT_KB_BINDING : uses
|
||||
CAMPAIGN ||--o{ CAMPAIGN_RUN : executes
|
||||
CAMPAIGN ||--o{ SEGMENT : contains
|
||||
CAMPAIGN_RUN ||--o{ AGENT_SESSION : starts
|
||||
CAMPAIGN_RUN ||--o{ RUN_EVENT : emits
|
||||
CAMPAIGN_RUN ||--o{ LLM_CALL : records
|
||||
SEGMENT ||--o{ QC_REPORT : checks
|
||||
CAMPAIGN ||--o{ ARTIFACT : produces
|
||||
LLM_CALL ||--o{ USAGE_EVENT : meters
|
||||
```
|
||||
|
||||
## 4. 任务核心逻辑
|
||||
|
||||
### 4.1 任务创建
|
||||
|
||||
任务创建只保存输入和初始选择,不立即调用模型:
|
||||
|
||||
1. 用户填写任务名称、导图或主题。
|
||||
2. 服务端确认用户属于有效组织,且有创建任务权限。
|
||||
3. 用户选择画布;服务端读取画布节点、连线和启停状态。
|
||||
4. 服务端校验 Agent、技能、知识库和模型目录引用。
|
||||
5. 任务进入 `draft`。
|
||||
|
||||
如果用户选择的模型被停用、Provider 已失效、知识库授权已撤销或 Agent 缺少必需知识库,任务创建应返回明确错误,而不是等到模型调用时才失败。
|
||||
|
||||
### 4.2 导图解析
|
||||
|
||||
解析由 Coordinator Agent 完成:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[导图/主题输入] --> B[输入护栏]
|
||||
B --> C[Coordinator Runtime]
|
||||
C --> D[识别内容节点]
|
||||
D --> E[绑定内容标签]
|
||||
E --> F[生成时间范围和任务目标]
|
||||
F --> G[识别产品/下一段/钩子]
|
||||
G --> H[标记不确定项]
|
||||
H --> I[生成 Segment 任务单]
|
||||
```
|
||||
|
||||
Coordinator 必须遵守:
|
||||
|
||||
- 不补写导图没有提供的产品、日期、人物或事实。
|
||||
- 一个 Segment 只承担一个清楚的内容目标。
|
||||
- 每个 Segment 必须有标题、内容标签、时间范围、导图原文和目标 Agent。
|
||||
- 不确定信息写入 `pending_confirms`,不能猜测后直接进入生产。
|
||||
|
||||
### 4.3 运行快照
|
||||
|
||||
创建 Run 时冻结完整配置:
|
||||
|
||||
```text
|
||||
CampaignRun.config_snapshot
|
||||
├── organization / user
|
||||
├── canvas
|
||||
├── segments[]
|
||||
│ └── primary Agent snapshot
|
||||
├── stages
|
||||
│ ├── coordinator
|
||||
│ ├── qc.structure
|
||||
│ ├── qc.content
|
||||
│ ├── qc.style
|
||||
│ ├── qc.cross
|
||||
│ └── composer
|
||||
├── model catalog/version/price
|
||||
└── memory and knowledge access snapshot
|
||||
```
|
||||
|
||||
快照写入后,任务只引用快照,不重新读取用户当前编辑中的规则。这样可以保证审查结果和最终成稿对应同一组配置。
|
||||
|
||||
### 4.4 Run 状态机
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> queued
|
||||
queued --> running
|
||||
running --> awaiting_review
|
||||
running --> failed
|
||||
running --> cancelled
|
||||
awaiting_review --> running: 人工继续/打回重跑
|
||||
awaiting_review --> completed: 所有段已通过并完成组合
|
||||
failed --> queued: 修复后重试
|
||||
cancelled --> queued: 管理员重新排队
|
||||
completed --> [*]
|
||||
```
|
||||
|
||||
同一 Campaign 只能有一个 `queued` 或 `running` 的活跃 Run。Run 取消、失败和恢复都保留原 Trace,不覆盖历史记录。
|
||||
|
||||
## 5. Agent 画布与调度逻辑
|
||||
|
||||
### 5.1 图结构
|
||||
|
||||
- 节点是画布上的执行实例,不是 Agent 定义本身。
|
||||
- `node_id` 标识画布节点,`agent_id` 指向 Agent 定义。
|
||||
- 同一个 Agent 可以放在多个节点上,形成并行或串行的多个实例。
|
||||
- 边 `from_node → to_node` 表示下游读取上游锚点卡。
|
||||
- 未连线的节点不共享上下文。
|
||||
|
||||
### 5.2 波次调度
|
||||
|
||||
服务端对画布执行拓扑排序:
|
||||
|
||||
1. 找到入度为 0 的节点作为第一波。
|
||||
2. 第一波完成后,把其出边节点的入度减一。
|
||||
3. 入度归零的节点进入下一波。
|
||||
4. 同一波次节点并行执行。
|
||||
5. 检测到环时拒绝运行,并提示具体环路。
|
||||
|
||||
节点停用时不会调用模型,下游收到 `skipped` 锚点。停用产品销售节点时,组合器必须知道“本场无产品”,不能自动补一个产品段。
|
||||
|
||||
### 5.3 融合 Agent
|
||||
|
||||
融合 Agent 用于把多个写法合成为一个自然段:
|
||||
|
||||
```text
|
||||
主 Agent 任务
|
||||
├── 心法写法 Agent
|
||||
├── 钩子写法 Agent
|
||||
└── 场景表达 Agent
|
||||
↓
|
||||
融合结果:一个自然口语段 + 一个结构化锚点卡
|
||||
```
|
||||
|
||||
融合时只传递结构化任务、允许的知识引用和上游锚点,不把各 Agent 的内部推理互相暴露。最终文本遵守统一的“大白话、自然口语、默认一段到底”样式,避免拼贴感。
|
||||
|
||||
## 6. Agent Runtime 核心逻辑
|
||||
|
||||
### 6.1 会话循环
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant O as 业务编排器
|
||||
participant R as Agent Runtime
|
||||
participant S as AgentSession
|
||||
participant M as Model Provider
|
||||
participant T as Tool
|
||||
participant E as RunEvent/LLMCall
|
||||
|
||||
O->>R: run_agent(task, snapshot, tools)
|
||||
R->>S: 创建或恢复会话
|
||||
R->>E: runtime_started + input_guardrail
|
||||
R->>M: 发送当前消息和工具定义
|
||||
M-->>R: 文本或 tool_calls
|
||||
R->>E: model_started/model_finished
|
||||
alt 工具调用
|
||||
R->>T: 校验参数并执行
|
||||
T-->>R: 工具结果
|
||||
R->>E: tool_started/tool_finished
|
||||
R->>S: 写入 tool 消息
|
||||
R->>M: 继续下一轮
|
||||
else 最终文本
|
||||
R->>E: output_guardrail
|
||||
R->>S: 写入完成结果
|
||||
R-->>O: completed/failed
|
||||
end
|
||||
```
|
||||
|
||||
### 6.2 会话恢复
|
||||
|
||||
`AgentSession` 保存消息、轮次、工具状态、审批状态、结果和错误。恢复时:
|
||||
|
||||
- 复用 `running`、`interrupted` 或 `waiting_approval` 会话。
|
||||
- 不重复执行已完成工具调用。
|
||||
- `pending_tool` 有审批决定后,先回放批准/拒绝结果,再继续模型循环。
|
||||
- 服务启动时把中断会话标记为可恢复,并归还未完成的知识片段预留。
|
||||
|
||||
### 6.3 工具审批
|
||||
|
||||
需要人工确认的工具调用进入 `waiting_approval`,不会因为接口返回成功就直接执行。审批动作必须记录:
|
||||
|
||||
```text
|
||||
requester session → pending_tool → approver user → decision → tool result
|
||||
```
|
||||
|
||||
工具批准接口只允许具有审查或管理权限的角色调用;工具本身还要在当前阶段的注册表中存在。
|
||||
|
||||
### 6.4 护栏和输出契约
|
||||
|
||||
Runtime 负责通用护栏,业务 Agent 负责领域契约:
|
||||
|
||||
| 层级 | 检查内容 |
|
||||
| --- | --- |
|
||||
| Runtime 输入 | 非空、长度上限、系统规则优先 |
|
||||
| Runtime 工具 | 工具是否注册、参数是否为合法 JSON |
|
||||
| Runtime 输出 | 非空、长度上限、文本可保存 |
|
||||
| Coordinator | Segment 字段完整、未知信息待确认 |
|
||||
| Production | 正文、引用、锚点卡完整 |
|
||||
| QC | 检查项必须带状态和问题说明 |
|
||||
| Composer | 只组合人工通过内容段 |
|
||||
|
||||
## 7. 知识库核心逻辑
|
||||
|
||||
### 7.1 建库管道
|
||||
|
||||
```text
|
||||
上传文件
|
||||
→ 计算内容哈希
|
||||
→ 写入云对象/本地源目录
|
||||
→ 解析格式
|
||||
→ 清洗文本
|
||||
→ 语义分块
|
||||
→ Embedding
|
||||
→ 写入向量索引
|
||||
→ 写入文件分类和版本
|
||||
→ 标记 ready
|
||||
```
|
||||
|
||||
支持 `.docx`、`.srt`、`.md`、`.txt`、`.json`、`.jsonl`。文件更新时先删除同名文件旧向量,再写入新版本,避免重复命中。
|
||||
|
||||
### 7.2 分类逻辑
|
||||
|
||||
分类分为 AI 建议和人工确认:
|
||||
|
||||
```text
|
||||
unclassified
|
||||
→ AI 分类任务
|
||||
→ ai_suggested
|
||||
→ 人工确认/修改
|
||||
→ human_confirmed
|
||||
```
|
||||
|
||||
分类树使用 `parent_id` 支持无限层级。文件保存 `category_id`、AI 建议分类、置信度、原因、内容哈希和修订号。移动文件分类只修改归属元数据,并在下一次增量索引时更新向量元数据中的完整分类路径。
|
||||
|
||||
### 7.3 检索与引用
|
||||
|
||||
Agent 生成前构造检索请求:
|
||||
|
||||
```text
|
||||
任务段目标
|
||||
+ 上游锚点卡
|
||||
+ Agent 规则里的检索意图
|
||||
+ 当前用户允许的知识库 ID
|
||||
+ 当前 Agent 已消费 chunk 排除集合
|
||||
```
|
||||
|
||||
检索结果必须带:知识库、文件、分类路径、chunk ID、原文、相似度、文件哈希和修订号。引用写入 `Segment.references`,并进入 QC 对证。
|
||||
|
||||
### 7.4 知识消费锁定
|
||||
|
||||
消费锁是 Agent 级别,不是全局锁:
|
||||
|
||||
```text
|
||||
Agent A 消费 chunk-001 → A 后续不可重复使用
|
||||
Agent B 未消费 chunk-001 → B 仍可使用
|
||||
```
|
||||
|
||||
状态流转:
|
||||
|
||||
```text
|
||||
available → reserved → consumed
|
||||
reserved → available(任务中断/模型失败)
|
||||
consumed → available(管理员人工释放)
|
||||
```
|
||||
|
||||
数据库对 `(agent_id, kb_id, chunk_id)` 建唯一约束,防止同一个 Agent 并发重复认领同一片段。
|
||||
|
||||
### 7.5 重建和回滚
|
||||
|
||||
重建必须遵循:
|
||||
|
||||
1. 读取当前索引快照。
|
||||
2. 标记 `indexing`。
|
||||
3. 按文件处理并记录进度。
|
||||
4. 所有文件成功后写入 `ready`。
|
||||
5. 任意文件失败时恢复旧快照和旧计数。
|
||||
|
||||
Chroma 不稳定时使用本地原子 JSON 向量文件作为检索兜底。KB3 当前基线为 73 个文件、2,717 个分块、512 维向量,数据库和独立进程读取结果一致。
|
||||
|
||||
## 8. 记忆库核心逻辑
|
||||
|
||||
### 8.1 记忆来源
|
||||
|
||||
记忆不是模型自动写入的隐式状态,而是可审查资源:
|
||||
|
||||
```text
|
||||
任务失败/人工修改/QC意见
|
||||
→ PendingMemory
|
||||
→ 人工确认
|
||||
→ Memory
|
||||
→ 绑定来源 Agent 和版本
|
||||
```
|
||||
|
||||
未确认记忆不能进入生产 Agent 的有效记忆上下文。
|
||||
|
||||
### 8.2 记忆与知识库同构
|
||||
|
||||
记忆库完全复用知识库的资源模型:
|
||||
|
||||
| 范围 | 默认使用者 | 修改者 |
|
||||
| --- | --- | --- |
|
||||
| `private` | 所有者及其 Agent | 所有者 |
|
||||
| `shared` | 被授权用户 | 所有者和管理员 |
|
||||
| `global` | 当前组织全部用户 | 管理员 |
|
||||
|
||||
管理员可以查看、导出、授权、撤销、发布全局和恢复私有。用户只能看到自己的私有记忆、获授权记忆和全局记忆。
|
||||
|
||||
### 8.3 记忆注入
|
||||
|
||||
Agent Runtime 注入记忆前执行:
|
||||
|
||||
1. 校验任务用户和组织。
|
||||
2. 计算允许读取的记忆 ID。
|
||||
3. 按来源 Agent、版本和状态筛选。
|
||||
4. 将记忆作为“已授权数据”注入,不允许记忆内容覆盖 Runtime 系统规则。
|
||||
5. 将使用的记忆版本写入任务快照。
|
||||
|
||||
撤销授权只影响新任务;已创建任务仍使用创建时的记忆快照。
|
||||
|
||||
## 9. 模型核心逻辑
|
||||
|
||||
### 9.1 管理端模型目录
|
||||
|
||||
模型使用链路为:
|
||||
|
||||
```text
|
||||
管理端接入 Provider
|
||||
→ 发现模型
|
||||
→ 规范化为 ModelCatalog
|
||||
→ 设置能力、可见性、费率和启用状态
|
||||
→ 按组织开放
|
||||
→ 用户端只读选择
|
||||
```
|
||||
|
||||
用户端不能新增 Provider、查看 API Key、修改 Base URL、发现模型、修改费率或输入任意模型名称。
|
||||
|
||||
### 9.2 模型选择和快照
|
||||
|
||||
用户选择 `model_catalog_id`,服务端校验:
|
||||
|
||||
- 模型目录存在且启用。
|
||||
- Provider 存在且启用。
|
||||
- 模型对当前组织可见。
|
||||
- 模型能力满足任务要求。
|
||||
- 当前用户和组织未超出配额。
|
||||
|
||||
通过后把 Provider、真实模型名、能力标签和费率版本写入 Run 快照。模型目录停用不会改变历史任务。
|
||||
|
||||
### 9.3 成人内容能力测试
|
||||
|
||||
“破限”在系统中落地为管理端模型能力兼容性测试,而不是用户自行上传提示词:
|
||||
|
||||
```text
|
||||
ModelCatalog
|
||||
+ adult-content-compat-v1
|
||||
+ 固定样例集
|
||||
+ Provider/网关路径
|
||||
+ 输出断言
|
||||
+ 通过率/拒绝率/超时率/费用
|
||||
→ 发布能力标签
|
||||
```
|
||||
|
||||
结果必须区分 `provider_blocked`、`gateway_blocked`、`model_refused`、`timeout`、`format_failed`、`supported` 和 `partial`。模型更新、Provider 路由变化、系统提示词变化或审查配置变化时重新回归。
|
||||
|
||||
## 10. 用户端与管理端逻辑
|
||||
|
||||
### 10.1 用户端闭环
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
L[登录] --> H[读取组织/角色/配额]
|
||||
H --> R[读取可用资源]
|
||||
R --> M[选择模型目录]
|
||||
M --> C[创建任务]
|
||||
C --> P[解析导图]
|
||||
P --> G[运行 Agent]
|
||||
G --> Q[查看 QC]
|
||||
Q --> V[人工审查]
|
||||
V --> O[组合和下载]
|
||||
O --> U[查看用量/账单]
|
||||
```
|
||||
|
||||
用户端所有写操作都带当前用户身份,所有资源查询都经过归属过滤。模型选择器只显示管理端开放的模型;知识库和记忆库按“我的/已授权/全局”分组。
|
||||
|
||||
### 10.2 管理端闭环
|
||||
|
||||
```text
|
||||
用户管理
|
||||
→ 组织/角色/配额
|
||||
→ Provider 和模型目录
|
||||
→ 成人内容能力测试
|
||||
→ 知识库/记忆授权
|
||||
→ 用量和账单
|
||||
→ 云存储和导出
|
||||
→ 审计复盘
|
||||
```
|
||||
|
||||
管理端可以查看其他用户的私有知识库和记忆,但查看、下载、导出、授权、撤销和删除都必须写入审计。
|
||||
|
||||
## 11. 认证、RBAC 与授权判断
|
||||
|
||||
### 11.1 认证流程
|
||||
|
||||
```text
|
||||
请求
|
||||
→ 读取 Bearer Token
|
||||
→ SHA-256 查找 AuthSession
|
||||
→ 检查撤销/过期
|
||||
→ 检查 AppUser 启用状态
|
||||
→ 写入 last_seen_at
|
||||
→ 得到 user_id / organization_id / role
|
||||
```
|
||||
|
||||
密码使用 PBKDF2-SHA256 派生摘要;数据库不保存明文密码,也不保存明文 Session Token。
|
||||
|
||||
### 11.2 权限判定
|
||||
|
||||
权限不是前端隐藏按钮,而是后端每个请求的强制条件:
|
||||
|
||||
```text
|
||||
身份认证
|
||||
→ 路由所需权限
|
||||
→ 组织范围
|
||||
→ 资源所有权/授权记录
|
||||
→ 操作级权限 read/use/manage
|
||||
→ 执行并记录审计
|
||||
```
|
||||
|
||||
用户端和管理端 API 逻辑分开。新增未知写接口默认归入管理配置权限,避免新接口漏保护。
|
||||
|
||||
### 11.3 资源权限矩阵
|
||||
|
||||
| 操作 | 私有资源所有者 | 获授权用户 | 全局用户 | 管理员 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `read` | 是 | 视授权 | 是 | 是,需审计 |
|
||||
| `use` | 是 | 视授权 | 是 | 是,需审计 |
|
||||
| `manage` | 视资源类型 | 否 | 否 | 是 |
|
||||
| `export` | 自己范围 | 允许范围 | 允许范围 | 全量或指定范围 |
|
||||
| `publish_global` | 否 | 否 | 否 | 是 |
|
||||
|
||||
## 12. 多用户并发与隔离
|
||||
|
||||
### 12.1 上下文隔离
|
||||
|
||||
每次模型请求都绑定:
|
||||
|
||||
```text
|
||||
organization_id
|
||||
user_id
|
||||
campaign_id
|
||||
run_id
|
||||
trace_id
|
||||
span_id
|
||||
session_id
|
||||
```
|
||||
|
||||
消息历史保存在独立 `AgentSession`,不放在 Provider 全局状态、不放在前端共享变量、不通过模型名称作为上下文键。
|
||||
|
||||
### 12.2 四层并发限制
|
||||
|
||||
| 层级 | 限制 |
|
||||
| --- | --- |
|
||||
| 用户级 | 并发 Run、Token 日/月额度、存储和导出 |
|
||||
| 组织级 | 总并发、总预算、总 Token |
|
||||
| 模型级 | Provider QPS、并发连接、超时、重试 |
|
||||
| 任务级 | 同一 Campaign 一个活跃 Run |
|
||||
|
||||
队列等待、限流、重试和取消都写入 Trace。一个 Provider 故障时,不影响其他 Provider 队列。
|
||||
|
||||
## 13. 计费和用量核心逻辑
|
||||
|
||||
### 13.1 计量原则
|
||||
|
||||
计量记录必须追加写入,不按页面统计临时计算。每条 `UsageEvent` 绑定调用归属:
|
||||
|
||||
```text
|
||||
user_id + organization_id + run_id + trace_id + provider + model + idempotency_key
|
||||
```
|
||||
|
||||
计量对象包括 LLM 输入/输出 Token、Embedding、OCR、Rerank、云存储和导出。
|
||||
|
||||
### 13.2 费用计算
|
||||
|
||||
```text
|
||||
LLM 费用 = 输入 Token × 输入费率 + 输出 Token × 输出费率
|
||||
总费用 = LLM + Embedding + OCR + Rerank + 存储 + 导出
|
||||
```
|
||||
|
||||
费用使用调用时冻结的费率版本。Provider 未返回 Token 时,估算值必须标记为 `estimated`,不能直接作为已结算值。
|
||||
|
||||
### 13.3 配额检查时机
|
||||
|
||||
```text
|
||||
创建任务前:检查用户/组织配额
|
||||
进入模型队列前:再次检查并发和预算
|
||||
调用返回后:写 UsageEvent
|
||||
任务结束后:结算本次实际用量
|
||||
```
|
||||
|
||||
配额策略支持 `warn`、`soft_limit` 和 `hard_limit`。达到硬限制时禁止新调用,并把原因显示在任务和 Trace 中。
|
||||
|
||||
## 14. 云存储和导出逻辑
|
||||
|
||||
### 14.1 文件生命周期
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> uploading
|
||||
uploading --> stored
|
||||
stored --> indexed
|
||||
indexed --> active
|
||||
active --> superseded: 文件更新
|
||||
superseded --> recycle_bin
|
||||
recycle_bin --> deleted
|
||||
uploading --> orphaned: 数据库提交失败
|
||||
orphaned --> deleted: 清理任务
|
||||
```
|
||||
|
||||
对象键按组织、用户、知识库、哈希和安全文件名组成,不以原始文件名作为唯一键。数据库只把已经校验哈希的对象标记为当前版本。
|
||||
|
||||
### 14.2 导出内容
|
||||
|
||||
导出任务必须包含 `manifest.json`,记录:
|
||||
|
||||
- 对象键、大小、哈希和版本。
|
||||
- 组织、用户、知识库/记忆归属。
|
||||
- 分类和授权状态。
|
||||
- Trace、账单和审计范围。
|
||||
- 导出发起人、时间、保留期和过期时间。
|
||||
|
||||
下载使用短时效签名地址,浏览器不接触云存储长期密钥。
|
||||
|
||||
## 15. 失败恢复和一致性
|
||||
|
||||
### 15.1 模型调用失败
|
||||
|
||||
| 失败 | 处理 |
|
||||
| --- | --- |
|
||||
| 超时/连接中断 | 按策略重试,写入每次尝试和耗时 |
|
||||
| 429/配额 | 进入限流或转人工,不伪造成功 |
|
||||
| Provider/模型不存在 | 直接失败,提示管理员修复目录 |
|
||||
| Provider 拦截 | 标记 `provider_blocked`,按能力路由规则处理 |
|
||||
| 网关拦截 | 标记 `gateway_blocked`,区分模型本体和网关 |
|
||||
| 空输出/截断 | 触发格式重试,仍失败则进入人工处理 |
|
||||
|
||||
### 15.2 RAG 失败
|
||||
|
||||
- 索引为 `indexing` 时禁止新任务使用该库,除非管理员明确允许旧版本。
|
||||
- 无命中是低置信结果,不得自动补写事实。
|
||||
- 重建失败恢复旧索引和旧计数。
|
||||
- 进程中断时归还 `reserved` 知识片段。
|
||||
- 向量库损坏时切换本地兜底索引,并记录降级事件。
|
||||
|
||||
### 15.3 组合失败
|
||||
|
||||
组合器不能把缺失段落静默填充为新内容:
|
||||
|
||||
```text
|
||||
缺段 → compose_report 标记缺失
|
||||
→ Campaign 保持 human_review/failed
|
||||
→ 通知中心提醒
|
||||
→ 人工修复、跳过或重新运行
|
||||
```
|
||||
|
||||
## 16. 核心不变量
|
||||
|
||||
以下规则是系统必须长期保持的不变量:
|
||||
|
||||
1. 没有有效身份和组织归属的请求不能访问业务 API。
|
||||
2. 用户端不能创建 Provider、查看 API Key 或输入任意模型名称。
|
||||
3. 模型调用必须使用启用且对当前组织可见的模型目录记录。
|
||||
4. 任务开始后,规则、技能、模型、知识和记忆必须从快照读取。
|
||||
5. Agent 只能检索被挂接且当前用户有权限使用的知识库。
|
||||
6. 同一个 Agent 不能重复消费同一个知识片段,其他 Agent 不受影响。
|
||||
7. 未确认记忆不能进入有效记忆上下文。
|
||||
8. Composer 只能组合已人工通过的段落。
|
||||
9. 每次模型调用必须有 `LLMCall`、Trace 和用量归属。
|
||||
10. 任何删除、授权、发布全局、导出和计费调整都必须有审计记录。
|
||||
11. 失败、等待审批、限流和降级不能标记为成功。
|
||||
12. 历史任务、账单和引用不能被当前配置修改覆盖。
|
||||
|
||||
## 17. 关键 API 逻辑分组
|
||||
|
||||
### 17.1 用户端
|
||||
|
||||
```text
|
||||
认证:/api/auth/status、/api/auth/login、/api/auth/logout
|
||||
模型:/api/models/available
|
||||
知识:/api/kbs、/api/kbs/{id}/search、/api/kbs/{id}/files/{name}
|
||||
记忆:/api/memories
|
||||
任务:/api/campaigns、/api/campaigns/{id}/parse、/api/campaigns/{id}/run
|
||||
审查:/api/segments/{id}/review、/api/segments/{id}/fix
|
||||
Trace:/api/traces、/api/traces/{trace_id}
|
||||
用量:/api/me/usage、/api/me/billing
|
||||
```
|
||||
|
||||
### 17.2 管理端
|
||||
|
||||
```text
|
||||
用户:/api/admin/users、/api/admin/organizations
|
||||
模型:/api/admin/model-providers、/api/admin/models
|
||||
能力测试:/api/admin/models/{id}/capability-tests
|
||||
知识授权:/api/admin/knowledge-bases/{id}/grants
|
||||
记忆授权:/api/admin/memories/{id}/grants
|
||||
计费:/api/admin/usage、/api/admin/billing/settlements
|
||||
导出:/api/admin/knowledge-bases/{id}/export、/api/admin/memories/{id}/export
|
||||
审计:/api/admin/audit
|
||||
```
|
||||
|
||||
## 18. 当前实现与 v6 目标对照
|
||||
|
||||
| 领域 | 当前 v5 实现 | v6 目标 |
|
||||
| --- | --- | --- |
|
||||
| Runtime | 已实现会话、工具、审批、恢复、护栏和 Trace | 增加用户/组织归属和配额上下文 |
|
||||
| 画布 | 已实现节点、连线、波次和快照 | 按用户隔离画布和模板 |
|
||||
| 知识库 | 已实现 RAG、分类、消费锁和 KB3 回滚 | 增加云对象、全局/私有/共享和授权 |
|
||||
| 记忆库 | 已实现待确认池、Agent 记忆和筛选删除 | 增加与知识库同构的可见性和授权 |
|
||||
| 模型 | 已实现 Provider CRUD、发现、测试和 Agent 绑定 | 收敛为管理端 ModelCatalog,用户端只读选择 |
|
||||
| 成人内容能力 | 已设计管理端兼容性测试和能力标签 | 实现测试套件、回归、发布和路由 |
|
||||
| 认证 | 已实现本地用户、PBKDF2、Session、RBAC | 增加组织、多租户和管理端角色 |
|
||||
| Trace | 已实现 Run/Session/Event/LLMCall 聚合 | 增加用户、组织和账单关联 |
|
||||
| 计费 | 已有 Token/耗时调用字段 | 新增 UsageEvent、费率版本、配额和结算 |
|
||||
| 存储 | 当前以本地 SQLite、源文件和向量兜底为主 | 迁移云对象存储和异步导出 |
|
||||
|
||||
## 19. 核心验收标准
|
||||
|
||||
### 19.1 任务链路
|
||||
|
||||
- 用户登录后可以创建任务、解析导图、运行 Agent、审查段落和组合成稿。
|
||||
- 每个 Run 都有唯一 `trace_id`,能看到模型调用、工具事件、QC 和产物。
|
||||
- 修改 Agent 规则或模型目录后,已运行任务的快照不变。
|
||||
|
||||
### 19.2 资源隔离
|
||||
|
||||
- 用户看不到其他用户未授权的知识库、记忆、任务、Trace 和账单。
|
||||
- 管理员可以查看和导出全量资源,所有动作有审计。
|
||||
- 全局知识库和全局记忆只允许管理员修改原文。
|
||||
- 用户端模型列表只包含管理端已启用且对当前组织开放的目录。
|
||||
|
||||
### 19.3 稳定性
|
||||
|
||||
- 同一用户不能并发消费同一知识片段。
|
||||
- 同一 Campaign 不能产生两个活跃 Run。
|
||||
- Provider、网关和模型版本变化能在 Trace 中区分。
|
||||
- KB3 重启后仍为 `ready/2717`,向量检索可返回结果。
|
||||
- 索引、模型、云存储和导出失败均有明确状态并可恢复。
|
||||
|
||||
### 19.4 计费
|
||||
|
||||
- 每次 LLM、Embedding、OCR 和存储行为都有用户/组织归属。
|
||||
- 费率版本变化不回写历史账单。
|
||||
- 预估、已计量和已结算状态可区分。
|
||||
- 用量明细可以回溯到 LLMCall、Run、Trace、Agent 和任务。
|
||||
|
||||
## 20. 结论
|
||||
|
||||
系统的核心不是“接入更多模型”或“堆更多 Agent”,而是把每一次生成变成一条可控、可复现、可审查、可计费的数据链:
|
||||
|
||||
```text
|
||||
谁发起
|
||||
→ 用了哪个版本的 Agent/模型
|
||||
→ 读取了哪些被授权的知识和记忆
|
||||
→ 产生了哪些模型/工具调用
|
||||
→ 经过哪些质检和人工决定
|
||||
→ 最终交付了什么
|
||||
→ 消耗了多少 AI 和存储资源
|
||||
```
|
||||
|
||||
v6 的用户端、管理端、云存储、模型能力测试、知识/记忆共享和计费,全部围绕这条链扩展,不改变 v5 已有的 Agent Runtime、QC、组合和 Trace 基础。
|
||||
Reference in New Issue
Block a user