# 私域 Agent 内容生产工作台:系统整体架构与功能检查文档 > 文档用途:给产品、运营、测试和维护人员逐项核对当前系统。内容依据 `/server/app`、`/web/src` 和启动脚本整理,描述的是代码已经实现或明确配置的行为;“待确认”项需要在实际环境中验收。本文不包含管理员密码、API 密钥等敏感信息。 > > 代码位置:`server/app/main.py`(FastAPI 路由)、`server/app/models.py`(SQLModel 数据模型)、`server/app/agents`(Agent Runtime)、`server/app/rag`(知识库检索)、`web/src`(React 前端)。 ## 1. 系统边界和运行拓扑 系统是一个单组织、本地持久化、可通过公网隧道访问的内容生产工作台。浏览器只访问 React 单页应用;前端通过 `/api` 调用 FastAPI;FastAPI 使用 SQLite 保存业务状态,知识库源文件和产物保存在数据目录,向量索引由 RAG 子系统维护。微信 iLink 连接由独立 Node sidecar 持有账号凭据,主 API 只保存哈希和引用。 ```mermaid flowchart LR U[浏览器用户] -->|HTTPS / HashRouter| W[React 工作台] W -->|/api + 会话令牌| A[FastAPI main.py] A --> DB[(SQLite workspace.db)] A --> FS[(data/ kb artifacts ocr models)] A --> R[RAG pipeline] R --> V[(向量/全文索引)] A --> RT[Agent Runtime] RT --> LLM[Provider / 模型] A --> Q[持久任务队列] A --> I[进度 SSE / 轮询] I --> W S[wechat_ilink_sidecar.mjs] -->|本机 127.0.0.1:8765| A S --> WX[官方 iLink 微信协议] CF[cloudflared / ngrok] --> A ``` ### 1.1 进程与端口 | 进程 | 作用 | 默认地址/端口 | 主要数据/日志 | |---|---|---|---| | FastAPI + Uvicorn | 认证、业务 API、任务调度和后台线程 | 开发 `8011`;生产 `8010` | `/tmp/yawan-uvicorn.log`;生产 `server/data` | | React/Vite | 开发预览;生产构建后的静态文件由现有部署方式提供 | 开发通常 `5173` | `web/dist` | | 微信 iLink sidecar | 多账号扫码、收发微信消息、状态回调 | `127.0.0.1:8765` | `/tmp/yawan-wechat-sidecar.log`;按账号隔离的 storage | | cloudflared/ngrok | 把生产 API/前端暴露到公网 | 隧道地址 | `/tmp/yawan-cloudflared.log`、`/tmp/yawan-ngrok.log` | ### 1.2 环境与存储 - `YAWAN_ENV=dev` 使用 `server/data-dev`;默认或 `prod` 使用 `server/data`。 - `YAWAN_DATA_DIR` 可指定绝对路径,把 `workspace.db`、`kb/`、`artifacts/`、`ocr/`、`models/`、`chroma/` 等整体迁移到外接硬盘。 - `YAWAN_CORS_ORIGINS` 控制允许的前端来源;生产默认包含 `https://agent.pducv.cn`。 - `DB_PATH`、`KB_DIR`、`ARTIFACTS_DIR`、`OCR_DIR`、`MODELS_DIR` 在 `server/app/config.py` 根据环境动态创建。 - 启动时 `init_db()` 建表、执行兼容迁移、恢复未完成的知识片段预留、对账物理文件与索引,并将空质检报告标记为需复检。 ## 2. 用户端功能地图 侧栏由 `web/src/shell.tsx` 的 `navFor()` 根据权限生成;隐藏侧栏只是第一层保护,`AppRouter.tsx` 的 `FeatureGate` 和后端中间件还会再次校验。训练营导图已经作为内容任务入口的兼容路由保留;技能库和记忆库作为 Agent 与技能页签;标签作为知识库页签。 | 功能栏 | 页面/路由 | 主要能力 | 主要权限 | |---|---|---|---| | 总览 | `/admin/overview` | 状态、自检、快捷入口、通知 | `read` | | 内容任务 | `/admin/tasks`、`/admin/tasks/:id` | 建任务、导图拆解、逐段生成、质检、组合和交付 | `feature:tasks`、`tasks:*` | | 运行记录 | `/admin/runs` | 运行状态、事件、工具审批、失败恢复 | `feature:runs`、`runs:read` | | 操作日志 | `/admin/audit-logs` | 用户动作审计 | `feature:audit`、`audit:read` | | Agent 与技能 | `/admin/agents`,`?tab=skills|memories` | Agent、技能、记忆、模型工具、数字人身份配置 | `feature:agents`、`agents:*` | | 数字人 | `/admin/digital-humans` | 文档蒸馏、测试、反馈、版本、授权、微信 Bot | `feature:digital-humans`、`digital_humans:read` | | 画布编排 | `/admin/flows` | 节点、边、波次、总监模式、授权 | `feature:flows`、`flows:read` | | 知识库 | `/admin/knowledge` | 建库、上传、去重、分类、预览、检索、消费记录 | `feature:knowledge`、`kb:*` | | 模型管理 | `/admin/settings/providers` | Provider、模型目录、默认模型、连接测试 | `feature:models`、`providers:*` | | 用量分析 | `/admin/settings/usage` | 用量事件、余额、点数发放、配额 | `feature:usage`、`usage:read`、`billing:manage` | | 系统日志 | `/admin/system-logs` | HTTP/应用/任务错误和 Trace | `feature:system-logs`、`system_logs:read` | | 访问控制 | `/admin/settings/access` | 成员、角色、资源授权、全局发布、版本审核 | `feature:access`、`roles/users/audit:manage` | | 功能开关 | `/admin/settings/flags` | 读取和修改应用功能开关 | `feature:flags`、`flags:read` | | 运营看板 | `/admin/ops` | 指标、告警、备份、死信队列 | `feature:ops`、`ops:*` | | 操作手册 | `/admin/manual` | 面向普通用户的使用说明 | 登录后可见 | ## 3. 认证、组织和权限模型 ### 3.1 登录链路 1. `GET /api/auth/status` 检查是否需要首次初始化。 2. 首次使用 `POST /api/auth/bootstrap` 创建管理员;之后使用 `POST /api/auth/login`。 3. 服务端生成不透明会话令牌,数据库只保存 SHA-256 哈希(`AuthSession`),默认有效期 12 小时。 4. 浏览器把令牌放入 API 请求的 `Authorization` 头;退出调用 `POST /api/auth/logout` 撤销会话。 5. `GET /api/auth/me` 返回当前用户、角色、组织和权限,前端据此渲染页面。 ### 3.2 内置角色 - **管理员 admin**:`*` 全部权限,仍受组织边界约束。 - **编辑 editor**:内容任务、Agent/画布、知识库、数字人查看、运行和日志等日常生产权限。 - **审查 reviewer**:查看和审查任务、知识库、记忆,不含配置和生产写入权限。 - **只读 viewer**:只能查看被允许的知识库内容。 角色存储在 `AppUser.role`,可维护的角色集合存储在 `RoleDefinition.permissions`。权限目录按“内容生产、资产与知识、数据与洞察、系统管理”等抽屉分组,仅改变展示方式,不改变已保存 key。 ### 3.3 访问判定顺序 1. HTTP 中间件确认 `/api` 请求已认证;微信回调为特例,必须在接口内用账号密钥校验。 2. `required_permission()` 校验方法和路径所需操作权限。 3. `feature_permissions()` 校验功能栏权限。 4. 资源访问函数(`require_kb`、`require_skill`、`require_canvas`、`require_memory` 等)校验组织、所有者、可见性和成员授权。 5. 组织 ID:`0` 表示全局资源;正整数表示租户。数据库迁移会添加索引和触发器,阻止非法组织值落库。 ### 3.4 可见性和授权 资源具有 `private/shared/global` 三种可见性。所有者可以管理自己的资源;共享资源通过 `*Grant` 表按 `read/use/manage/export` 授权;全局资源对普通用户只允许查看和使用,不能导出或修改全局本体。普通用户对全局资源的修改/删除写入 `ResourceRevision`,管理员审核后才合并。`ResourceFork` 记录个人副本与全局源的版本基线。 ## 4. 数据模型和绑定关系 ### 4.1 核心实体 | 实体 | 表 | 关键字段/职责 | |---|---|---| | 组织 | `Organization` | 租户名称、slug、启用状态 | | 用户/角色/会话 | `AppUser`、`RoleDefinition`、`AuthSession` | 本地账号、PBKDF2 密码摘要、RBAC、可撤销登录 | | Agent | `Agent` | 角色类型、标签、知识库 ID/分类、融合 Agent、模型、工具、规则、数字人、发布快照 | | 技能 | `AgentSkill`、`AgentSkillBinding`、`AgentSkillGrant` | 技能指令、版本、挂载 Agent、成员授权 | | 数字人 | `DigitalHuman`、`DigitalHumanGrant` | 十一维人格档案、蒸馏元数据、版本、来源文件和授权 | | 微信账号 | `WeChatBotAccount` | 所有者、组织、Agent、状态、二维码、凭据哈希/引用 | | 画布 | `Canvas`、`CanvasGrant` | 节点 Agent、边、总监 Agent/模式、授权 | | 知识库 | `KnowledgeBase` | 源目录、索引状态、文件/片段计数、分段策略、所有权 | | 分类/文件 | `KnowledgeCategory`、`KnowledgeFile` | 无限层级分类、AI 推荐分类、文件哈希和 revision | | 消费记录 | `KnowledgeUsage` | Agent+知识库+片段唯一锁、引用、状态、禁用标记 | | 任务/内容段 | `Campaign`、`Segment` | 导图原文、画布快照、段级 Agent、状态、锚点、引用、历史版本 | | 质检/产物 | `QCReport`、`Artifact` | 结构/内容/风格/跨稿质检,组合成稿和下载预览 | | 运行 | `CampaignRun`、`RunEvent`、`AgentSession`、`TaskQueueItem` | 可恢复执行、进度事件、工具调用会话、租约/重试/死信 | | AI 用量 | `LLMCall`、`UsageEvent`、`PointAccount`、`PointTransaction`、`UsageQuota` | 调用追踪、不可变计量、余额流水和配额 | | 日志/通知/记忆 | `AuditLog`、`SystemLog`、`Notification`、`PendingMemory`、`Memory` | 用户动作、系统故障、待读提醒、Agent 长期记忆 | | 版本提案 | `ResourceRevision`、`ResourceFork` | 全局资源个人修改、删除提案及冲突基线 | ### 4.2 绑定关系(当前代码语义) ```mermaid erDiagram APP_USER ||--o{ AGENT : owns APP_USER ||--o{ KNOWLEDGE_BASE : owns APP_USER ||--o{ DIGITAL_HUMAN : owns AGENT }o--o{ AGENT_SKILL : mounts AGENT }o--o{ KNOWLEDGE_BASE : reads AGENT }o--o{ AGENT : fusion AGENT }o--|| DIGITAL_HUMAN : identity CANVAS }o--o{ AGENT : nodes CAMPAIGN }o--|| CANVAS : snapshot CAMPAIGN ||--o{ SEGMENT : contains SEGMENT }o--|| AGENT : assigned SEGMENT }o--o{ KNOWLEDGE_BASE : consumes AGENT ||--o{ MEMORY : accumulates CAMPAIGN_RUN ||--o{ RUN_EVENT : emits CAMPAIGN_RUN ||--o{ AGENT_SESSION : resumes LLM_CALL ||--o| USAGE_EVENT : measured ``` - **Agent→知识库**:`Agent.kb_ids` 和 `kb_category_ids` 保存挂接及分类范围;任务创建时运行快照冻结,生成时不读取后来新增的未授权库。 - **Agent→技能**:`AgentSkillBinding` 多对多;任务快照记录技能指令。 - **Agent→数字人**:`Agent.digital_human_id` 绑定身份;运行时数字人人格优先于 Agent 的 `persona_json`。 - **Agent→记忆**:`Memory.agent_id` 归属 Agent;记忆候选按用户、组织、画布范围过滤并冻结到运行快照。 - **画布→Agent/知识/记忆**:画布节点保存 Agent;画布授权只连带允许依赖资源的读/用,不放大编辑、删除、导出权限。 - **内容任务→画布**:`Campaign.canvas_snapshot` 是创建时快照,之后修改画布不会改变历史任务。 - **知识库消费隔离**:`KnowledgeUsage` 唯一约束为 `(agent_id,kb_id,chunk_id)`,不同 Agent 的消费互不锁定;`banned=true` 的片段永久排除检索。 - **微信账号→Agent**:一个 `WeChatBotAccount.agent_id` 绑定一个 Agent;sidecar 收到消息时把账号 ID、Agent ID、会话 ID 一并回传,后端再次校验所有权和授权。 ## 5. Agent 与技能工作区 ### 5.1 Agent 配置 可创建、编辑、停用、发布和删除非内置 Agent。职责类型代码为 `production`、`training_map`、`qc`、`service`、`coordinator`、`composer`。生产 Agent 可配置内容标签和融合 Agent;知识库可以限定到分类;模型可跟随全局默认或指定 Provider/目录模型;`allowed_tools` 控制 Runtime 工具。 发布接口 `POST /api/agents/{id}/publish` 调用快照冻结逻辑,将规则、模型、技能、知识边界和记忆候选固化到 `runtime_snapshot`。任务创建又会把该快照复制到 `Segment.runtime_snapshot`,保证生成中途修改配置不会改变本次任务。 ### 5.2 技能和记忆 技能支持 Markdown 导入(`POST /api/skills/import`)、版本和 Agent 多选挂载;技能自身可以按成员授权。记忆分为 L1 规则、L2 纠错、L3 偏好、L4 成功等层级,先进入 `PendingMemory`,审批后写入 `Memory`。Runtime 在模型真正调用前记录注入记忆的次数,避免恢复会话重复计量。 ### 5.3 删除与绑定检查(现状和验收点) 当前删除接口会先检查引用关系:被画布节点、融合 Agent、历史任务或其他资源引用的 Agent/技能/知识库/记忆/数字人可能被拒绝删除,前端会提示先解绑。产品要求“弹出一键解绑所有后再删除”时,验收应确保: - 明确列出将解除的绑定(Agent、技能、画布节点、知识库分类、数字人、记忆、微信账号等)。 - 一键操作在同一事务或可恢复事务中完成;失败不得留下半解绑状态。 - 历史任务的快照、日志、质检和账单保留,不因删除配置而丢失。 - 全局资源的普通用户操作仍只能建立个人 `ResourceRevision`,不能直接解绑全局本体。 - 删除微信账号先停止 sidecar 实例、清理二维码和凭据引用,再删除数据库记录。 ## 6. 数字人蒸馏和微信 iLink ### 6.1 蒸馏流程 1. `POST /api/digital-humans/distill` 上传或选择文档,服务端抽取代表性样本。 2. `_dh_distill()` 生成 `persona` 与 `persona_meta`,记录来源文件、覆盖范围和不确定性,状态为 `testing` 或 `distilling`。 3. `POST /api/digital-humans/{id}/test-write` 进行人工试写;`/redistill` 根据反馈提升版本号。 4. 补充素材通过 `/redistill` 上传并生成待测试新版本;微信对话不会自动写入数字人人格。 5. 创建数字人时自动生成同名默认 Agent 并绑定;后续可继续创建多个 Agent 绑定同一数字人,运行时把人格档案合并进系统提示。 ### 6.2 iLink 账号流程 - 前端数字人页调用 `POST /api/wechat/bot/accounts/connect`,后端生成账号级密钥(只保存哈希)并转发到 `YAWAN_WECHAT_ADAPTER_URL`。 - sidecar 使用 `@wechatbot/wechatbot`、Node 22 和每账号独立 storage 目录;登录回调把 `pending_qr`、`connected`、`error`、`disconnected` 和二维码状态回传 API。 - 微信消息签名为 HMAC-SHA256,后端验证时间戳、账号密钥、账号状态、Agent 绑定、组织和所有者;会话按账号/用户/Agent 隔离。 - 删除调用 `DELETE /api/wechat/bot/accounts/{id}`,sidecar 停止对应 Bot 并回调断开。 - 生产环境需要 `.env.production` 中的 `YAWAN_WECHAT_ADAPTER_URL=http://127.0.0.1:8765`,并由 `守护隧道.sh` 检查 8765 端口自动拉起。 ## 7. 知识库、索引和检索 ### 7.1 导入链路 支持 `.doc/.docx/.srt/.md/.txt/.json/.jsonl/.pdf` 以及音视频转写后索引。大文件走 `uploads/init`、分片上传、`uploads/{id}/finish`;目录导入走 `import-folder`。文件落盘后计算 `content_hash`,同内容文件跳过,重复片段在索引阶段去重。`KnowledgeFile.revision` 在同名内容变化时递增。 ```text 上传/分片 → 文件哈希和去重 → 文本解析或媒体转写 → 分段 → Embedding → 向量/全文索引 → 后台预热 → ready ``` `index_status`:`empty`、`indexing`、`ready`、`needs_reindex`、`error`。启动对账会比较磁盘文件、文件表和向量计数;不会因为对账自动重建大库。 ### 7.2 分类和预览 `KnowledgeCategory` 为无限层级树;文件同时保存人工分类 `category_id` 和 AI 建议 `ai_category_id`、置信度、理由。`POST /api/kbs/{kid}/classify` 批量推荐,`.../classification/confirm` 人工确认。知识库页签提供文件、分类、检索测试、消费记录和设置;文件查看走预览接口,管理员可查看全部消费记录,普通用户只返回自己有权看到的记录。 ### 7.3 检索模式 - **full**:选定知识库/分类的全部已索引资料分批阅读/检索,时间和用量较高。 - **quick**:按查询相关性召回,适合快速生成。 - **reuse**:复用已阅读缓存,减少重复解析和模型调用。 RAG 管道包含查询校验、Embedding、召回、去重、消费锁和后处理,并记录阶段耗时和缓存命中率;`/api/kbs/{kid}/search` 和 `/api/kbs/search` 提供检索测试。知识片段消费状态为 `reserved`、`consumed`、`available`,进程启动会归还中断留下的 `reserved`。 ## 8. 内容任务和训练营导图 ### 8.1 创建和拆解 `POST /api/campaigns` 创建任务并保存导图文本、所选画布快照、知识库范围和 Agent;`POST /api/campaigns/{cid}/parse` 调用 coordinator 将导图拆为 `Segment`。每段包含节点、标题、时间范围、标签、指定 Agent、知识分类限制和运行快照。拆解失败可由 `POST /api/campaigns/{cid}/reparse` 重新拆解。 训练营导图 API 位于 `server/app/training_map.py`,核心输入包括主题、至少一个知识库、可选分类、天数和 Agent。严格模型校验:天数连续、节点标题和叶子内容去重、每个叶子必须有证据来源;导图节点只保留框架短语,详细正文在内容任务生成。导图建议支持整套方案、单天、单日导图和全部导图修改,生成阶段支持进度事件。 全库评估采用分层摘要:原始片段按库分批阅读并递归归并;同一组织、用户、主题、知识库/分类范围及模型签名下,完全相同批次会写入 `training-corpus/summary-cache.sqlite`,后续草稿或重试可增量复用,缓存使用 WAL、忙等待和单批次文件锁避免并发重复调用。通用全文预读仍使用按知识库隔离的 `training-knowledge` 清单;两类缓存均不写入 `KnowledgeUsage` 消费账本。 ### 8.2 连续生成和跳过 任务运行使用 `CampaignRun`、`Segment.status` 和锚点卡:上游段产出 `anchor_card`,下游只接收摘要和最后确认段结尾,避免重复全文。跳过段会被记录为 `skipped`,后续段不能假设用户已经学会该前置知识,需要补足最小前提。段状态包括 `pending/running/qc/human_review/approved/rework/failed/skipped`。 逐段操作接口: - `POST /api/campaigns/{cid}/segments/{sid}`:新增段。 - `PUT /api/campaigns/{cid}/segments/{sid}`:修改 Agent、分类或正文。 - `DELETE /api/campaigns/{cid}/segments/{sid}`:删除段。 - `POST /api/segments/{sid}/review`:通过、打回或跳过。 - `POST /api/segments/{sid}/fix`:提交修改意见并重新生成。 - `POST /api/campaigns/{cid}/run-step`:运行下一步。 - `POST /api/campaigns/{cid}/run`:启动完整流水线;支持暂停、取消、恢复。 ### 8.3 质检、组合和交付 质检门包括 `structure`、`content`、`style`、`cross`;报告存放在 `QCReport`,空检查列表在启动迁移时自动标记 FAIL。全部段通过后 `POST /api/campaigns/{cid}/compose` 生成 `Artifact`,支持预览和下载。运行期间每次模型调用都关联 `trace_id`、Agent、段、Provider、模型和用量事件。 ## 9. Agent Runtime、工具和 AI 调用 Runtime 的系统工具:`knowledge_search`、`read_upstream_anchors`、`read_agent_memory`、`request_handoff`;联网工具 `web_search`、`web_collect` 默认关闭,启用后需人工审批。每个 `AgentSession` 保存消息、工具状态、轮次、阶段和结果,可从检查点恢复;每个运行共享 240 轮模型预算,耗尽即停止并写入事件。 每次调用的记录路径: ```text AgentSession → RuntimeContext → LLMCall → UsageEvent → PointTransaction(如结算) ↘ RunEvent / Trace / SystemLog ``` 模型选择:Agent 可指定 `model_provider_id/model_catalog_id/model_name`,否则跟随 `/api/settings/model-default`。Provider 通过 `/api/providers` 管理,支持连接测试、发现模型、刷新目录和删除;密钥来自配置或本地密钥存储,错误响应经过脱敏处理。 ## 10. 日志、追踪、通知和用量 ### 10.1 日志 - **AuditLog 操作日志**:记录用户、动作、资源、结果;不记录请求正文、令牌和密钥。典型动作包括登录、建库、上传、建 Agent、改权限、生成任务等。 - **SystemLog 系统日志**:记录 HTTP 失败、应用错误、任务失败、RAG/队列异常和 Trace;错误处理中间件会把具体 `detail` 写入日志。级别支持 `INFO/WARNING/ERROR`,前端可按来源、状态和时间查看。 - **RunEvent/LLMCall**:运行级工具调用、Agent、模型、重试、耗时和失败原因;用于运行记录和 Trace 详情。 接口:`/api/audit-logs`、`/api/system-logs`、`/api/llm_calls`、`/api/traces`、`/api/traces/{trace_id}`。 ### 10.2 通知和进度 `Notification` 记录失败、待审查、记忆待确认等提醒;`GET /api/notifications`、`POST /api/notifications/{id}/read`、`POST /api/notifications/read-all` 支持单条和一键已读。生成进度由 `/api/events/progress`(SSE)和 `/api/events/progress-poll`(轮询)提供,前端 `ProgressToast` 显示 AI 工作阶段。 ### 10.3 用量和点数 `UsageEvent` 是追加式计量账本,服务类型包括 `llm/embedding/ocr/storage/export/rerank`,具备幂等键、价格版本、输入输出数量和金额分。`PointAccount` 保存余额,`PointTransaction` 保存充值/扣费/调整流水,`UsageQuota` 保存每日/月度 token、金额、存储和并发限制。用户端 `/api/me/usage`、`/api/points/me` 只返回本人;管理员端 `/api/admin/usage/*` 和 `/api/admin/points/*` 可按用户/组织汇总和发放。 ## 11. 任务队列、可靠性和恢复 `TaskQueueItem` 提供幂等 `task_key`、租约、重试退避和死信状态。`CampaignRun` 的 `checkpoint`、`pause_requested`、`cancel_requested` 支持服务重启后恢复。后台线程负责运行任务、索引、预热和告警;进程启动会回收未完成的知识消费预留和历史异常质检。 运营接口包括: - `GET /api/ops/dashboard`:健康指标。 - `POST /api/ops/alerts/sweep`:扫描告警。 - `POST /api/ops/dead-letter/{task_id}/requeue`:死信重放。 - `GET/POST /api/ops/backup`、`POST /api/ops/backup/drill`:备份和恢复演练。 - `GET /api/system/status`、`GET /api/health`:API、RAG、队列等状态检查。 ## 12. 管理员资源发布和版本审核 管理员资源页按 Agent、技能、知识库、画布、数字人、记忆分别查看授权。对应接口提供成员 grant、撤销、发布全局和导出。普通用户编辑全局资源时,后端创建 `ResourceRevision(operation=update/delete)` 和必要的 `ResourceFork`;管理员通过 `/api/admin/resource-revisions/{id}/approve` 或 `reject` 审核。审核批准后才改变全局资源版本,个人删除只隐藏自己的视图,不影响其他用户。 ## 13. API 分组速查 ### 认证与管理 `/auth/status`、`/auth/bootstrap`、`/auth/login`、`/auth/logout`、`/auth/me`、`/auth/users`、`/auth/roles`;管理员资源授权集中在 `/admin/{agents,skills,knowledge-bases,canvases,digital-humans,memories}`。 ### Agent、技能、数字人和画布 `/agents`、`/agents/{id}/publish`、`/agents/{id}/fork`、`/skills`、`/skills/import`、`/skills/{id}/agents`、`/digital-humans/*`、`/canvases`、`/canvases/{id}/fork`。 ### 知识库和上传 `/kbs`、`/kbs/{id}`、`/kbs/{id}/categories`、`/kbs/{id}/files/*`、`/kbs/{id}/classify`、`/kbs/{id}/search`、`/kbs/search`、`/uploads/init`、`/uploads/{id}/chunk/{index}`、`/uploads/{id}/finish`、`/kbs/{id}/import`、`/kbs/{id}/rebuild`。 ### 任务与运行 `/campaigns`、`/campaigns/{id}/parse`、`/campaigns/{id}/reparse`、`/campaigns/{id}/segments/*`、`/campaigns/{id}/run`、`/runs/{id}`、`/agent-sessions/{id}`、`/segments/{id}/review`、`/segments/{id}/fix`、`/campaigns/{id}/compose`、`/artifacts/{id}/preview`。 ### 微信 `/wechat/bot/accounts`(列表、连接、更新、绑定 Agent、删除)、`/wechat/bot/accounts/{id}/callback`(sidecar 状态回调)、`/wechat/bot/reply`(签名消息转发)。 ## 14. 从用户角度的标准操作链 1. 登录后在“模型管理”确认可用 Provider 和默认模型。 2. 在“知识库”建库,上传文件/目录,等待索引状态为“就绪”;必要时执行去重、分类和预览。 3. 在“Agent 与技能”创建 Agent,选择职责、挂接知识库/分类、技能、模型和数字人,保存并发布。 4. 在“画布编排”用节点和连线编排 Agent;检查每个节点是否有唯一 Agent 和有效知识范围。 5. 在“内容任务”粘贴训练营导图/框架,选择画布和知识范围,创建任务并拆解;若失败使用“重新拆解”。 6. 查看每个内容段的 Agent、知识引用和锚点;可更换 Agent、修改分类、生成、质检、通过/打回/跳过。 7. 全部段通过后组合成稿,在预览页面复核并下载交付。 8. 需要微信服务时,在“数字人 → 微信 Bot 连接”选择已配置 Agent,生成二维码,扫码后确认状态为“已连接”。 9. 在“运行记录、操作日志、系统日志、用量分析”核对执行、错误、模型调用和余额。 ## 15. 逐项验收清单 ### 账号与权限 - [ ] 非管理员直接访问无权限路由显示明确中文提示,API 返回 403/404 且不泄露资源存在性。 - [ ] 普通用户看不到未授权 Agent、知识库、技能、数字人、记忆和画布。 - [ ] 全局资源个人修改/删除生成个人版本提案,不影响其他用户。 - [ ] 账号删除是永久删除;停用只改变 `enabled`,两者按钮和审计动作不同。 - [ ] 删除有关联资源时可查看依赖,并验证一键解绑事务、历史快照和日志保留。 ### 知识库 - [ ] 首次打开知识库不会显示旧库残留或短暂的“不存在”;详情加载有明确状态。 - [ ] 同内容文件和完全重复片段被跳过,导入结果显示跳过数量。 - [ ] 子分类有文件时父分类计数同步;分类树可展开/收起。 - [ ] 普通用户消费记录只包含自己可用的 Agent/片段;管理员可按用户筛选。 - [ ] 预览按钮返回正确文件标题和正文;大文件不阻塞列表首屏。 - [ ] full/quick/reuse 三种检索模式显示估算耗时、进度和失败原因。 ### AI 生成与任务 - [ ] 导图先输出框架文本,确认后才能进入内容任务;节点标题/叶子内容无重复。 - [ ] 导图每天按前置关系递进;跳过内容段后,后续段能看到桥接提示。 - [ ] 内容段显示当前 Agent、模型、知识分类和引用来源。 - [ ] 拆解失败、生成失败、AI 修改、图片/OCR/预读均有进度条、重试入口和日志。 - [ ] 质检四道门均产生可追踪报告;空报告自动判为需复检。 - [ ] 运行暂停、取消、恢复后不会重复扣费或重复消费片段。 ### 微信 iLink - [ ] 选择 Agent 后二维码出现;扫码成功后二维码隐藏且列表显示“已连接”。 - [ ] 已连接账号仍显示删除按钮;删除后 sidecar 实例停止、状态回调断开、刷新不复现。 - [ ] 多账号使用不同 storage 目录和账号密钥;账号 A 无法调用账号 B 的 Agent/会话。 - [ ] 绑定 Agent 变更实时同步 sidecar;失效/过期/错误状态能回传并允许重新扫码。 ### 可靠性与部署 - [ ] 生产只使用 `data/`(或明确的 `YAWAN_DATA_DIR`),开发只使用 `data-dev/`。 - [ ] 后端、sidecar、隧道守护进程均可单独重启;502/1033 时日志能定位是 API、隧道还是 sidecar。 - [ ] 启动后未完成运行、片段预留和索引状态能正确恢复或标记。 - [ ] 生产构建通过 `npm run build`,前端动态模块版本与静态资源缓存一致。 ## 16. 当前限制和风险边界 - SQLite + NullPool 适合单机/中小规模;多实例横向扩展前需要共享数据库、对象存储和队列,不能直接把本地文件目录挂到多个实例。 - iLink sidecar 依赖 Node.js 22 和 `@wechatbot/wechatbot`;官方适配器不可用时只会显示配置/连接错误,不能在浏览器端直接完成协议登录。 - 本地向量和全文索引路径由 `server/app/rag` 管理;若切换 Qdrant 等外部服务,需要同步配置、迁移和故障回退策略,当前代码仍保留本地存储能力。 - AI 输出受模型可用性、点数余额、Runtime 轮次预算和知识索引状态影响;任何“全库阅读”都可能显著增加时间和用量。 - 日志会对密钥、令牌和请求正文脱敏;若需要排查具体模型错误,应使用 Trace ID、Provider 状态和服务端原始日志,而不是把密钥写入前端提示。 ## 16.1 性能基线与运行维护 - SQLite 连接统一启用 WAL、`busy_timeout=30000`、`synchronous=NORMAL` 和外键约束,并建立日志、知识库文件/分类/消费、授权、运行事件、队列等复合索引。 - 知识片段消费预留、确认和释放使用批量查询/`executemany`,减少逐片段 SQL 往返和写锁竞争。 - RAG 检索记录校验、Embedding、召回、后处理和总耗时,并保留缓存命中率;缓存键包含知识库版本、范围、模型和检索参数。 - 管理员可调用 `GET /api/ops/performance` 查看最近 512 次 API 的 P50/P95/P99、慢接口、状态分布及 RAG 阶段指标。该指标为进程内基线,重启后重新采样。 - 启动阶段只做必要初始化;知识库文件对账和全文索引预热由后台维护线程执行,避免大库扫描阻塞首屏和健康检查。 - 生产守护脚本使用单实例锁,避免重复守护进程同时启动后端,降低内存争抢和 SQLite 写锁风险。 - 普通 INFO/DEBUG/WARNING 系统日志与 AI 观测日志进入有界批量队列(最多 1000 条、每批 100 条、最长 1 秒刷盘);ERROR、关键审计、计量账本和任务状态仍同步写入。队列丢弃/失败计数可通过性能指标追踪,进程优雅退出会先刷盘。 - 性能指标现在通过匿名指标信封从 RAG 子进程回传 API 进程,包含 SQL 次数、SQL 耗时、锁错误、RAG 各阶段耗时和错误样本,避免把查询正文、令牌或原始路径写入指标。 - 当前任务队列仍是旁路记录,内容生成/导图/上传依赖进程内线程和内存进度总线;外部 Worker 尚未启用。直接启用会造成重复执行和 SSE 进度丢失,必须先完成原子租约认领、持久化进度游标及唯一执行模式切换。 - 2026-09-13 基线(本机冷启动、37 段产品信息库):首次检索约 3.37 秒,其中 Embedding 约 2.93 秒、召回约 0.41 秒;相同查询命中缓存约 6 毫秒。该样本不能代表 9.8 万段以上大库,需在空闲、内容生成和索引运行中分别采样 P50/P95/P99。 - Worker 审计结论:`TaskQueueItem.lease_next` 当前不是原子认领,且内容任务入队后仍由内存线程直接执行;上传、拆解、导图和 SSE 也依赖进程内状态。因此暂不启用内容生成外部 Worker,下一安全阶段仅考虑可幂等的 FTS 预热;迁移前需先完成原子租约、唯一执行模式、持久化进度游标和幂等验收。 - 2026-09-13 Embedding 诊断已细分为模型加载、Tokenizer、Encode 推理、向量后处理/序列化、进程启动和 IPC 残差,并记录来源、数量、模型版本、维度、PID、缓存命中及 Worker 是否复用。管理员性能接口会聚合这些阶段的 P50/P95;`embedding_count` 可识别 quick 检索误做批量向量化。 - 查询向量 LRU 与检索候选池缓存已分离:向量缓存只依赖规范化 query、模型/版本和策略(模型版本代表向量维度契约);候选池缓存包含知识库/分类文件范围、权限签名、索引版本、检索模式和 top-k。知识库版本变化只影响候选池,避免无关地清空查询向量。 - 2026-09-13 热态未命中采样(单库产品信息,15 条不同 query):首条冷启动约 4.17 秒,其中模型加载约 3.06 秒;模型常驻后总耗时 P50 约 15.93ms、P95 约 25.84ms,Embedding P95 约 16.70ms,Encode P95 约 16.59ms,召回 P95 约 4.30ms,`embedding_count=1` 且 15 条均未命中查询缓存。六库联合采样(约 15 万段)首条冷启动约 7.48 秒,热态未命中约 0.66~0.78 秒,主要耗时在多库召回而非 Embedding。 - 查询缓存复测确认:同 query、同 top-k 第二次命中候选池约 17ms;改变 top-k 后候选池重新计算约 45ms,但查询向量缓存命中、Embedding 耗时约 0ms。缓存键已修复首次维度从未知切换到 512 导致的伪未命中问题。 - 2026-09-13 六库召回稳定性优化:召回线程池改为进程内固定 4 个 Worker,避免每次请求创建线程并限制高并发时的磁盘争用;只读 FTS 索引使用带 inode/版本校验的共享连接、页缓存和 mmap,索引原子替换后自动重连。新增 `fts_connection_reused` 指标,用于区分连接复用与索引自身耗时。 - 2026-09-13 六库热态未命中复测(生产 6 库):Embedding 已常驻后约 14~129ms,召回约 0.64~0.91 秒;瓶颈集中在心法、情欲内容的大型 FTS 索引(约 461MB/862MB)和对应向量 I/O,模型加载不再是稳态瓶颈。后续优先做大库索引体积与查询词规模优化,暂不切换模型或向量数据库。 - 2026-09-13 向量查询进一步优化:移除检索热路径上的 `collection.count()`。该调用在外置盘冷读时,108135 段库约 1.7 秒,而实际向量查询约 20ms;Chroma/Qdrant 对空集合均直接返回空结果,因此无需先 count。检索指标现在只记录 collection、filter、vector 三段真实 I/O。 - 2026-09-13 空闲态 10 条不同 query 只读采样:P50 约 556ms,P95 约 1.25s;首条冷启动约 6.43s,后续 Embedding 约 6~345ms。4 路并发只读采样全部完成,未再出现 `database is locked`;高并发仍受单个常驻 RAG Worker 的队列容量限制,继续保持单 Worker 以控制内存峰值。 - 2026-09-13 稳定性修复:Embedding 用量事件改为独立短事务提交,计量写入失败只记录告警,不再让知识库检索失败;避免内容任务并发时主业务事务与用量写入互相持有 SQLite 写锁。 - 计量短事务设置 500ms 忙等待上限;数据库暂时繁忙时只丢弃本次非关键计量并保留检索结果,避免用户看到 30 秒级假性超时。 ## 17. 检查记录模板 | 检查日期 | 环境(dev/prod) | 页面/API | 操作步骤 | 预期 | 实际 | Trace/截图 | 结论 | |---|---|---|---|---|---|---|---| | | | | | | | | | 维护此文档时,应以代码中的模型字段、路由和权限 key 为准;新增功能同时补充“功能地图、数据模型、API、权限、验收清单”五个位置。