Files
wecom_it_smart_desk/docs/03-技术架构/增量设计-知识库迭代与痛点缓解-20260707.md
T

1148 lines
54 KiB
Markdown
Raw Normal View History

# 增量架构设计:知识库自动迭代修复 + 生产痛点缓解
> 文档版本: v1.0
> 日期: 2026-07-07
> 架构师: 高见远(software-architect
> 关联文档: 增量PRD-知识库迭代与痛点缓解-20260707.md / 主PRD-v1.2 §11.1 D1-D9 / 复杂场景重构技术方案 v1.1
> 设计理念: 对齐 TeliChat 白盒图模型,以 Neo4j 图即真相源为核心,三条通道 Suggestion → 审核 → 写图 → 派生 flat 视图
---
## 目录
1. [Part A: 系统设计](#part-a-系统设计)
- 1. 实现方案与框架选型
- 2. 文件列表及相对路径
- 3. 数据结构与接口(Mermaid 类图)
- 4. 程序调用流程(Mermaid 时序图)
- 5. 待明确事项
2. [Part B: 任务分解](#part-b-任务分解)
- 6. 依赖包列表
- 7. 任务列表(有序、含依赖)
- 8. 共享知识
- 9. 任务依赖图
---
# Part A: 系统设计
## 1. 实现方案与框架选型
### 1.1 核心技术挑战
| # | 挑战 | 难在哪 | 对应决策 |
|---|------|--------|----------|
| 1 | 桩→真AI生成 | `_generate_*_suggestion` 返回 `[待AI生成]`,需真实调用 Dify 并输出结构化 JSON | D2, P0-1 |
| 2 | 知识迭代产物直写 Neo4j 图 | 当前 backend **无任何 Neo4j 模块**,需从零构建客户端+图schema+写操作 | D1, P0-4 |
| 3 | 审批状态机五态流转 | pending→queued→approved→applied→graph_synced,需串联 API+服务+Neo4j | D7, P0-6 |
| 4 | 置信门控统一契约 | AI 回复需统一带 `confidence`,低于 0.7 触发「转人工+上下文」 | D3, P0-3 |
| 5 | 三通道输入归一化 | A(会话-Dify)/B(训练师手动)/C(文档-RAGFlow) 三种来源统一落 `KnowledgeSuggestion` | D2 |
| 6 | Qwen-VL 截图理解 | 员工发截图→本地 Qwen-VL→Dify 后端→结构化描述入上下文 | D5, P1-3 |
### 1.2 框架与库选型
#### 1.2.1 Neo4j 驱动:`neo4j` 官方异步驱动
```
neo4j@^5.26.0 — 官方 Python 异步驱动(支持 async/await,与 FastAPI 生态天然匹配)
```
**选型理由**
- `neo4j` 5.x 原生支持 `AsyncDriver` + `AsyncSession`,与 FastAPI/SQLAlchemy async 生态一致,无需额外线程池。
- 支持 `execute_read`/`execute_write` 事务分离,图写操作天然适合写事务。
- 自带 `neo4j.time` 类型映射、连接池、重试策略,减轻自建客户端负担。
**替代方案评估**
- `py2neo`:已停止维护(最后 release 2021),不支持 Neo4j 5.x,淘汰。
- `neomodel`:基于 py2neo,同样不维护,且 OGM 过度抽象不利于直接 Cypher 控制,淘汰。
**连接配置**(写入 `app/config.py`):
```python
neo4j_uri: str = "bolt://localhost:7687" # Neo4j bolt 协议
neo4j_user: str = "neo4j"
neo4j_password: str = "" # 仅从环境变量注入
neo4j_database: str = "neo4j" # 默认数据库
neo4j_max_connection_lifetime: int = 3600 # 连接最大存活时间(秒)
neo4j_max_connection_pool_size: int = 50 # 连接池上限
```
#### 1.2.2 Dify 集成:复用现有 `WingmanService` 范式
**不做新客户端**,直接扩展 `WingmanService`
- 新增 `generate_knowledge_suggestion()` 方法,复用 `_build_context_messages` + `_call_wingman_api` + `_parse_json_response`
- 新增专用 `_KNOWLEDGE_SUGGESTION_PROMPT` 模板,要求输出结构化 JSON
```json
{
"suggestion_type": "new_faq|update",
"title": "问题标题",
"content": "答案内容",
"category": "硬件|软件|网络|安全|账号|其他",
"tags": ["VPN", "连接"],
"confidence": 0.86,
"issue": "VPN问题",
"action": "VPN连接修复",
"relation_type": "LEADS_TO",
"parent_issue": "网络问题"
}
```
#### 1.2.3 RAGFlow 集成:复用现有 `integrations/ragflow/` 客户端
- 现有 `backend/app/integrations/ragflow/client.py` 已有基础 API 客户端。
- 新增 `RagflowIngestionService` 封装"上传文档→等待处理→拉取结构化结果→生成 KnowledgeSuggestion"流程。
#### 1.2.4 Qwen-VL 调用方式:经 Dify 后端
- Qwen-VL`Qwen3-VL-8B-Instruct`)本地部署,Dify 工作流中配置 `vision-completion` 节点。
- 后端接收图片消息→上传至临时存储→调用 Dify vision 工作流(非流式)→获取结构化描述文本→注入当前会话上下文。
- 预留接口参数 `vision_model` 以便后续升级至 Qwen3-VL-32B-Instruct。
#### 1.2.5 架构模式
```
┌─────────────────────────────────────────────────────────────┐
│ 三层架构(后端) │
│ │
│ API 层(router.py + knowledge_iteration.py + wingman.py
│ │ │
│ ▼ │
│ 服务层(KnowledgeIterationService + WingmanService │
│ + Neo4jClient + VisionService + RagflowIngestion
│ │ │
│ ▼ │
│ 持久层(SQLAlchemy/PostgreSQL + neo4j AsyncDriver/Neo4j
│ │
│ 前端:三端独立 │
│ - H5(员工端): Vue3+Vant4 — 分诊卡片+置信门控+截图上传 │
│ - 坐席控制台: Vue3+ElementPlus — 内联审批+排除+独立队列 │
│ - 管理后台: Vue3+Element+Tailwind — 提案审阅+训练师录入 │
└─────────────────────────────────────────────────────────────┘
```
### 1.3 图 Schema 迁移策略
**原则**:对齐复杂场景重构 v1.1 的 TeliChat 白盒图模型,以 **Issue → Action → Relation** 为核心。
#### 1.3.1 Neo4j 节点标签与属性
| 标签 | 属性 | 对齐复杂场景重构 |
|------|------|-----------------|
| `Issue` | `uuid`, `name`, `category`, `created_at`, `updated_at`, `source_suggestion_id` | `Issue {name, category}` |
| `Action` | `uuid`, `name`, `description`, `created_at`, `updated_at`, `source_suggestion_id` | `Action {name}` |
| `Info` | `uuid`, `name`, `value`, `modifiers`(list), `created_at` | `Info {name}` + 信息项修饰 |
| `Session` | `session_id`, `current_node` | `Session {id, current_node}` |
#### 1.3.2 关系类型
| 关系 | 方向 | 属性 | 对齐复杂场景重构 |
|------|------|------|-----------------|
| `LEADS_TO` | Issue→Issue 或 Issue→Action | `order: int`, `weight: float` | 完全对齐 |
| `RELATES_TO` | Issue↔Issue | `type: str` | `CAN_JUMP_TO` → 简化为 `RELATES_TO {type:"jump"}` |
| `HAS_ACTION` | Issue→Action | — | `LEADS_TO` 已覆盖 |
| `PROVIDED` | Session→Info | `timestamp: datetime`, `status: str` | 完全对齐 |
| `CORRECTED_TO` | Info→Info | `timestamp: datetime` | 完全对齐 |
#### 1.3.3 图初始化 Cypher
```cypher
// 创建约束
CREATE CONSTRAINT issue_uuid IF NOT EXISTS FOR (i:Issue) REQUIRE i.uuid IS UNIQUE;
CREATE CONSTRAINT action_uuid IF NOT EXISTS FOR (a:Action) REQUIRE a.uuid IS UNIQUE;
// 创建索引
CREATE INDEX issue_category IF NOT EXISTS FOR (i:Issue) ON (i.category);
CREATE INDEX issue_name IF NOT EXISTS FOR (i:Issue) ON (i.name);
```
---
## 2. 文件列表及相对路径
> 标注说明:`[新]` 新增文件 / `[改]` 修改文件 / `[不]` 故意不动
### 2.1 后端 — 配置与依赖
| 相对路径 | 操作 | 说明 |
|----------|------|------|
| `backend/requirements.txt` | `[改]` | 新增 `neo4j>=5.26.0`、`Pillow>=10.0`(截图预处理) |
| `backend/app/config.py` | `[改]` | 新增 Neo4j / Qwen-VL / confidence_gate_threshold / RAGFlow ingestion 配置项 |
| `backend/alembic/versions/xxxx_add_graph_confidence_audience_fields.py` | `[新]` | Alembic migrationKnowledgeSuggestion + KnowledgeBase 字段扩展 |
### 2.2 后端 — 模型层
| 相对路径 | 操作 | 说明 |
|----------|------|------|
| `backend/app/models/knowledge_suggestion.py` | `[改]` | 新增 `confidence`, `audience`, `issue`, `action`, `relation_type`, `parent_issue`, `graph_meta`(JSON), `graph_sync_status`, `source_failed`, `queued_at`, `applied_at` |
| `backend/app/models/knowledge_base.py` | `[改]` | 新增 `graph_sync_status`, `graph_node_uuid` 字段 |
### 2.3 后端 — Schema 层
| 相对路径 | 操作 | 说明 |
|----------|------|------|
| `backend/app/schemas/knowledge_suggestion.py` | `[改]` | 所有请求/响应 Schema 新增图字段、audience、confidence;新增 `KnowledgeSuggestionRewrite`(改写请求) |
| `backend/app/schemas/enums.py` | `[新]` | `AudienceEnum`, `SuggestionStatusEnum`, `GraphSyncStatusEnum`, `SourceTypeEnum`, `RelationTypeEnum` 枚举集中定义 |
### 2.4 后端 — Neo4j 模块(全新)
| 相对路径 | 操作 | 说明 |
|----------|------|------|
| `backend/app/services/neo4j_client.py` | `[新]` | Neo4j AsyncDriver 封装(连接池、写事务、读事务、图初始化) |
| `backend/app/models/neo4j_schema.py` | `[新]` | Neo4j 图节点/关系 Pydantic 模型:`IssueNode`, `ActionNode`, `RelationEdge` |
### 2.5 后端 — 服务层
| 相对路径 | 操作 | 说明 |
|----------|------|------|
| `backend/app/services/knowledge_iteration_service.py` | `[改]` | **核心重写**:真 AI 生成(替换 TODO 占位)、Dify 调用、审批状态机五态流转、Neo4j 图写入、audience 自动标注、conf<0.7 转人工标记 |
| `backend/app/services/wingman_service.py` | `[改]` | 新增 `generate_knowledge_suggestion()`、`_KNOWLEDGE_SUGGESTION_PROMPT` |
| `backend/app/services/vision_service.py` | `[新]` | Qwen-VL 截图理解服务(上传→Dify vision workflow→结构化描述→注入上下文) |
| `backend/app/services/ragflow_ingestion_service.py` | `[新]` | RAGFlow 文档上传→ETL→结构化→生成 KnowledgeSuggestion(通道 C |
| `backend/app/services/content_moderation_service.py` | `[不]` | **不动** — 维持 WARN 不升级 |
### 2.6 后端 — API 层
| 相对路径 | 操作 | 说明 |
|----------|------|------|
| `backend/app/api/router.py` | `[改]` | **取消 L32 注释**,挂载 `knowledge_iteration_router`prefix=`/admin/knowledge-iteration`);新增 `vision_router`、`approval_queue_router` |
| `backend/app/api/knowledge_iteration.py` | `[改]` | 扩展现有 6 端点:list 支持 audience/confidence 筛选;approve/reject 触发 Neo4j 写图+状态流转;新增 `rewrite` 端点 |
| `backend/app/api/approval_queue.py` | `[新]` | 独立队列 API`GET /queued`、`POST /{id}/queue`、`POST /{id}/dequeue`、`GET /stats` |
| `backend/app/api/vision.py` | `[新]` | 图片上传+视觉理解 API`POST /api/vision/analyze` → 返回结构化描述 |
| `backend/app/api/ragflow_ingestion.py` | `[新]` | RAGFlow 文档上传+处理 API`POST /api/ragflow/ingest` → 返回 pending 提案 |
### 2.7 前端 — H5 员工端(Vue3+Vant4
| 相对路径 | 操作 | 说明 |
|----------|------|------|
| `frontend-h5/src/components/TriageCard.vue` | `[新]` | 分诊置顶卡片组件(是/否/概率选择题、步骤进度条、专家模式开关)D4/P1-1 |
| `frontend-h5/src/components/ConfidenceGateBanner.vue` | `[新]` | 置信门控横幅:conf<0.7 时显示「转人工」入口+已收集上下文快照 D3/P0-3 |
| `frontend-h5/src/components/ImageUploader.vue` | `[新]` | 截图上传+中途补图组件(调用 vision APID5/P1-3 |
| `frontend-h5/src/composables/useConfidenceGate.ts` | `[新]` | 置信门控逻辑复用 composable |
### 2.8 前端 — 坐席控制台(Vue3+ElementPlus
| 相对路径 | 操作 | 说明 |
|----------|------|------|
| `frontend-agent/src/components/chat/ApprovalInlineCard.vue` | `[新]` | 内联审批卡片(采纳/驳回/改写 + 拓扑预览 + audience 下拉)D7/P0-6 |
| `frontend-agent/src/components/chat/AgentExclusionPanel.vue` | `[新]` | 坐席排除控件(勾选排除错误项+加推荐标记+不能代用户确认)D9/P1-2 |
| `frontend-agent/src/views/ApprovalQueue.vue` | `[新]` | 独立队列页(提案列表+筛选+批量操作)D7/P0-6 |
| `frontend-agent/src/composables/useApprovalQueue.ts` | `[新]` | 审批队列状态管理 composable |
### 2.9 前端 — 管理后台(Vue3+Element+Tailwind
| 相对路径 | 操作 | 说明 |
|----------|------|------|
| `frontend-admin/src/views/KnowledgeIteration.vue` | `[新]` | 知识迭代提案管理页(列表+审阅+图字段编辑+训练师手动录入入口) |
| `frontend-admin/src/views/RagflowIngestion.vue` | `[新]` | RAGFlow 文档上传页(通道 CP1-5 |
### 2.10 测试
| 相对路径 | 操作 | 说明 |
|----------|------|------|
| `backend/tests/test_knowledge_iteration.py` | `[改]` | 更新 4/4 桩断言→真实 AI 生成断言 |
| `backend/tests/test_neo4j_client.py` | `[新]` | Neo4j 客户端单元测试(连接/CRUD/图遍历) |
| `backend/tests/test_confidence_gate.py` | `[新]` | 置信门控逻辑测试 |
| `backend/tests/test_approval_state_machine.py` | `[新]` | 审批状态机测试(五态流转) |
---
## 3. 数据结构与接口(Mermaid 类图)
```mermaid
classDiagram
direction TB
%% ── 枚举 ──────────────────────────────────────────
class AudienceEnum {
<<enumeration>>
employee_quick_reply
engineer_workguide
}
class SuggestionStatusEnum {
<<enumeration>>
pending
queued
approved
rejected
applied
graph_synced
expired
}
class GraphSyncStatusEnum {
<<enumeration>>
pending
synced
failed
}
class SourceTypeEnum {
<<enumeration>>
annotation
conversation
ai_uncertain
manual
document_ragflow
}
class RelationTypeEnum {
<<enumeration>>
LEADS_TO
RELATES_TO
CAN_JUMP_TO
}
%% ── PostgreSQL 模型 ───────────────────────────────
class KnowledgeSuggestion {
+str id
+str suggestion_type
+SuggestionStatusEnum status
+str title
+str content
+str category
+List~str~ tags
+SourceTypeEnum source_type
+List~str~ source_data
+str reason
+str reject_reason
+str reviewer_id
+datetime reviewed_at
+datetime created_at
+datetime updated_at
+float confidence
+AudienceEnum audience
+str issue
+str action
+RelationTypeEnum relation_type
+str parent_issue
+dict graph_meta
+GraphSyncStatusEnum graph_sync_status
+bool source_failed
+datetime queued_at
+datetime applied_at
}
class KnowledgeBase {
+str id
+str category
+str title
+str content
+List~str~ tags
+int view_count
+int use_count
+GraphSyncStatusEnum graph_sync_status
+str graph_node_uuid
+datetime created_at
+datetime updated_at
}
class Conversation {
+str id
+str employee_id
+str status
+str session_type
+datetime created_at
}
%% ── Neo4j 图节点模型 ──────────────────────────────
class IssueNode {
+str uuid
+str name
+str category
+datetime created_at
+datetime updated_at
+str source_suggestion_id
}
class ActionNode {
+str uuid
+str name
+str description
+datetime created_at
+str source_suggestion_id
}
class InfoNode {
+str uuid
+str name
+str value
+List~str~ modifiers
+datetime created_at
}
class RelationEdge {
+str from_uuid
+str to_uuid
+RelationTypeEnum type
+int order
+float weight
}
%% ── Pydantic Schema ───────────────────────────────
class KnowledgeSuggestionCreate {
+str suggestion_type
+str title
+str content
+str category
+List~str~ tags
+SourceTypeEnum source_type
+List~str~ source_data
+str reason
+float confidence
+AudienceEnum audience
+str issue
+str action
+RelationTypeEnum relation_type
+str parent_issue
+dict graph_meta
}
class KnowledgeSuggestionResponse {
+str id
+str suggestion_type
+SuggestionStatusEnum status
+str title
+str content
+str category
+List~str~ tags
+SourceTypeEnum source_type
+float confidence
+AudienceEnum audience
+str issue
+str action
+RelationTypeEnum relation_type
+str parent_issue
+dict graph_meta
+GraphSyncStatusEnum graph_sync_status
+bool source_failed
+datetime queued_at
+datetime applied_at
+datetime created_at
}
class KnowledgeSuggestionApprove {
<<request>>
}
class KnowledgeSuggestionReject {
<<request>>
+str reject_reason
}
class KnowledgeSuggestionRewrite {
<<request>>
+str title
+str content
+str category
+List~str~ tags
+float confidence
+AudienceEnum audience
+str issue
+str action
+RelationTypeEnum relation_type
+str parent_issue
}
class VisionRequest {
<<request>>
+str conversation_id
+bytes image_file
}
class VisionResponse {
+str description
+float confidence
+dict metadata
}
class RagflowIngestionRequest {
<<request>>
+str file_name
+bytes file_data
+str category_hint
}
class RagflowIngestionResponse {
+str task_id
+str status
+List~KnowledgeSuggestionResponse~ suggestions
}
%% ── 服务类 ────────────────────────────────────────
class KnowledgeIterationService {
-str ai_api_url
-str ai_api_key
+analyze_and_generate_suggestions(db, days) dict
-_analyze_annotation_data(db, days) dict
-_analyze_conversation_data(db, days) dict
-_generate_update_suggestion(db, source_type, source_data, reason) KnowledgeSuggestion
-_generate_new_faq_suggestion(db, source_type, source_data, reason) KnowledgeSuggestion
-_check_existing_suggestion(db, source_id) bool
-_auto_tag_audience(db, source_type, source_data) AudienceEnum
+approve_suggestion(db, suggestion_id, reviewer_id) KnowledgeSuggestion
+reject_suggestion(db, suggestion_id, reviewer_id, reason) KnowledgeSuggestion
+rewrite_suggestion(db, suggestion_id, reviewer_id, data) KnowledgeSuggestion
+queue_suggestion(db, suggestion_id) KnowledgeSuggestion
+dequeue_approve(db, suggestion_id, reviewer_id) KnowledgeSuggestion
+sync_to_neo4j(neo4j_client, suggestion) bool
+get_suggestion_stats(db) dict
+get_queue_stats(db) dict
}
class WingmanService {
-str api_url
-str api_key
-int timeout
-httpx.AsyncClient _client
+generate_draft(conversation_id, messages, db) dict
+generate_summary(conversation_id, messages) dict
+suggest_tags(conversation_id, messages, existing_tags) dict
+generate_knowledge_suggestion(context_messages) dict
-_build_context_messages(messages, system_prompt) list
-_call_wingman_api(context_messages) str
-_parse_json_response(content, default) dict
-_estimate_confidence(content) float
+close()
}
class Neo4jClient {
-str uri
-str user
-str password
-str database
-AsyncDriver _driver
+initialize()
+close()
+create_issue_node(issue) IssueNode
+create_action_node(action) ActionNode
+create_relation(from_uuid, to_uuid, rel) RelationEdge
+merge_issue(name, category, props) IssueNode
+merge_action(name, props) ActionNode
+find_issue_by_name(name) IssueNode
+find_related_issues(uuid, rel_type) List~IssueNode~
+execute_write_query(cypher, params) result
+execute_read_query(cypher, params) result
+health_check() bool
}
class VisionService {
-str dify_vision_api_url
-str dify_vision_api_key
-str local_vision_model
+analyze_screenshot(image_bytes, conversation_id) VisionResponse
-_preprocess_image(image_bytes) bytes
-_call_vision_workflow(processed_image) dict
+inject_to_conversation_context(description, conversation_id)
}
class RagflowIngestionService {
-RagflowClient client
+upload_and_process(file_data, file_name, category_hint) RagflowIngestionResponse
+poll_processing_status(task_id) str
+create_suggestions_from_result(result) List~KnowledgeSuggestion~
}
%% ── 关系 ──────────────────────────────────────────
KnowledgeSuggestion ..> AudienceEnum : uses
KnowledgeSuggestion ..> SuggestionStatusEnum : uses
KnowledgeSuggestion ..> SourceTypeEnum : uses
KnowledgeSuggestion ..> RelationTypeEnum : uses
KnowledgeSuggestion ..> GraphSyncStatusEnum : uses
KnowledgeBase ..> GraphSyncStatusEnum : uses
KnowledgeIterationService --> WingmanService : 调用 AI 生成
KnowledgeIterationService --> Neo4jClient : 写图同步
KnowledgeIterationService --> KnowledgeSuggestion : 管理
KnowledgeIterationService --> KnowledgeBase : 落库
KnowledgeSuggestionCreate --> KnowledgeSuggestion : 创建
KnowledgeSuggestionResponse --> KnowledgeSuggestion : 返回
KnowledgeSuggestionApprove --> KnowledgeSuggestion : 状态变更
KnowledgeSuggestionReject --> KnowledgeSuggestion : 状态变更
KnowledgeSuggestionRewrite --> KnowledgeSuggestion : 内容更新
IssueNode <--> RelationEdge : 关联
ActionNode <--> RelationEdge : 关联
Neo4jClient --> IssueNode : CRUD
Neo4jClient --> ActionNode : CRUD
Neo4jClient --> RelationEdge : 管理
VisionService --> WingmanService : 复用 _call_wingman_api 范式
RagflowIngestionService --> KnowledgeSuggestion : 产出
```
---
## 4. 程序调用流程(Mermaid 时序图)
### 4.1 主流程:会话 → Dify → 建议 → 内联审批 → 写 Neo4j 图
```mermaid
sequenceDiagram
actor 员工 as 👤 员工
actor 坐席 as 👤 坐席
actor 训练师 as 👤 AI训练师
participant H5 as H5前端
participant AgentFE as 坐席控制台
participant API as FastAPI
participant KIS as KnowledgeIterationService
participant WS as WingmanService
participant Dify as Dify AI Platform
participant DB as PostgreSQL
participant NEO as Neo4jClient
participant N4J as Neo4j 图数据库
Note over 员工,N4J: === 通道 A: 会话→Dify→建议 ===
员工->>H5: 发送 IT 问题(如"VPN 连不上"
H5->>API: POST /api/h5/conversations/current/messages
API->>Dify: 调用 Dify Agent(员工端 AI
Dify-->>API: AI 回复 + confidence: 0.62
API-->>H5: 返回消息(含 confidence
alt confidence < 0.7(门控触发)
H5->>H5: 渲染「转人工」卡片 + 已收集上下文
员工->>H5: 点击「转人工」
H5->>API: POST 转人工请求(附上下文快照)
end
Note over API,N4J: === 会话结束后触发分析 ===
API->>KIS: analyze_and_generate_suggestions(db, days=7)
KIS->>DB: 查询过去N天转人工/标注为无用 的会话
DB-->>KIS: 返回候选数据
loop 每个候选会话
KIS->>WS: generate_knowledge_suggestion(context_messages)
WS->>WS: _build_context_messages(messages, KN_SUGGEST_PROMPT)
WS->>Dify: _call_wingman_api(context_messages)
Dify-->>WS: 结构化 JSONtitle/content/category/tags/confidence/issue/action/relation
WS->>WS: _parse_json_response(content, default)
WS-->>KIS: dict {title, content, category, confidence, issue, action, ...}
KIS->>KIS: _auto_tag_audience(source_type, source_data)
Note over KIS: source_session_type=="employee" → employee_quick_reply<br/>source_session_type=="engineer" → engineer_workguide
KIS->>DB: INSERT KnowledgeSuggestionstatus=pending, 含图字段)
end
KIS->>API: 返回分析结果统计
Note over 坐席,N4J: === D7 内联审批 ===
坐席->>AgentFE: 浏览会话中的提案卡片
AgentFE->>API: GET /api/admin/knowledge-iteration/suggestions?status=pending
API-->>AgentFE: 提案列表(含拓扑预览、confidence、audience
alt 坐席选择「内联审批」
坐席->>AgentFE: 在会话内联卡片点击「采纳」
AgentFE->>API: POST /api/admin/knowledge-iteration/suggestions/{id}/approve
Note over API: 鉴权: require_admin / require_trainer
API->>KIS: approve_suggestion(db, suggestion_id, reviewer_id)
KIS->>DB: UPDATE status=approved, reviewed_at=now()
KIS->>DB: INSERT KnowledgeBase (含 graph_sync_status=pending)
KIS->>DB: UPDATE suggestion status=applied
Note over KIS,N4J: D1 解读2·直接写图
KIS->>NEO: merge_issue(issue_name, category, props)
NEO->>N4J: MERGE (i:Issue {name: $name}) ON CREATE SET i+=$props
N4J-->>NEO: IssueNode(uuid=...)
KIS->>NEO: merge_action(action_name, props)
NEO->>N4J: MERGE (a:Action {name: $name}) ON CREATE SET a+=$props
N4J-->>NEO: ActionNode(uuid=...)
KIS->>NEO: create_relation(issue_uuid, action_uuid, rel)
NEO->>N4J: MATCH (i),(a) WHERE i.uuid=$i AND a.uuid=$a CREATE (i)-[:LEADS_TO {order:$o,weight:$w}]->(a)
KIS->>DB: UPDATE suggestion graph_sync_status=synced
KIS->>DB: UPDATE KnowledgeBase graph_sync_status=synced, graph_node_uuid=...
API-->>AgentFE: 200 OK(含更新后提案)
else 坐席选择「驳回」
AgentFE->>API: POST /api/admin/knowledge-iteration/suggestions/{id}/reject {reject_reason}
API->>KIS: reject_suggestion(db, id, reviewer_id, reason)
KIS->>DB: UPDATE status=rejected
API-->>AgentFE: 200 OK
else 坐席选择「改写」
AgentFE->>API: POST /api/admin/knowledge-iteration/suggestions/{id}/rewrite {title, content, ...}
API->>KIS: rewrite_suggestion(db, id, reviewer_id, data)
KIS->>DB: UPDATE title/content/category/tags/confidence...
KIS->>DB: UPDATE status=pending(重新审批)
API-->>AgentFE: 200 OK
end
Note over 训练师,N4J: === D7 独立队列(未处理提案) ===
训练师->>AgentFE: 打开独立队列页
AgentFE->>API: GET /api/admin/approval-queue/queued?status=pending
Note over API: 未处理的=SESSION_CLOSED 后仍 pending 的提案<br/>或手动标记 queued
API-->>AgentFE: 队列列表
训练师->>AgentFE: 审核队列中的提案
AgentFE->>API: POST /api/admin/approval-queue/{id}/dequeue-approve
Note over API,N4J: 同 approve_suggestion 流程→写图
```
### 4.2 子流程:截图 → Qwen-VL 视觉理解
```mermaid
sequenceDiagram
actor 员工 as 👤 员工
participant H5 as H5前端
participant API as FastAPI
participant VS as VisionService
participant Dify as DifyQwen-VL 工作流)
participant QwenVL as Qwen3-VL-8B-Instruct
participant DB as PostgreSQL
员工->>H5: 点击📷上传截图
H5->>H5: 预览截图、允许追加描述文字
员工->>H5: [发送]
H5->>API: POST /api/vision/analyzemultipart: image + conversation_id
API->>VS: analyze_screenshot(image_bytes, conversation_id)
VS->>VS: _preprocess_image(image_bytes) → resize/compress
VS->>Dify: POST Dify vision workflow(携带 image base64
Dify->>QwenVL: 调用本地 Qwen-VL 推理
QwenVL-->>Dify: 结构化描述 JSON
Dify-->>VS: {description, detected_ui_elements, error_codes, ...}
VS-->>API: VisionResponse {description, confidence, metadata}
API->>VS: inject_to_conversation_context(description, conversation_id)
VS->>DB: INSERT/UPDATE 会话消息(sender_type=system, content=视觉理解描述)
API-->>H5: {code:0, data: {description, confidence}}
H5->>H5: 展示「AI 已理解截图内容:…」
Note over H5: 后续消息中,视觉描述作为上下文参与 Dify 推理
```
### 4.3 子流程:文档 → RAGFlow → KB(通道 C
```mermaid
sequenceDiagram
actor 训练师 as 👤 AI训练师
participant AdminFE as 管理后台
participant API as FastAPI
participant RIS as RagflowIngestionService
participant RGF as RAGFlow Server
participant KIS as KnowledgeIterationService
participant DB as PostgreSQL
训练师->>AdminFE: 上传非标准格式文档(.docx/.pdf/图片)
AdminFE->>API: POST /api/ragflow/ingestmultipart: file + category_hint
API->>RIS: upload_and_process(file_data, file_name, category_hint)
RIS->>RGF: POST /api/v1/datasets/{id}/documents/upload
RGF-->>RIS: {document_id, status: "processing"}
loop 轮询处理状态(最多 5 分钟)
RIS->>RGF: GET /api/v1/datasets/{id}/documents/{doc_id}
RGF-->>RIS: {status: "completed|failed"}
end
RIS->>RGF: GET /api/v1/datasets/{id}/documents/{doc_id}/chunks
RGF-->>RIS: 结构化段落列表
RIS->>RIS: create_suggestions_from_result(chunks)
Note over RIS: 每个段落 → KnowledgeSuggestion<br/>source_type=document_ragflow
loop 每个结构化片段
RIS->>KIS: 创建 pending 提案(复用 D7 审批流)
KIS->>DB: INSERT KnowledgeSuggestionstatus=pending, audience=engineer_workguide
end
RIS-->>API: RagflowIngestionResponse {task_id, status, suggestions}
API-->>AdminFE: 200 OK(提案列表,等待训练师审核)
```
### 4.4 子流程:坐席代答/排除(D9)
```mermaid
sequenceDiagram
actor 坐席 as 👤 坐席
actor 员工 as 👤 员工
participant AgentFE as 坐席控制台
participant H5 as H5前端
participant API as FastAPI
participant DB as PostgreSQL
Note over 员工: AI 已发送分诊选择题(如"您的系统版本是?")
Note over 坐席: 坐席通过镜像看到相同选择题
坐席->>AgentFE: 在排除面板中勾选「macOS」为错误项
AgentFE->>AgentFE: 选项置灰/划除(local UI
坐席->>AgentFE: 点击「Win10」加推荐标记⭐
AgentFE->>API: POST /api/triage/{message_id}/agent-exclude<br/>{excluded_options: ["macOS"], recommended_option: "Win10"}
API->>DB: 记录排除动作到审计日志(D7 留痕)
API-->>AgentFE: 200 OK
Note over API,H5: WebSocket 推送排除/推荐事件到员工 H5
H5->>H5: 渲染「坐席已排除"macOS",推荐您选 Win10/Win11」
Note over H5: 坐席不可代用户点确认——最终确认按钮仍在用户侧
员工->>H5: 自主选择「Win10」并确认
H5->>API: POST /api/triage/{message_id}/user-confirm {selected: "Win10"}
alt 30s 未确认
H5->>H5: 推送确认/取消提醒卡片(D9 超时机制)
end
```
### 4.5 子流程:审批状态机五态流转
```mermaid
sequenceDiagram
participant SRC as 通道A/B/C
participant KIS as KnowledgeIterationService
participant DB as PostgreSQL
participant NEO as Neo4jClient
participant N4J as Neo4j
Note over SRC,N4J: pending → queued → approved → applied → graph_synced
SRC->>KIS: 生成提案(Dify/手动/RAGFlow
KIS->>DB: INSERT status=pending
alt 会话关闭且提案仍 pending
KIS->>DB: UPDATE status=queued, queued_at=now()
Note over DB: 进入独立队列(D7
end
alt 训练师内联审批「采纳」
KIS->>DB: UPDATE status=approved, reviewer_id=..., reviewed_at=now()
KIS->>DB: INSERT KnowledgeBase(同步创建 flat KB 条目)
KIS->>DB: UPDATE suggestion status=applied, applied_at=now()
Note over DB: applied → KB 条目已落库
KIS->>NEO: merge_issue + merge_action + create_relation
NEO->>N4J: Cypher 事务写入
N4J-->>NEO: OK
KIS->>DB: UPDATE suggestion graph_sync_status=synced
KIS->>DB: UPDATE knowledge_base graph_sync_status=synced
Note over DB: graph_synced → 图已同步
else 训练师「驳回」
KIS->>DB: UPDATE status=rejected, reject_reason=...
else 训练师「改写」
KIS->>DB: UPDATE content/title/... + status=pending
Note over DB: 回退到 pending,重新走审批
else 超时(待确认参数)
KIS->>DB: UPDATE status=expired
Note over DB: 转训练师独立工单(D7)
end
alt Neo4j 写图失败(graph_sync_status=failed
KIS->>DB: UPDATE graph_sync_status=failed
Note over DB: 已有 applied 的 KB 条目,图同步失败进入重试队列
end
```
---
## 5. 待明确事项(来自增量PRD §8 + 架构分析)
| # | 待明确事项 | 当前假设/默认值 | 影响范围 |
|---|-----------|---------------|---------|
| 1 | **Neo4j 测试容器选型** | 推荐 `testcontainers-python[neo4j]`,本地开发用 Docker Neo4j 容器;CI 用 `neo4j:5-enterprise` 镜像 | 测试策略/pytest fixture |
| 2 | **分诊概率展示形式** | 默认**百分比**(如"72%"),精确到整数;不直接披露原始 confidence 给员工 | H5 TriageCard 组件 |
| 3 | **专家模式默认值** | 默认**关**(分步模式),普通员工首屏体验优先 | H5 ExpertModeToggle 组件 |
| 4 | **独立队列超时时间** | 默认 **72 小时** 未处理→`expired`,到期前 24 小时企微通知训练师 | ApprovalQueueService |
| 5 | **置信阈值分场景微调** | 默认统一 0.7,预留 `confidence_thresholds` JSON 配置字段(按 category),本期不实现按场景分阈值 | config.py |
| 6 | **audience 第三类** | 当前仅 `employee_quick_reply` / `engineer_workguide` 两类;如需"管理运营KB"由后续 P2 扩展 | AudienceEnum |
| 7 | **Qwen-VL 部署资源** | 假设本地已部署 Qwen3-VL-8B-Instruct(显存≥24GB),Dify 工作流已配置 vision-completion 节点 | VisionService / P1-3 |
| 8 | **RAGFlow 触发时机** | **训练师手动上传**触发,非定时扫描;格式范围:.docx/.pdf/.txt/.png/.jpg | P1-5 |
| 9 | **坐席代答超时** | 30s 未确认→推送提醒卡片;**不自动采用**推荐项(严格 D9:最终确认权在用户) | AgentExclusionPanel |
| 10 | **Neo4j 客户端分期** | Neo4j 客户端基础设施在 **T01 实现**,图写入在 **T03 串联** | 任务编排 |
---
# Part B: 任务分解
## 6. 依赖包列表
```
# ── 核心新增 ──
neo4j>=5.26.0 # Neo4j 官方异步驱动(bolt 协议)
Pillow>=10.0.0 # 截图预处理(resize/compress
# ── 测试(仅测试环境) ──
testcontainers[neo4j]>=4.0.0 # Neo4j 测试容器(CI 本地模拟)
pytest-asyncio>=0.23.0 # 异步测试 fixture(已有)
# ── 复用(无需新增) ──
# httpx>=0.25.0 — 已有,Dify/RAGFlow HTTP 调用
# sqlalchemy>=2.0 — 已有,ORM
# fastapi>=0.110 — 已有,Web 框架
# pydantic>=2.0 — 已有,Schema 验证
# alembic>=1.13 — 已有,数据库迁移
# redis>=5.0 — 已有,缓存/队列
# wordfilter>=0.3 — 已有,敏感词检测(不动)
```
## 7. 任务列表(有序、含依赖)
### T01: 项目基础设施 — Neo4j 环境 + 配置 + 迁移
| 属性 | 值 |
|------|-----|
| **Task ID** | T01 |
| **优先级** | P0(Tier0 前置,阻塞所有后续任务) |
| **工期** | 1-2 天 |
| **依赖** | 无 |
**目标**:搭建 Neo4j 连接基础设施、Alembic 迁移新增字段、配置项扩展。
**源文件**7 个):
| # | 文件 | 操作 | 关键内容 |
|---|------|------|---------|
| 1 | `backend/requirements.txt` | `[改]` | 新增 `neo4j>=5.26.0`、`Pillow>=10.0.0` |
| 2 | `backend/app/config.py` | `[改]` | 新增 `neo4j_uri/neo4j_user/neo4j_password/neo4j_database` 配置项;新增 `confidence_gate_threshold: float = 0.7`;新增 `ragflow_ingestion_enabled: bool = False` |
| 3 | `backend/app/services/neo4j_client.py` | `[新]` | `Neo4jClient` 类:`__init__`(uri/user/password/database)→`AsyncDriver``initialize()`→验证连接+创建约束/索引;`close()`→释放驱动;`health_check()`→`RETURN 1``execute_write_query(cypher, params)`→写事务;`execute_read_query(cypher, params)`→读事务 |
| 4 | `backend/app/models/neo4j_schema.py` | `[新]` | Pydantic 模型:`IssueNode(uuid,name,category,created_at,updated_at,source_suggestion_id)``ActionNode(uuid,name,description,created_at,source_suggestion_id)``RelationEdge(from_uuid,to_uuid,type,order,weight)` |
| 5 | `backend/alembic/versions/xxxx_add_graph_confidence_audience.py` | `[新]` | Alembic migration`knowledge_suggestions` 表新增 `confidence`(Float)、`audience`(String(30))、`issue`(String(256))、`action`(String(256))、`relation_type`(String(30))、`parent_issue`(String(256))、`graph_meta`(JSON)、`graph_sync_status`(String(20), default='pending')、`source_failed`(Boolean, default=False)、`queued_at`(DateTime)、`applied_at`(DateTime)`knowledge_base` 表新增 `graph_sync_status`(String(20))、`graph_node_uuid`(String(36)) |
| 6 | `backend/app/schemas/enums.py` | `[新]` | `AudienceEnum(employee_quick_reply, engineer_workguide)`、`SuggestionStatusEnum(pending,queued,approved,rejected,applied,graph_synced,expired)`、`GraphSyncStatusEnum(pending,synced,failed)`、`SourceTypeEnum(annotation,conversation,ai_uncertain,manual,document_ragflow)`、`RelationTypeEnum(LEADS_TO,RELATES_TO,CAN_JUMP_TO)` |
| 7 | `docker-compose.dev.yml` | `[改]` | 新增 `neo4j` 服务定义(image: `neo4j:5-enterprise`, ports: `7474:7474`/`7687:7687`, env: `NEO4J_AUTH=neo4j/test1234` |
**验收标准**
- `Neo4jClient.health_check()` 返回 `True`Docker Neo4j 启动后)
- Alembic migration 在 PostgreSQL 可执行 `upgrade`/`downgrade`
- `config.py` 新增配置项可通过环境变量注入
---
### T02: 数据与状态层 — 模型扩展 + Schema + Neo4j 基础 CRUD
| 属性 | 值 |
|------|-----|
| **Task ID** | T02 |
| **优先级** | P0Tier1 |
| **工期** | 1-2 天 |
| **依赖** | T01 |
**目标**:扩展 PostgreSQL 模型与 Pydantic Schema,实现 Neo4j 基础图节点 CRUD。
**源文件**7 个):
| # | 文件 | 操作 | 关键内容 |
|---|------|------|---------|
| 1 | `backend/app/models/knowledge_suggestion.py` | `[改]` | 在 `KnowledgeSuggestion` 类中新增 12 个字段:`confidence: Mapped[Optional[float]]`、`audience: Mapped[Optional[str]]`(String(30))、`issue: Mapped[Optional[str]]`(String(256))、`action: Mapped[Optional[str]]`(String(256))、`relation_type: Mapped[Optional[str]]`(String(30))、`parent_issue: Mapped[Optional[str]]`(String(256))、`graph_meta: Mapped[Optional[dict]]`(JSON)、`graph_sync_status: Mapped[str]`(String(20), default='pending')、`source_failed: Mapped[bool]`(Boolean, default=False)、`queued_at: Mapped[Optional[datetime]]`、`applied_at: Mapped[Optional[datetime]]`;新增索引 `idx_suggestion_audience`、`idx_suggestion_confidence`、`idx_suggestion_graph_sync` |
| 2 | `backend/app/models/knowledge_base.py` | `[改]` | 新增 `graph_sync_status: Mapped[str]`(String(20), default='pending')、`graph_node_uuid: Mapped[Optional[str]]`(String(36)) |
| 3 | `backend/app/schemas/knowledge_suggestion.py` | `[改]` | `KnowledgeSuggestionCreate`:新增 `confidence`(Optional[float])、`audience`(Optional[AudienceEnum])、`issue/action/relation_type/parent_issue`(Optional[str])、`graph_meta`(Optional[dict])。`KnowledgeSuggestionResponse`:新增全部 12 个扩展字段。新增 `KnowledgeSuggestionRewrite`(用于训练师改写提案) |
| 4 | `backend/app/services/neo4j_client.py` | `[改]` | 扩展 T01 的 `Neo4jClient``create_issue_node(issue: IssueNode) → IssueNode``create_action_node(action: ActionNode) → ActionNode``create_relation(from_uuid, to_uuid, rel: RelationEdge) → bool``merge_issue(name, category, props) → IssueNode`MERGE 幂等);`merge_action(name, props) → ActionNode``find_issue_by_name(name) → Optional[IssueNode]``find_related_issues(uuid, rel_type) → List[IssueNode]` |
| 5 | `backend/app/schemas/enums.py` | `[改]` | 补充枚举文档注释 + `__str__` 方法 |
| 6 | `backend/tests/test_neo4j_client.py` | `[新]` | 测试:`test_health_check`、`test_create_issue_node`、`test_create_action_node`、`test_create_relation`、`test_merge_issue_idempotent`、`test_find_issue_by_name`、`test_find_related_issues` |
| 7 | `backend/app/dependencies.py` | `[改]` | 新增 `dep_neo4j_client()` 依赖注入函数(单例/请求级) |
**验收标准**
- `KnowledgeSuggestion` 模型新字段可通过 SQLAlchemy 正常读写
- `KnowledgeSuggestionCreate` 可接受图字段并验证类型
- `Neo4jClient` 所有 CRUD 方法通过 pytest(需要 Neo4j 测试容器)
---
### T03: 核心业务服务 — AI 生成 + 置信门控 + 审批 + 写图
| 属性 | 值 |
|------|-----|
| **Task ID** | T03 |
| **优先级** | P0Tier1 核心) |
| **工期** | 2-3 天 |
| **依赖** | T02 |
**目标**:实现真 AI 知识建议生成、置信门控逻辑、审批状态机、audience 自动标注、Neo4j 图同步。
**源文件**8 个):
| # | 文件 | 操作 | 关键内容 |
|---|------|------|---------|
| 1 | `backend/app/services/wingman_service.py` | `[改]` | 新增 `_KNOWLEDGE_SUGGESTION_PROMPT`(要求输出结构化 JSONtitle/content/category/tags/confidence/issue/action/relation_type/parent_issue);新增 `generate_knowledge_suggestion(context_messages: List[Dict]) → Dict[str, Any]` 方法(复用 `_build_context_messages`+`_call_wingman_api`+`_parse_json_response` |
| 2 | `backend/app/services/knowledge_iteration_service.py` | `[改]` | **核心重写**`_generate_update_suggestion` 和 `_generate_new_faq_suggestion` 移除 `[待AI生成]` 占位→调用 `WingmanService.generate_knowledge_suggestion()`Dify 不可用时设 `source_failed=True`;新增 `_auto_tag_audience(db, source_type, source_data) → AudienceEnum`(查 `Conversation.session_type`→映射 audience);新增 `_apply_confidence_gate(suggestion) → bool`conf<0.7→标记 source_failed);`approve_suggestion` 扩展→状态机五态流转+Neo4j 写图(调用 `Neo4jClient.merge_issue/merge_action/create_relation`);新增 `rewrite_suggestion(db, id, reviewer_id, data)`;新增 `queue_suggestion(db, id)`;新增 `dequeue_approve(db, id, reviewer_id)`;新增 `sync_to_neo4j(neo4j_client, suggestion) → bool` |
| 3 | `backend/app/services/vision_service.py` | `[新]` | `VisionService` 类:`__init__`(dify_vision_api_url, dify_vision_api_key, model="Qwen3-VL-8B-Instruct")`analyze_screenshot(image_bytes, conversation_id) → VisionResponse``_preprocess_image(image_bytes) → bytes`Pillow resize→max 1024px, compress JPEG quality=85);`_call_vision_workflow(processed_image) → dict`httpx→Dify vision workflow);`inject_to_conversation_context(description, conversation_id)` |
| 4 | `backend/app/services/ragflow_ingestion_service.py` | `[新]` | `RagflowIngestionService` 类:`upload_and_process(file_data, file_name, category_hint) → RagflowIngestionResponse``poll_processing_status(task_id, max_wait=300) → str``create_suggestions_from_result(chunks) → List[KnowledgeSuggestion]`source_type=document_ragflow, audience=engineer_workguide |
| 5 | `backend/tests/test_knowledge_iteration.py` | `[改]` | 重写 4/4 桩断言→真 AI 生成断言(Mock Dify 返回→验证 title/content 非 `[待AI生成]`);新增 `test_source_failed_on_dify_unavailable`;新增 `test_auto_tag_audience`;新增 `test_confidence_gate_below_threshold` |
| 6 | `backend/tests/test_approval_state_machine.py` | `[新]` | 测试五态流转:`test_pending_to_approved`、`test_approved_to_applied_to_graph_synced`、`test_rejected`、`test_rewrite_resets_to_pending`、`test_pending_to_queued`、`test_queued_to_approved`、`test_expired` |
| 7 | `backend/tests/test_confidence_gate.py` | `[新]` | 测试:`test_confidence_above_07_passes`、`test_confidence_below_07_marks_source_failed`、`test_threshold_configurable` |
| 8 | `backend/app/services/__init__.py` | `[改]` | 导出新增服务类 |
**验收标准**
- `_generate_*_suggestion` 生成内容不再含 `[待AI生成]`(通过 Dify/Mock
- Dify 不可用时 `source_failed=True`,不写伪数据
- `confidence < 0.7` 的提案标记 `source_failed=True`
- `approve_suggestion` 触发 Neo4j 图写入,`graph_sync_status` 正确流转到 `synced`
- 审批状态机所有合法转换通过测试
---
### T04: API 层 — 路由挂载 + 新端点 + Qwen-VL + RAGFlow
| 属性 | 值 |
|------|-----|
| **Task ID** | T04 |
| **优先级** | P0Tier1 |
| **工期** | 1-2 天 |
| **依赖** | T03 |
**目标**:挂载知识迭代路由、新增独立队列/视觉/RAGFlow API、更新前端接口契约。
**源文件**7 个):
| # | 文件 | 操作 | 关键内容 |
|---|------|------|---------|
| 1 | `backend/app/api/router.py` | `[改]` | **取消 L32 注释**`from app.api.knowledge_iteration import router as knowledge_iteration_router``api_router.include_router(knowledge_iteration_router, prefix="/admin/knowledge-iteration", tags=["知识库自动迭代"])`;新增 `vision_router`、`approval_queue_router`、`ragflow_router` 挂载 |
| 2 | `backend/app/api/knowledge_iteration.py` | `[改]` | 扩展现有 6 端点:`list_suggestions` 新增 `audience`/`confidence_min`/`confidence_max` 查询参数;`approve_suggestion` 改为调用 `KnowledgeIterationService.approve_suggestion`(触发 Neo4j 写图+状态流转);新增 `POST /suggestions/{id}/rewrite`(训练师改写);`POST /suggestions/{id}/queue`(进队列);`POST /suggestions/{id}/dequeue-approve`(队列审批) |
| 3 | `backend/app/api/approval_queue.py` | `[新]` | `GET /queued?status=queued&audience=&page=&page_size=`(独立队列列表);`GET /queued/stats`(队列统计);`POST /queued/{id}/dequeue-approve`(队列中审批) |
| 4 | `backend/app/api/vision.py` | `[新]` | `POST /api/vision/analyze`multipart: image + conversation_id → VisionResponse);`GET /api/vision/models`(可用的 vision 模型列表) |
| 5 | `backend/app/api/ragflow_ingestion.py` | `[新]` | `POST /api/ragflow/ingest`multipart: file + category_hint → RagflowIngestionResponse);`GET /api/ragflow/tasks/{task_id}`(查询处理状态) |
| 6 | `backend/app/api/__init__.py` | `[改]` | 导出新路由模块 |
| 7 | `backend/tests/test_api_knowledge_iteration.py` | `[新]` | API 集成测试:`test_list_suggestions_with_new_filters`、`test_approve_triggers_graph_sync`、`test_rewrite_endpoint`、`test_queue_endpoint` |
**验收标准**
- `GET /api/admin/knowledge-iteration/suggestions` 返回 200(非 404
- OpenAPI 文档可见 knowledge_iteration 路由(P0-2
- `POST /api/admin/knowledge-iteration/suggestions/{id}/approve` 触发 Neo4j 写图(P0-6
- `POST /api/vision/analyze` 返回结构化描述(P1-3
- `POST /api/ragflow/ingest` 返回 pending 提案(P1-5
---
### T05: 前端组件 — 分诊卡片 + 审批UI + 排除控件 + 队列
| 属性 | 值 |
|------|-----|
| **Task ID** | T05 |
| **优先级** | P0/P1Tier1 |
| **工期** | 2-3 天 |
| **依赖** | T04 |
**目标**:三端前端组件落地,覆盖分诊门控、内联审批、坐席排除、独立队列、RAGFlow 上传。
**源文件**12 个):
| # | 文件 | 操作 | 关键内容 | 落点 |
|---|------|------|---------|------|
| 1 | `frontend-h5/src/components/TriageCard.vue` | `[新]` | 分诊置顶卡片:AI 分步问题(是/否/概率选择题)、步骤进度(1/3)、专家模式开关 | H5P1-1/D4 |
| 2 | `frontend-h5/src/components/ConfidenceGateBanner.vue` | `[新]` | 置信门控横幅:conf<0.7 时渲染「转人工」入口+已收集上下文快照 | H5(P0-3/D3 |
| 3 | `frontend-h5/src/components/ImageUploader.vue` | `[新]` | 截图上传+中途补图+视觉理解结果展示 | H5(P1-3/D5 |
| 4 | `frontend-h5/src/composables/useConfidenceGate.ts` | `[新]` | conf<0.7 判定、转人工上下文组装、阈值读取 | H5 |
| 5 | `frontend-agent/src/components/chat/ApprovalInlineCard.vue` | `[新]` | 内联审批卡片:title/content/confidence/topology 预览(Issue→Action 小图)、[采纳][驳回][改写] 按钮、audience 下拉 | 坐席(P0-6/D7 |
| 6 | `frontend-agent/src/components/chat/AgentExclusionPanel.vue` | `[新]` | 坐席排除:多选排除+推荐标记+30s 倒计时+不可代确认 | 坐席(P1-2/D9 |
| 7 | `frontend-agent/src/views/ApprovalQueue.vue` | `[新]` | 独立队列页:表格(来源/audience/confidence/状态/时间)+批量操作+筛选 | 坐席(P0-6/D7 |
| 8 | `frontend-agent/src/composables/useApprovalQueue.ts` | `[新]` | 队列数据获取、筛选状态、审批动作封装 | 坐席 |
| 9 | `frontend-admin/src/views/KnowledgeIteration.vue` | `[新]` | 知识迭代管理:提案列表+审阅+图字段编辑(issue/action/relation/parent+训练师手动录入入口 | 管理后台(P0-6/P2-1 |
| 10 | `frontend-admin/src/views/RagflowIngestion.vue` | `[新]` | RAGFlow 文档上传:拖拽上传+处理进度+生成提案预览 | 管理后台(P1-5) |
| 11 | `frontend-agent/src/App.vue` | `[改]` | 注册审批队列路由 `/approval-queue` | 坐席 |
| 12 | `frontend-admin/src/router/index.ts` | `[改]` | 注册 knowledge-iteration、ragflow-ingestion 路由 | 管理后台 |
**验收标准**
- 员工端 AI 回复 conf<0.7 时出现「转人工」卡片(P0-3)
- 坐席端会话中显示内联审批卡片(P0-6)
- 独立队列页可查看/筛选/审批(P0-6)
- 坐席可排除选项但不能代用户确认(P1-2)
- 管理后台可上传文档触发 RAGFlow(P1-5
---
## 8. 共享知识
### 8.1 Neo4j 图节点属性与复杂场景重构命名映射约定
| 本设计 | 复杂场景重构 v1.1 | 说明 |
|--------|------------------|------|
| `Issue.name` | `Issue.name` | **完全对齐**,如"VPN问题" |
| `Issue.category` | `Issue.category` | **完全对齐**,如"网络" |
| `Action.name` | `Action.name` | **完全对齐**,如"个人VPN开通" |
| `RelationEdge.type=LEADS_TO` | `LEADS_TO {type:"可选", order:N}` | **完全对齐**`order` 和 `weight` 为图边属性 |
| `RelationEdge.type=RELATES_TO` | `CAN_JUMP_TO {type:"跳转"}` | **语义简化**:统一用 `RELATES_TO` 含子类型 |
| `InfoNode.modifiers` | `InformationItem.modifiers` | **完全对齐**`固定/增量/明确/隐含/复述/必需` 六种修饰 |
| `Issue.parent_issue` | 无直接对应 | **扩展**:通过 `KnowledgeSuggestion.parent_issue` 关联父 Issue,写入 Neo4j 时创建 `LEADS_TO` 或 `RELATES_TO` 关系 |
**图写入时的去重策略**:使用 `MERGE` 而非 `CREATE`,按 `Issue.name` / `Action.name` 唯一键幂等写入。
### 8.2 confidence 计算口径
| 来源 | 计算方式 | 说明 |
|------|---------|------|
| Dify 生成 | Dify 工作流输出中包含 `confidence` 字段(由 LLM 自评 + prompt 约束输出 0.0-1.0 | 通道 A 自动 |
| 训练师手动 | 默认 1.0(训练师录入视为最高置信) | 通道 B |
| RAGFlow 预处理 | 默认 0.85(结构化提取降一档) | 通道 C |
| Wingman 估算 | 复用现有 `_estimate_confidence()`(基于内容长度/不确定措辞启发式) | 通道 A 兜底 |
| 门控阈值 | **全局 0.7**`settings.confidence_gate_threshold`),低于此值标记 `source_failed=True` + 前端渲染转人工 | D3 |
### 8.3 audience 判定规则
```
判定函数: determine_audience(source_type, source_data)
IF source_type == "manual" OR source_type == "document_ragflow":
→ 默认 engineer_workguide(坐席可改)
IF source_type in ("annotation", "conversation", "ai_uncertain"):
→ 查 Conversation.session_type:
"employee" → employee_quick_reply
"engineer" → engineer_workguide
(其他/未知) → employee_quick_reply(保守默认)
训练师审核时可覆盖 audience。
```
### 8.4 审计日志格式
所有审批/改写/排除动作写入审计日志(复用现有 `audit_logs` 表),格式:
```json
{
"action": "approve_suggestion|reject_suggestion|rewrite_suggestion|agent_exclude",
"target_id": "<suggestion_id or message_id>",
"operator_id": "<reviewer_id or agent_id>",
"timestamp": "ISO8601",
"details": {"previous_status": "pending", "new_status": "approved", ...}
}
```
### 8.5 后端 API 统一响应格式
所有 API 沿用现有格式:
```json
{"code": 0, "message": "success", "data": {...}}
```
---
## 9. 任务依赖图
```mermaid
graph TD
T01["T01: 项目基础设施<br/>Neo4j + 配置 + 迁移<br/>P0 · Tier0<br/>7 文件"]
T02["T02: 数据与状态层<br/>模型 + Schema + Neo4j CRUD<br/>P0 · Tier1<br/>7 文件"]
T03["T03: 核心业务服务<br/>AI生成 + 门控 + 审批 + 写图<br/>P0 · Tier1<br/>8 文件"]
T04["T04: API 层<br/>路由挂载 + 新端点 + Vision + RAGFlow<br/>P0 · Tier1<br/>7 文件"]
T05["T05: 前端组件<br/>分诊 + 审批UI + 排除 + 队列<br/>P0/P1 · Tier1<br/>12 文件"]
T01 --> T02
T02 --> T03
T03 --> T04
T04 --> T05
style T01 fill:#FF6B6B,color:#fff
style T02 fill:#4ECDC4,color:#fff
style T03 fill:#45B7D1,color:#fff
style T04 fill:#96CEB4,color:#fff
style T05 fill:#FFEAA7,color:#333
```
**Tier 分期说明**
- **Tier0T01**Neo4j 客户端 + 图 schema + 配置 + 迁移 → **前置阶段**,必须最先完成。
- **Tier1T02-T05**:数据层 → 服务层 → API 层 → 前端 → **核心交付阶段**,串行依赖链。
- **不在本次迭代**:复杂场景引擎(非线性跳转/多意图并行/任务中断恢复)、敏感词 BLOCK 升级、DLP 实质整合、Neo4j 图测试容器 CI 集成(P2)。
---
*本文档为增量架构设计 v1.0,架构师高见远(software-architect),2026-07-07*