50 KiB
雅文内容创造工作台 · v6 用户端、管理端与云化设计
文档日期:2026-08-27
文档状态:v6 设计 + v6.1 提示模板实现同步
关联文档:设计文档 v5
核心逻辑:核心逻辑设计文档 v6
从零落地:核心逻辑设计文档 v6:从 0 到 1
本文只修改设计文档,不代表本轮已经修改源码
0. 这次要解决什么
当前 v5 已经具备本地 Agent Runtime、知识库、任务编排、认证、Trace 和 KB3 稳定索引。本 v6 设计在此基础上增加六个企业化能力:
- 面向普通用户的用户端,以及面向运营人员的管理端。
- 按用户统计 AI 调用量、Token、Embedding、OCR 和存储量,并形成可审计的计费账单。
- 所有源文件、向量快照、产物和导出包迁移到云对象存储。
- 增加全局知识库、私有知识库和管理员授权共享机制。
- 模型连接、模型发现和模型费率全部收敛到管理端,用户端只选择已开放模型。
- 记忆库复用知识库的私有、共享、全局、授权、撤销、导出和审计逻辑。
本版本的关键原则是:所有权与使用权分离、全局资源与私有资源隔离、计费以真实调用账本为准、管理端可见但不能绕过审计。
1. 产品形态
1.1 用户端
普通用户只看到自己的工作空间,以及管理员授权给他的资源:
- 我的任务:创建任务、运行 Agent、查看进度、审查内容和下载成稿。
- 我的 Agent:创建和维护自己的生产 Agent、技能绑定和规则。
- 我的知识库:上传、分类、预览、检索和删除自己的私有素材。
- 全局知识库:读取管理员开放的公共资料;不能删除和修改原文。
- 共享知识库:管理员明确授予当前用户后才显示。
- 记忆库:管理自己的记忆,以及管理员授予的共享/全局记忆。
- 模型选择:只能从管理端已接入并开放的模型目录中选择,不能添加 Provider、API Key 或模型。
- 用量与账单:查看本月 AI 用量、余额/额度、调用明细和导出记录。
- 我的记忆:只管理自己的私有记忆,不能读取其他用户未授权的记忆。
1.2 管理端
管理员使用独立的管理端导航,不与用户端混在同一组页面里:
- 用户与组织:账号、状态、角色、所属组织和配额。
- 全局知识库:创建和维护所有用户可用的公共知识。
- 知识库总览:查看全部用户私有知识库的元数据、容量、索引状态和归属。
- 授权中心:把某个私有知识库授权给指定用户,或开放给全部用户。
- 记忆库总览:查看全部用户记忆、来源 Agent、可见性、使用者和版本。
- 模型目录:接入 Provider、维护模型列表、费率、能力、启用状态和用户可见范围。
- AI 用量与计费:按用户、Provider、模型、时间和任务查看用量与费用。
- 云存储与导出:导出数据库、知识库文件、向量索引、Trace 和账单。
- 安全审计:查看登录、权限变更、知识库授权、导出和计费调整记录。
管理端可以“看见”用户私有知识库的元数据和内容预览,但所有查看、下载、导出行为都要写入审计日志;默认不改变文件归属和内容。
2. 总体架构变化
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 账号层级
Organization
└── UserAccount
├── UserRoleBinding
├── UsageQuota
├── BillingAccount
├── KnowledgeBase(私有)
├── Agent
└── Memory
同一个用户只能在当前组织范围内使用组织资源。未来需要跨组织时,使用组织成员关系授权,不直接复用另一组织的用户 ID。
3.2 角色
| 角色 | 用户端能力 | 管理端能力 |
|---|---|---|
user |
使用自己的 Agent、私有库、获授权的共享库和全局库 | 无 |
reviewer |
额外执行内容审查、查看审查 Trace | 无用户管理能力 |
operator |
使用用户端全部功能 | 查看用户、处理导出、处理索引和授权申请 |
admin |
使用全部用户端功能 | 用户、知识库、权限、计费、云存储和审计全管理 |
owner |
组织内全部功能 | 当前组织最高权限,不跨组织 |
管理员接口和用户接口使用不同的权限前缀:
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。管理员可以执行两种授权动作:
- 授权给指定用户:保持私有归属不变,增加可使用者。
- 开放给全部用户:将可见性改为
global,所有用户可以检索,但只有管理员可以修改原文。
取消授权只影响后续检索,不删除原文件、不改变历史任务的引用快照。
4.2 访问判定顺序
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 增加:
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 表单只请求:
GET /api/models/available
返回当前用户所在组织可用的模型目录。用户选择的是目录 ID,不是 Provider 地址或自由文本;保存 Agent 时服务端再次校验目录状态和组织可见性。
模型目录变更不覆盖历史任务快照:
- 任务创建时保存 Provider、模型名、能力和费率版本。
- 管理员停用模型后,旧 Run 可以继续恢复或审计。
- 新建任务和重跑任务只能选择当前启用模型。
- 账单使用快照中的费率版本,不按当前目录价格回算历史费用。
5.3 模型相关审计
以下管理动作写入审计:Provider 新增/删除、API Key 替换、模型启停、费率变更、组织可见范围变更。用户只能看到自己的模型选择记录和调用账单,不能看到其他 Provider 的密钥、内部地址和组织费率策略。
5.4 多用户并发治理
多个用户同时使用同一个模型不会共享错上下文,原因是每次调用都绑定完整的归属键:
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;因此“等待”不会被误认为“模型混乱”。
模型目录必须使用版本化和软停用:
- 同一个 Provider 的模型名称变化时创建新的目录版本,不覆盖旧记录。
- 管理员停用只禁止新任务,不删除历史目录和账单费率。
- Provider 临时故障时只影响绑定该 Provider 的队列,其他模型继续运行。
- 用量账本使用调用发起用户归属,不使用最后一个修改 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,不把测试样例全文写入普通用户日志。
管理端可以单个测试、批量测试或按计划回归:
- 选择一个或多个已接入模型。
- 选择测试套件和生成参数,冻结测试输入、温度、最大输出长度和超时。
- 并行调用模型,记录每个样例的状态、输出哈希和断言结果。
- 计算通过率、成人内容兼容等级、稳定性和平均费用。
- 更新
ModelCatalog的能力状态;只有达到管理员设定阈值的模型才显示为“可用于成人内容”。 - 测试结束后生成 Trace 和报告,支持与上一个模型版本做回归对比。
Provider 侧的内容策略仍然会影响结果;出现 provider_blocked 时,目录应标记为“该 Provider 当前不支持此能力”,而不是把模型标记为已兼容。系统通过管理员选择其他已接入模型或调整路由来满足业务要求,测试结果不覆盖 Provider 的服务策略。
模型目录增加以下字段:
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、中转层、账号和版本下表现可能不同,外置审查和版本更新也会让之前的测试结果失效。这些属于社区观察,作为线索而不是生产结论:
- 关于破限/破甲的疑问:讨论了模型本体偏好与模型前置拦截层的差异。
- 破限词仓库没了,谁还有备份的:反映提示词仓库和测试结果存在时效性,且不同接入方式结果不同。
- 更新了破限工具的 ZCode 版本:提到成人向创作在不同模型上的结果差异,并指出本地部署模型更容易保持可控测试环境。
- 关于成人内容模型的公开讨论:显示社区通常按模型和接入渠道分别试用,而不是假设存在一个适用于全部 Provider 的固定方案。
系统据此采用以下工程结论:
- 不把“破限成功”作为永久能力,而是把它记录为“某 Provider + 某模型版本 + 某测试套件”的一次测试结果。
- 同一个目录模型至少测试直连 Provider 和实际中转/网关两条路径,区分模型行为与前置审查层行为。
- 每次模型版本、Provider 路由、系统提示词或外置审查配置变化,都触发
adult-content-compat回归;旧结果保留,新结果生成新版本。 - 失败结果必须区分
provider_blocked、gateway_blocked、model_refused、timeout、format_failed,不能用一个“破限失败”状态掩盖根因。 - 只有管理员可以查看原始测试输出和发布能力标签;用户端只看到已发布的能力等级和最后测试时间。
测试实现可采用 Promptfoo 的 Provider × Test Case × Assertion 矩阵,也可用 Garak 的 Probe/Detector 机制做回归探测;两者都应在工作台内部保存输入哈希、断言、通过率和 Trace,而不是直接把第三方工具输出当作生产路由结论。
6. 云存储设计
6.1 存储职责
云对象存储保存大文件和可导出产物,关系数据库只保存元数据、权限、哈希和生命周期状态。
| 数据 | 存储位置 | 数据库记录 |
|---|---|---|
| 原始上传文件 | 对象存储 | CloudObject + KnowledgeFile |
| 解析后的文本快照 | 对象存储 | 文件哈希和版本 |
| 向量索引快照 | 对象存储或托管向量库 | 索引版本和校验值 |
| Markdown/DOCX 成稿 | 对象存储 | Artifact 的对象键和哈希 |
| Trace 导出包 | 对象存储 | ExportJob |
| 账单导出 | 对象存储 | BillingExport |
6.2 对象键规范
对象键不使用用户原始文件名作为唯一标识,避免重名覆盖:
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 费用公式
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 计费时序
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:
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 只需补充:
organization_id
user_id
usage_event_id
billing_status
这样一次账单可以回溯到模型调用、Agent、内容段、任务和最终产物。
9. 用户端页面设计
9.1 首页总览
首屏显示四个指标:
- 本月已用 Token / 剩余额度。
- 本月预估费用 / 已结算费用。
- 私有知识库数量和存储占用。
- 当前运行任务和待审查数量。
顶部显示当前组织和账号,不显示其他用户的名称、用量或私有资源。
9.2 知识库页面
页面分为三个 Tab:
- 我的知识库:上传、分类、预览、重建、删除。
- 已授权知识库:只显示管理员授予当前用户的库。
- 全局知识库:只读浏览和检索,显示来源与版本。
每个知识库卡片显示:可见性、所有者、授权状态、文件数、分块数、索引状态、容量和最近更新时间。用户不能在列表中看到未授权私有库。
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 知识库总览与授权中心
管理端表格显示:
知识库名称 | 所有者 | 类型 | 文件数 | 容量 | 索引状态 | 使用者数 | 最近访问 | 操作
操作包括:查看、导出、分类维护、重建索引、授权指定用户、开放全局、撤销授权。任何“开放全局”操作都要二次确认,并记录变更前后的可见性。
10.3 记忆库总览与授权中心
管理员可以按用户、Agent、组织、可见性和状态查看全部记忆,并执行:
- 查看、预览和导出用户私有记忆。
- 授权指定用户使用某条记忆或某组记忆。
- 将记忆发布为组织全局记忆,或恢复为私有/共享状态。
- 修改版本、停用过期记忆、撤销授权和恢复授权。
管理员的查看、下载、导出和授权动作都写入 AccessAudit;撤销授权只影响新建任务,历史任务继续保留运行快照。
10.4 模型目录管理
管理员在模型目录页面完成 Provider 和模型生命周期管理:
- 新增 Provider 并安全保存 API Key。
- 调用 Provider 的模型发现接口。
- 逐个启用/停用模型,设置能力标签和费率版本。
- 按组织开放模型;用户端只读显示可用目录。
- 查看模型调用量、错误率、Token 和费用。
- 运行成人内容能力兼容性测试,查看版本间的通过率、拒绝率、超时率和成本变化。
- 仅在测试结果达到阈值后,发布或下架模型的“支持成人内容”能力标签。
10.5 计费管理
管理员可以设置 Provider/模型费率、套餐配额、预警阈值和超额策略;可以按用户、组织、任务和 Trace 查询费用,并对异常账单执行带原因的调账。
计费页面区分:
- 原始用量。
- 费率版本。
- 预估金额。
- 已结算金额。
- 管理员调整金额。
11. API 设计
11.1 用户端 API
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
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 兼容策略
- 现有
AppUser迁移为第一个Organization下的管理员账号。 - 现有
KnowledgeBase默认归属该组织和管理员,历史库先标记为private。 - 现有
Memory、Agent、Campaign、Segment、Trace 和 Artifact 追加organization_id/user_id,历史数据使用迁移时的拥有者补齐;历史记忆默认为private。 - 现有 Provider 和模型列表迁移为管理端
ModelCatalog,历史 Agent 的模型引用转换为目录 ID;用户端不继承 Provider 写入权限。 - 本地源文件先上传到对象存储,校验哈希一致后再切换读取路径。
- KB3 的 2,717 个分块和 512 维向量先作为一个 index version 上传,不重新计算 Embedding。
- 迁移完成前保留本地 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。
计费流程为:
请求进入
→ 解析发起用户和组织
→ 读取 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 和审计,不用于给用户充值。