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

2082 lines
72 KiB
Markdown
Raw Normal View History

# 增量设计:知识库迭代与痛点缓解
> **文档版本**v1.0
> **创建日期**2026-07-11
> **文档类型**:回溯文档(已部署功能)+ 前瞻设计(未实现功能)
> **测试报告引用**`docs/06-测试质量/Tier0-测试报告-20260708.md`89/89 通过)
> **技术栈**FastAPI + SQLAlchemy + PostgreSQL + Redis + Neo4j / Vue3 + Element Plus + Vant4 + ECharts
---
## 目录
1. [概述](#1-概述)
2. [系统架构总览](#2-系统架构总览)
3. [各功能模块技术方案](#3-各功能模块技术方案)
- 3.1 [分诊交互](#31-分诊交互)
- 3.2 [置信门控](#32-置信门控)
- 3.3 [内联审批卡片](#33-内联审批卡片)
- 3.4 [拓扑预览](#34-拓扑预览)
- 3.5 [重复检测](#35-重复检测)
- 3.6 [代答排除](#36-代答排除)
- 3.7 [知识迭代管理](#37-知识迭代管理)
- 3.8 [图谱可视化](#38-图谱可视化)
- 3.9 [合并去重](#39-合并去重)
- 3.10 [会话关闭→建议→审核→写图](#310-会话关闭建议审核写图)
4. [功能依赖关系图](#4-功能依赖关系图)
5. [全链路数据流图](#5-全链路数据流图)
6. [未实现功能设计](#6-未实现功能设计)
7. [已知问题与后续优化方向](#7-已知问题与后续优化方向)
---
## 1. 概述
### 1.1 功能背景
IT智能服务台在持续运营中暴露出三大痛点:
1. **知识库更新滞后**:AI 回复不准确的问题需要人工发现→人工编写→人工录入,平均更新周期超过 2 周。
2. **低置信回复无兜底**AI 回复 confidence 低于阈值时,员工无感知,直接收到低质量回答,体验差。
3. **重复知识堆积**:多个来源(会话分析、标注分析、手动录入)生成的建议缺乏去重机制,导致知识图谱中出现重复 Issue 节点。
为解决上述痛点,本项目实施了"知识库迭代与痛点缓解"功能集,包含 10 个功能模块,覆盖从 AI 回复质量保障到知识图谱自动维护的完整闭环。
### 1.2 目标
| 目标 | 衡量指标 |
|------|---------|
| 知识库自动迭代 | 会话关闭后自动生成知识建议,训练师审核后自动写入知识图谱 |
| 低置信兜底 | confidence < 0.7 时前端展示转人工入口,携带上下文快照 |
| 知识去重 | 采纳建议前检测重复,支持合并去重操作 |
| 图谱可视化 | 管理后台 ECharts 力导向图展示 Neo4j 知识图谱全貌 |
| 分步分诊 | 复杂问题拆分为分步选择题,降低员工认知负担 |
### 1.3 范围
本功能集涉及 10 个功能模块,按部署状态分为两类:
| # | 功能 | 代码状态 | 部署状态 | 文档类型 |
|---|------|---------|---------|---------|
| 1 | 分诊交互 | 仅前端组件 | 未接入后端 | 前瞻设计 |
| 2 | 置信门控 | 后端配置 + 前端组件 | 生产在线 | 回溯文档 |
| 3 | 内联审批卡片 | 后端 + 前端 | 生产在线 | 回溯文档 |
| 4 | 拓扑预览 | 仅原型 SVG | 未实现后端子图查询 API 对接 | 前瞻设计 |
| 5 | 重复检测 | 后端 + 前端 | 生产在线 | 回溯文档 |
| 6 | 代答排除 | 仅前端组件方法 | 未实现 | 前瞻设计 |
| 7 | 知识迭代管理 | 47KB 服务 + 21KB API | 生产在线 | 回溯文档 |
| 8 | 图谱可视化 | Neo4j + ECharts | Neo4j 运行中 | 回溯文档 |
| 9 | 合并去重 | 后端 + 前端 | 生产在线 | 回溯文档 |
| 10 | 会话关闭→建议→审核→写图 | 全链路 | 生产在线 | 回溯文档 |
### 1.4 术语表
| 术语 | 说明 |
|------|------|
| KnowledgeSuggestion | 知识建议,AI 分析生成的待审核知识条目 |
| Issue | 知识图谱中的问题节点(Neo4j :Issue 标签) |
| Action | 知识图谱中的动作/解决方案节点(Neo4j :Action 标签) |
| confidence | AI 生成置信度(0.0-1.0),门控阈值 0.7 |
| audience | 受众类型:employee_quick_reply(员工快捷回复)/ engineer_workguide(工程师作业指导) |
| 五态流转 | pending → queued → approved → applied → graph_synced |
| 通道 A | 会话/标注/AI不确定 → 自动生成知识建议 |
| 通道 B | 训练师手动录入知识建议 |
| 通道 C | RAGFlow 文档 ETL → 知识建议(预留,未实现) |
---
## 2. 系统架构总览
### 2.1 架构总览图
```mermaid
graph TB
subgraph "H5 员工端"
H5_Triage[分诊卡片 TriageCard]
H5_ConfGate[置信门控 ConfidenceGateBanner]
H5_Chat[AI 对话]
end
subgraph "Agent 坐席端"
AG_Approval[内联审批卡片 ApprovalInlineCard]
AG_Queue[独立审批队列 ApprovalQueue]
AG_Chat[坐席会话]
end
subgraph "Admin 管理后台"
ADM_Knowledge[知识迭代管理 KnowledgeIteration]
ADM_Graph[图谱可视化 ECharts]
end
subgraph "Backend FastAPI"
API_Conv[会话 API conversations.py]
API_KI[知识迭代 API knowledge_iteration.py]
API_Queue[审批队列 API approval_queue.py]
Svc_KI[知识迭代服务 KnowledgeIterationService]
Svc_Wingman[Wingman AI 服务]
Neo4j_Client[Neo4j 客户端]
end
subgraph "数据存储"
PG[(PostgreSQL)]
Redis[(Redis)]
Neo4j[(Neo4j 图数据库)]
Dify[Dify AI 平台]
end
%% H5 交互
H5_Chat -->|AI回复| H5_ConfGate
H5_Triage -->|分步选择| H5_Chat
H5_ConfGate -->|confidence<0.7| API_Conv
%% 会话关闭触发
AG_Chat -->|结单| API_Conv
API_Conv -->|异步触发| Svc_KI
Svc_KI -->|调用AI| Svc_Wingman
Svc_Wingman --> Dify
Svc_KI -->|写入建议| PG
%% 审批流程
AG_Approval -->|采纳/驳回/改写| API_KI
AG_Queue -->|队列审批| API_Queue
ADM_Knowledge -->|管理审核| API_KI
%% 知识落库 + 写图
API_KI --> Svc_KI
Svc_KI -->|创建KB条目| PG
Svc_KI -->|写图| Neo4j_Client
Neo4j_Client --> Neo4j
%% 图谱可视化
ADM_Graph -->|查询图数据| API_KI
API_KI --> Neo4j_Client
%% 重复检测
ADM_Knowledge -->|检查重复| API_KI
API_KI --> Svc_KI
Svc_KI -->|查SQL| PG
Svc_KI -->|查图| Neo4j_Client
style H5_Triage fill:#fff3e0,stroke:#ff9800
style H5_ConfGate fill:#e8f5e9,stroke:#4caf50
style AG_Approval fill:#e3f2fd,stroke:#2196f3
style Neo4j fill:#e8eaf6,stroke:#3f51b5
style Dify fill:#fce4ec,stroke:#e91e63
```
### 2.2 技术栈分布
| 层级 | 技术选型 | 说明 |
|------|---------|------|
| 后端框架 | FastAPI + SQLAlchemy 2.0 (async) | 异步 ORMAsyncSession |
| 关系数据库 | PostgreSQL | knowledge_suggestions、knowledge_base 表 |
| 图数据库 | Neo4j 6.2.0 (AsyncDriver) | Issue/Action 节点 + 关系边 |
| 缓存 | Redis | 会话状态、恢复点 |
| AI 平台 | Dify (Wingman Agent) | 知识建议生成、意图识别 |
| 管理后台 | Vue3 + Element Plus + ECharts | 列表管理 + 力导向图 |
| 坐席端 | Vue3 + Element Plus | 内联审批卡片 + 队列 |
| H5 员工端 | Vue3 + Vant4 | 分诊卡片 + 置信门控横幅 |
| 风格 | 企微浅色扁平 | accent=#07C160 |
### 2.3 API 路由前缀
| 模块 | 前缀 | 说明 |
|------|------|------|
| 知识迭代管理 | `/api/admin/knowledge-iteration/*` | 12 条路由 |
| 独立审批队列 | `/api/admin/approval-queue/*` | 3 条路由 |
| 会话管理 | `/api/conversations/*` | 含结单触发 |
---
## 3. 各功能模块技术方案
---
### 3.1 分诊交互
#### 功能描述
AI 分诊式回复,将复杂 IT 问题拆分为分步选择题(是/否/含概率推荐),卡片置顶悬浮展示,支持专家模式切换。
**当前状态**:仅前端组件(`TriageCard.vue`),未接入后端 API。
#### 数据模型
```mermaid
classDiagram
class TriageStep {
+String question
+List~TriageOption~ options
+List~String~ collectedContext
}
class TriageOption {
+String label
+Boolean selected
+Number probability
+Boolean recommended
+Boolean excluded
}
class TriageCard {
+Boolean visible
+Number step
+Number total
+List~TriageStep~ steps
+Number confidence
+toggleCollapse()
+selectOption(idx)
+handleConfirm()
+handleSkip()
+setExcludedOptions(labels)
+setRecommendedOption(label)
}
TriageCard --> TriageStep : contains
TriageStep --> TriageOption : contains
```
#### API 接口设计(前瞻 — 未实现)
| 方法 | 路径 | 请求 | 响应 | 说明 |
|------|------|------|------|------|
| POST | `/api/h5/triage/start` | `{conversation_id, question}` | `{steps: TriageStep[], total: int}` | 发起分诊,AI 拆分复杂问题为分步选择题 |
| POST | `/api/h5/triage/step` | `{conversation_id, step_index, selected_label}` | `{next_step: TriageStep, collected_context: string[]}` | 提交当前步骤选择,获取下一步 |
| POST | `/api/h5/triage/skip` | `{conversation_id, step_index}` | `{next_step: TriageStep}` | 跳过当前步骤 |
| POST | `/api/h5/triage/transfer` | `{conversation_id, context: string[]}` | `{conversation_id, status: "waiting_agent"}` | 分诊上下文转人工 |
#### 核心流程(前瞻设计)
```mermaid
sequenceDiagram
participant H5 as H5 员工端
participant API as FastAPI 后端
participant Dify as Dify AI
participant DB as PostgreSQL
H5->>API: POST /api/h5/triage/start {conversation_id, question}
API->>Dify: 调用 Dify 分诊 prompt(拆分复杂问题为分步)
Dify-->>API: 返回 steps[] (question + options + probability)
API-->>H5: {steps, total}
loop 每一步
H5->>H5: 展示 TriageCard,员工选择选项
H5->>API: POST /api/h5/triage/step {step_index, selected_label}
API->>DB: 记录已收集上下文
API->>Dify: 根据选择动态调整后续步骤
Dify-->>API: 返回 next_step
API-->>H5: {next_step, collected_context}
end
alt 所有步骤完成
H5->>API: POST /api/h5/triage/complete
API->>Dify: 根据收集的上下文生成最终答案
Dify-->>API: 返回最终回复
API-->>H5: 返回 AI 回复
else 转人工
H5->>API: POST /api/h5/triage/transfer {context}
API->>DB: 会话状态 → waiting_agent
API-->>H5: 转人工成功
end
```
#### 前端交互设计
**组件文件**`frontend-h5/src/components/TriageCard.vue`
| 交互元素 | 说明 |
|---------|------|
| 置顶悬浮 | `position: sticky; top: 0; z-index: 100` |
| 步骤进度 | "第 X/Y 步" 显示在标题栏 |
| 选项列表 | 单选模式,点击选中/取消 |
| 概率展示 | 百分比标签(≥70% 绿色高亮),不披露原始 confidence |
| 推荐标记 | ⭐推荐 标签(坐席侧设置) |
| 排除标记 | 已排除 标签 + 灰显 + 不可点击 |
| 专家模式 | van-switch 开关,开启后展示后续步骤预览 |
| 折叠/展开 | 点击标题栏切换 |
| 底部操作 | "跳过" + "下一步/完成" |
**关键设计约束(D4 硬约束)**
- 一次给几步由 AI 判复杂度自适应
- 概率展示为百分比(不披露原始 confidence 给员工)
- 专家模式默认关(分步),老手可开一把梭
- 卡片置顶/悬浮
#### 技术选型与依赖
| 依赖 | 版本 | 用途 |
|------|------|------|
| Vue3 | ^3.4 | 响应式框架 |
| Vant4 | ^4.8 | 移动端 UIvan-switch, van-button, van-tag |
#### 部署状态
**未实现** — 前端组件已开发(530 行),但后端 API 未实现,Dify 分诊 prompt 未配置。
---
### 3.2 置信门控
#### 功能描述
当 AI 回复的 confidence 低于全局阈值 0.7 时,在 H5 前端渲染"转人工"入口并附已收集的上下文快照。门控阈值可通过 `settings.confidence_gate_threshold` 配置。
**当前状态**:生产在线。后端配置项 + 前端组件 + composable 逻辑封装。
#### 数据模型
```mermaid
classDiagram
class ConfidenceGateConfig {
+Float confidence_gate_threshold = 0.7
+String source = "settings.confidence_gate_threshold"
}
class ConfidenceGateResult {
+Boolean triggered
+Number displayProbability
+String severity
+Boolean shouldShowTransfer
}
class useConfidenceGate {
+Ref~Float~ gateThreshold
+Ref~Number~ lastConfidence
+Ref~String[]~ contextSnapshot
+Computed~ConfidenceGateResult~ gateResult
+Computed~Boolean~ showGateBanner
+evaluateConfidence(confidence, context)
+addContext(items)
+prepareTransferToHuman() String[]
+reset()
+updateThreshold(newThreshold)
}
class ConfidenceGateBanner {
+Boolean visible
+Number confidence
+String[] contextSnapshot
+String reason
+displayProbability
+severityClass
+handleTransferToHuman()
+handleContinueAI()
}
useConfidenceGate --> ConfidenceGateResult : produces
ConfidenceGateBanner --> useConfidenceGate : consumes
```
#### 配置项
| 配置项 | 默认值 | 来源 | 说明 |
|--------|--------|------|------|
| `confidence_gate_threshold` | 0.7 | `config.py``CONFIDENCE_GATE_THRESHOLD` 环境变量 | 全局置信门控阈值 |
```python
# backend/app/config.py
confidence_gate_threshold: float = 0.7
```
#### 核心流程
```mermaid
sequenceDiagram
participant H5 as H5 员工端
participant Gate as useConfidenceGate
participant Banner as ConfidenceGateBanner
participant API as FastAPI 后端
H5->>API: 发送问题
API->>API: AI 回复 + confidence 值
API-->>H5: {reply, confidence: 0.45}
H5->>Gate: evaluateConfidence(0.45, context)
Gate->>Gate: triggered = 0.45 < 0.7 = true
Gate->>Gate: severity = "warning" (0.3 ≤ 0.45 < 0.5)
Gate-->>H5: gateResult = {triggered: true, shouldShowTransfer: true}
H5->>Banner: visible=true, confidence=0.45
Banner->>Banner: displayProbability = 45%
Banner->>Banner: severityClass = "warning"
Banner-->>H5: 展示横幅 + "转人工" + "继续询问 AI"
alt 员工点击转人工
Banner->>Gate: prepareTransferToHuman()
Gate-->>Banner: contextSnapshot[]
Banner->>API: POST /api/conversations/transfer {context}
API-->>Banner: 转人工成功
else 员工点击继续询问 AI
Banner->>Gate: dismissGate()
Gate-->>H5: dismissed = true
end
```
#### 前端交互设计
**组件文件**`frontend-h5/src/components/ConfidenceGateBanner.vue`
**逻辑封装**`frontend-h5/src/composables/useConfidenceGate.ts`
| 严重程度 | 条件 | 配色 | 图标 | 文案 |
|---------|------|------|------|------|
| critical | confidence < 0.3 | 红色背景 `#fff0f0` + 红色左边框 `#ee0a24` | 🚨 | AI 非常不确定此回复,建议转人工处理 |
| warning | 0.3 ≤ confidence < 0.5 | 橙色背景 `#fff7f0` + 橙色左边框 `#ff976a` | ⚠️ | AI 对此回复把握较低,可能需要人工协助 |
| caution | 0.5 ≤ confidence < 0.7 | 蓝色背景 `#f0f7ff` + 蓝色左边框 `#1989fa` | 💡 | AI 对此回复不太确定,你可选择转人工确认 |
**展示元素**
- AI 把握度:百分比整数(如 "45%"),不显示原始 0.45
- 已收集上下文快照:标签列表
- 操作按钮:"转人工处理"danger+ "继续询问 AI"default
- 反馈理由选项:答非所问/信息不完整/回答不准确/过于笼统/其他
#### 技术选型与依赖
| 依赖 | 版本 | 用途 |
|------|------|------|
| Vue3 | ^3.4 | Composition API |
| Vant4 | ^4.8 | van-button, van-tag |
#### 部署状态
**生产在线** — 后端配置项 `confidence_gate_threshold=0.7` 已在 config.py 中定义,前端 `ConfidenceGateBanner.vue` + `useConfidenceGate.ts` 已部署。
---
### 3.3 内联审批卡片
#### 功能描述
坐席在会话中直接审批知识建议的内联卡片,支持采纳/驳回/改写操作,展示拓扑预览、confidence、audience 下拉编辑。未处理的提案在会话关闭后进入独立审批队列。
**当前状态**:生产在线。后端 API + 前端组件完整实现。
#### 数据模型
```mermaid
classDiagram
class KnowledgeSuggestion {
+String id
+String suggestion_type
+String status
+String title
+String content
+String category
+List~String~ tags
+String source_type
+List~String~ source_data
+Float confidence
+String audience
+String issue
+String action
+String relation_type
+String parent_issue
+Dict graph_meta
+String graph_sync_status
+Boolean source_failed
+DateTime queued_at
+DateTime applied_at
+String reviewer_id
+DateTime reviewed_at
+String reject_reason
}
class SuggestionStatusEnum {
<<enumeration>>
pending
queued
approved
rejected
applied
graph_synced
expired
}
class ApprovalInlineCard {
+SuggestionData suggestion
+Boolean readonly
+DuplicateItem[] duplicates
+handleApprove()
+handleReject()
+toggleRewrite()
+submitRewrite()
+onAudienceChange()
}
ApprovalInlineCard --> KnowledgeSuggestion : displays
KnowledgeSuggestion --> SuggestionStatusEnum : status
```
#### 状态机
```mermaid
stateDiagram-v2
[*] --> pending : AI生成/手动录入
pending --> queued : 会话关闭未处理
pending --> approved : 内联审批通过
pending --> rejected : 驳回
pending --> expired : 超时
queued --> approved : 队列审批通过
queued --> rejected : 队列驳回
queued --> expired : 超时
approved --> applied : KB条目落库
approved --> rejected : 撤销
applied --> graph_synced : Neo4j写图成功
rejected --> [*] : 终态
graph_synced --> [*] : 终态
expired --> [*] : 终态
```
**合法状态转换表**`schemas/enums.py`):
| 当前状态 | 允许转换到 |
|---------|-----------|
| pending | queued, approved, rejected, expired |
| queued | approved, rejected, expired |
| approved | applied, rejected |
| applied | graph_synced |
| graph_synced | (终态) |
| rejected | (终态) |
| expired | (终态) |
#### API 接口设计
| 方法 | 路径 | 请求体 | 响应 | 说明 |
|------|------|--------|------|------|
| POST | `/api/admin/knowledge-iteration/suggestions/{id}/approve` | `{}` | `{code:0, data: KnowledgeSuggestionResponse}` | 审核通过(触发 KB 落库 + Neo4j 写图) |
| POST | `/api/admin/knowledge-iteration/suggestions/{id}/reject` | `{reject_reason: string}` | `{code:0, data: KnowledgeSuggestionResponse}` | 审核拒绝 |
| POST | `/api/admin/knowledge-iteration/suggestions/{id}/rewrite` | `{title?, content?, category?, ...}` | `{code:0, data: KnowledgeSuggestionResponse}` | 改写提案(重置为 pending |
| POST | `/api/admin/knowledge-iteration/suggestions/{id}/queue` | — | `{code:0, data: KnowledgeSuggestionResponse}` | 放入独立队列 |
| POST | `/api/admin/knowledge-iteration/suggestions/{id}/dequeue-approve` | — | `{code:0, data: KnowledgeSuggestionResponse}` | 队列中审批通过 |
| GET | `/api/admin/approval-queue/queued` | `?status=&audience=&page=&page_size=` | `{code:0, data:{total, items[]}}` | 获取队列列表 |
| GET | `/api/admin/approval-queue/queued/stats` | — | `{code:0, data:{queued_total, pending_total, by_audience, by_source_type}}` | 队列统计 |
| POST | `/api/admin/approval-queue/queued/{id}/dequeue-approve` | — | `{code:0, data: KnowledgeSuggestionResponse}` | 队列审批通过 |
#### 核心流程
```mermaid
sequenceDiagram
participant AG as 坐席端 ApprovalInlineCard
participant API as FastAPI
participant Svc as KnowledgeIterationService
participant DB as PostgreSQL
participant Neo4j as Neo4j
Note over AG: 提案 status=pending/queued
alt 采纳
AG->>API: POST /suggestions/{id}/approve
API->>Svc: approve_suggestion(db, id, reviewer_id, neo4j_client)
Svc->>Svc: 校验状态转换 pending/queued → approved
Svc->>DB: 更新 status=approved, reviewer_id, reviewed_at
Svc->>DB: 创建 KnowledgeBase 条目 → status=applied
Svc->>Neo4j: sync_to_neo4j (merge_issue + merge_action + create_relation)
alt 写图成功
Svc->>DB: status=graph_synced, graph_sync_status=synced
Svc->>DB: 回填 kb.graph_node_uuid
else 写图失败
Svc->>DB: graph_sync_status=failed
end
Svc-->>API: suggestion (graph_synced)
API-->>AG: {code:0, data: suggestion}
end
alt 驳回
AG->>API: POST /suggestions/{id}/reject {reject_reason}
API->>Svc: reject_suggestion(db, id, reviewer_id, reason)
Svc->>DB: status=rejected, reject_reason
Svc-->>API: suggestion (rejected)
API-->>AG: {code:0, data: suggestion}
end
alt 改写
AG->>API: POST /suggestions/{id}/rewrite {title, content, ...}
API->>Svc: rewrite_suggestion(db, id, reviewer_id, data)
Svc->>DB: 更新字段 + status=pending (重置)
Svc-->>API: suggestion (pending)
API-->>AG: {code:0, data: suggestion}
end
alt 入队
AG->>API: POST /suggestions/{id}/queue
API->>Svc: queue_suggestion(db, id)
Svc->>Svc: 校验 pending → queued
Svc->>DB: status=queued, queued_at
Svc-->>API: suggestion (queued)
API-->>AG: {code:0, data: suggestion}
end
```
#### 前端交互设计
**组件文件**`frontend-agent/src/components/chat/ApprovalInlineCard.vue`
| 卡片区域 | 元素 | 说明 |
|---------|------|------|
| 头部 | 类型图标 + 类型文本 | 💡新FAQ / 🔄内容更新 / 🔀合并去重 |
| 头部 | 置信度标签 | ≥70% success / ≥50% warning / <50% danger |
| 头部 | 状态标签 | pending/queued/approved/rejected/applied/graph_synced |
| 头部 | 重复标记 | ⚠可能重复(danger, effect=dark |
| 重复警告 | 重复项列表 | 名称 + 类型标签 + 相似度百分比 |
| 核心信息 | 标题 + 内容 | 内容截断 150 字符 |
| 拓扑预览 | SVG 缩略图 | parent_issue → issue → action 节点链 |
| 拓扑预览 | 文本流 | 蓝色 parent → 绿色 issue → 橙色 action |
| audience | 下拉选择 | employee_quick_reply / engineer_workguide |
| 改写表单 | 标题/内容/分类输入框 | 展开时显示,提交后重置 pending |
| 操作按钮 | 采纳(success) / 改写(warning) / 驳回(danger) | readonly 时显示已处理状态 |
#### 技术选型与依赖
| 依赖 | 版本 | 用途 |
|------|------|------|
| Vue3 | ^3.4 | Composition API |
| Element Plus | ^2.6 | el-tag, el-select, el-input, el-button |
#### 部署状态
**生产在线** — 后端 `knowledge_iteration.py` + `approval_queue.py` + 前端 `ApprovalInlineCard.vue` + `ApprovalQueue.vue` 均已部署。
---
### 3.4 拓扑预览
#### 功能描述
在审批卡片中展示知识建议对应的图谱拓扑结构(Issue → Action 小缩略图),帮助训练师直观理解建议的图谱关系。
**当前状态**:仅前端 SVG 原型缩略图。后端 `query_issue_subgraph` 方法已实现但未通过 API 暴露给前端调用。
#### 数据模型
拓扑预览数据来源于 `KnowledgeSuggestion` 的图字段:
```mermaid
classDiagram
class TopologyPreview {
+String parent_issue
+String issue
+String action
+String relation_type
}
class MiniGraphNode {
+Number x
+Number y
+String label
+String type
}
class MiniGraphEdge {
+Number x1
+Number y1
+Number x2
+Number y2
}
TopologyPreview --> MiniGraphNode : generates
TopologyPreview --> MiniGraphEdge : generates
```
#### 已实现部分
**前端 SVG 缩略图**`ApprovalInlineCard.vue`):
- 根据 `suggestion.parent_issue``suggestion.issue``suggestion.action` 三个字段生成节点
- 节点颜色:parent=蓝色 `#409eff`、issue=绿色 `#67c23a`、action=橙色 `#e6a23c`
- 节点间距 90px,半径 issue=12px / action=9px
- 虚线连线 `stroke-dasharray="4,2"`
- 标签超过 6 字符截断为 "前6字…"
**后端子图查询**`neo4j_client.py`):
- `query_issue_subgraph(issue_name, depth=1)` 方法已实现
- 以指定 Issue 为中心,向外扩展 depth 层关系
- 返回 ECharts 格式的 `{nodes, links}`
#### API 接口设计(前瞻 — 需新增)
| 方法 | 路径 | 请求 | 响应 | 说明 |
|------|------|------|------|------|
| GET | `/api/admin/knowledge-iteration/suggestions/{id}/topology` | — | `{code:0, data:{nodes:[], links:[]}}` | 获取建议对应的图谱子图拓扑 |
#### 前瞻设计方案
1. **新增 API 端点**:在 `knowledge_iteration.py` 中添加 `/suggestions/{id}/topology` 路由
2. **调用链**API → `neo4j_client.query_issue_subgraph(issue_name, depth=1)` → 返回子图 JSON
3. **前端增强**`ApprovalInlineCard.vue` 中将 SVG 缩略图替换为 ECharts mini graph(或保留 SVG + 可点击展开)
4. **交互**:点击缩略图弹出全屏子图预览 modal
#### 部署状态
**部分实现** — 前端 SVG 缩略图已实现(基于 suggestion 字段静态渲染),后端子图查询方法已实现但未通过 API 暴露。
---
### 3.5 重复检测
#### 功能描述
在采纳知识建议前检测是否存在重复,利用 Neo4j 图结构(同名 Issue)+ SQL 文本相似(标题模糊匹配)双重检测,返回重复项列表供训练师参考。
**当前状态**:生产在线。
#### 数据模型
```mermaid
classDiagram
class DuplicateResult {
+String type
+String name
+String suggestion_id
+String suggestion_type
+String issue
+String action
+String status
+Float similarity
+String source
}
class FindDuplicatesParams {
+String issue_name
+String title
+String suggestion_id
+Neo4jClient neo4j_client
}
class KnowledgeIterationService {
+find_duplicates(db, issue_name, title, suggestion_id, neo4j_client) List~DuplicateResult~
+_calc_similarity(a, b) Float
}
KnowledgeIterationService --> DuplicateResult : produces
```
#### 重复检测类型
| 类型 | 来源 | 检测方式 | 相似度计算 |
|------|------|---------|-----------|
| `same_issue` | Neo4j | 同名 Issue 节点精确匹配 | 1.0 |
| `similar_issue` | Neo4j | Issue 名称前缀匹配(前 10 字符) | 公共前缀 / 最大长度 |
| `title_similar` | SQL | 标题 ILIKE 模糊匹配(前 20 字符) | 前缀匹配 + 长度比 |
**相似度计算算法**`_calc_similarity`):
1. 完全匹配 → 1.0
2. 包含匹配 → 0.5 + 0.5 × (shorter / longer)
3. 公共前缀匹配 → common_prefix_len / max_len
#### API 接口设计
| 方法 | 路径 | 请求 | 响应 | 说明 |
|------|------|------|------|------|
| GET | `/api/admin/knowledge-iteration/suggestions/{id}/duplicates` | — | `{code:0, data:{suggestion_id, has_duplicates: bool, duplicates: DuplicateResult[]}}` | 检查指定建议是否存在重复 |
#### 核心流程
```mermaid
sequenceDiagram
participant ADM as 管理后台
participant API as FastAPI
participant Svc as KnowledgeIterationService
participant DB as PostgreSQL
participant Neo4j as Neo4j
ADM->>API: GET /suggestions/{id}/duplicates
API->>DB: 查询 suggestion (获取 issue, title)
DB-->>API: suggestion
API->>Svc: find_duplicates(db, issue, title, id, neo4j_client)
rect rgb(245, 247, 250)
Note over Svc,DB: 1. SQL 层面:标题模糊匹配
Svc->>DB: SELECT * FROM knowledge_suggestions WHERE status IN (approved, applied, graph_synced) AND title ILIKE '%keyword%' AND id != suggestion_id
DB-->>Svc: sql_duplicates[]
Svc->>Svc: 计算 title_similar 相似度
end
rect rgb(232, 234, 246)
Note over Svc,Neo4j: 2. Neo4j 层面:同名 Issue
Svc->>Neo4j: find_issue_by_name(issue_name)
Neo4j-->>Svc: existing_issue (含 source_suggestion_id)
Svc->>DB: 查关联 suggestion
Svc->>Svc: 记录 same_issue (similarity=1.0)
end
rect rgb(232, 234, 246)
Note over Svc,Neo4j: 3. Neo4j 层面:相似 Issue(前缀匹配)
Svc->>Neo4j: MATCH (i:Issue) WHERE i.name STARTS WITH $prefix AND i.name <> $exact_name
Neo4j-->>Svc: similar_issues[]
Svc->>Svc: 计算 similar_issue 相似度
end
Svc->>Svc: 按相似度降序排列
Svc-->>API: duplicates[]
API-->>ADM: {code:0, data:{has_duplicates, duplicates}}
```
#### 前端交互设计
| 交互 | 说明 |
|------|------|
| 触发 | 详情弹窗中点击"检查重复"按钮 |
| 结果展示 | 弹窗显示重复项表格 |
| 无重复 | 绿色文字 "✅ 未发现重复,可安全采纳" |
| 有重复 | 橙色 Alert 警告 + 重复项表格 |
| 表格列 | 名称 / 匹配类型(同名Issue/相似Issue/标题相似)/ 相似度百分比 / 操作(合并) |
| 合并操作 | 点击"合并"调用 merge API |
#### 部署状态
**生产在线** — 后端 `find_duplicates` 方法 + API 路由 + 前端重复检查弹窗均已部署。
---
### 3.6 代答排除
#### 功能描述
坐席在分诊卡片中排除某些选项,被排除的选项灰显且不可点击,引导员工选择更合适的路径。
**当前状态**:仅前端组件方法(`setExcludedOptions`),未接入后端。
#### 数据模型
```mermaid
classDiagram
class TriageOption {
+String label
+Boolean selected
+Boolean excluded
+Boolean recommended
}
class ExclusionRequest {
+String conversation_id
+List~String~ excluded_labels
+String reason
}
```
#### 已实现部分
**前端方法**`TriageCard.vue`):
```typescript
// 暴露方法供父组件调用
defineExpose({
/** 设置坐席排除项 */
setExcludedOptions(labels: string[]) {
currentOptions.value.forEach(o => {
if (labels.includes(o.label)) {
o.excluded = true
o.selected = false
}
})
},
/** 设置坐席推荐项 */
setRecommendedOption(label: string) {
currentOptions.value.forEach(o => {
o.recommended = o.label === label
})
},
})
```
**排除样式**
- 边框:`#ebedf0`(灰)
- 背景:`#f5f5f5`(浅灰)
- 透明度:0.5
- 光标:`not-allowed`
- 文字:删除线
#### API 接口设计(前瞻 — 未实现)
| 方法 | 路径 | 请求 | 响应 | 说明 |
|------|------|------|------|------|
| POST | `/api/agent/triage/exclude` | `{conversation_id, excluded_labels: string[]}` | `{code:0, data:{excluded: true}}` | 坐席排除分诊选项 |
| POST | `/api/agent/triage/recommend` | `{conversation_id, recommended_label: string}` | `{code:0, data:{recommended: true}}` | 坐席推荐分诊选项 |
#### 前瞻设计方案
1. **后端新增**:在 conversations API 或新建 triage API 中添加排除/推荐端点
2. **WebSocket 推送**:坐席排除选项后,通过 WS 实时推送到 H5 员工端
3. **Dify Prompt 增强**:将排除的选项传入 Dify,影响后续步骤生成
4. **审计日志**:记录坐席排除/推荐操作
#### 部署状态
**未实现** — 前端 `TriageCard.vue``setExcludedOptions` / `setRecommendedOption` 方法已定义,但无后端 API 对接,无 WS 推送机制。
---
### 3.7 知识迭代管理
#### 功能描述
管理后台的知识迭代提案管理页面,支持提案列表(含筛选/分页)、审阅提案详情、图字段编辑(issue/action/relation/parent)、训练师手动录入入口(通道 B)、触发分析。
**当前状态**:生产在线。47KB 服务 + 21KB API + 完整前端页面。
#### 数据模型
```mermaid
classDiagram
class KnowledgeSuggestion {
+String id : UUID
+String suggestion_type : "new_faq"|"update"|"outdated"
+String status : "pending"|"queued"|"approved"|"rejected"|"applied"|"graph_synced"|"expired"
+String title
+String content
+String category : "硬件"|"软件"|"网络"|"安全"|"账号"|"其他"
+List~String~ tags : JSON
+String source_type : "annotation"|"conversation"|"ai_uncertain"|"manual"|"document_ragflow"|"merge"
+List~String~ source_data : JSON
+String reason
+Float confidence
+String audience : "employee_quick_reply"|"engineer_workguide"
+String issue
+String action
+String relation_type : "LEADS_TO"|"RELATES_TO"|"CAN_JUMP_TO"
+String parent_issue
+Dict graph_meta : JSON
+String graph_sync_status : "pending"|"synced"|"failed"
+Boolean source_failed
+DateTime queued_at
+DateTime applied_at
+String reviewer_id
+DateTime reviewed_at
+String reject_reason
+DateTime created_at
+DateTime updated_at
}
class KnowledgeBase {
+String id : UUID
+String category
+String title
+String content
+List~String~ tags : JSON
+Integer view_count
+Integer use_count
+String graph_sync_status
+String graph_node_uuid
+DateTime created_at
+DateTime updated_at
}
class KnowledgeIterationService {
+Float confidence_gate_threshold
+generate_knowledge_suggestion(db, source_type, source_data, reason) KnowledgeSuggestion
+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
+_build_context_from_source(db, source_type, source_data) List
+_auto_tag_audience(db, source_type, source_data) AudienceEnum
+_apply_confidence_gate(confidence) Boolean
+_check_existing_suggestion(db, source_id) Boolean
+approve_suggestion(db, id, reviewer_id, neo4j_client) KnowledgeSuggestion
+reject_suggestion(db, id, reviewer_id, reason) KnowledgeSuggestion
+rewrite_suggestion(db, id, reviewer_id, data) KnowledgeSuggestion
+queue_suggestion(db, id) KnowledgeSuggestion
+dequeue_approve(db, id, reviewer_id, neo4j_client) KnowledgeSuggestion
+sync_to_neo4j(neo4j_client, suggestion) Boolean
+get_suggestion_stats(db) Dict
+get_queue_stats(db) Dict
}
KnowledgeIterationService --> KnowledgeSuggestion : manages
KnowledgeIterationService --> KnowledgeBase : creates
```
#### ER 图
```mermaid
erDiagram
knowledge_suggestions ||--o| knowledge_base : "approved → creates KB"
knowledge_suggestions {
string id PK
string suggestion_type
string status
string title
text content
string category
json tags
string source_type
json source_data
float confidence
string audience
string issue
string action
string relation_type
string parent_issue
json graph_meta
string graph_sync_status
boolean source_failed
datetime queued_at
datetime applied_at
string reviewer_id
datetime reviewed_at
text reject_reason
text reason
datetime created_at
datetime updated_at
}
knowledge_base {
string id PK
string category
string title
text content
json tags
integer view_count
integer use_count
string graph_sync_status
string graph_node_uuid
datetime created_at
datetime updated_at
}
```
#### 数据库索引
| 索引名 | 字段 | 用途 |
|--------|------|------|
| idx_suggestion_status | status | 按状态筛选 |
| idx_suggestion_type | suggestion_type | 按类型筛选 |
| idx_suggestion_created | created_at | 按时间排序 |
| idx_suggestion_audience | audience | 按受众筛选 |
| idx_suggestion_confidence | confidence | 按置信度范围筛选 |
| idx_suggestion_graph_sync | graph_sync_status | 按图同步状态筛选 |
#### API 接口设计
| 方法 | 路径 | 请求参数 | 响应 | 说明 |
|------|------|---------|------|------|
| POST | `/api/admin/knowledge-iteration/analyze` | `?days=7` | `{code:0, data:{annotations_analyzed, conversations_analyzed, suggestions_generated}}` | 触发分析并生成建议 |
| GET | `/api/admin/knowledge-iteration/suggestions` | `?status=&suggestion_type=&audience=&confidence_min=&confidence_max=&page=&page_size=` | `{code:0, data:{total, items[]}}` | 获取建议列表 |
| GET | `/api/admin/knowledge-iteration/suggestions/{id}` | — | `{code:0, data: KnowledgeSuggestionResponse}` | 获取建议详情 |
| POST | `/api/admin/knowledge-iteration/suggestions/{id}/approve` | `{}` | `{code:0, data: KnowledgeSuggestionResponse}` | 审核通过 |
| POST | `/api/admin/knowledge-iteration/suggestions/{id}/reject` | `{reject_reason}` | `{code:0, data: KnowledgeSuggestionResponse}` | 审核拒绝 |
| POST | `/api/admin/knowledge-iteration/suggestions/{id}/rewrite` | `{title?, content?, ...}` | `{code:0, data: KnowledgeSuggestionResponse}` | 改写提案 |
| POST | `/api/admin/knowledge-iteration/suggestions/{id}/queue` | — | `{code:0, data: KnowledgeSuggestionResponse}` | 放入独立队列 |
| POST | `/api/admin/knowledge-iteration/suggestions/{id}/dequeue-approve` | — | `{code:0, data: KnowledgeSuggestionResponse}` | 队列中审批 |
| GET | `/api/admin/knowledge-iteration/stats` | — | `{code:0, data: KnowledgeSuggestionStatsResponse}` | 获取统计 |
| GET | `/api/admin/knowledge-iteration/graph` | `?limit=100&issue_name=` | `{code:0, data:{nodes:[], links:[]}}` | 获取知识图谱数据 |
| GET | `/api/admin/knowledge-iteration/suggestions/{id}/duplicates` | — | `{code:0, data:{suggestion_id, has_duplicates, duplicates[]}}` | 检查重复 |
| POST | `/api/admin/knowledge-iteration/suggestions/{id}/merge` | `{duplicate_id}` | `{code:0, data: KnowledgeSuggestionResponse}` | 合并重复建议 |
#### 分析与生成流程
```mermaid
sequenceDiagram
participant ADM as 管理后台
participant API as FastAPI
participant Svc as KnowledgeIterationService
participant Wingman as WingmanService
participant Dify as Dify AI
participant DB as PostgreSQL
ADM->>API: POST /analyze?days=7
API->>Svc: analyze_and_generate_suggestions(db, days=7)
rect rgb(255, 245, 230)
Note over Svc,DB: 1. 分析标注数据(useless 标注 ≥3 次)
Svc->>DB: SELECT * FROM conversation_annotations WHERE feedback='useless' AND created_at >= since
DB-->>Svc: annotations[]
Svc->>Svc: 按 message_id 分组统计高频错误
loop 每个高频错误 (count ≥ 3)
Svc->>Svc: _generate_update_suggestion()
Svc->>Wingman: generate_knowledge_suggestion(context_messages)
Wingman->>Dify: 调用 Dify API
Dify-->>Wingman: {title, content, category, tags, confidence, issue, action, ...}
Wingman-->>Svc: ai_result
Svc->>Svc: 置信门控: confidence < 0.7 → source_failed=True
Svc->>Svc: audience 自动标注
Svc->>DB: INSERT knowledge_suggestion
end
end
rect rgb(230, 245, 255)
Note over Svc,DB: 2. 分析会话数据(waiting_agent/agentServing
Svc->>DB: SELECT * FROM conversations WHERE status IN ('waiting_agent','agentServing') AND created_at >= since
DB-->>Svc: conversations[]
Svc->>Svc: 采样 min(20, len)
loop 每个采样会话
Svc->>Svc: 检查是否已有 pending 建议(避免重复)
Svc->>Svc: _generate_new_faq_suggestion()
Svc->>Wingman: generate_knowledge_suggestion(context_messages)
Wingman->>Dify: 调用 Dify API
Dify-->>Wingman: ai_result
Wingman-->>Svc: ai_result
Svc->>Svc: 置信门控 + audience 标注
Svc->>DB: INSERT knowledge_suggestion
end
end
Svc-->>API: {annotations_analyzed, conversations_analyzed, suggestions_generated}
API-->>ADM: {code:0, data: result}
```
#### audience 自动标注规则(D8
| source_type | 判定逻辑 | audience |
|-------------|---------|----------|
| manual | 直接判定 | engineer_workguide |
| document_ragflow | 直接判定 | engineer_workguide |
| annotation | 查 Conversation → 默认 | employee_quick_reply |
| conversation | 查 Conversation → 默认 | employee_quick_reply |
| ai_uncertain | 查 Conversation → 默认 | employee_quick_reply |
| 其他/未知 | 保守默认 | employee_quick_reply |
#### 置信门控逻辑(D3
```python
# 置信门控:confidence < 0.7 → source_failed=True
if not source_failed and confidence < self.confidence_gate_threshold:
source_failed = True
logger.info(f"置信度 {confidence} 低于门控阈值 {self.confidence_gate_threshold},标记 source_failed")
```
**门控效果**
- `source_failed=True` 的建议标题为 `[生成失败] 新FAQ建议``[生成失败] 优化建议`
- 前端卡片样式变红(`approval-inline-card--failed`
- 不影响审批流程,训练师仍可手动改写后采纳
#### 前端交互设计
**页面文件**`frontend-admin/src/views/KnowledgeIteration.vue`
| 页面区域 | 功能 |
|---------|------|
| 页面标题 | "📚 知识迭代管理" |
| 视图切换 | 列表 / 图谱(el-button-group |
| 操作按钮 | 手动录入(通道 B)/ 触发分析 |
| 统计概要 | 待审核 / 队列中 / 已通过 / 已应用 / 已同步 |
| 筛选栏 | 状态 / 受众 / 置信度下限 / 置信度上限 |
| 提案表格 | 标题 / 类型 / 状态 / 置信度 / 受众 / 来源 / 创建时间 / 操作 |
| 操作按钮 | 采纳 / 驳回 / 详情 |
| 分页 | el-pagination |
| 详情弹窗 | 标题/内容/分类/受众编辑 + 图字段编辑(Issue/Action/关系类型/父Issue |
| 重复检查 | 检查重复按钮 → 重复结果弹窗 |
| 手动录入 | 标题/内容/分类/受众/图字段 → 提交(confidence=1.0, source_type=manual |
#### 部署状态
**生产在线** — 后端 12 条 API 路由已注册,47KB 服务文件完整实现,前端页面 980 行 Vue3 组件已部署。
---
### 3.8 图谱可视化
#### 功能描述
管理后台使用 ECharts 力导向图可视化 Neo4j 知识图谱,支持全图查询和按 Issue 名称的子图查询。
**当前状态**Neo4j 运行中,ECharts 可视化已部署。
#### 数据模型
```mermaid
classDiagram
class IssueNode {
+String uuid
+String name
+String category
+DateTime created_at
+DateTime updated_at
+String source_suggestion_id
}
class ActionNode {
+String uuid
+String name
+String description
+DateTime created_at
+String source_suggestion_id
}
class RelationEdge {
+String from_uuid
+String to_uuid
+String type : "LEADS_TO"|"RELATES_TO"|"CAN_JUMP_TO"
+Integer order
+Float weight
}
class Neo4jClient {
+String uri
+String user
+String password
+String database
+AsyncDriver _driver
+initialize()
+close()
+health_check() Boolean
+execute_write_query(cypher, params)
+execute_read_query(cypher, params)
+merge_issue(name, category, props) IssueNode
+merge_action(name, props) ActionNode
+find_issue_by_name(name) IssueNode
+create_relation(from_uuid, to_uuid, rel) Boolean
+query_full_graph(limit) Dict
+query_issue_subgraph(issue_name, depth) Dict
}
Neo4jClient --> IssueNode : manages
Neo4jClient --> ActionNode : manages
Neo4jClient --> RelationEdge : manages
IssueNode --> RelationEdge : from
ActionNode --> RelationEdge : to
```
#### Neo4j 图 Schema
**约束**
```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
```
**索引**
```cypher
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)
CREATE INDEX action_name IF NOT EXISTS FOR (a:Action) ON (a.name)
```
#### API 接口设计
| 方法 | 路径 | 请求参数 | 响应 | 说明 |
|------|------|---------|------|------|
| GET | `/api/admin/knowledge-iteration/graph` | `?limit=100&issue_name=` | `{code:0, data:{nodes:[], links:[]}}` | 获取知识图谱数据 |
**响应数据格式**ECharts 力导向图兼容):
```json
{
"code": 0,
"data": {
"nodes": [
{"id": "uuid", "name": "VPN问题", "category": "网络", "label": "VPN问题", "type": "issue"},
{"id": "uuid", "name": "个人VPN开通", "category": "", "label": "个人VPN开通", "type": "action"}
],
"links": [
{"source": "issue_uuid", "target": "action_uuid", "type": "LEADS_TO", "weight": 1.0}
]
}
}
```
#### 核心流程
```mermaid
sequenceDiagram
participant ADM as 管理后台
participant API as FastAPI
participant Client as Neo4jClient
participant Neo4j as Neo4j
ADM->>API: GET /graph?limit=200
API->>Client: get_neo4j_client()
alt Neo4j 不可用
Client-->>API: None
API-->>ADM: {code:0, data:{nodes:[], links:[]}, message:"Neo4j 不可用"}
end
alt 全图查询(无 issue_name
Client->>Neo4j: MATCH (i:Issue) RETURN ... LIMIT $limit
Neo4j-->>Client: issue_nodes[]
Client->>Neo4j: MATCH (a:Action) RETURN ... LIMIT $limit
Neo4j-->>Client: action_nodes[]
Client->>Neo4j: MATCH (n)-[r]->(m) WHERE ... LIMIT $limit*3
Neo4j-->>Client: relations[]
else 子图查询(有 issue_name
Client->>Neo4j: MATCH path = (center:Issue {name: $name})-[*0..1]-(neighbor) ...
Neo4j-->>Client: subgraph_nodes[]
Client->>Neo4j: MATCH (center:Issue {name: $name})-[r*1..1]-(neighbor) ...
Neo4j-->>Client: subgraph_links[]
end
Client-->>API: {nodes, links}
API-->>ADM: {code:0, data: graph_data}
```
#### 前端交互设计
| 配置项 | 值 | 说明 |
|--------|-----|------|
| 图表类型 | `graph` (force layout) | ECharts 力导向图 |
| Issue 节点 | 绿色 `#67c23a`, symbolSize=28 | 问题节点 |
| Action 节点 | 橙色 `#e6a23c`, symbolSize=22 | 动作节点 |
| 连线颜色 | `#c0c4cc`, curveness=0.3 | 曲线连线 |
| 连线宽度 | `max(0.5, weight * 1.5)` | 按 weight 粗细 |
| 排斥力 | repulsion=300 | 力导向参数 |
| 重力 | gravity=0.1 | 力导向参数 |
| 边长度 | [100, 250] | 边长度范围 |
| 缩放 | roam=true | 支持鼠标缩放平移 |
| 高亮 | focus='adjacency' | 悬停高亮相邻节点 |
| 筛选 | 按 Issue 名称筛选子图 | 留空查全图 |
| 节点/关系计数 | 实时显示 | "节点: X | 关系: Y" |
| 响应式 | ResizeObserver | 自动 resize |
#### Neo4j 连接配置
| 配置项 | 默认值 | 环境变量 |
|--------|--------|---------|
| neo4j_uri | `bolt://localhost:7687` | `NEO4J_URI` |
| neo4j_user | `neo4j` | `NEO4J_USER` |
| neo4j_password | (无默认值) | `NEO4J_PASSWORD` |
| neo4j_database | `neo4j` | `NEO4J_DATABASE` |
| neo4j_max_connection_lifetime | 3600(秒) | — |
| neo4j_max_connection_pool_size | 50 | — |
| neo4j_connection_acquisition_timeout | 30(秒) | — |
#### 部署状态
**生产在线** — Neo4j 容器 `wecom_it_neo4j` 运行中,Neo4j 6.2.0 驱动已安装,API 路由已注册,ECharts 可视化已部署。
---
### 3.9 合并去重
#### 功能描述
将重复的知识建议合并到主建议中,标签和元数据合并,重复建议标记为 rejected(合并归入)。
**当前状态**:生产在线。
#### 数据模型
```mermaid
classDiagram
class MergeRequest {
+String primary_id
+String duplicate_id
+String reviewer_id
}
class MergeResult {
+KnowledgeSuggestion primary
+KnowledgeSuggestion duplicate
}
class KnowledgeIterationService {
+merge_suggestions(db, primary_id, duplicate_id, reviewer_id) KnowledgeSuggestion
}
MergeRequest --> KnowledgeIterationService : input
KnowledgeIterationService --> MergeResult : output
```
#### API 接口设计
| 方法 | 路径 | 请求体 | 响应 | 说明 |
|------|------|--------|------|------|
| POST | `/api/admin/knowledge-iteration/suggestions/{id}/merge` | `{duplicate_id: string}` | `{code:0, data: KnowledgeSuggestionResponse}` | 合并重复建议 |
#### 核心流程
```mermaid
sequenceDiagram
participant ADM as 管理后台
participant API as FastAPI
participant Svc as KnowledgeIterationService
participant DB as PostgreSQL
ADM->>API: POST /suggestions/{primary_id}/merge {duplicate_id}
API->>Svc: merge_suggestions(db, primary_id, duplicate_id, reviewer_id)
Svc->>DB: SELECT * FROM knowledge_suggestions WHERE id = primary_id
DB-->>Svc: primary (主建议)
alt 主建议不存在
Svc-->>API: None
API-->>ADM: {code:404, message:"主建议不存在"}
end
Svc->>DB: SELECT * FROM knowledge_suggestions WHERE id = duplicate_id
DB-->>Svc: duplicate (重复建议)
alt 重复建议存在
Svc->>Svc: 合并标签: merged_tags = set(primary.tags + duplicate.tags)
Svc->>Svc: 合并 graph_meta: primary.graph_meta.update(duplicate.graph_meta)
Svc->>DB: UPDATE duplicate SET status='rejected', reject_reason='已合并至建议 {primary_id}(去重)', reviewer_id, reviewed_at
end
Svc->>DB: COMMIT
Svc->>DB: REFRESH primary
Svc-->>API: primary (合并后)
API-->>ADM: {code:0, message:"建议合并完成,重复建议已标记为已驳回(合并归入)", data: primary}
```
#### 合并规则
| 字段 | 合并策略 |
|------|---------|
| tags | 并集去重:`set(primary.tags + duplicate.tags)` |
| graph_meta | 深度合并:`primary.graph_meta.update(duplicate.graph_meta)` |
| status (duplicate) | → `rejected` |
| reject_reason (duplicate) | → `已合并至建议 {primary_id}(去重)` |
| reviewer_id (duplicate) | → 当前审核人 |
| reviewed_at (duplicate) | → 当前时间 |
| primary 其他字段 | 保持不变 |
#### 前端交互设计
| 交互 | 说明 |
|------|------|
| 触发入口 | 重复检测结果弹窗中每行的"合并"按钮 |
| 请求参数 | `suggestion_id`(主建议,URL 路径参数)+ `duplicate_id`(重复建议,请求体) |
| 成功反馈 | 关闭重复弹窗 + 刷新列表 + 刷新统计 |
#### 部署状态
**生产在线** — 后端 `merge_suggestions` 方法 + API 路由 + 前端合并操作均已部署。
---
### 3.10 会话关闭→建议→审核→写图
#### 功能描述
全链路闭环:坐席结单 → 异步触发 AI 生成知识建议 → 训练师审核 → KB 落库 → Neo4j 写图。
**当前状态**:生产在线。全链路打通。
#### 全链路数据流
```mermaid
flowchart LR
A[坐席结单] --> B[异步触发\n知识建议生成]
B --> C{Dify 可用?}
C -->|是| D[调用 Wingman AI\n生成结构化建议]
C -->|否| E[source_failed=True\n标题=生成失败]
D --> F{confidence ≥ 0.7?}
F -->|是| G[创建 KnowledgeSuggestion\nstatus=pending]
F -->|否| H[source_failed=True\n标记低置信]
E --> G
H --> G
G --> I{训练师审核}
I -->|采纳| J[status=approved]
I -->|驳回| K[status=rejected\n终态]
I -->|改写| L[重置 status=pending\n重新审核]
I -->|入队| M[status=queued\n独立队列]
M --> N[队列审批\n→ approved]
J --> O[创建 KnowledgeBase 条目\nstatus=applied]
N --> O
O --> P{Neo4j 写图}
P -->|成功| Q[status=graph_synced\ngraph_sync_status=synced\n回填 kb.graph_node_uuid]
P -->|失败| R[graph_sync_status=failed\n可重试]
Q --> S[终态:知识图谱更新]
R --> T[后续优化:\n重试队列]
style A fill:#e3f2fd
style Q fill:#e8f5e9
style S fill:#c8e6c9
style K fill:#ffebee
```
#### 详细时序图
```mermaid
sequenceDiagram
participant AG as 坐席端
participant API_Conv as 会话 API
participant Svc_KI as 知识迭代服务
participant Wingman as Wingman AI
participant Dify as Dify
participant DB as PostgreSQL
participant Neo4j as Neo4j
participant ADM as 管理后台
%% 阶段1:会话关闭 → 异步生成建议
rect rgb(227, 242, 253)
Note over AG,DB: 阶段1:会话关闭 → 异步生成建议
AG->>API_Conv: POST /api/conversations/{id}/resolve (结单)
API_Conv->>DB: 会话状态 → resolved/closed
API_Conv-->>AG: 结单成功(不阻塞)
API_Conv->>API_Conv: asyncio.ensure_future(_trigger_knowledge_suggestion())
Note over API_Conv: 独立 db session 后台任务
API_Conv->>Svc_KI: generate_knowledge_suggestion(db, "conversation", [conv_id], reason)
Svc_KI->>Svc_KI: _check_existing_suggestion() — 避免重复
Svc_KI->>Svc_KI: _build_context_from_source() — 获取消息历史
Svc_KI->>Wingman: generate_knowledge_suggestion(context_messages)
Wingman->>Dify: 调用 Dify API
Dify-->>Wingman: {title, content, confidence, issue, action, ...}
Wingman-->>Svc_KI: ai_result
Svc_KI->>Svc_KI: 置信门控: confidence < 0.7 → source_failed
Svc_KI->>Svc_KI: audience 自动标注
Svc_KI->>DB: INSERT knowledge_suggestion (status=pending)
Svc_KI-->>API_Conv: suggestion
end
%% 阶段2:训练师审核
rect rgb(255, 243, 224)
Note over ADM,DB: 阶段2:训练师审核
ADM->>Svc_KI: GET /suggestions (查看待审核列表)
Svc_KI->>DB: SELECT * FROM knowledge_suggestions WHERE status='pending'
DB-->>ADM: suggestions[]
ADM->>ADM: 训练师查看详情,编辑图字段
alt 采纳
ADM->>Svc_KI: POST /suggestions/{id}/approve
Svc_KI->>Svc_KI: 校验 pending → approved (状态机)
Svc_KI->>DB: UPDATE status=approved, reviewer_id, reviewed_at
end
end
%% 阶段3KB 落库 + Neo4j 写图
rect rgb(232, 245, 233)
Note over Svc_KI,Neo4j: 阶段3KB 落库 + Neo4j 写图
Svc_KI->>DB: INSERT knowledge_base (title, content, category, tags)
Svc_KI->>DB: UPDATE suggestion status=applied, applied_at
Svc_KI->>Svc_KI: sync_to_neo4j(neo4j_client, suggestion)
rect rgb(232, 234, 246)
Note over Svc_KI,Neo4j: Neo4j 写图步骤
Svc_KI->>Neo4j: merge_issue(issue, category, props) — MERGE 幂等
Neo4j-->>Svc_KI: IssueNode (uuid)
opt 有父 Issue
Svc_KI->>Neo4j: merge_issue(parent_issue, ...)
Neo4j-->>Svc_KI: parent_node
Svc_KI->>Neo4j: create_relation(parent → issue, type, weight)
end
opt 有 Action
Svc_KI->>Neo4j: merge_action(action, props)
Neo4j-->>Svc_KI: ActionNode (uuid)
Svc_KI->>Neo4j: create_relation(issue → action, type, weight=confidence)
end
end
alt 写图成功
Svc_KI->>DB: UPDATE suggestion status=graph_synced, graph_sync_status=synced
Svc_KI->>DB: UPDATE kb graph_sync_status=synced, graph_node_uuid=issue_node.uuid
else 写图失败
Svc_KI->>DB: UPDATE suggestion graph_sync_status=failed
Svc_KI->>DB: UPDATE kb graph_sync_status=failed
end
Svc_KI->>DB: COMMIT
end
ADM->>Svc_KI: 响应 {code:0, data: suggestion (graph_synced)}
```
#### 会话关闭触发点
**文件**`backend/app/api/conversations.py``resolve_conversation` 函数
**关键代码**
```python
# 会话结单后异步触发知识建议生成
async def _trigger_knowledge_suggestion():
"""异步生成知识建议的后台任务(独立 db session)。"""
from app.database import _get_session_factory
from app.services.knowledge_iteration_service import KnowledgeIterationService
factory = _get_session_factory()
async with factory() as bg_db:
knowledge_service = KnowledgeIterationService()
suggestion = await knowledge_service.generate_knowledge_suggestion(
db=bg_db,
source_type="conversation",
source_data=[str(conversation_id)],
reason=f"会话'{conversation_id}'已结单,自动生成知识迭代建议",
)
if suggestion:
bg_db.add(suggestion)
await bg_db.commit()
# 创建后台任务(不阻塞结单响应)
_asyncio.ensure_future(_trigger_knowledge_suggestion())
```
**设计要点**
1. **不阻塞结单**:使用 `asyncio.ensure_future` 异步执行,结单响应立即返回
2. **独立 db session**:后台任务使用独立的 `_get_session_factory()` 创建新 session,避免与主请求 session 冲突
3. **失败不影响主流程**:知识建议生成失败时仅记录日志,不影响结单
4. **避免重复**`_check_existing_suggestion` 检查是否已有 pending 建议
#### Neo4j 写图逻辑(sync_to_neo4j
```mermaid
flowchart TD
A[approve_suggestion 触发] --> B{suggestion.issue 存在?}
B -->|否| C[return True\n无图字段不视为失败]
B -->|是| D[merge_issue\nMERGE Issue 节点]
D --> E{suggestion.parent_issue 存在?}
E -->|是| F[merge_issue\nMERGE 父 Issue 节点]
F --> G[create_relation\n父Issue → 当前Issue]
E -->|否| H{suggestion.action 存在?}
G --> H
H -->|是| I[merge_action\nMERGE Action 节点]
I --> J[create_relation\nIssue → Action\nweight=confidence]
H -->|否| K[return True]
J --> K
K --> L[写图成功]
style L fill:#c8e6c9
```
**MERGE 幂等写入**
- Issue 节点按 `name` MERGE(同名不重复创建)
- Action 节点按 `name` MERGE
- 关系通过 `MATCH + CREATE` 创建
#### 部署状态
**生产在线** — 全链路已打通,从会话结单到 Neo4j 写图完整闭环。测试通过率 89/89。
---
## 4. 功能依赖关系图
```mermaid
graph TB
subgraph "H5 员工端功能"
F1[1.分诊交互]
F2[2.置信门控]
F6[6.代答排除]
end
subgraph "坐席端功能"
F3[3.内联审批卡片]
F4[4.拓扑预览]
end
subgraph "管理后台功能"
F5[5.重复检测]
F7[7.知识迭代管理]
F8[8.图谱可视化]
F9[9.合并去重]
end
subgraph "全链路功能"
F10[10.会话关闭→建议→审核→写图]
end
subgraph "基础设施"
NEO4J[Neo4j 图数据库]
DIFY[Dify AI 平台]
PG[(PostgreSQL)]
end
%% 依赖关系
F2 -->|confidence < 0.7 触发| F10
F1 -->|分诊上下文转人工| F10
F6 -->|排除选项影响| F1
F10 -->|生成 KnowledgeSuggestion| F3
F10 -->|生成 KnowledgeSuggestion| F7
F3 -->|展示拓扑| F4
F3 -->|检查重复| F5
F5 -->|发现重复| F9
F7 -->|管理审核| F3
F7 -->|查看图谱| F8
F7 -->|检查重复| F5
F7 -->|合并去重| F9
%% 基础设施依赖
F2 --> DIFY
F10 --> DIFY
F10 --> PG
F3 --> PG
F5 --> NEO4J
F5 --> PG
F7 --> PG
F8 --> NEO4J
F9 --> PG
F10 --> NEO4J
F4 --> NEO4J
%% 样式
style F1 fill:#fff3e0,stroke:#ff9800,stroke-dasharray: 5 5
style F4 fill:#fff3e0,stroke:#ff9800,stroke-dasharray: 5 5
style F6 fill:#fff3e0,stroke:#ff9800,stroke-dasharray: 5 5
style F2 fill:#e8f5e9,stroke:#4caf50
style F3 fill:#e3f2fd,stroke:#2196f3
style F5 fill:#e8f5e9,stroke:#4caf50
style F7 fill:#e8f5e9,stroke:#4caf50
style F8 fill:#e8f5e9,stroke:#4caf50
style F9 fill:#e8f5e9,stroke:#4caf50
style F10 fill:#e8f5e9,stroke:#4caf50
style NEO4J fill:#e8eaf6,stroke:#3f51b5
style DIFY fill:#fce4ec,stroke:#e91e63
style PG fill:#e8eaf6,stroke:#3f51b5
```
**图例**
- 🟢 绿色边框:生产在线
- 🟠 橙色虚线边框:未实现/仅前端组件
- 🔵 蓝色:基础设施
**核心依赖链**
```
置信门控 → 会话关闭→建议→审核→写图 → 内联审批卡片 → 重复检测 → 合并去重
拓扑预览
```
---
## 5. 全链路数据流图
### 5.1 通道 A:会话自动生成(全链路闭环)
```mermaid
flowchart TD
Start([员工提问]) --> AI_Reply[AI 回复]
AI_Reply --> ConfCheck{confidence ≥ 0.7?}
ConfCheck -->|是| Normal[正常回复]
ConfCheck -->|否| GateBanner[置信门控横幅<br/>展示转人工入口]
GateBanner --> Transfer{员工选择}
Transfer -->|转人工| WaitingAgent[会话 → waiting_agent]
Transfer -->|继续 AI| Normal
Normal --> Resolved{问题解决?}
Resolved -->|是| Close1[员工关闭]
Resolved -->|否| WaitingAgent
WaitingAgent --> AgentServe[坐席接管]
AgentServe --> Close2[坐席结单]
Close1 --> AsyncGen[异步触发<br/>知识建议生成]
Close2 --> AsyncGen
AsyncGen --> BuildCtx[构建对话上下文<br/>获取消息历史]
BuildCtx --> CallAI[调用 Dify Wingman<br/>生成结构化建议]
CallAI --> ConfGate{confidence ≥ 0.7?}
ConfGate -->|是| CreateSuggestion[创建 KnowledgeSuggestion<br/>status=pending]
ConfGate -->|否| MarkFailed[source_failed=True<br/>标题=生成失败]
MarkFailed --> CreateSuggestion
CreateSuggestion --> NotifyAgent[通知坐席<br/>内联审批卡片]
CreateSuggestion --> NotifyAdmin[通知训练师<br/>管理后台列表]
NotifyAgent --> Review{审核决策}
NotifyAdmin --> Review
Review -->|采纳| Approve[status=approved]
Review -->|驳回| Reject[status=rejected 终态]
Review -->|改写| Rewrite[修改字段<br/>重置 pending]
Review -->|入队| Queue[status=queued<br/>独立队列]
Queue --> QueueReview[队列审批]
QueueReview -->|通过| Approve
QueueReview -->|驳回| Reject
Rewrite --> Review
Approve --> CreateKB[创建 KnowledgeBase 条目<br/>status=applied]
CreateKB --> WriteNeo4j[Neo4j 写图<br/>merge_issue + merge_action]
WriteNeo4j --> SyncCheck{写图成功?}
SyncCheck -->|是| GraphSynced[status=graph_synced<br/>回填 kb.graph_node_uuid]
SyncCheck -->|否| SyncFailed[graph_sync_status=failed<br/>待重试]
GraphSynced --> Done([知识图谱更新完成])
style GateBanner fill:#fff3e0
style AsyncGen fill:#e3f2fd
style CreateSuggestion fill:#e8f5e9
GraphSynced fill:#c8e6c9
style Reject fill:#ffebee
style Done fill:#c8e6c9
```
### 5.2 通道 B:训练师手动录入
```mermaid
flowchart LR
A[训练师点击<br/>手动录入] --> B[填写表单<br/>标题/内容/分类/受众/图字段]
B --> C[提交<br/>source_type=manual<br/>confidence=1.0]
C --> D[创建 KnowledgeSuggestion<br/>status=pending]
D --> E[审核流程<br/>同通道 A]
```
### 5.3 通道 CRAGFlow 文档 ETL(预留未实现)
```mermaid
flowchart LR
A[RAGFlow 文档上传] --> B[ETL 处理<br/>文档→FAQ]
B --> C[source_type=document_ragflow<br/>audience=engineer_workguide]
C --> D[创建 KnowledgeSuggestion<br/>status=pending]
D --> E[审核流程<br/>同通道 A]
```
### 5.4 三通道汇总
```mermaid
graph TB
subgraph "通道 A:会话自动生成"
A1[会话关闭] --> A2[Dify AI 生成] --> A3[KnowledgeSuggestion]
end
subgraph "通道 B:手动录入"
B1[训练师录入] --> B2[confidence=1.0] --> B3[KnowledgeSuggestion]
end
subgraph "通道 CRAGFlow(预留)"
C1[文档 ETL] --> C2[自动提取] --> C3[KnowledgeSuggestion]
end
A3 --> S[统一审核队列<br/>status=pending]
B3 --> S
C3 --> S
S --> R{审核}
R -->|采纳| AP[approved → applied → graph_synced]
R -->|驳回| RJ[rejected]
R -->|改写| RW[重置 pending]
R -->|入队| Q[queued → 队列审批]
style S fill:#e3f2fd
style AP fill:#e8f5e9
```
---
## 6. 未实现功能设计
### 6.1 分诊交互 — 前瞻设计
#### 当前状态
前端组件 `TriageCard.vue` 已完成(530 行),包含完整的 UI 交互:步骤进度、选项列表、概率展示、专家模式、折叠/展开、跳过/确认。但后端 API 未实现,Dify 分诊 prompt 未配置。
#### 建议实现方案
**后端新增**
1. **新增 API 文件**`backend/app/api/triage.py`
- `POST /api/h5/triage/start` — 发起分诊
- `POST /api/h5/triage/step` — 提交步骤选择
- `POST /api/h5/triage/skip` — 跳过步骤
- `POST /api/h5/triage/transfer` — 转人工
2. **Dify Prompt 设计**
- 输入:员工问题文本
- 输出:分步选择题数组 `[{question, options: [{label, probability}], total_steps}]`
- 复杂度自适应:简单问题 1-2 步,复杂问题 3-5 步
3. **数据模型**
- 复用 `Conversation` 表,增加 `triage_steps` JSON 字段存储分诊过程
- 或新建 `triage_sessions`
4. **集成点**
- H5 对话页面在 AI 回复前调用分诊 API
- 分诊完成后将收集的上下文传入 Dify 生成最终回复
#### 预估工作量
| 任务 | 工作量 |
|------|--------|
| 后端 API + 服务 | 2 人日 |
| Dify Prompt 调试 | 3 人日 |
| H5 前端对接 | 1 人日 |
| 测试 | 1 人日 |
| **合计** | **7 人日** |
### 6.2 拓扑预览 — 前瞻设计
#### 当前状态
前端 SVG 缩略图已实现(基于 suggestion 的 issue/parent_issue/action 字段静态渲染),后端 `query_issue_subgraph` 方法已实现但未通过 API 暴露。
#### 建议实现方案
1. **新增 API 端点**
```python
@router.get("/suggestions/{suggestion_id}/topology")
@require_admin
async def get_suggestion_topology(suggestion_id: str, ...):
# 查询 suggestion 获取 issue 名称
# 调用 neo4j_client.query_issue_subgraph(issue_name, depth=1)
# 返回 {nodes, links}
```
2. **前端增强**
- SVG 缩略图保留为快速预览
- 点击缩略图弹出 ECharts mini graph modal 展示完整子图
- 子图支持节点点击跳转到图谱可视化页面
3. **降级处理**
- Neo4j 不可用时回退到当前 SVG 静态渲染
- suggestion 无 issue 字段时不展示拓扑
#### 预估工作量
| 任务 | 工作量 |
|------|--------|
| 后端 API 端点 | 0.5 人日 |
| 前端 ECharts modal | 1 人日 |
| 测试 | 0.5 人日 |
| **合计** | **2 人日** |
### 6.3 代答排除 — 前瞻设计
#### 当前状态
前端 `TriageCard.vue` 中 `setExcludedOptions` / `setRecommendedOption` 方法定义完成,但无后端 API 对接,无 WS 推送机制。
#### 建议实现方案
1. **后端新增**
- `POST /api/agent/triage/exclude` — 坐席排除选项
- `POST /api/agent/triage/recommend` — 坐席推荐选项
2. **WebSocket 推送**
- 坐席排除/推荐操作后,通过 WS 实时推送到 H5 员工端
- H5 端接收后调用 `TriageCard.setExcludedOptions()` / `setRecommendedOption()`
3. **Dify Prompt 增强**
- 将排除的选项作为上下文传入 Dify,影响后续步骤生成
- 避免 AI 在后续步骤中再次推荐已排除的选项
4. **审计日志**
- 记录坐席排除/推荐操作(操作人、时间、排除的选项、原因)
#### 预估工作量
| 任务 | 工作量 |
|------|--------|
| 后端 API + WS 推送 | 1.5 人日 |
| 坐席端前端对接 | 1 人日 |
| H5 前端对接 | 0.5 人日 |
| 测试 | 1 人日 |
| **合计** | **4 人日** |
---
## 7. 已知问题与后续优化方向
### 7.1 已知问题
| # | 问题 | 影响 | 严重程度 | 当前处理 |
|---|------|------|---------|---------|
| 1 | Neo4j 写图失败后无自动重试 | `graph_sync_status=failed` 的建议停留在 applied 状态,图数据不完整 | P1 | 人工触发重新审批 |
| 2 | `_analyze_conversation_data` 采样限制 20 条 | 分析超过 20 条会话时仅采样前 20 条,可能遗漏 | P2 | 可接受,后续调大采样 |
| 3 | audience 自动标注默认 employee_quick_reply | Conversation 模型无 session_type 字段,无法精确区分员工/工程师会话 | P2 | 保守默认,训练师可手动修改 |
| 4 | 相似度计算为简单前缀匹配 | 无法检测语义相似但文字不同的重复 Issue | P2 | 后续可引入向量相似度 |
| 5 | 会话关闭异步任务无重试机制 | Dify 不可用时建议生成失败,无自动重试 | P2 | source_failed 标记,训练师可手动改写 |
| 6 | 过期状态 expired 无定时任务 | 设计中有 expired 状态(72h 超时),但无定时任务自动触发 | P3 | 待实现定时任务 |
| 7 | `create_relation` 使用 CREATE 而非 MERGE | 重复审批同一建议可能创建重复关系边 | P2 | 后续改为 MERGE |
| 8 | 前端 `createSuggestion` 直接调用 POST /suggestions | API 路由中无 POST /suggestions 创建端点(仅列表 GET | P1 | 需补充创建 API 或使用其他路径 |
### 7.2 后续优化方向
#### 短期(P0-P1
1. **Neo4j 写图重试队列**
- 新增定时任务扫描 `graph_sync_status=failed` 的建议
- 自动重试写图,最多 3 次
- 超过重试次数通知管理员
2. **补充手动创建建议 API**
- 前端 `createSuggestion` 调用的 POST /suggestions 端点需补充
- 或确认是否通过其他路由处理
3. **关系边 MERGE 幂等**
- `create_relation` 改用 MERGE 替代 CREATE
- 避免重复审批产生重复关系
#### 中期(P2
4. **向量相似度去重**
- 引入 embedding 模型计算 Issue 名称的语义相似度
- 替代当前的前缀匹配算法
- 提高重复检测准确率
5. **过期定时任务**
- 实现 72h 超时自动 expired 的定时任务
- 使用 APScheduler 或 Celery beat
6. **分诊交互后端实现**
- 实现分诊 API + Dify Prompt
- 打通 TriageCard 前后端
7. **拓扑预览 API 对接**
- 暴露 `query_issue_subgraph` 为 API
- 前端 ECharts mini graph 展示
#### 长期(P3
8. **RAGFlow 通道 C 实现**
- 部署 RAGFlow 服务
- 实现文档 ETL → KnowledgeSuggestion 自动生成
- `ragflow_ingestion_enabled` 配置开关已预留
9. **知识图谱推理**
- 基于 Neo4j 图结构进行路径推荐
- 员工提问时推荐相关 Issue→Action 路径
10. **全链路监控看板**
- 建议生成→审核→写图各阶段耗时统计
- 转化漏斗:生成数 → 采纳数 → 写图成功数
- Dify 调用成功率监控
---
## 附录
### A. 数据库迁移
| 迁移版本 | 说明 |
|---------|------|
| 043_knowledge_iteration | 创建 knowledge_suggestions 表 + conversation_annotations 表 |
| 044_automation | 自动化相关表(后续迁移) |
### B. 测试覆盖
| 测试层级 | 测试数 | 通过率 | 报告 |
|---------|--------|--------|------|
| Tier0 基础测试 | 41 | 100% | `docs/06-测试质量/Tier0-测试报告-20260708.md` |
| Tier1 API 测试 | 34 | 100% | 同上 |
| CSV 验证 | 14 | 100% | 同上 |
| P2 可视化测试 | — | — | `docs/06-测试质量/P0串联+P2可视化-测试报告-20260708.md` |
| **合计** | **89** | **100%** | — |
### C. 关键文件索引
| 文件 | 行数 | 说明 |
|------|------|------|
| `backend/app/api/knowledge_iteration.py` | 568 | 12 条 API 路由 |
| `backend/app/api/approval_queue.py` | 208 | 3 条队列 API 路由 |
| `backend/app/services/knowledge_iteration_service.py` | 1197 | 核心服务 |
| `backend/app/services/neo4j_client.py` | 759 | Neo4j 异步客户端 |
| `backend/app/models/knowledge_suggestion.py` | 260 | 数据模型 |
| `backend/app/models/knowledge_base.py` | 143 | 数据模型 |
| `backend/app/models/neo4j_schema.py` | 115 | 图节点 Pydantic 模型 |
| `backend/app/schemas/enums.py` | 159 | 枚举 + 状态机 |
| `backend/app/schemas/knowledge_suggestion.py` | 208 | 请求/响应 Schema |
| `backend/app/config.py` | 469 | 配置项 |
| `backend/app/api/conversations.py` | ~400+ | 会话关闭触发点 |
| `frontend-admin/src/views/KnowledgeIteration.vue` | 982 | 管理后台页面 |
| `frontend-agent/src/components/chat/ApprovalInlineCard.vue` | 695 | 内联审批卡片 |
| `frontend-h5/src/components/TriageCard.vue` | 530 | 分诊卡片 |
| `frontend-h5/src/components/ConfidenceGateBanner.vue` | 332 | 置信门控横幅 |
| `frontend-h5/src/composables/useConfidenceGate.ts` | 181 | 置信门控逻辑 |
---
> **文档结束**
> 本文档基于代码分析生成,已部署功能为回溯文档,未实现功能为前瞻设计。
> 如有疑问请联系架构组。