From 5fbb72aa82be6e33c396428c319307097e1acdab Mon Sep 17 00:00:00 2001 From: MerCry Date: Sat, 28 Feb 2026 00:30:54 +0800 Subject: [PATCH] =?UTF-8?q?feat(admin):=20v0.7.0=20=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E7=9B=91=E6=8E=A7=E5=8A=9F=E8=83=BD=E5=A2=9E=E5=BC=BA=20-=20Da?= =?UTF-8?q?shboard=E7=BB=9F=E8=AE=A1=E5=8D=A1=E7=89=87=E4=B8=8E=E5=AF=B9?= =?UTF-8?q?=E8=AF=9D=E8=BF=BD=E8=B8=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Dashboard 统计卡片增强 - 新增四个监控统计卡片:意图规则命中、Prompt模板、话术流程、护栏拦截 - 支持时间范围筛选(今日/本周/本月/最近7天/最近30天) - 显示Top 3排行数据,卡片支持点击跳转 - 完整流程测试台 - RAG实验室新增完整流程测试模式切换 - 支持12步执行流程时间线展示 - 支持步骤详情展开查看输入输出 - 流程配置开关(意图识别、话术流程、RAG检索、输出护栏、上下文记忆) - 对话追踪页面 - 对话列表支持会话ID、时间范围、流程、护栏筛选 - 对话详情展示触发规则、使用模板、话术流程 - 执行链路时间线展示 - 导出功能支持JSON/CSV格式 - 监控导航路由 - 新增 /admin/monitoring/conversations 路由 验收标准: AC-ASA-45~AC-ASA-52, AC-ASA-65~AC-ASA-68 --- ...7.0-window3-dashboard-tracking-progress.md | 223 ++++++ ai-service-admin/src/api/dashboard.ts | 69 +- ai-service-admin/src/api/flow-test.ts | 117 ++++ ai-service-admin/src/api/monitoring.ts | 115 ++++ ai-service-admin/src/router/index.ts | 6 + .../admin/monitoring/ConversationTracking.vue | 632 ++++++++++++++++++ .../src/views/dashboard/index.vue | 333 ++++++++- ai-service-admin/src/views/rag-lab/index.vue | 497 +++++++++++--- 8 files changed, 1877 insertions(+), 115 deletions(-) create mode 100644 .claude/progress/v0.7.0-window3-dashboard-tracking-progress.md create mode 100644 ai-service-admin/src/api/flow-test.ts create mode 100644 ai-service-admin/src/views/admin/monitoring/ConversationTracking.vue diff --git a/.claude/progress/v0.7.0-window3-dashboard-tracking-progress.md b/.claude/progress/v0.7.0-window3-dashboard-tracking-progress.md new file mode 100644 index 0000000..533b9fa --- /dev/null +++ b/.claude/progress/v0.7.0-window3-dashboard-tracking-progress.md @@ -0,0 +1,223 @@ +# v0.7.0 窗口3:Dashboard + 流程测试 + 对话追踪 - 进度文档 + +## 1. 任务概述 + +实现 v0.7.0 迭代中的**核心监控基础设施**,包括 Dashboard 统计增强、完整流程测试台(12步执行链路)、对话追踪与导出功能。这是整个监控系统的核心支撑。 + +## 2. 需求文档引用 + +- spec/ai-service-admin/requirements.md - 第10节(v0.7.0),AC-ASA-45 ~ AC-ASA-52, AC-ASA-65 ~ AC-ASA-68 +- spec/ai-service/requirements.md - 第13节(v0.7.0),AC-AISVC-91 ~ AC-AISVC-95, AC-AISVC-108 ~ AC-AISVC-110 + +## 3. 总体进度 + +- [x] 后端任务(6个) + - [x] T16.1-T16.5: 监控数据模型与基础设施 + - [x] T16.6-T16.8: Dashboard 统计增强 + - [x] T16.9-T16.12: Orchestrator 监控增强 + - [x] T16.33-T16.36: 对话追踪服务 + - [x] T16.37-T16.39: 对话导出服务 +- [x] 前端任务(4个) + - [x] P13-02-P13-04: Dashboard 统计卡片增强 + - [x] P13-05-P13-08: 完整流程测试台 + - [x] P13-20-P13-23: 对话追踪页面 + - [x] P13-24-P13-25: 监控导航菜单 + +## 4. Phase 详细进度 + +### Phase 1: 监控数据模型与基础设施 (T16.1-T16.5) +**状态**: ✅ 已完成 +**文件修改记录**: +- ✅ 修改: ai-service/app/models/entities.py + - 扩展 ChatMessage 实体,新增监控字段: prompt_template_id, intent_rule_id, flow_instance_id, guardrail_triggered, guardrail_words + - 新增 FlowTestRecord 实体(流程测试记录) + - 新增 FlowTestStepResult 模型 + - 新增 ExportTask 实体(导出任务) + - 新增 ExportTaskStatus 枚举 + - 新增 ConversationDetail 模型 + +### Phase 2: Redis 统计缓存层 (T16.2) +**状态**: ✅ 已完成 +**文件修改记录**: +- ✅ 创建: ai-service/app/services/monitoring/cache.py + - MonitoringCache 类:Redis 缓存层 + - incr_counter: 原子计数器 + - get/set_dashboard_stats: Dashboard 缓存 + - add_to_leaderboard/get_leaderboard: 排行榜 +- ✅ 修改: ai-service/app/core/config.py + - 新增 redis_url, redis_enabled, dashboard_cache_ttl, stats_counter_ttl 配置 +- ✅ 修改: ai-service/pyproject.toml + - 新增 redis>=5.0.0 依赖 + +### Phase 3: Dashboard 统计增强 (T16.6-T16.8) +**状态**: ✅ 已完成 +**文件修改记录**: +- ✅ 创建: ai-service/app/services/monitoring/dashboard_service.py + - DashboardService 类 + - get_enhanced_stats: 获取增强统计 + - _get_intent_rule_stats: 意图规则统计 + - _get_template_stats: 模板使用统计 + - _get_flow_stats: 流程激活统计 + - _get_guardrail_stats: 护栏拦截统计 +- ✅ 修改: ai-service/app/api/admin/dashboard.py + - 扩展 GET /admin/dashboard/stats + - 新增 start_date, end_date, include_enhanced 参数 + - 返回增强监控统计 + +### Phase 4: Orchestrator 监控增强 (T16.9-T16.12) +**状态**: ✅ 已完成 +**文件修改记录**: +- ✅ 创建: ai-service/app/services/monitoring/recorder.py + - MonitoringRecorder 类:执行记录器 + - StepMetrics 数据类:步骤指标 + - start_step/end_step: 步骤计时 + - record_intent_hit: 记录意图命中 + - record_template_usage: 记录模板使用 + - record_flow_activation: 记录流程激活 + - record_guardrail_block: 记录护栏拦截 + - save_test_record: 保存测试记录 + +### Phase 5: 对话追踪服务 (T16.33-T16.36) +**状态**: ✅ 已完成 +**文件修改记录**: +- ✅ 修改: ai-service/app/api/admin/monitoring.py + - GET /admin/monitoring/conversations: 对话列表 + - GET /admin/monitoring/conversations/{message_id}: 对话详情 + +### Phase 6: 对话导出服务 (T16.37-T16.39) +**状态**: ✅ 已完成 +**文件修改记录**: +- ✅ 修改: ai-service/app/api/admin/monitoring.py + - POST /admin/monitoring/conversations/export: 创建导出任务 + - GET /admin/monitoring/conversations/export/{task_id}: 获取导出状态 + - GET /admin/monitoring/conversations/export/{task_id}/download: 下载导出文件 + +### Phase 7: 流程测试 API +**状态**: ✅ 已完成 +**文件修改记录**: +- ✅ 创建: ai-service/app/api/admin/flow_test.py + - POST /admin/test/flow-execution: 执行完整12步流程测试 + - GET /admin/test/flow-execution/{test_id}: 获取测试结果 + - GET /admin/test/flow-executions: 列出测试记录 + - POST /admin/test/compare: 对比测试 +- ✅ 修改: ai-service/app/api/admin/__init__.py +- ✅ 修改: ai-service/app/main.py + +### Phase 8: 数据库迁移 +**状态**: ✅ 已完成 +**文件修改记录**: +- ✅ 创建: ai-service/scripts/migrations/002_add_monitoring_fields.sql + - chat_messages 表新增监控字段 + - 创建 flow_test_records 表 + - 创建 export_tasks 表 + - 创建相关索引 + +### Phase 9: 前端 Dashboard 统计卡片增强 (P13-02-P13-04) +**状态**: ✅ 已完成 +**文件修改记录**: +- ✅ 修改: ai-service-admin/src/api/dashboard.ts + - 新增 DashboardStats 接口类型定义 + - 新增 IntentRuleStat, PromptTemplateStat, ScriptFlowStat, GuardrailWordStat 类型 + - 扩展 getDashboardStats 支持时间范围参数 +- ✅ 修改: ai-service-admin/src/views/dashboard/index.vue + - 新增时间范围筛选器(日期选择器 + 快捷选项) + - 新增四个监控统计卡片:意图规则命中、Prompt 模板、话术流程、护栏拦截 + - 卡片支持点击跳转到对应监控页面 + - 显示 Top 3 排行数据 + +### Phase 10: 前端完整流程测试台 (P13-05-P13-08) +**状态**: ✅ 已完成 +**文件修改记录**: +- ✅ 创建: ai-service-admin/src/api/flow-test.ts + - FlowExecutionRequest/Response 接口 + - FlowExecutionStep 接口 + - executeFlowTest, getFlowTestResult, listFlowTests, compareFlowTest 函数 +- ✅ 修改: ai-service-admin/src/views/rag-lab/index.vue + - 新增"完整流程测试"模式切换开关 + - 新增流程配置开关(意图识别、话术流程、RAG检索、输出护栏、上下文记忆) + - 新增 12 步执行流程时间线展示 + - 支持步骤展开查看详细输入输出 + - 显示最终响应和置信度 + +### Phase 11: 前端对话追踪页面 (P13-20-P13-23) +**状态**: ✅ 已完成 +**文件修改记录**: +- ✅ 修改: ai-service-admin/src/api/monitoring.ts + - 新增 ConversationItem, ConversationDetail 接口 + - 新增 ExportTaskResponse, ExportRequest 接口 + - 新增 listConversations, getConversationDetail 函数 + - 新增 createExportTask, getExportStatus, getExportDownloadUrl 函数 +- ✅ 创建: ai-service-admin/src/views/admin/monitoring/ConversationTracking.vue + - 对话列表页面(支持会话ID、时间范围、流程、护栏筛选) + - 对话详情抽屉(显示用户消息、AI回复、触发规则、使用模板、话术流程) + - 执行链路时间线展示(12步流程详情) + - 导出功能(支持 JSON/CSV 格式) + +### Phase 12: 前端监控导航菜单 (P13-24-P13-25) +**状态**: ✅ 已完成 +**文件修改记录**: +- ✅ 修改: ai-service-admin/src/router/index.ts + - 新增 /admin/monitoring/conversations 路由 + +## 5. 技术上下文 + +### 项目结构 +- **前端**: `ai-service-admin/` - Vue 3 + Element Plus + TypeScript +- **后端**: `ai-service/` - Python FastAPI + SQLModel + PostgreSQL + Redis + +### 核心约定 +- 多租户隔离: 所有数据访问必须带 tenant_id 过滤 +- 实体使用 SQLModel 定义,支持 Pydantic 验证 +- API 使用 FastAPI Router 组织 + +### 新增依赖 +- redis>=5.0.0: Redis 异步客户端 + +## 6. 会话历史 + +### 会话 1 (2026-02-27) +- 完成: 阅读需求文档和设计文档,创建进度文档 +- 完成: 所有后端任务实现 +- 问题: metadata 字段名与 SQLModel 父类冲突 +- 解决方案: 重命名为 step_metadata + +### 会话 2 (2026-02-27) +- 完成: 所有前端任务实现 +- Dashboard 统计卡片增强 +- RAG 实验室完整流程测试台 +- 对话追踪页面 +- 监控导航路由 + +## 7. 下一步行动 + +**任务已全部完成** + +## 8. 待解决问题 + +暂无 + +## 9. 最终验收标准 + +### Dashboard 统计增强 (AC-AISVC-91, AC-AISVC-92) +- [x] GET /admin/dashboard/stats 返回意图规则命中率 +- [x] GET /admin/dashboard/stats 返回 Prompt 模板使用次数 +- [x] GET /admin/dashboard/stats 返回话术流程激活次数 +- [x] GET /admin/dashboard/stats 返回护栏拦截次数 +- [x] 支持时间范围筛选参数 +- [x] 前端展示四个监控统计卡片 +- [x] 前端支持时间范围筛选 + +### 完整流程测试 (AC-AISVC-93, AC-AISVC-94, AC-AISVC-95) +- [x] POST /admin/test/flow-execution 执行完整12步流程 +- [x] 返回每一步的详细执行结果 +- [x] 支持对比测试 +- [x] 前端展示12步执行时间线 +- [x] 前端支持步骤详情展开 + +### 对话追踪 (AC-AISVC-108, AC-AISVC-109, AC-AISVC-110) +- [x] GET /admin/monitoring/conversations 返回对话列表 +- [x] GET /admin/monitoring/conversations/{id} 返回执行链路详情 +- [x] POST /admin/monitoring/conversations/export 导出对话记录 +- [x] 前端对话列表页面 +- [x] 前端对话详情展示 +- [x] 前端导出功能(JSON/CSV) diff --git a/ai-service-admin/src/api/dashboard.ts b/ai-service-admin/src/api/dashboard.ts index 0d7ef78..b6f4dbd 100644 --- a/ai-service-admin/src/api/dashboard.ts +++ b/ai-service-admin/src/api/dashboard.ts @@ -1,8 +1,73 @@ import request from '@/utils/request' -export function getDashboardStats() { +export interface DashboardStatsParams { + start_date?: string + end_date?: string + include_enhanced?: boolean +} + +export interface IntentRuleStat { + ruleId: string + ruleName: string + hitCount: number + hitRate: number +} + +export interface PromptTemplateStat { + templateId: string + templateName: string + usageCount: number +} + +export interface ScriptFlowStat { + flowId: string + flowName: string + activationCount: number + completionRate: number +} + +export interface GuardrailWordStat { + word: string + category: string + hitCount: number +} + +export interface DashboardStats { + knowledgeBases: number + totalDocuments: number + totalMessages: number + totalSessions: number + totalTokens: number + promptTokens: number + completionTokens: number + aiRequestsCount: number + avgLatencyMs: number + lastLatencyMs: number | null + lastRequestTime: string | null + slowRequestsCount: number + errorRequestsCount: number + p95LatencyMs: number + p99LatencyMs: number + minLatencyMs: number + maxLatencyMs: number + latencyThresholdMs: number + intentRuleHitRate: number + intentRuleHitCount: number + topIntentRules: IntentRuleStat[] + promptTemplateUsageCount: number + topPromptTemplates: PromptTemplateStat[] + scriptFlowActivationCount: number + scriptFlowCompletionRate: number + topScriptFlows: ScriptFlowStat[] + guardrailBlockCount: number + guardrailBlockRate: number + topGuardrailWords: GuardrailWordStat[] +} + +export function getDashboardStats(params?: DashboardStatsParams): Promise { return request({ url: '/admin/dashboard/stats', - method: 'get' + method: 'get', + params }) } diff --git a/ai-service-admin/src/api/flow-test.ts b/ai-service-admin/src/api/flow-test.ts new file mode 100644 index 0000000..8ceb191 --- /dev/null +++ b/ai-service-admin/src/api/flow-test.ts @@ -0,0 +1,117 @@ +import request from '@/utils/request' + +export interface FlowExecutionRequest { + message: string + session_id?: string + user_id?: string + enable_flow?: boolean + enable_intent?: boolean + enable_rag?: boolean + enable_guardrail?: boolean + enable_memory?: boolean + compare_mode?: boolean +} + +export interface FlowExecutionStep { + step: number + name: string + status: 'success' | 'failed' | 'skipped' + duration_ms: number + input?: Record + output?: Record + error?: string +} + +export interface FlowExecutionResponse { + testId: string + sessionId: string + status: string + steps: FlowExecutionStep[] + finalResponse: { + reply: string + confidence: number | null + should_transfer: boolean + sources?: any[] + } | null + totalDurationMs: number + createdAt: string +} + +export interface FlowTestRecord { + testId: string + sessionId: string + status: string + stepCount: number + totalDurationMs: number + createdAt: string +} + +export interface FlowTestListResponse { + data: FlowTestRecord[] + page: number + pageSize: number + total: number +} + +export interface CompareRequest { + message: string + baseline_config?: Record + test_config?: Record +} + +export interface CompareResult { + baseline: { + sessionId: string + reply: string + confidence: number | null + durationMs: number + steps: FlowExecutionStep[] + } + test: { + sessionId: string + reply: string + confidence: number | null + durationMs: number + steps: FlowExecutionStep[] + } + comparison: { + durationDiffMs: number + confidenceDiff: number + } +} + +export function executeFlowTest(data: FlowExecutionRequest): Promise { + return request({ + url: '/admin/test/flow-execution', + method: 'post', + data + }) +} + +export function getFlowTestResult(testId: string): Promise { + return request({ + url: `/admin/test/flow-execution/${testId}`, + method: 'get' + }) +} + +export function listFlowTests(params?: { + session_id?: string + status?: string + page?: number + pageSize?: number +}): Promise { + return request({ + url: '/admin/test/flow-executions', + method: 'get', + params + }) +} + +export function compareFlowTest(data: CompareRequest): Promise { + return request({ + url: '/admin/test/compare', + method: 'post', + data + }) +} diff --git a/ai-service-admin/src/api/monitoring.ts b/ai-service-admin/src/api/monitoring.ts index 47236c3..135e18f 100644 --- a/ai-service-admin/src/api/monitoring.ts +++ b/ai-service-admin/src/api/monitoring.ts @@ -330,3 +330,118 @@ export function getGuardrailBlocks( params }) } + +export interface ConversationItem { + id: string + sessionId: string + userMessage: string + aiReply: string | null + hasFlow: boolean + hasGuardrail: boolean + createdAt: string +} + +export interface ConversationListResponse { + data: ConversationItem[] + page: number + pageSize: number + total: number +} + +export interface ConversationDetail { + conversationId: string + sessionId: string + userMessage: string + aiReply: string | null + triggeredRules: Array<{ + id: string + name: string + responseType: string + }> + usedTemplate: { + id: string + name: string + } | null + usedFlow: { + id: string + flowId: string + status: string + currentStep: number + } | null + executionTimeMs: number | null + confidence: number | null + shouldTransfer: boolean + guardrailTriggered: boolean + guardrailWords: string[] | null + executionSteps: Array<{ + step: number + name: string + status: string + duration_ms: number + input?: Record + output?: Record + error?: string + }> | null + createdAt: string +} + +export interface ExportTaskResponse { + taskId: string + status: string + format: string + createdAt: string + fileName?: string + fileSize?: number + totalRows?: number + completedAt?: string + errorMessage?: string +} + +export interface ExportRequest { + format?: 'json' | 'csv' + session_id?: string + start_date?: string + end_date?: string +} + +export function listConversations(params?: { + session_id?: string + start_date?: string + end_date?: string + has_flow?: boolean + has_guardrail?: boolean + page?: number + pageSize?: number +}): Promise { + return request({ + url: '/admin/monitoring/conversations', + method: 'get', + params + }) +} + +export function getConversationDetail(messageId: string): Promise { + return request({ + url: `/admin/monitoring/conversations/${messageId}`, + method: 'get' + }) +} + +export function createExportTask(data: ExportRequest): Promise { + return request({ + url: '/admin/monitoring/conversations/export', + method: 'post', + data + }) +} + +export function getExportStatus(taskId: string): Promise { + return request({ + url: `/admin/monitoring/conversations/export/${taskId}`, + method: 'get' + }) +} + +export function getExportDownloadUrl(taskId: string): string { + return `/admin/monitoring/conversations/export/${taskId}/download` +} diff --git a/ai-service-admin/src/router/index.ts b/ai-service-admin/src/router/index.ts index 7591d87..93b5470 100644 --- a/ai-service-admin/src/router/index.ts +++ b/ai-service-admin/src/router/index.ts @@ -94,6 +94,12 @@ const routes: Array = [ name: 'GuardrailMonitoring', component: () => import('@/views/admin/monitoring/Guardrails.vue'), meta: { title: '输出护栏监控' } + }, + { + path: '/admin/monitoring/conversations', + name: 'ConversationTracking', + component: () => import('@/views/admin/monitoring/ConversationTracking.vue'), + meta: { title: '对话追踪' } } ] diff --git a/ai-service-admin/src/views/admin/monitoring/ConversationTracking.vue b/ai-service-admin/src/views/admin/monitoring/ConversationTracking.vue new file mode 100644 index 0000000..5c1c17c --- /dev/null +++ b/ai-service-admin/src/views/admin/monitoring/ConversationTracking.vue @@ -0,0 +1,632 @@ + + + + + diff --git a/ai-service-admin/src/views/dashboard/index.vue b/ai-service-admin/src/views/dashboard/index.vue index d7660f5..2070348 100644 --- a/ai-service-admin/src/views/dashboard/index.vue +++ b/ai-service-admin/src/views/dashboard/index.vue @@ -1,13 +1,27 @@