# 雅文内容创造工作台 · 从 0 到 1 核心逻辑设计文档 v6 > 文档日期:2026-08-26 > 文档定位:从零开始理解、设计、实现和验收整套系统的主文档 > 关联文档:设计文档 v6:用户端、管理端与云化设计 > 当前实现参考:系统设计文档 v5 + v6.1/v6.2 已落地模块 > 交付范围:本文档描述系统逻辑和实施顺序,并同步记录已经实现的服务端、前端和数据迁移 ## 0. 先回答三个问题 ### 0.1 这个系统是什么 这是一个多用户内容生产平台。用户输入主题、导图或任务目标,系统通过多个 Agent 分工完成: ~~~text 理解任务 → 拆成内容段 → 调用知识和记忆 → 生成内容 → 质量检查 → 人工审查 → 组合成稿 → 保存到云端 → 记录用量和账单 ~~~ ### 0.2 为什么要拆成用户端和管理端 普通用户关注“完成内容”,管理端关注“控制资源”: | 端 | 关注点 | | --- | --- | | 用户端 | 创建任务、选择可用模型、使用知识库、审查内容、下载成稿、查看用量 | | 管理端 | 管理用户、Provider、模型目录、知识/记忆授权、点数、账单、云存储和审计 | 用户端只消费管理端开放的能力。Provider 凭据、模型发现、费率和能力标签由管理端统一维护。 ### 0.3 系统最重要的主线是什么 每一次生成都必须回答: ~~~text 谁发起的? 使用哪个 Agent 版本? 使用哪个模型版本? 读取了哪些获授权的知识和记忆? 产生了哪些调用和费用? 经过了哪些质检和人工决定? 最终交付了什么? ~~~ 这条主线就是系统的核心逻辑。 ## 1. 从零建立系统的顺序 从 0 到 1 不按页面数量推进,而按依赖关系推进: ~~~mermaid flowchart LR P0[P0 身份和组织] --> P1[P1 资源归属和权限] P1 --> P2[P2 模型目录] P1 --> P3[P3 知识库和记忆库] P2 --> P4[P4 Agent Runtime] P3 --> P4 P4 --> P5[P5 任务/QC/组合] P5 --> P6[P6 计费/云存储/审计] P6 --> P7[P7 验收和运营] ~~~ | 阶段 | 目标 | 产出 | | --- | --- | --- | | P0 | 让系统知道谁在使用 | Organization、User、Session | | P1 | 让资源有边界 | owner、visibility、grant、RBAC | | P2 | 让模型受控可选 | Provider、ModelCatalog、能力标签 | | P3 | 让 Agent 有事实和经验 | KnowledgeBase、Memory、引用和消费状态 | | P4 | 让 Agent 可稳定执行 | Runtime、工具、审批、恢复、Trace | | P5 | 让内容可交付 | Campaign、Segment、QC、人工审查、Composer | | P6 | 让平台可运营 | 云存储、计量、账单、导出和审计 | | P7 | 让系统可上线 | 权限矩阵、故障演练、数据迁移和验收 | ## 2. 第一层:身份、组织和角色 ### 2.1 组织 组织是数据隔离的第一层。个人工作区也按一个组织处理: ~~~text Organization └── UserAccount ├── Agents ├── KnowledgeBases ├── Memories ├── Campaigns ├── UsageQuota └── BillingAccount ~~~ 所有业务对象都保存 organization_id。跨组织读取必须通过明确的组织授权关系。 ### 2.2 用户 用户至少有以下属性: | 字段 | 作用 | | --- | --- | | user_id | 稳定的用户标识 | | organization_id | 所属组织 | | username | 登录名 | | display_name | 工作台展示名称 | | status | 启用、停用、锁定 | | role | 用户、审查者、运营、管理员 | | quota_id | 当前配额方案 | ### 2.3 角色 | 角色 | 主要能力 | | --- | --- | | user | 使用自己的资源和已授权资源,运行任务和查看自己的账单 | | reviewer | 额外执行人工审查、处理打回和工具审批 | | operator | 处理用户、索引、导出和授权运营工作 | | admin | 管理组织、Provider、模型、知识、记忆、计费和审计 | | owner | 当前组织的最高管理权限 | 角色只决定“能做什么”,资源授权决定“能对哪份数据做”。两者同时成立才允许执行。 ## 3. 第二层:资源所有权和可见性 ### 3.1 资源统一字段 ~~~text organization_id owner_user_id visibility access_grants ~~~ 适用对象:Agent、知识库、知识文件、记忆、画布、任务、Trace、产物和导出包。 ### 3.2 三种可见性 | 可见性 | 默认使用者 | 修改者 | | --- | --- | --- | | private | 所有者及其 Agent | 所有者或管理员 | | shared | 被授权用户 | 所有者和管理员 | | global | 当前组织全部用户 | 管理员 | ### 3.3 统一访问判断 ~~~text 1. 认证当前用户 2. 确认组织范围 3. 确认资源存在且状态有效 4. 判断是否为所有者 5. 判断是否为 global 6. 判断是否存在 active grant 7. 判断操作权限 read/use/manage/export 8. 记录审计并执行 ~~~ 查询层先生成允许访问的 ID 集合,再读取数据。前端入口控制只是体验措施,真正的权限判断必须在 API 和数据查询层完成。 ## 4. 第三层:模型目录逻辑 ### 4.1 Provider 和模型的关系 ~~~text Provider └── ModelCatalog ├── 模型真实名称 ├── 能力标签 ├── 费率版本 ├── 组织可见范围 └── 启用状态 ~~~ Provider 保存连接信息;ModelCatalog 保存用户可选的模型能力。用户端只接触 ModelCatalog。 ### 4.2 管理端操作顺序 ~~~text 新增 Provider → 安全保存凭据 → 发现模型列表 → 规范化模型记录 → 设置能力和费率 → 设置组织可见范围 → 启用模型 ~~~ 管理端可以管理 Provider、发现模型、修改能力标签、停用模型和调整费率版本。每次变化都写审计。 ### 4.3 用户端操作顺序 ~~~text GET /api/models/available → 返回当前组织可用目录 → 用户选择目录 ID → 服务端校验 enabled、visibility、capabilities 和 quota → 写入 Agent 或任务快照 ~~~ 用户端表单不接收 Provider 地址、API Key、模型自由文本和费率字段。 ### 4.4 成人内容能力测试 系统把“破限”定义为管理员维护的模型能力兼容性测试: ~~~mermaid flowchart TD A[选择模型目录] --> B[选择版本化测试套件] B --> C[冻结样例、参数和 Provider 路径] C --> D[执行多模型/多网关测试] D --> E[逐样例断言] E --> F[统计通过率、拒绝率、超时率和费用] F --> G[管理员发布能力标签] G --> H[用户端读取标签并选择] ~~~ 结果至少区分: ~~~text supported partial provider_blocked gateway_blocked model_refused timeout format_failed ~~~ 模型版本、Provider 路径、网关配置或系统提示词变化后重新回归。旧结果保留,新结果生成新版本。用户端只看到管理员发布的能力标签和测试时间。 ## 5. 第四层:知识库逻辑 ### 5.1 知识库创建 ~~~text 用户或管理员创建 KnowledgeBase → 写入组织和所有者 → 默认 visibility=private → 创建云存储前缀 → 创建向量索引命名空间 → 状态=empty ~~~ 普通用户创建的库默认属于本人。管理员可以把库授权给指定用户,或发布为当前组织的全局库。 ### 5.2 文件导入 ~~~mermaid flowchart LR U[上传文件] --> H[计算 SHA-256] H --> O[写云对象临时版本] O --> P[解析 docx/srt/md/txt/json/jsonl] P --> C[清洗和语义分块] C --> E[Embedding] E --> V[写向量索引] V --> M[写文件元数据和分类] M --> R[状态=ready] ~~~ 文件表保存:文件名、哈希、修订号、分类、AI 分类建议、置信度和状态。重复上传同名文件时,先替换旧向量,再增加修订号。 ### 5.3 AI 分类和人工确认 ~~~text unclassified → AI 生成分类建议 → ai_suggested → 人工确认/修改/移动 → human_confirmed ~~~ 分类树使用 parent_id 支持无限层级。文件移动分类只改变文件归属和向量元数据中的分类路径,原始文件哈希保持不变。 ### 5.4 知识检索 Agent 检索输入由四部分组成: ~~~text 任务段目标 + 上游锚点卡 + Agent 规则中的检索意图 + 当前用户允许的知识库集合 + 当前 Agent 已消费 chunk 的排除集合 ~~~ 检索结果必须带知识库、文件、分类路径、chunk ID、原文、相似度、文件哈希和修订号,并写入 Segment.references。 ### 5.5 知识消费规则 消费锁按 Agent 隔离: ~~~text Agent A 使用 chunk-001 → A 后续排除 chunk-001 Agent B 未使用 chunk-001 → B 仍可检索 chunk-001 ~~~ 状态流转: ~~~text available → reserved → consumed reserved → available(任务中断或模型失败) consumed → available(管理员人工释放) ~~~ 数据库使用 agent_id、kb_id、chunk_id 的组合唯一约束,避免并发重复认领。 ### 5.6 知识库共享 管理员通过 KnowledgeBaseGrant 授权: | 权限 | 能力 | | --- | --- | | read | 浏览和预览原文 | | use | Agent 检索和消费 chunk | | manage | 分类、重建、删除和文件维护 | | export | 在范围内创建导出任务 | 授权撤销后,新任务立即按新权限计算;已创建任务继续使用快照中的引用和版本。 ## 6. 第五层:记忆库逻辑 ### 6.1 记忆从哪里来 ~~~mermaid flowchart LR A[QC 意见/人工修改/失败原因] --> B[PendingMemory] B --> C[人工确认] C --> D[Memory] D --> E[绑定来源 Agent、版本和可见性] E --> F[后续任务注入] ~~~ 未确认记忆处于待处理状态,不进入有效 Agent 记忆上下文。 ### 6.2 记忆与知识库同构 记忆同样拥有 owner_user_id、organization_id、visibility 和授权记录: | 范围 | 读取者 | 编辑者 | | --- | --- | --- | | private | 所有者及其 Agent | 所有者 | | shared | 被授权用户 | 所有者和管理员 | | global | 当前组织全部用户 | 管理员 | 管理员可以查看、导出、授权、撤销、发布全局和恢复私有。用户只能读取自己的记忆、已授权记忆和全局记忆。 ### 6.3 记忆注入 ~~~text 任务用户/组织校验 → 计算 allowed_memory_ids → 过滤 active 状态、来源 Agent 和版本 → 注入 Agent Runtime → 写入任务快照 ~~~ 记忆内容作为数据输入,优先级低于 Runtime 系统规则。任务创建后,撤销授权不会覆盖已有快照。 ## 7. 第六层:Agent 定义和画布 ### 7.1 Agent 定义 一个 Agent 至少包含: ~~~text name role rules + rules_version content_tags skill_bindings kb_bindings memory_scope model_catalog_id status ~~~ Agent 定义描述“它擅长什么”;画布节点描述“这次任务是否在这里执行它”。 ### 7.2 画布 ~~~text Canvas.nodes = [{node_id, agent_id, enabled}] Canvas.edges = [{from_node, to_node}] ~~~ 节点表示执行实例,边表示锚点卡依赖。一个 Agent 可以放置多个节点,支持同类内容并行生成。 ### 7.3 波次调度 ~~~mermaid flowchart TD A[读取节点和边] --> B{存在环?} B -- 是 --> X[拒绝运行并提示环路] B -- 否 --> C[计算入度] C --> D[找入度为0的节点] D --> E[同一波次并行执行] E --> F[完成后更新下游入度] F --> G{还有节点?} G -- 是 --> D G -- 否 --> H[调度完成] ~~~ 停用节点不进入执行波次,下游收到 skipped 状态。 ### 7.4 融合 Agent 融合 Agent 接收多个生产 Agent 的结构化结果,把不同写法合成一个自然段: ~~~text 任务段 + 心法结果 + 钩子结果 + 场景结果 + 上游锚点 → 融合正文 → 统一锚点卡 ~~~ 融合过程不拼接内部推理,不重复调用未授权知识,最终文本遵守任务的默认口语样式。 ## 8. 第七层:Agent Runtime ### 8.1 Runtime 负责什么 Runtime 是所有 Agent 的统一执行壳,负责: - 创建和恢复 AgentSession。 - 发送模型请求和接收工具调用。 - 记录 LLMCall、RunEvent、Span 和 Token。 - 管理工具参数、审批和结果回放。 - 执行输入/输出护栏。 - 响应取消、超时和服务重启。 业务层负责任务内容,Runtime 负责执行可靠性。 ### 8.2 会话数据 每个会话保存: ~~~text session_id run_id / campaign_id / segment_id agent_id / agent_name / phase trace_id / parent_session_id status / turn / max_turns messages / tool_state result_text / result_meta / error ~~~ 消息历史属于当前 Session,不放在 Provider 全局上下文中。多个用户同时使用同一模型时,消息、权限和 Trace 仍然彼此分开。 ### 8.3 Runtime 状态机 ~~~mermaid stateDiagram-v2 [*] --> running running --> waiting_approval: 工具需要审批 waiting_approval --> running: 批准或拒绝 running --> interrupted: 进程中断 interrupted --> running: 恢复 running --> completed: 输出通过护栏 running --> failed: 模型/工具/护栏失败 running --> cancelled: 收到取消请求 completed --> [*] failed --> [*] cancelled --> [*] ~~~ ### 8.4 工具调用 ~~~text 模型提出 tool_call → 校验工具是否注册 → 校验参数是否为 JSON 对象 → 判断是否需要人工审批 → 执行工具 → 写入工具结果 → 继续模型循环 ~~~ 工具调用有独立 span_id,并通过 parent_span_id 指向触发它的模型请求。 ### 8.5 护栏 | 护栏 | 规则 | | --- | --- | | 输入 | 空输入、超长输入进入失败状态 | | 工具 | 未注册工具和非法参数返回工具错误 | | 输出 | 空输出、超长输出进入失败状态 | | 轮次 | 达到最大轮次后结束并记录原因 | | 取消 | 任务取消后不再发起新的模型请求 | ## 9. 第八层:内容任务生产链路 ### 9.1 从主题到任务段 ~~~text 用户输入主题/导图 → Coordinator 拆解 → 生成 Segment 列表 → 每段绑定标签、时间、目标 Agent → 标记待确认项 → 用户确认后进入 Run ~~~ ### 9.2 单个内容段 一个 Segment 的最小输入: ~~~text content_tag title time_range mindmap_node product_ref upstream_anchor_cards agent_snapshot allowed_kb_ids allowed_memory_ids model_snapshot ~~~ 输出必须包含正文、引用列表、锚点卡、状态和运行 Trace。 ### 9.3 内容段状态 ~~~text pending → running → qc → human_review → approved ├→ rework → running ├→ failed └→ skipped ~~~ 失败段不吞掉其他段;任务整体显示待处理失败,直到人工修复、重跑、跳过或停用。 ## 10. 第九层:QC、人工审查和组合 ### 10.1 四道 QC | 闸门 | 检查内容 | | --- | --- | | structure | 标题、时间、顺序、段落完整性 | | content | 事实、引用、任务目标和内容覆盖 | | style | 大白话、口播感、品牌语气和格式 | | cross | 与上下游锚点、产品、概念和情绪曲线一致 | 每道 QC 都要输出带状态的检查项。空检查列表不视为通过。 ### 10.2 人工审查 QC PASS 只表示自动检查通过,内容仍进入人工审查。人工可以: - 通过。 - 打回并填写意见。 - 修改内容后重新质检。 - 选择换模型重跑。 - 选择调整任务切片重跑。 - 跳过本段并让组合器显示缺段。 人工决定写入审查事件,并关联当前 Segment 和 Trace。 ### 10.3 组合器 Composer 只读取人工通过的段落: ~~~text 读取通过段落 → 按画布和内容顺序排序 → 对齐锚点卡 → 检查全文一致性 → 生成组合报告 → 输出 Markdown/DOCX → 写 Artifact 和下载地址 ~~~ 存在缺段、跨段矛盾或总检失败时,Campaign 保持审查状态,不生成已交付状态。 ## 11. 第十层:多用户并发隔离 ### 11.1 调用归属键 所有运行和模型调用绑定: ~~~text organization_id user_id campaign_id run_id trace_id span_id session_id ~~~ 同一模型被多个用户同时使用时,系统按 Session 组装消息,按用户和组织写入账单。 ### 11.2 四层限制 | 层级 | 限制 | | --- | --- | | 用户 | 并发任务、Token、存储和导出额度 | | 组织 | 总并发、总预算、总 Token | | 模型 | Provider QPS、连接数、超时和重试 | | 任务 | 同一 Campaign 一个活跃 Run | 队列等待、限流、重试和取消写入 Trace。一个 Provider 的故障只影响绑定它的队列。 ## 12. 第十一层:计费和用量 ### 12.1 计量事件 每一次 AI 或存储行为追加一条 UsageEvent: ~~~text user_id organization_id run_id / trace_id provider / model service_type quantity pricing_version status idempotency_key ~~~ 计量对象包括:LLM 输入/输出 Token、Embedding、OCR、Rerank、云存储和导出。 ### 12.2 费用计算 ~~~text LLM 费用 = 输入 Token × 输入费率 + 输出 Token × 输出费率 总费用 = LLM + Embedding + OCR + Rerank + 存储 + 导出 ~~~ 费用使用调用时冻结的费率版本。Provider 未返回 Token 时,估算值必须标记为 estimated,不能直接作为已结算值。 ### 12.3 配额检查 ~~~text 创建任务前检查额度 → 进入模型队列前检查并发 → 调用返回后记录真实用量 → 任务结束后完成结算 ~~~ 支持 warn、soft_limit 和 hard_limit 三种策略。 ## 13. 第十二层:云存储和导出 ### 13.1 存储分工 | 数据 | 云对象存储 | 关系数据库 | | --- | --- | --- | | 原始文件 | 文件正文 | 哈希、版本、归属、对象键 | | 文本快照 | 解析后的文本 | 版本和状态 | | 向量索引 | 索引文件或托管向量库 | 索引版本和校验值 | | 最终成稿 | Markdown/DOCX | Artifact 元数据 | | Trace/账单导出 | ZIP/JSON/CSV | ExportJob 状态 | ### 13.2 文件生命周期 ~~~text uploading → stored → indexed → active active → superseded → recycle_bin → deleted uploading → orphaned → deleted ~~~ 对象键使用组织、用户、知识库、文件哈希和安全文件名,防止同名覆盖。数据库提交失败时对象保持临时状态,清理任务回收孤儿对象。 ### 13.3 导出 导出包必须带 manifest.json,列出对象键、文件哈希、归属、分类、授权、Trace、账单范围、发起人和过期时间。下载通过短时效签名地址完成。 ## 14. 第十三层:认证、RBAC 和审计 ### 14.1 登录 ~~~text 读取 Bearer Token → 查询 Token 摘要 → 检查 Session 是否撤销/过期 → 检查用户状态 → 解析组织和角色 → 更新 last_seen_at ~~~ 密码使用 PBKDF2-SHA256 派生摘要,Session 数据库存储 Token 摘要。 ### 14.2 审计事件 以下事件必须记录操作者、目标对象、前后值、Trace、时间和结果: - 登录、退出和 Session 撤销。 - 角色、组织和配额变化。 - Provider/API Key、模型启停和费率变化。 - 知识库/记忆库查看、下载、授权、撤销和全局发布。 - 文件、索引、任务、产物和导出删除。 - 账单结算和管理员调账。 - 成人内容能力测试和标签发布。 ## 15. 第十四层:数据模型最小集合 ### 15.1 身份和权限 ~~~text Organization AppUser / UserAccount AuthSession UserRoleBinding ~~~ ### 15.2 Agent 和任务 ~~~text Agent AgentSkill AgentSkillBinding Canvas Campaign CampaignRun Segment AgentSession RunEvent LLMCall QCReport Artifact ~~~ ### 15.3 知识、记忆和授权 ~~~text KnowledgeBase KnowledgeFile KnowledgeCategory KnowledgeBaseGrant KnowledgeUsage PendingMemory Memory MemoryGrant ~~~ ### 15.4 模型、计费和云存储 ~~~text ModelProvider ModelCatalog ModelOrganizationGrant ModelCapabilityTest UsageEvent UsageRate UsageQuota BillingAccount UsageSettlement BillingAdjustment CloudObject ExportJob AccessAudit ~~~ ## 16. 第十五层:API 逻辑边界 ### 16.1 用户端 API ~~~text /api/auth/* /api/models/available /api/agents /api/canvases /api/kbs /api/memories /api/campaigns /api/segments /api/runs /api/traces /api/me/usage /api/me/billing ~~~ 每个接口都使用当前用户和组织上下文,资源查询按 owner、visibility 和 grant 过滤。 ### 16.2 管理端 API ~~~text /api/admin/users /api/admin/organizations /api/admin/model-providers /api/admin/models /api/admin/models/{id}/capability-tests /api/admin/knowledge-bases /api/admin/memories /api/admin/usage /api/admin/billing /api/admin/exports /api/admin/audit ~~~ 管理端接口要求管理权限;导出、密钥、计费调整和全局发布使用更细粒度权限。 ## 17. 第十六层:从 0 到 1 的实施计划 ### P0:建立可登录的工作区 1. 创建 Organization。 2. 创建第一个 admin。 3. 建立 AppUser、AuthSession 和角色表。 4. 所有 API 统一接收用户和组织上下文。 5. 首次启动完成认证状态检查。 验收:管理员可以登录、退出、撤销 Session,普通请求没有身份时进入认证流程。 ### P1:建立资源边界 1. 给 Agent、知识库、记忆、任务、Trace 和产物补齐 owner/organization 字段。 2. 建立 private/shared/global 规则。 3. 建立统一 grant 表和权限判定服务。 4. 为查看、使用、管理和导出分别设权限。 验收:用户之间的数据查询互相隔离,管理员可以审计跨用户访问。 ### P2:建立管理端模型目录 1. Provider 只在管理端创建。 2. 管理端发现并规范化模型。 3. 建立 ModelCatalog、能力标签和费率版本。 4. 用户端只读取 available 模型。 5. 加入成人内容能力测试和回归版本。 验收:用户可以选择已开放模型,管理端可以停用模型和发布能力标签,历史任务快照保持原样。 ### P3:建立知识库和记忆库 1. 上传文件到对象存储。 2. 解析、分块、Embedding 和索引。 3. AI 分类建议和人工确认。 4. 建立知识消费锁。 5. 建立 PendingMemory 到 Memory 的确认流程。 6. 让记忆复用知识库的授权逻辑。 验收:用户只检索允许的知识/记忆,同一 Agent 不重复消费已用 chunk,其他 Agent 仍可使用。 ### P4:建立 Agent Runtime 1. 创建 AgentSession。 2. 加载任务快照。 3. 执行模型调用、工具调用和审批。 4. 写入 LLMCall、RunEvent、Span 和 Trace。 5. 支持取消、失败、重试和服务重启恢复。 验收:一次会话可以恢复;工具审批不会丢失;多用户上下文彼此隔离。 ### P5:建立内容生产和交付 1. Coordinator 将导图拆成 Segment。 2. 画布按拓扑波次调度。 3. Production Agent 生成内容和锚点卡。 4. 四道 QC 输出检查项。 5. 人工通过、打回、重跑或跳过。 6. Composer 组合通过段落并生成 Artifact。 验收:缺段和失败段有明确状态;只有通过人工审查的段落进入最终成稿。 ### P6:建立计费、云存储和运营 1. 将 LLMCall、Embedding、OCR、存储和导出接入 UsageEvent。 2. 建立 UsageRate、Quota、Settlement 和 Adjustment。 3. 建立云对象版本、导出包和 manifest。 4. 建立管理员总览和审计页面。 验收:费用可以回溯到用户、任务、Run、Trace、模型和 Agent;导出内容可按 manifest 恢复。 ## 18. 一次完整运行示例 ~~~text 用户 USER_A 登录 ORGANIZATION_X → 选择管理员开放的 MODEL_CATALOG_01 → 创建“今晚直播任务” → 选择画布 CANVAS_01 → Coordinator 拆出 8 个 Segment → 任务快照冻结 Agent/规则/技能/知识/记忆/模型/费率 → Runtime 为每段创建独立 Session → 生产 Agent 检索允许的知识库 → 当前 Agent 排除已经消费过的 chunk → 输出正文、引用和锚点卡 → 四道 QC 检查 → 用户人工审查并通过 8 段 → Composer 组合成 Markdown/DOCX → Artifact 上传云存储 → UsageEvent 记录 Token 和费用 → Trace 页面回放整次运行 ~~~ 如果某段失败: ~~~text 记录失败原因 → 释放 reserved chunk → 其他段继续执行 → 通知用户/管理员 → 人工选择重试、换模型、改规则、调整切片或跳过 → 重新质检并更新 Trace ~~~ ## 19. 最终验收清单 ### 19.1 身份和权限 - 首次启动可以创建管理员。 - 用户端和管理端入口分离。 - 用户只能读取自己的资源和有效授权资源。 - 管理端跨用户操作都有审计。 ### 19.2 模型 - Provider 只由管理端维护。 - 用户只能选择开放模型目录。 - 模型版本、能力标签和费率可追踪。 - 成人内容能力测试有版本、断言、结果和回归记录。 ### 19.3 知识和记忆 - 私有、共享、全局逻辑一致。 - AI 分类建议可人工确认、修改和移动。 - Agent 级消费锁生效。 - 待确认记忆不会提前进入生产上下文。 ### 19.4 运行和交付 - 任务快照保证运行可复现。 - Agent Runtime 支持工具、审批、取消和恢复。 - QC、人工审查和组合状态清晰。 - 失败段不会伪装成成功成稿。 ### 19.5 计费和云端 - 每次模型调用都有用户、组织、Run 和 Trace 归属。 - 估算、计量和结算状态可区分。 - 文件、向量、产物和导出包有哈希与版本。 - 导出包带 manifest,可进行完整核对。 ## 20. 结论 从 0 到 1 建设这套系统,先建立身份和数据边界,再接入受控模型,随后建设知识/记忆和 Runtime,最后接入任务生产、审查、组合、计费和云存储。 核心逻辑不是某个单独页面,而是下面这条可追溯闭环: ~~~text 身份 → 资源权限 → 配置快照 → Agent 执行 → 知识/记忆引用 → 模型调用 → QC/人工决定 → 成稿产物 → 用量账单 → Trace/审计 ~~~ 只要这条闭环稳定,后续增加更多 Agent、模型、知识库、用户和云存储容量,都可以沿着同一套规则扩展。 ## 21. 提示工程落地补充(v6.1,已实现) 提示工程不再作为散落在执行器里的字符串,而是作为独立的 `AgentPromptTemplate` 配置管理。模板包含: ```text name / desc role_prompt / task_template constraints[] / examples[] output_schema / style version / enabled / builtin ``` 新任务创建时,Agent 快照同时冻结规则、技能、记忆、模型和提示模板版本。运行时按固定顺序组织上下文: ```text 角色 → 任务模板 → 表达风格 → Agent 规则 → 模板约束 → Zero/One/Few-Shot 示例 → 技能、融合建议、记忆、上游锚点 → 知识库材料 → Runtime 硬规则 → 输出协议与 Schema ``` 模板支持的变量包括 `{agent_name}`、`{agent_role}`、`{title}`、`{content_tag}`、`{time_range}`、`{mindmap_node}` 和 `{product_ref}`。未知变量保持原样,避免普通花括号被误替换。 输出协议当前用于锚点卡 JSON。运行器在正文落盘前执行轻量 Schema 校验,至少检查 JSON 对象、`required` 字段和字段类型;校验失败会释放本轮知识片段并进入重做/人工处理,不会把无效结果标记为已交付。 管理端新增 `/api/prompt-templates` CRUD 页面,Agent 管理页可以绑定启用模板。模板内容变化自动递增版本;被 Agent 使用的模板不能直接删除,内置模板只允许停用。旧任务使用冻结快照,不随模板后续修改漂移。 这部分把文章中的“角色 + 任务 + 约束 + 示例 + 结构化输出 + 测试闭环”映射到工作台,同时保留知识库来源边界、Agent 消费锁、锚点连续性、QC 和人工审查等既有硬规则。 ### 21.1 任务契约:把业务目标锁进每一次生成 参考本地部署实践,任务不能只提交一段导图。新任务还要填写两个字段: ```text objective 本次任务唯一业务目标 success_criteria 人工可以逐条判断的验收标准 ``` 这两个字段会写入 `Campaign`,并在 `CampaignRun.config_snapshot.campaign_contract` 中冻结,同时记录导图哈希。它们贯穿 Coordinator 拆解、Segment 生成、四道 QC 和 Composer 总检: ```text 业务目标 + 验收标准 → 拆解时每段只服务一个目标 → 生成时禁止脱离目标自行扩展 → QC 判断目标覆盖和标准满足情况 → 组合时核对全文是否仍然完成原目标 ``` 旧任务缺少这两个字段时使用兼容默认值,不影响历史运行;新任务必须同时填写唯一目标和验收标准。目标与导图冲突时由人工确认,不由 Agent 猜测或偷偷扩展范围。 ## 22. 模型目录落地补充(v6.2,已实现) Provider 与用户可选模型已经拆为两层: ```text ModelProvider(管理端连接信息、API Key、Base URL) └── ModelCatalog(用户端可见模型、能力标签、费率版本、启用状态) ``` Provider 新增、编辑或同步模型清单时,系统会幂等写入 `ModelCatalog`;不再出现在 Provider 清单中的历史模型会被停用而不是物理删除,保证历史任务快照仍可追溯。用户端只访问 `GET /api/models/available`,返回模型目录 ID、显示名称、能力状态和费率版本,不返回 Provider 地址或密钥。 Agent 可以保存 `model_catalog_id`。服务端创建和更新 Agent 时会校验目录项、Provider 状态和真实模型名称,拒绝不存在、停用或不属于 Provider 清单的模型。任务快照同时记录目录项信息,Provider 配置变化不会覆盖历史运行。 管理端模型目录使用 `GET/PUT /api/admin/models`,Provider、模型发现、模型测试和默认模型配置统一收敛到管理权限;普通用户只能读取已启用目录。前端 Agent 管理页已从 Provider 列表切换为可用模型目录。 ## 23. 资源边界与授权落地(v6.3 P1,已实现) 本阶段把多用户隔离从设计约定落实为服务端统一判定。新增 `Organization`,并为 Agent、Canvas、Campaign、KnowledgeBase、PendingMemory、Memory、Artifact 和 AppUser 增加 `organization_id`、`owner_user_id`、`visibility`。新建资源默认绑定当前登录用户;普通用户提交的 `global/shared` 请求会被强制收敛为 `private`,只有管理员可以发布范围。 知识库和记忆库分别增加授权表: ```text KnowledgeBaseGrant(kb_id, user_id, permission) MemoryGrant(memory_id, user_id, permission) ``` 授权级别为 `read / use / manage / export`,其中 `use` 包含读取,`manage` 包含全部操作,`export` 只允许导出和读取。全局资源允许组织内用户读取和使用;共享资源必须命中有效授权;私有资源只对所有者和管理员可见。权限撤销后,新请求立即失效,历史任务仍由快照保留可追溯记录。 服务端所有知识库详情、上传、分类、索引、检索、消费释放和删除操作都经过统一访问辅助层;Agent 挂接知识库、融合 Agent、画布节点也会验证当前用户的使用权限。任务、Run、Agent Session、审查、组合和成稿下载/预览沿 Campaign 归属检查,避免通过关联 ID 绕过资源边界。成稿和待确认记忆在生成时继承任务的组织、所有者和可见性。 管理端授权接口: ```text 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 GET /api/admin/memories POST /api/admin/memories/{id}/grants DELETE /api/admin/memories/{id}/grants/{grant_id} POST /api/admin/memories/{id}/publish-global GET /api/auth/roles PUT /api/auth/roles/{role} 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 ``` 管理员可以查看所有知识库、记忆及授权对象;普通用户仍只调用用户端列表和检索接口。迁移采用幂等列补齐和 `create_all`,不删除原始文件、SQLite 数据、向量索引或历史成稿。当前已通过资源隔离、授权分级、旧功能回归和真实数据库启动验证。 ## 24. 用量计量与账单落地(v6.4 P2/P3,已实现) 本阶段把模型、向量和 OCR 的消耗统一纳入追加式 `UsageEvent` 账本。事件保存用户、组织、任务、Run、Segment、Trace、Agent、Provider、模型、服务类型、计量单位、输入/输出数量、费率版本、金额(人民币分)和幂等键;同一幂等键重复写入时复用原事件,不修改历史金额。 ```text LLMCall(user_id, organization_id, usage_event_id, billing_status) └── UsageEvent(service_type=llm, unit=token) Embedding 建库/重建/检索 ──> UsageEvent(service_type=embedding) OCR 导图识别 ──> UsageEvent(service_type=ocr, unit=image) ``` 模型目录中的 `input_rate / output_rate / rate_version` 在调用返回时复制到事件,费用使用整数分计算;Provider 未返回 Token 时保留 `estimated` 状态,不伪装成已测量值。运行记录保存 `user_id / organization_id`,管理员代运行时账单归属发起运行的账号,普通任务则继承任务所有者。 用户端接口为 `GET /api/usage/summary` 和 `GET /api/usage/events`,只返回当前账号在本组织内的事件;工作台新增“用量与账单”页面,支持日/月、服务类型筛选、Token/费用/事件统计和 Trace 明细。管理端接口为 `/api/admin/usage/summary`、`/api/admin/usage/events`、`/api/admin/quotas`,可按用户、模型、服务和周期审计,并通过配额接口配置 Token、金额、存储、并发上限及 `warn / soft_limit / hard_limit` 策略。 任务启动前执行配额检查;未配置配额时保持兼容,配置软/硬上限后达到 Token 或金额上限返回 429。`UsageQuota` 与事件账本使用唯一约束和索引,服务重启通过幂等迁移补齐,不影响既有任务、成稿、知识向量和 Trace。 ## 25. 企业级双入口与权限边界(v6.5,已实现) 参考 Microsoft 365/Entra 管理中心和 Keycloak 的通用模式,系统采用“同一身份、两个入口、服务端统一授权”的结构: ```text 同一账号与组织 ├── /app 用户工作台:全部业务能力,数据只显示本人/已授权/全局资源 └── /admin 管理控制台:全部业务能力 + 全组织配置、授权、审计与访问控制 ``` 管理员登录后默认进入 `/admin`,普通成员直接进入 `/app`。两个入口是严格隔离的路由:管理员访问 `/app`、普通成员访问 `/admin` 都会被入口守卫拦截,不显示另一门户内容,也没有门户切换或跳转按钮。两端共享认证会话和业务组件,但以账号角色决定唯一可进入的门户;服务端仍以 RBAC 和资源行级权限作为最终判定。 服务端权限按“入口 + 资源 + 操作”三层执行。用户端保留任务、Agent、画布、标签、技能、提示模板、知识库、记忆库、模型目录和用量账单等全部业务页面;其中 Agent、画布、标签、技能、模板、知识库、记忆和任务按本人/已授权/全局范围过滤,用户创建的资源默认为私有。Provider 连接、API Key、模型发现、模型目录费率与能力发布、全组织授权、配额和访问控制只在管理端执行。编辑角色可以管理自己的业务资源,审查角色执行审查动作,查看角色保持只读。前端入口隔离用于降低误操作,真实限制由中间件和资源访问层共同完成。 用户端与管理端共享登录会话和审计链,但使用不同导航、工作区标题、入口地址和 API 权限。用户端的“用量与账单”只查询当前用户事件,不展示配额编辑器;Token、金额、存储和并发配额只能由管理端配置。管理端可以查看全组织账单与资源,用户端只能查看本人、已授权和全局资源。两端后续可以拆成两个独立前端部署,不需要重写业务 API。 画布授权规则:`CanvasGrant` 是 Agent 流程的授权根。管理员向用户授予画布的 `read / use / manage / export` 权限后,画布节点中的 Agent 及其挂接知识库、确认记忆按同一流程范围提供查看或运行能力;该继承只覆盖查看和运行,不放大资源的编辑、删除或导出权限。用户在授权画布运行中产生的新记忆仍以当前用户为 owner、默认 private;管理员可以在管理端查看、导出并单独发布到全局。记忆库页面保留用于查看、确认和删除用户自己的记忆,但不再提供单独的用户授权入口。 ### 25.1 自定义角色生命周期与中文权限目录(v6.6) 角色不再是前端写死的四个选项。管理员在“访问控制 → 角色权限矩阵”中填写中文角色名称、职责说明并勾选权限,服务端生成内部角色标识;成员分配角色时只显示中文名称。系统内置“管理员、编辑、审查、只读”只能调整权限,不能删除;自定义角色没有成员使用时可以删除,仍被成员使用时先调整成员角色再删除。 ```text GET /api/auth/roles POST /api/auth/roles PUT /api/auth/roles/{role} DELETE /api/auth/roles/{role} ``` 权限目录的界面名称为“查看内容、内容编辑、内容审查、运行追踪、配置查看、系统配置、成员管理、管理控制台”。英文键只存在于服务端判定和数据库,不作为用户界面文案。每次请求都重新读取角色权限,角色调整不需要重启服务。 ### 25.2 记忆元数据与索引加载规则(v6.6) 记忆记录新增 `title`、`description`、`privacy`、`tags`、`timestamp`、`index_status`、`usage_count` 和 `last_used_at`。历史记录使用创建时间补齐沉淀日期。运行时只允许 `active + indexed` 的记忆进入 Agent 快照,并按使用次数和最近记录最多加载 50 条;人工修改记忆后标记 `needs_reindex`,重建索引完成后才重新参与生成。 记忆仍采用“待确认池 → 人工确认 → 已生效记忆 → Agent 画布运行”的闭环。下一阶段补充五层中文分类、总索引/子索引、来源证据、冲突候选、过期任务和经验升级技能的人工工作流。 ## 26. 点数余额替代成员 Token 配额(v6.7) 平台统一使用点数作为 AI 使用余额,换算规则固定为 `10 点数 = 1 Token`。用户端只显示当前账号的点数余额、可折算 Token 数和自己的用量账单;点数余额低于 10 时,模型调用在进入 Provider 前直接停止。 管理端通过“用量与账单 → 用户点数”为本组织成员增加点数。充值动作写入 `PointTransaction(kind=credit)`,模型调用成功后按实际 Token(Provider 没有返回用量时按 1 Token 的最低计量)写入 `PointTransaction(kind=debit)`,使用幂等键避免重复扣点。点数账户和流水按 `user_id + organization_id` 隔离,管理员可以查看本组织余额和充值原因。 旧 `UsageQuota` 表与 `/api/admin/quotas` 接口仅为历史数据兼容保留,不再出现在页面,也不参与任务启动或模型调用的可用性判断。AI 是否可用只由点数余额决定;费用账单仍由 `UsageEvent` 记录,用于审计和成本统计,不等同于用户点数余额。