34 KiB
私域 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 只保存哈希和引用。
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、技能、记忆、模型工具、数字人身份配置 |
| 数字人 | /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 登录链路
GET /api/auth/status检查是否需要首次初始化。- 首次使用
POST /api/auth/bootstrap创建管理员;之后使用POST /api/auth/login。 - 服务端生成不透明会话令牌,数据库只保存 SHA-256 哈希(
AuthSession),默认有效期 12 小时。 - 浏览器把令牌放入 API 请求的
Authorization头;退出调用POST /api/auth/logout撤销会话。 GET /api/auth/me返回当前用户、角色、组织和权限,前端据此渲染页面。
3.2 内置角色
- 管理员 admin:
*全部权限,仍受组织边界约束。 - 编辑 editor:内容任务、Agent/画布、知识库、数字人查看、运行和日志等日常生产权限。
- 审查 reviewer:查看和审查任务、知识库、记忆,不含配置和生产写入权限。
- 只读 viewer:只能查看被允许的知识库内容。
角色存储在 AppUser.role,可维护的角色集合存储在 RoleDefinition.permissions。权限目录按“内容生产、资产与知识、数据与洞察、系统管理”等抽屉分组,仅改变展示方式,不改变已保存 key。
3.3 访问判定顺序
- HTTP 中间件确认
/api请求已认证;微信回调为特例,必须在接口内用账号密钥校验。 required_permission()校验方法和路径所需操作权限。feature_permissions()校验功能栏权限。- 资源访问函数(
require_kb、require_skill、require_canvas、require_memory等)校验组织、所有者、可见性和成员授权。 - 组织 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 绑定关系(当前代码语义)
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 蒸馏流程
POST /api/digital-humans/distill上传或选择文档,服务端抽取代表性样本。_dh_distill()生成persona与persona_meta,记录来源文件、覆盖范围和不确定性,状态为testing或distilling。POST /api/digital-humans/{id}/test-write进行人工试写;/redistill根据反馈提升版本号。- 补充素材通过
/redistill上传并生成待测试新版本;微信对话不会自动写入数字人人格。 - 创建数字人时自动生成同名默认 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 在同名内容变化时递增。
上传/分片 → 文件哈希和去重 → 文本解析或媒体转写 → 分段
→ 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 轮模型预算,耗尽即停止并写入事件。
每次调用的记录路径:
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. 从用户角度的标准操作链
- 登录后在“模型管理”确认可用 Provider 和默认模型。
- 在“知识库”建库,上传文件/目录,等待索引状态为“就绪”;必要时执行去重、分类和预览。
- 在“Agent 与技能”创建 Agent,选择职责、挂接知识库/分类、技能、模型和数字人,保存并发布。
- 在“画布编排”用节点和连线编排 Agent;检查每个节点是否有唯一 Agent 和有效知识范围。
- 在“内容任务”粘贴训练营导图/框架,选择画布和知识范围,创建任务并拆解;若失败使用“重新拆解”。
- 查看每个内容段的 Agent、知识引用和锚点;可更换 Agent、修改分类、生成、质检、通过/打回/跳过。
- 全部段通过后组合成稿,在预览页面复核并下载交付。
- 需要微信服务时,在“数字人 → 微信 Bot 连接”选择已配置 Agent,生成二维码,扫码后确认状态为“已连接”。
- 在“运行记录、操作日志、系统日志、用量分析”核对执行、错误、模型调用和余额。
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、权限、验收清单”五个位置。