Files
yawan-workbench/设计文档v6-用户端管理端云化与计费设计.md
T

905 lines
50 KiB
Markdown
Raw 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.
# 雅文内容创造工作台 · v6 用户端、管理端与云化设计
> 文档日期:2026-08-27
> 文档状态:v6 设计 + v6.1 提示模板实现同步
> 关联文档:[设计文档 v5](./设计文档v5-系统设计.md)
> 核心逻辑:[核心逻辑设计文档 v6](./核心逻辑设计文档v6.md)
> 从零落地:[核心逻辑设计文档 v6:从 0 到 1](./核心逻辑设计文档v6-从0到1.md)
> 本文只修改设计文档,不代表本轮已经修改源码
## 0. 这次要解决什么
当前 v5 已经具备本地 Agent Runtime、知识库、任务编排、认证、Trace 和 KB3 稳定索引。本 v6 设计在此基础上增加六个企业化能力:
1. 面向普通用户的用户端,以及面向运营人员的管理端。
2. 按用户统计 AI 调用量、Token、Embedding、OCR 和存储量,并形成可审计的计费账单。
3. 所有源文件、向量快照、产物和导出包迁移到云对象存储。
4. 增加全局知识库、私有知识库和管理员授权共享机制。
5. 模型连接、模型发现和模型费率全部收敛到管理端,用户端只选择已开放模型。
6. 记忆库复用知识库的私有、共享、全局、授权、撤销、导出和审计逻辑。
本版本的关键原则是:**所有权与使用权分离、全局资源与私有资源隔离、计费以真实调用账本为准、管理端可见但不能绕过审计**。
## 1. 产品形态
### 1.1 用户端
普通用户只看到自己的工作空间,以及管理员授权给他的资源:
- 我的任务:创建任务、运行 Agent、查看进度、审查内容和下载成稿。
- 我的 Agent:创建和维护自己的生产 Agent、技能绑定和规则。
- 我的知识库:上传、分类、预览、检索和删除自己的私有素材。
- 全局知识库:读取管理员开放的公共资料;不能删除和修改原文。
- 共享知识库:管理员明确授予当前用户后才显示。
- 记忆库:管理自己的记忆,以及管理员授予的共享/全局记忆。
- 模型选择:只能从管理端已接入并开放的模型目录中选择,不能添加 Provider、API Key 或模型。
- 用量与账单:查看本月 AI 用量、余额/额度、调用明细和导出记录。
- 我的记忆:只管理自己的私有记忆,不能读取其他用户未授权的记忆。
### 1.2 管理端
管理员使用独立的管理端导航,不与用户端混在同一组页面里:
- 用户与组织:账号、状态、角色、所属组织和配额。
- 全局知识库:创建和维护所有用户可用的公共知识。
- 知识库总览:查看全部用户私有知识库的元数据、容量、索引状态和归属。
- 授权中心:把某个私有知识库授权给指定用户,或开放给全部用户。
- 记忆库总览:查看全部用户记忆、来源 Agent、可见性、使用者和版本。
- 模型目录:接入 Provider、维护模型列表、费率、能力、启用状态和用户可见范围。
- AI 用量与计费:按用户、Provider、模型、时间和任务查看用量与费用。
- 云存储与导出:导出数据库、知识库文件、向量索引、Trace 和账单。
- 安全审计:查看登录、权限变更、知识库授权、导出和计费调整记录。
管理端可以“看见”用户私有知识库的元数据和内容预览,但所有查看、下载、导出行为都要写入审计日志;默认不改变文件归属和内容。
## 2. 总体架构变化
```mermaid
flowchart LR
U[普通用户端] --> G[统一 API 网关]
A[管理端] --> G
G --> IAM[身份、组织与 RBAC]
G --> TENANT[租户与资源授权]
G --> ORCH[Agent Runtime / 任务编排]
G --> BILL[用量计量与计费]
G --> KB[RAG 知识库服务]
G --> EXP[导出任务服务]
IAM --> DB[(关系数据库)]
TENANT --> DB
BILL --> DB
ORCH --> DB
KB --> META[知识库元数据]
KB --> OBJ[云对象存储]
KB --> VEC[云向量存储或本地加速索引]
EXP --> OBJ
ORCH --> LLM[模型 Provider]
ORCH --> BILL
A --> AUDIT[审计日志]
U --> AUDIT
```
### 2.1 资源边界
每个请求先解析出三个边界:
| 边界 | 作用 |
| --- | --- |
| `organization_id` | 组织或租户隔离,决定用户属于哪个企业空间 |
| `owner_user_id` | 私有资源的所有者,决定默认可见范围 |
| `visibility` | `private`、`shared`、`global` 三种知识库可见性 |
管理员权限是跨用户的管理权限,不会把私有知识库自动变成公共知识库。只有执行“授权共享”或“设为全局”操作后,资源的使用范围才改变。
## 3. 用户、组织与角色设计
### 3.1 账号层级
```text
Organization
└── UserAccount
├── UserRoleBinding
├── UsageQuota
├── BillingAccount
├── KnowledgeBase(私有)
├── Agent
└── Memory
```
同一个用户只能在当前组织范围内使用组织资源。未来需要跨组织时,使用组织成员关系授权,不直接复用另一组织的用户 ID。
### 3.2 角色
| 角色 | 用户端能力 | 管理端能力 |
| --- | --- | --- |
| `user` | 使用自己的 Agent、私有库、获授权的共享库和全局库 | 无 |
| `reviewer` | 额外执行内容审查、查看审查 Trace | 无用户管理能力 |
| `operator` | 使用用户端全部功能 | 查看用户、处理导出、处理索引和授权申请 |
| `admin` | 使用全部用户端功能 | 用户、知识库、权限、计费、云存储和审计全管理 |
| `owner` | 组织内全部功能 | 当前组织最高权限,不跨组织 |
管理员接口和用户接口使用不同的权限前缀:
```text
user:read 用户读取自己的资源
user:write 用户修改自己的资源
admin:users 管理用户与角色
admin:kb 管理所有知识库和授权
admin:memory 管理所有记忆和授权
admin:models 管理 Provider、模型目录和模型授权
admin:billing 查看和调整计费规则
admin:export 创建和下载全量导出
admin:audit 查看审计日志
```
### 3.3 模型配置权限边界
模型连接属于管理端资源,用户端只消费“可用模型目录”,不接触 Provider 凭据:
| 操作 | 用户端 | 管理端 |
| --- | --- | --- |
| 新增/修改/删除 Provider | 禁止 | 允许 |
| 填写或查看 API Key | 禁止 | 允许,界面只显示脱敏摘要 |
| 从 Provider 发现模型 | 禁止 | 允许 |
| 启用/停用模型 | 禁止 | 允许 |
| 修改模型费率和能力标签 | 禁止 | 允许 |
| 给 Agent 选择模型 | 允许,在可用目录内选择 | 允许全部模型 |
| 直接输入任意模型名称 | 禁止 | 可作为受控维护动作 |
用户创建或编辑 Agent 时,模型字段只能引用 `ModelCatalog` 中状态为 `enabled` 且对当前组织可见的记录。用户端不显示 Provider 管理入口,也不接受 `base_url`、`api_key` 或任意自定义模型名。管理员停用模型后,历史任务继续使用已冻结的运行快照,新任务不能再选择该模型。
## 4. 知识库可见性与授权模型
### 4.1 三类知识库
| 类型 | 创建者 | 默认使用者 | 修改者 |
| --- | --- | --- | --- |
| 私有知识库 `private` | 普通用户或管理员代建 | 仅所有者 | 所有者;管理员可代维护 |
| 共享知识库 `shared` | 普通用户或管理员 | 被授权用户列表 | 所有者和管理员 |
| 全局知识库 `global` | 管理员 | 当前组织全部用户 | 管理员 |
用户自己上传的知识库默认是 `private`。管理员可以执行两种授权动作:
1. 授权给指定用户:保持私有归属不变,增加可使用者。
2. 开放给全部用户:将可见性改为 `global`,所有用户可以检索,但只有管理员可以修改原文。
取消授权只影响后续检索,不删除原文件、不改变历史任务的引用快照。
### 4.2 访问判定顺序
```mermaid
flowchart TD
R[收到知识库读取请求] --> S{账号已启用?}
S -- 否 --> X[返回 401/403]
S -- 是 --> M{管理员管理动作?}
M -- 是 --> L[允许管理范围内读取并记录审计]
M -- 否 --> O{当前用户是所有者?}
O -- 是 --> L2[允许读写私有库]
O -- 否 --> G{visibility = global?}
G -- 是 --> L3[允许只读检索]
G -- 否 --> P{存在有效授权记录?}
P -- 是 --> L4[允许按授权范围读取]
P -- 否 --> D[拒绝访问]
```
检索服务必须在数据库层先得到“允许查询的知识库 ID 列表”,再调用向量搜索;不能先搜索全库后在结果层过滤。
### 4.3 授权记录
建议新增 `KnowledgeBaseGrant`:
| 字段 | 含义 |
| --- | --- |
| `id` | 授权记录 ID |
| `kb_id` | 知识库 ID |
| `grantee_user_id` | 被授权用户;全员开放时为空 |
| `grantee_organization_id` | 被授权组织 |
| `permission` | `read`、`use`、`manage` |
| `status` | `active`、`revoked`、`expired` |
| `granted_by` | 执行授权的管理员 |
| `expires_at` | 可选到期时间 |
| `created_at`、`revoked_at` | 生命周期时间 |
`use` 允许 Agent 检索并消费 chunk,`read` 只允许人工浏览,`manage` 允许分类、重建和文件维护。普通用户不能给自己追加授权,也不能把私有库开放给全部用户。
### 4.4 记忆库与画布组合授权
记忆库保留知识库的所有权和可见性字段,但运行时授权根改为 Agent 画布。用户创建的 Agent 记忆默认是 `private`;管理员授权某个画布后,画布节点 Agent 的知识库和确认记忆一起获得查看/运行范围,不再要求为同一流程重复授权记忆。
| 记忆范围 | 默认可见者 | 用户端行为 | 管理端行为 |
| --- | --- | --- | --- |
| 私有记忆 `private` | 所有者及其 Agent | 查看、编辑、删除、绑定自己的 Agent | 可查看、导出、代维护,所有行为审计 |
| 共享记忆 `shared` | 画布授权用户 | 读取并在授权画布中使用 | 通过画布授权、撤销、修改可使用者 |
| 全局记忆 `global` | 当前组织全部用户 | 只读使用,不修改原文 | 创建、编辑、版本管理和下架 |
记忆的访问判定顺序为:管理员管理动作 → 所有者 → 全局 → 有效画布授权 → 兼容的历史 `MemoryGrant` → 拒绝。用户端的记忆检索必须先得到允许访问的记忆 ID 集合,再注入 Agent Runtime,不能先读取全量记忆后在前端过滤。
画布授权使用 `read`、`use`、`manage`、`export` 四种权限;画布对依赖知识和记忆的继承只覆盖查看和使用,不放大编辑、删除、导出权限。旧 `MemoryGrant` 仅用于迁移兼容,管理端新界面不再创建单独记忆授权。撤销画布授权只影响后续运行;已经创建的任务仍保留其运行快照和引用来源。
建议新增 `MemoryGrant`,字段结构与 `KnowledgeBaseGrant` 一致,并在 `Memory` 增加:
```text
owner_user_id
organization_id
visibility: private | shared | global
source_agent_id
version
```
管理员查看或导出其他用户记忆时必须写入 `AccessAudit`,用户不能通过修改 Agent ID 绕过记忆归属校验。
## 5. 模型目录与选择
### 5.1 管理端模型目录
Provider 的 API Key、Base URL 和模型发现全部由管理端维护。管理端将发现结果规范化为 `ModelCatalog`,用户只看到安全的展示字段:
| 字段 | 说明 |
| --- | --- |
| `id` | 稳定的模型目录 ID |
| `provider_id` | 所属 Provider |
| `model_name` | Provider 上的真实模型名 |
| `display_name` | 用户端展示名 |
| `capabilities` | 文本、工具调用、视觉、长上下文等能力 |
| `enabled` | 是否允许新任务选择 |
| `visibility` | `global`、组织范围或管理员专用 |
| `pricing_version` | 当前计费费率版本 |
管理员添加 Provider 后,可以点击“发现模型”获取列表,再逐个启用或停用。发现失败只影响目录刷新,不暴露 API Key 和 Provider 错误细节给普通用户。
### 5.2 用户端模型选择
用户端 Agent 表单只请求:
```text
GET /api/models/available
```
返回当前用户所在组织可用的模型目录。用户选择的是目录 ID,不是 Provider 地址或自由文本;保存 Agent 时服务端再次校验目录状态和组织可见性。
模型目录变更不覆盖历史任务快照:
1. 任务创建时保存 Provider、模型名、能力和费率版本。
2. 管理员停用模型后,旧 Run 可以继续恢复或审计。
3. 新建任务和重跑任务只能选择当前启用模型。
4. 账单使用快照中的费率版本,不按当前目录价格回算历史费用。
### 5.3 模型相关审计
以下管理动作写入审计:Provider 新增/删除、API Key 替换、模型启停、费率变更、组织可见范围变更。用户只能看到自己的模型选择记录和调用账单,不能看到其他 Provider 的密钥、内部地址和组织费率策略。
### 5.4 多用户并发治理
多个用户同时使用同一个模型不会共享错上下文,原因是每次调用都绑定完整的归属键:
```text
organization_id + user_id + campaign_id + run_id + trace_id + span_id
```
运行时不把消息历史放在 Provider 或全局内存中;每个 Agent Session 独立保存自己的消息、工具状态和配置快照。模型请求发送前由服务端按当前 Session 组装消息,返回后再按同一 `run_id/trace_id` 写入调用账本。
并发控制分为四层:
| 层级 | 控制内容 | 目的 |
| --- | --- | --- |
| 用户级 | 并发 Run 数、Token 日/月额度 | 防止单个用户占满资源 |
| 组织级 | 总并发、总 Token、预算上限 | 防止一个组织影响其他组织 |
| 模型级 | Provider QPS、并发连接、超时和重试 | 遵守模型服务限制 |
| 任务级 | 同一 Campaign 只允许一个活跃 Run | 防止重复计费和结果覆盖 |
请求进入后先经过配额检查,再进入带组织和模型键的队列。队列状态、限流等待、重试和失败都会写入 Trace;因此“等待”不会被误认为“模型混乱”。
模型目录必须使用版本化和软停用:
1. 同一个 Provider 的模型名称变化时创建新的目录版本,不覆盖旧记录。
2. 管理员停用只禁止新任务,不删除历史目录和账单费率。
3. Provider 临时故障时只影响绑定该 Provider 的队列,其他模型继续运行。
4. 用量账本使用调用发起用户归属,不使用最后一个修改 Agent 的用户归属。
因此,多个用户可以同时选择同一模型;他们的上下文、权限、配额、Trace 和账单分别隔离。真正需要避免的是“共享消息历史、按名称动态解析模型、无用户归属的用量记录”,这些在本设计中全部禁止。
### 5.5 成人内容能力兼容性测试
用户所说的“破限”在系统中落地为**管理员可执行、可回归、可审计的成人内容能力兼容性测试**。测试记录模型在指定内容类型上的真实表现,不把测试结果伪装成模型能力,也不把某个 Provider 的策略状态传播给其他 Provider。
测试分为四个维度:
| 维度 | 测试内容 | 结果示例 |
| --- | --- | --- |
| 成人内容生成 | 合规的成人向文本、角色设定和情节续写样例 | `supported`、`provider_blocked`、`partial` |
| 中文表达 | 大白话、段落样式、连续口语和上下文衔接 | `pass`、`format_mismatch` |
| Agent 结构 | 锚点卡、工具调用、JSON 结构和多轮恢复 | `pass`、`schema_failed` |
| 稳定性 | 超时、限流、空输出、长度和重复调用 | `stable`、`timeout`、`rate_limited` |
测试套件使用版本号和固定样例集,例如 `adult-content-compat-v1`。样例内容存放在管理员控制的测试集内,测试结果只保存哈希、分类、状态、模型版本、Provider、Token、耗时和 Trace,不把测试样例全文写入普通用户日志。
管理端可以单个测试、批量测试或按计划回归:
1. 选择一个或多个已接入模型。
2. 选择测试套件和生成参数,冻结测试输入、温度、最大输出长度和超时。
3. 并行调用模型,记录每个样例的状态、输出哈希和断言结果。
4. 计算通过率、成人内容兼容等级、稳定性和平均费用。
5. 更新 `ModelCatalog` 的能力状态;只有达到管理员设定阈值的模型才显示为“可用于成人内容”。
6. 测试结束后生成 Trace 和报告,支持与上一个模型版本做回归对比。
Provider 侧的内容策略仍然会影响结果;出现 `provider_blocked` 时,目录应标记为“该 Provider 当前不支持此能力”,而不是把模型标记为已兼容。系统通过管理员选择其他已接入模型或调整路由来满足业务要求,测试结果不覆盖 Provider 的服务策略。
模型目录增加以下字段:
```text
content_capability: general | adult_supported | adult_partial | adult_unavailable
capability_test_version
capability_tested_at
capability_score
capability_status
```
生产任务在创建时声明内容能力需求。运行时只从满足需求且对当前组织可见的目录中选择;任务开始后把能力结果和费率一起写入快照。管理员更新测试结果不会改变已运行任务,后续新任务和重跑任务使用最新目录状态。
这种设计避免了多用户场景下的三个混乱来源:用户自己上传“解除限制”提示词、模型名称相同但 Provider 不同、模型更新后旧任务被新能力覆盖。
### 5.6 公开资料检索结论与采用方式
2026-08-26 对 Linux.do `/latest` 及其公开主题进行检索。`/latest` 本身只是主题索引页,没有一套可直接复现的模型能力规范;相关主题中的用户反馈显示,同一个模型在不同 Provider、中转层、账号和版本下表现可能不同,外置审查和版本更新也会让之前的测试结果失效。这些属于社区观察,作为线索而不是生产结论:
- [关于破限/破甲的疑问](https://linux.do/t/topic/2512323):讨论了模型本体偏好与模型前置拦截层的差异。
- [破限词仓库没了,谁还有备份的](https://linux.do/t/topic/2504365):反映提示词仓库和测试结果存在时效性,且不同接入方式结果不同。
- [更新了破限工具的 ZCode 版本](https://linux.do/t/topic/2524019):提到成人向创作在不同模型上的结果差异,并指出本地部署模型更容易保持可控测试环境。
- [关于成人内容模型的公开讨论](https://linux.do/t/topic/1680571):显示社区通常按模型和接入渠道分别试用,而不是假设存在一个适用于全部 Provider 的固定方案。
系统据此采用以下工程结论:
1. 不把“破限成功”作为永久能力,而是把它记录为“某 Provider + 某模型版本 + 某测试套件”的一次测试结果。
2. 同一个目录模型至少测试直连 Provider 和实际中转/网关两条路径,区分模型行为与前置审查层行为。
3. 每次模型版本、Provider 路由、系统提示词或外置审查配置变化,都触发 `adult-content-compat` 回归;旧结果保留,新结果生成新版本。
4. 失败结果必须区分 `provider_blocked`、`gateway_blocked`、`model_refused`、`timeout`、`format_failed`,不能用一个“破限失败”状态掩盖根因。
5. 只有管理员可以查看原始测试输出和发布能力标签;用户端只看到已发布的能力等级和最后测试时间。
测试实现可采用 Promptfoo 的 Provider × Test Case × Assertion 矩阵,也可用 Garak 的 Probe/Detector 机制做回归探测;两者都应在工作台内部保存输入哈希、断言、通过率和 Trace,而不是直接把第三方工具输出当作生产路由结论。
## 6. 云存储设计
### 6.1 存储职责
云对象存储保存大文件和可导出产物,关系数据库只保存元数据、权限、哈希和生命周期状态。
| 数据 | 存储位置 | 数据库记录 |
| --- | --- | --- |
| 原始上传文件 | 对象存储 | `CloudObject` + `KnowledgeFile` |
| 解析后的文本快照 | 对象存储 | 文件哈希和版本 |
| 向量索引快照 | 对象存储或托管向量库 | 索引版本和校验值 |
| Markdown/DOCX 成稿 | 对象存储 | `Artifact` 的对象键和哈希 |
| Trace 导出包 | 对象存储 | `ExportJob` |
| 账单导出 | 对象存储 | `BillingExport` |
### 6.2 对象键规范
对象键不使用用户原始文件名作为唯一标识,避免重名覆盖:
```text
org/{organization_id}/users/{user_id}/kb/{kb_id}/files/{sha256}-{safe_name}
org/{organization_id}/users/{user_id}/kb/{kb_id}/index/{index_version}.json
org/{organization_id}/campaigns/{campaign_id}/artifacts/{artifact_id}.docx
org/{organization_id}/exports/{export_job_id}/{part_name}
```
写入流程:上传临时对象 → 计算 SHA-256 → 写入数据库元数据 → 原子切换当前版本 → 删除过期临时对象。数据库提交失败时不把对象标记为当前版本;对象清理任务按状态和保留期回收孤儿文件。
### 6.3 下载与导出
- 用户下载自己的文件或有权访问的全局/共享文件。
- 管理员导出全部或指定用户数据,但必须选择范围、原因和保留期。
- API 返回短时效签名地址,不把云存储长期密钥下发到浏览器。
- 导出任务异步执行,页面显示排队、打包、上传、完成和失败状态。
- 导出包包含 `manifest.json`,列出文件、哈希、归属、分类、权限和创建时间。
## 7. AI 使用量计费
### 7.1 计量对象
每一次 AI 行为都生成一条不可变用量事件:
| 计量项 | 来源 | 计费单位 |
| --- | --- | --- |
| LLM 输入 | `LLMCall.prompt_tokens` | 百万 Token |
| LLM 输出 | `LLMCall.completion_tokens` | 百万 Token |
| Embedding | RAG 导入和查询 | 千 Token 或向量次数 |
| OCR | 导图图片 OCR | 页数/图片数 |
| 重排 | 可选 Rerank Provider | 次数或 Token |
| 云存储 | 对象存储统计 | GB·月 |
| 导出 | 导出任务 | GB 或次数 |
每条计量事件携带 `user_id`、`organization_id`、`campaign_id`、`run_id`、`trace_id`、Provider、模型、数量、费率版本和幂等键。管理员修改费率不会回写历史事件。
### 7.2 费用公式
```text
llm_fee = prompt_tokens / 1,000,000 * prompt_rate
+ completion_tokens / 1,000,000 * completion_rate
embedding_fee = embedding_tokens / 1,000 * embedding_rate
ocr_fee = image_count * ocr_rate
storage_fee = gb_month * storage_rate
total_fee = llm_fee + embedding_fee + ocr_fee + storage_fee + export_fee
```
最终金额按费率版本保存,不从当前 Provider 配置实时反算。内部计费精度使用整数最小货币单位,界面再格式化为元。
### 7.3 用量账本
建议新增:
- `UsageEvent`:单次 AI 行为原始计量,追加写入,不允许普通用户修改。
- `UsageRate`:Provider/模型/服务类型的费率和生效时间。
- `BillingAccount`:用户或组织余额、额度、冻结和状态。
- `UsageSettlement`:按日/月汇总的结算结果。
- `BillingAdjustment`:管理员手工调账,必须填写原因并关联审计事件。
- `UsageQuota`:日/月 Token、存储、并发和导出限制。
### 7.4 计费时序
```mermaid
sequenceDiagram
participant User as 用户
participant Runtime as Agent Runtime
participant LLM as Provider
participant Meter as 用量计量
participant Bill as 账单服务
participant Admin as 管理端
User->>Runtime: 发起任务
Runtime->>LLM: 模型请求
LLM-->>Runtime: 输出与 Token 统计
Runtime->>Meter: 写入不可变 UsageEvent
Meter->>Bill: 按费率计算预估费用
Bill-->>User: 更新用量与额度
Admin->>Bill: 查询、导出或调整账单
Bill-->>Admin: 汇总、明细和审计记录
```
在 Provider 没有返回 Token 时,系统可以使用本地 tokenizer 做“估算”标记,但不能把估算值伪装成计费确认值。账单中区分 `measured`、`estimated`、`settled` 三种状态。
### 7.5 超额策略
用户达到配额后按组织策略处理:
- `warn`:继续执行,仅提示超额。
- `soft_limit`:允许当前任务完成,禁止新任务排队。
- `hard_limit`:暂停新的 LLM、Embedding 和 OCR 请求。
已经进入运行中的任务根据 Run 策略完成或取消,取消动作必须写入 Trace 和账单状态。
## 8. 数据模型扩展
### 8.1 账号与组织
建议在现有 `AppUser` 之上增加:
| 表 | 关键字段 | 说明 |
| --- | --- | --- |
| `Organization` | `id`、`name`、`status`、`plan_id` | 企业或个人工作区 |
| `UserAccount` | `user_id`、`organization_id`、`status` | 用户与组织关系 |
| `UserRoleBinding` | `user_id`、`role`、`scope` | 角色和作用域 |
| `BillingPlan` | `id`、`name`、`quota`、`rates` | 套餐和配额 |
| `UsageQuota` | `user_id`、`period`、`limits`、`used` | 用户用量限制 |
### 8.2 知识库与云对象
建议扩展现有 `KnowledgeBase`:
```text
owner_user_id
organization_id
visibility: private | shared | global
storage_provider
storage_prefix
index_version
source_bytes
retention_policy
```
新增:
| 表 | 作用 |
| --- | --- |
| `KnowledgeBaseGrant` | 用户/组织授权关系 |
| `CloudObject` | 对象键、版本、哈希、大小、存储类和删除状态 |
| `ExportJob` | 导出范围、发起人、进度、对象键和过期时间 |
| `AccessAudit` | 查看、下载、授权、撤销和导出行为 |
### 8.3 模型目录与记忆库
新增模型目录表 `ModelCatalog`,由管理端维护,用户端只引用目录 ID:
| 表 | 关键字段 | 说明 |
| --- | --- | --- |
| `ModelCatalog` | `provider_id`、`model_name`、`capabilities`、`enabled`、`visibility`、`pricing_version` | 管理端接入并开放给用户选择的模型 |
| `ModelOrganizationGrant` | `model_id`、`organization_id`、`status` | 可选的组织级模型授权 |
| `ModelCapabilityTest` | `model_id`、`suite_version`、`status`、`score`、`trace_id` | 管理端模型能力兼容性测试结果 |
| `ModelCapabilityCase` | `test_id`、`case_hash`、`dimension`、`assertions`、`result` | 单个测试样例的可审计断言结果 |
| `MemoryGrant` | `memory_id`、`grantee_user_id`、`permission`、`status` | 记忆库共享/全局授权 |
现有 `Memory` 增加 `owner_user_id`、`organization_id`、`visibility`、`source_agent_id` 和 `version`。用户端只能维护自己的私有记忆;共享和全局记忆由授权判定服务控制,规则与 `KnowledgeBaseGrant` 相同。
### 8.4 任务与账单关联
现有 `LLMCall` 已经有 `run_id`、`campaign_id`、`agent_id`、`trace_id`、Token 和耗时字段。v6 只需补充:
```text
organization_id
user_id
usage_event_id
billing_status
```
这样一次账单可以回溯到模型调用、Agent、内容段、任务和最终产物。
## 9. 用户端页面设计
### 9.1 首页总览
首屏显示四个指标:
- 本月已用 Token / 剩余额度。
- 本月预估费用 / 已结算费用。
- 私有知识库数量和存储占用。
- 当前运行任务和待审查数量。
顶部显示当前组织和账号,不显示其他用户的名称、用量或私有资源。
### 9.2 知识库页面
页面分为三个 Tab:
1. 我的知识库:上传、分类、预览、重建、删除。
2. 已授权知识库:只显示管理员授予当前用户的库。
3. 全局知识库:只读浏览和检索,显示来源与版本。
每个知识库卡片显示:可见性、所有者、授权状态、文件数、分块数、索引状态、容量和最近更新时间。用户不能在列表中看到未授权私有库。
### 9.3 用量与账单页面
提供时间筛选、任务筛选、模型筛选和导出按钮:
- 用量趋势:输入 Token、输出 Token、Embedding、OCR、存储。
- 调用明细:时间、Agent、模型、Trace、数量、状态、费用。
- 配额状态:当前值、上限、预警线。
- 账单导出:生成当前用户可见范围的 CSV/JSON 包。
### 9.4 模型与记忆页面
- 模型选择器只展示 `/api/models/available` 返回的启用模型;不显示 Provider API Key、Base URL 和发现按钮。
- 用户不能新增、编辑或删除模型,也不能输入任意模型名称;表单保存时服务端再次校验目录 ID。
- 用户在模型卡片上只看到管理员确认的能力标签,例如“支持成人内容”“部分支持”或“当前不可用”,不能自行修改该标签。
- 记忆库页面分为“我的记忆”“已授权记忆”“全局记忆”三个范围,支持查看、确认、停用和删除当前用户有权限管理的条目。
- 共享/全局记忆显示所有者、版本、来源 Agent 和授权状态,但用户不能修改原文。
## 10. 管理端页面设计
### 10.1 用户与组织
管理员可以:
- 创建、停用、重置和删除用户。
- 设置角色、组织、套餐、配额和并发限制。
- 查看用户最近登录、任务数、知识库数量和本月用量摘要。
- 强制撤销用户全部 Session。
### 10.2 知识库总览与授权中心
管理端表格显示:
```text
知识库名称 | 所有者 | 类型 | 文件数 | 容量 | 索引状态 | 使用者数 | 最近访问 | 操作
```
操作包括:查看、导出、分类维护、重建索引、授权指定用户、开放全局、撤销授权。任何“开放全局”操作都要二次确认,并记录变更前后的可见性。
### 10.3 记忆库总览与授权中心
管理员可以按用户、Agent、组织、可见性和状态查看全部记忆,并执行:
- 查看、预览和导出用户私有记忆。
- 授权指定用户使用某条记忆或某组记忆。
- 将记忆发布为组织全局记忆,或恢复为私有/共享状态。
- 修改版本、停用过期记忆、撤销授权和恢复授权。
管理员的查看、下载、导出和授权动作都写入 `AccessAudit`;撤销授权只影响新建任务,历史任务继续保留运行快照。
### 10.4 模型目录管理
管理员在模型目录页面完成 Provider 和模型生命周期管理:
1. 新增 Provider 并安全保存 API Key。
2. 调用 Provider 的模型发现接口。
3. 逐个启用/停用模型,设置能力标签和费率版本。
4. 按组织开放模型;用户端只读显示可用目录。
5. 查看模型调用量、错误率、Token 和费用。
6. 运行成人内容能力兼容性测试,查看版本间的通过率、拒绝率、超时率和成本变化。
7. 仅在测试结果达到阈值后,发布或下架模型的“支持成人内容”能力标签。
### 10.5 计费管理
管理员可以设置 Provider/模型费率、套餐配额、预警阈值和超额策略;可以按用户、组织、任务和 Trace 查询费用,并对异常账单执行带原因的调账。
计费页面区分:
- 原始用量。
- 费率版本。
- 预估金额。
- 已结算金额。
- 管理员调整金额。
## 11. API 设计
### 11.1 用户端 API
```text
GET /api/me/usage
GET /api/me/billing
GET /api/me/exports
POST /api/me/exports
GET /api/models/available
GET /api/kbs?scope=mine|granted|global
GET /api/kbs/{id}/access
POST /api/kbs/{id}/import
GET /api/kbs/{id}/search
GET /api/kbs/{id}/files/{filename}
GET /api/memories?scope=mine|granted|global
POST /api/memories/{id}/decide
PUT /api/memories/{id}
DELETE /api/memories/{id}
```
接口返回结果必须经过当前用户可见范围过滤;`scope=mine` 不能返回管理员代建但归属其他用户的私有库。
`GET /api/models/available` 是用户端唯一的模型目录入口,只返回管理员已启用且当前组织可见的模型。用户端不开放 Provider CRUD、模型发现、费率修改和 API Key 相关接口。
### 11.2 管理端 API
```text
GET /api/admin/organizations
GET /api/admin/users
POST /api/admin/users/{id}/revoke-sessions
PUT /api/admin/users/{id}/quota
GET /api/admin/knowledge-bases
POST /api/admin/knowledge-bases/{id}/grants
DELETE /api/admin/knowledge-bases/{id}/grants/{grant_id}
POST /api/admin/knowledge-bases/{id}/publish-global
POST /api/admin/knowledge-bases/{id}/export
GET /api/admin/memories
POST /api/admin/memories/{id}/publish-global
GET /api/admin/canvases
POST /api/admin/canvases/{id}/grants
DELETE /api/admin/canvases/{id}/grants/{grant_id}
POST /api/admin/canvases/{id}/publish-global
GET /api/admin/knowledge-bases/{id}/export
GET /api/admin/canvases/{id}/export
GET /api/admin/memories/{id}/export
GET /api/admin/model-providers
POST /api/admin/model-providers
PUT /api/admin/model-providers/{id}
DELETE /api/admin/model-providers/{id}
POST /api/admin/model-providers/{id}/discover
GET /api/admin/models
PUT /api/admin/models/{id}
POST /api/admin/models/{id}/organization-grants
POST /api/admin/models/{id}/capability-tests
GET /api/admin/models/{id}/capability-tests
POST /api/admin/models/{id}/capability-tests/{test_id}/publish
GET /api/admin/usage
GET /api/admin/billing/settlements
POST /api/admin/billing/adjustments
GET /api/admin/audit
```
管理端模型接口和画布授权接口只允许管理员权限;记忆的用户使用范围由 `CanvasGrant` 继承计算。普通用户即使知道管理端路径,也只能得到 `403`,不会得到 Provider 配置或其他用户的管理数据。
能力测试接口只接受管理端预置的测试套件 ID,拒绝由普通用户或前端传入任意“破限提示词”。测试执行和发布结果写入 Trace、`ModelCapabilityTest` 与审计日志。
### 11.3 响应和错误
| 状态码 | 场景 |
| --- | --- |
| `401` | 未登录或 Session 过期 |
| `403` | 已登录但没有用户/管理端权限,或没有知识库授权 |
| `404` | 资源不存在,或为了防止枚举而隐藏未授权资源 |
| `409` | 重复授权、重复结算或并发修改冲突 |
| `422` | 计费、导出或存储参数不合法 |
| `429` | 用户或组织达到并发/调用限额 |
| `503` | 云存储、Embedding 或 Provider 暂时不可用 |
## 12. 数据安全与审计
### 12.1 最小权限
- 用户检索只在“所有者 + 有效授权 + 全局库”集合中执行。
- 管理员查看私有库内容需要 `admin:kb`,下载/导出还需要 `admin:export`。
- 用户端只能读取自己可用的 `ModelCatalog`,模型 Provider 和费率只对 `admin:models` 开放。
- 用户记忆只在“所有者 + 有效画布授权 + 全局记忆”集合中注入 Agent Runtime;旧 `MemoryGrant` 仅作为迁移兼容。
- 计费明细按用户和组织隔离;普通用户不能查看其他用户 Token 或费用。
- 记忆、任务、Trace 和产物沿用同一所有者/组织边界。
### 12.2 审计事件
以下操作必须记录操作者、目标对象、前后值、IP/客户端、Trace 和结果:
- 登录、退出、Session 撤销和角色变更。
- 查看、下载、导出用户私有知识库。
- 查看、下载、导出用户私有记忆。
- 授权、撤销授权、开放全局和恢复私有。
- Provider/API Key 替换、模型启停、模型组织授权和费率版本变更。
- 成人内容能力测试的发起、样例套件版本、结果发布、能力标签变更和回归差异。
- 修改 Provider 费率、配额、套餐和手工调账。
- 删除文件、删除知识库和索引回滚。
### 12.3 删除与保留
用户删除私有知识库时进入回收站,不立即物理删除;默认保留 30 天,管理员可以在审计确认后提前清理。全局知识库删除需要管理员二次确认,并保留历史任务引用的内容哈希和快照。
## 13. 从 v5 迁移到 v6
### 13.1 兼容策略
1. 现有 `AppUser` 迁移为第一个 `Organization` 下的管理员账号。
2. 现有 `KnowledgeBase` 默认归属该组织和管理员,历史库先标记为 `private`。
3. 现有 `Memory`、Agent、Campaign、Segment、Trace 和 Artifact 追加 `organization_id/user_id`,历史数据使用迁移时的拥有者补齐;历史记忆默认为 `private`。
4. 现有 Provider 和模型列表迁移为管理端 `ModelCatalog`,历史 Agent 的模型引用转换为目录 ID;用户端不继承 Provider 写入权限。
5. 本地源文件先上传到对象存储,校验哈希一致后再切换读取路径。
6. KB3 的 2,717 个分块和 512 维向量先作为一个 index version 上传,不重新计算 Embedding。
7. 迁移完成前保留本地 SQLite、原始文件和 `vector_fallback` 目录,验证通过后再进入清理周期。
### 13.2 迁移验收
迁移必须逐项验证:
- 用户只能看到自己的私有库和已授权库。
- 用户只能选择管理端已开放的模型,不能创建 Provider、修改 API Key 或输入任意模型名。
- 用户只能看到自己的私有记忆和已授权/全局记忆,记忆授权撤销后新任务立即失效。
- 管理员可以查看和导出所有库,但操作有审计记录。
- KB3 重启后仍为 `ready/2717`,引用和 chunk ID 不变化。
- 一次 LLM 调用可以从账单回溯到 `LLMCall`、Run、Trace 和用户。
- 对象哈希、数据库哈希和导出 manifest 一致。
- 撤销授权后,新任务检索不到该库,历史任务仍能查看已有引用快照。
## 14. 实施阶段建议
### 阶段 P1:边界和云对象
- 新增组织、用户归属、资源所有者和可见性字段。
- 将现有 Provider/模型整理成管理端 `ModelCatalog`,先确定用户端只读选择边界。
- 建立 `adult-content-compat-v1` 等版本化能力测试套件,先校验模型目录再向用户端发布能力标签。
- 建立对象存储适配层、对象键规范和上传/下载生命周期。
- 先迁移原始文件和最终产物,不改变 Agent 业务流程。
### 阶段 P2:全局库与授权
- 增加 `KnowledgeBaseGrant` 和授权判定服务。
- 增加 `MemoryGrant`,让记忆库和知识库使用同一套私有/共享/全局判定。
- 用户端拆分“我的/已授权/全局”三个知识库范围。
- 用户端拆分“我的/已授权/全局”三个记忆范围。
- 管理端增加知识库和记忆库总览、授权和导出入口。
### 阶段 P3:用量计量与账单
- 将 `LLMCall`、Embedding、OCR 和存储事件统一写入 `UsageEvent`。
- 增加费率版本、配额、预警、结算和调账。
- 管理端完成按用户、组织、模型和 Trace 的账单查询。
### 阶段 P4:迁移与压测
- 迁移当前数据并执行权限矩阵测试。
- 测试对象存储断点续传、重复上传、孤儿文件清理和导出恢复。
- 测试并发 Agent、额度耗尽、授权撤销和管理员审计。
## 15. 设计完成标准
当以下条件全部满足,v6 设计可以进入实现验收:
- 用户端和管理端导航、权限和 API 边界清晰分离。
- 用户端没有 Provider CRUD、模型发现、API Key 和费率修改入口,只能选择管理员开放的模型目录。
- 成人内容模型能力由管理端版本化测试结果发布;用户端只读查看能力标签,不能自行“破限”或改写测试结论。
- 私有、共享、全局三种知识库访问规则可以通过数据库授权记录解释。
- 记忆库沿用同样的私有、共享、全局、授权、撤销和审计规则。
- 管理员能查看、预览、导出每个用户私有知识库,同时所有行为可审计。
- 管理员能查看、预览、导出每个用户私有记忆,并能授权给指定用户或全部用户。
- AI 用量可以按用户和组织精确归集到 Trace,费率变更不影响历史账单。
- 云存储对象有哈希、版本、生命周期和导出 manifest。
- 重启、索引失败、云存储暂时不可用和配额超限都有明确状态,不产生假成功。
- v5 的 Agent Runtime、QC、组合、记忆和 KB3 既有行为保持兼容。
## 16. v6.1 提示模板与结构化输出(已实现)
根据《提示工程实战指南》的工程化原则,Agent 配置增加独立的 `AgentPromptTemplate`。模板字段为角色提示、任务模板、约束列表、上下文示例、输出 Schema、表达风格和版本状态。它与 Agent 规则分离,避免规则、任务数据和示例互相污染。
运行时固定使用“角色 → 任务 → 风格 → Agent 规则 → 约束 → 示例 → 技能/记忆/锚点/知识 → Runtime 硬规则 → 输出协议”的分层提示。用户模板只负责组织输入,知识来源边界、Agent 级消费锁、工具审批、取消、QC 和人工审查由 Runtime 保持最高优先级。
新建任务时保存模板完整快照并记录版本。模板更新自动递增版本;历史任务继续使用旧快照。输出协议以锚点卡 JSON 为当前生产 Schema,运行器在产物写入前执行 `required` 和字段类型校验,失败结果释放知识片段并进入重做或人工处理。
管理端入口:`GET/POST /api/prompt-templates`、`GET/PUT/DELETE /api/prompt-templates/{id}`;Agent 管理中的 `prompt_template_id` 只允许引用启用模板。内置模板允许停用,已绑定模板需要解除关系后再删除。
## 17. v6.2 模型目录边界(已实现)
Provider 仅负责连接信息和模型发现,用户可选项由独立 `ModelCatalog` 管理。Provider 模型清单发生变化时,系统自动同步目录并停用消失的历史项;目录项保留能力状态、费率版本和启用状态,供管理员后续测试发布。
用户端只能调用 `GET /api/models/available` 获取启用目录,Agent 保存目录 ID 并由服务端再次校验 Provider、模型名称和启用状态。Provider 列表、模型发现、模型连通性测试、目录能力和费率修改均收敛到管理权限,历史任务仍使用其冻结的 Provider/模型快照。
## 18. v6.3 资源边界与授权实现(P1,已完成)
服务端已新增 `Organization` 和统一资源范围字段 `organization_id / owner_user_id / visibility`,覆盖 Agent、画布、任务、知识库、待确认记忆、记忆和成稿。普通用户创建的资源自动绑定当前用户并默认为私有;全局发布与共享范围由管理员控制。
知识库和记忆库分别使用 `KnowledgeBaseGrant`、`MemoryGrant` 保存用户授权,权限分为 `read / use / manage / export`。`use` 自动包含读取,`manage` 包含全部操作,`export` 只用于导出与读取。用户列表、详情、上传、分类、索引、检索、记忆确认/删除、任务运行、Trace 和成稿下载均在服务端检查组织、所有者、可见性和有效授权;撤销授权只影响后续请求,不破坏历史任务快照。
管理端已提供知识库和记忆库的总览、指定用户授权、撤销授权和发布全局接口。Provider、模型目录、知识/记忆授权均由 `/api/admin/*` RBAC 保护,用户端不获得配置写权限。成稿、待确认记忆和运行链路创建时继承所属任务的范围字段,避免关联资源出现跨用户泄漏。
本阶段迁移是幂等的:已有 SQLite、原始文件、向量索引和成稿保留,新增列与授权表在启动时补齐。资源隔离、授权分级、模型目录、Agent Runtime 和前端构建均已完成自动化回归验证。
## 19. 用量计量与账单实现(v6.4,已完成)
系统已使用追加式 `UsageEvent` 作为唯一用量账本,覆盖 LLM、Embedding 和 OCR。每条事件包含 `user_id`、`organization_id`、`campaign_id`、`run_id`、`segment_id`、`trace_id`、Agent、Provider、模型、服务类型、单位、数量、输入/输出 Token、费率、费率版本、金额(人民币分)、状态和唯一幂等键。`LLMCall` 通过 `usage_event_id` 回链事件,并记录 `billing_status`。
计费流程为:
```text
请求进入
→ 解析发起用户和组织
→ 读取 ModelCatalog 当前费率快照
→ Provider 返回真实 Token(或本地估算)
→ 追加 UsageEvent
→ LLMCall/Trace 回链
→ 周期汇总与配额检查
```
建库、重建索引和知识检索都记录 Embedding 事件,导图 OCR 记录一次图像事件。Provider 未提供 Token 时标记 `estimated`;`measured`、`estimated`、`settled`、`void` 在界面和汇总中分开统计。费率后续调整只影响新事件,历史金额保持费率版本快照。
用户端新增 `/api/usage/summary`、`/api/usage/events` 和“用量与账单”入口;管理员新增 `/api/admin/usage/summary`、`/api/admin/usage/events`、`/api/admin/quotas` 及配额新增/删除接口,可按用户、模型、服务类型和日/月周期筛选。管理员代运行任务时,`CampaignRun.user_id` 保存实际发起账号,LLM 账单优先继承该字段,防止多人共用模型造成串账。
`UsageQuota` 支持 Token、金额、存储、并发限制与 `warn / soft_limit / hard_limit` 策略。任务启动前做配额预检;未配置配额时不改变原有行为,达到软/硬限制时返回 429。事件幂等唯一索引、配额唯一索引及用户/组织/时间索引均通过启动迁移补齐,重复启动不会重复建表或重复计费。
## 20. 企业级双入口与 RBAC 收口(v6.5,已实现)
企业产品通常采用同一身份体系下的独立用户门户和管理控制台:用户进入 `/app`,管理员进入 `/admin`。两者共享登录会话、组织和审计链,但拥有不同的导航、页面职责和 API 权限。门户入口是账号角色的固定边界,管理员和普通用户都没有跳转到另一门户的入口。
本项目的入口职责如下:
| 入口 | 可见范围 | 典型动作 |
| --- | --- | --- |
| 用户工作台 `/app` | 全部业务页面,但数据限定为本人、已授权和全局资源 | 新建任务、管理自己的 Agent/画布/标签/技能/模板/知识库/记忆、选择已发布模型、查看账单 |
| 管理控制台 `/admin` | 全部业务页面 + 全组织资源与配置 | 成员/RBAC、Provider、模型目录、Agent、技能、标签、模板、授权、配额、审计 |
服务端中间件对 `/api/admin/*`、Provider、模型默认配置、模型发现和模型目录治理接口要求 `admin:manage` 或管理员配置权限;普通用户可以读取 `/api/models/available` 的已发布模型目录,但不接触连接凭据、费率治理、配额配置和能力发布。标签、技能、提示模板、Agent、画布、知识库和记忆库在用户端保留完整业务操作,并通过组织、所有者、可见性和 Grant 做行级过滤。用户用量接口只按当前会话用户查询,管理端账单接口只由管理员访问。前端路由守卫和服务端资源判定共同抵抗跨门户与越权请求。
账号响应新增 `portal` 和 `permissions` 字段。登录后服务端返回的 `portal` 决定唯一入口,前端将管理员定向 `/admin`、普通用户定向 `/app`;访问不匹配的入口只显示入口阻断页。该设计便于未来将 `/app` 与 `/admin` 拆为独立前端或独立域名,同时保留当前单体部署的平滑迁移路径。
### 20.1 画布作为组合授权根
`CanvasGrant` 授权对象是一个可运行 Agent 流程的组合边界。管理员给用户授予画布的 `read / use / manage / export` 权限后,画布中的 Agent、Agent 关联知识库以及该 Agent 的已确认记忆按同一范围参与查看和运行;系统不再要求为同一画布重复配置记忆授权。该继承仅允许查看和使用,不把知识库或记忆的编辑、删除、导出能力传递给用户。用户运行后产生的新记忆使用当前用户作为 owner,默认保存为私有;管理员可查看、导出并发布到全局。记忆库页面继续提供个人记忆管理,管理端保留全组织审计和全局发布能力。
### 20.2 角色管理补充(v6.6)
角色属于租户级 RBAC 配置。管理员可以在管理控制台创建中文角色、填写职责说明、选择权限、修改权限并删除自定义角色。内置角色仅允许调整权限;自定义角色仍被成员使用时,删除请求返回业务冲突,避免成员瞬间失去权限。服务端为自定义角色生成内部标识,前端和导出报告只展示中文角色名称与中文权限名称。
权限目录:查看内容、内容编辑、内容审查、运行追踪、配置查看、系统配置、成员管理、管理控制台。角色接口为 `GET/POST/PUT/DELETE /api/auth/roles`,成员创建和修改会校验角色是否存在,并继承当前管理员所属组织。
### 20.3 记忆库治理补充(v6.6)
记忆记录采用“待确认 → 已生效 → 可索引调用”的状态链。除原有 Agent、层级、正文、来源和可见性外,记录还保存标题、描述、隐私范围、标签、沉淀日期、索引状态、使用次数和最近使用时间。人工编辑后进入 `needs_reindex`,索引完成后才可进入 Agent 快照;运行时优先加载高使用频次且已建立索引的记忆,单 Agent 加载上限为 50 条。
该设计对齐记忆库文章的五层记忆、两级分类、元数据、总索引/子索引和人工确认原则。生产云化阶段还需增加对象存储中的索引文件、来源证据、版本链、冲突检测和过期任务,且所有读写均按租户和画布授权范围执行。
### 20.4 SaaS 生产门槛
当前本地版已具备租户字段、用户级账单、资源行级授权和独立 `/app`、`/admin` 入口;上线 SaaS 前必须将 SQLite、本地文件和本地向量回退替换为云数据库、对象存储和托管向量索引,并接入密钥托管、限流、组织邀请、平台管理员分层、审计留存和账单结算。详见《SaaS与记忆库全面审查报告》。
## 20.5 点数余额规则(v6.7)
用户 AI 使用额度改为点数余额,统一换算为 `10 点数 = 1 Token`。用户端只能查看自己的点数和用量账单;管理端可以按组织成员增加点数并查看余额。余额低于 10 点数时,服务端在模型请求前返回“点数余额不足”,不向 Provider 发起请求。
每次模型调用成功后,根据实际输入与输出 Token 扣除 `Token × 10` 点数;Provider 未提供 Token 时按 1 Token 最低计量,并在 `UsageEvent` 中保留估算状态。充值与扣点均写入不可变 `PointTransaction` 流水,充值使用管理员操作幂等键,扣点使用模型用量事件幂等键。余额、流水和账单都按用户与组织隔离,多用户同时调用同一个模型时互不串账。
`UsageQuota` 及其管理接口仅保留为旧版本数据兼容,不再作为页面入口和运行时限制。管理端页面不再提供“成员配额”编辑器,平台的 AI 可用性只由点数余额控制;`UsageEvent` 仍用于成本、费率快照、Trace 和审计,不用于给用户充值。