From 7ab3575374c510c1df54822e093ad2b0c33def5e Mon Sep 17 00:00:00 2001 From: Yaojia Wang Date: Mon, 6 Apr 2026 16:23:54 +0200 Subject: [PATCH] vault backup: 2026-04-06 16:23:54 --- 2 - Projects/Smart Support.md | 194 ++++++++++--- .../Smart Support/Phase 1 - 核心框架.md | 1 + .../Phase 2 - 多 Agent + 安全.md | 177 +++--------- 2 - Projects/Smart Support/Phase 2 Dev Log.md | 43 +++ .../Phase 3 - OpenAPI 自动发现.md | 201 +++---------- 2 - Projects/Smart Support/Phase 3 Dev Log.md | 42 +++ .../Smart Support/Phase 4 - 分析 + 回放.md | 265 +++--------------- 2 - Projects/Smart Support/Phase 4 Dev Log.md | 41 +++ .../Smart Support/Phase 5 - 打磨 + 演示.md | 122 ++++---- 2 - Projects/Smart Support/Phase 5 Dev Log.md | 56 ++++ 10 files changed, 507 insertions(+), 635 deletions(-) create mode 100644 2 - Projects/Smart Support/Phase 2 Dev Log.md create mode 100644 2 - Projects/Smart Support/Phase 3 Dev Log.md create mode 100644 2 - Projects/Smart Support/Phase 4 Dev Log.md create mode 100644 2 - Projects/Smart Support/Phase 5 Dev Log.md diff --git a/2 - Projects/Smart Support.md b/2 - Projects/Smart Support.md index b9439fa..2e8d468 100644 --- a/2 - Projects/Smart Support.md +++ b/2 - Projects/Smart Support.md @@ -1,7 +1,8 @@ --- created: 2026-03-29 +updated: 2026-04-06 type: project -status: active +status: completed deadline: "" tags: - ai-agent @@ -14,6 +15,8 @@ tags: - customer-support - websocket - postgresql + - react + - docker --- # Smart Support @@ -31,35 +34,56 @@ AI 客服行动层框架。粘贴你的 API,获得一个能执行真实操作 ``` 核心组件: -- **langgraph-supervisor** v1.1 - 多 Agent 编排 -- **langchain-mcp-adapters** - MCP 工具集成 -- **PostgresSaver** - 会话状态持久化 -- **interrupt()** - 写操作人工确认 +- **langgraph-supervisor** v0.0.31 -- 多 Agent 编排 +- **langchain-mcp-adapters** -- MCP 工具集成 +- **langgraph-checkpoint-postgres** v3.0.5 -- 会话状态持久化 +- **interrupt()** -- 写操作人工确认(30 分钟 TTL 自动取消) ## 技术栈 -- Python 3.11+, FastAPI, LangGraph v1.1 -- React(前端), PostgreSQL(Docker Compose) -- Claude Sonnet 4.6(可切换 LLM) +| 组件 | 技术 | 版本/说明 | +|------|------|-----------| +| 后端 | Python 3.11+ / FastAPI | Web 框架 + WebSocket | +| Agent 编排 | LangGraph 1.x | Supervisor 模式多 Agent 路由 | +| 检查点 | langgraph-checkpoint-postgres | PostgreSQL 持久化 | +| MCP | langchain-mcp-adapters | MultiServerMCPClient | +| 数据库 | PostgreSQL 16 | Docker Compose 部署 | +| LLM | Claude Sonnet 4.6(默认) | 支持 Anthropic/OpenAI/Google 切换 | +| 前端 | React 19 + TypeScript + Vite 6 | React Router 7.x | +| 测试 | pytest 8.3+ / vitest 4.1.2 | 后端 516 测试 92%+ 覆盖率 | +| 部署 | Docker Compose | PostgreSQL + FastAPI + nginx | +| 代码质量 | ruff 0.9+ | Python linting + formatting | ## 核心特性 - 多 Agent 协作,YAML 驱动配置 -- OpenAPI 规范自动生成 MCP 服务器 + Agent 配置(LLM 辅助分类 + 人工审核) -- 写操作人工确认(30 分钟超时自动取消) -- 对话回放 + 数据分析仪表盘 -- Webhook 升级通知 +- 意图分类(单意图/多意图/模糊检测),LLM 结构化输出 +- OpenAPI 规范自动生成 @tool 函数 + Agent YAML(LLM 辅助分类 + 人工审核) +- 写操作人工确认(interrupt(),30 分钟 TTL 超时自动取消) +- 对话回放 + 数据分析仪表盘(解决率、Agent 使用率、升级率、成本) +- Webhook 升级通知(指数退避重试) - 垂直行业模板(电商、SaaS、金融科技) +- SSRF 防护(私有 IP 拦截、DNS 重绑定防御、重定向链验证) +- WebSocket 流式输出 + 速率限制(10 msg/10s per thread) +- 错误分类 + 自动重试(ErrorCategory 枚举,可重试错误指数退避) ## 开发阶段 | 阶段 | 周期 | 内容 | 状态 | 详情 | |------|------|------|------|------| | Phase 1 | 第 1-3 周 | 核心框架 | COMPLETED (2026-03-30) | [[Smart Support/Phase 1 - 核心框架]] | -| Phase 2 | 第 3-4 周 | 多 Agent + 安全 | 未开始 | [[Smart Support/Phase 2 - 多 Agent + 安全]] | -| Phase 3 | 第 4-6 周 | OpenAPI 自动发现 | 未开始 | [[Smart Support/Phase 3 - OpenAPI 自动发现]] | -| Phase 4 | 第 6-7 周 | 分析 + 回放 | 未开始 | [[Smart Support/Phase 4 - 分析 + 回放]] | -| Phase 5 | 缓冲周 | 打磨 + 演示 | 未开始 | [[Smart Support/Phase 5 - 打磨 + 演示]] | +| Phase 2 | 第 3-4 周 | 多 Agent + 安全 | COMPLETED (2026-03-30) | [[Smart Support/Phase 2 - 多 Agent + 安全]] | +| Phase 3 | 第 4-6 周 | OpenAPI 自动发现 | COMPLETED (2026-03-30) | [[Smart Support/Phase 3 - OpenAPI 自动发现]] | +| Phase 4 | 第 6-7 周 | 分析 + 回放 | COMPLETED (2026-03-31) | [[Smart Support/Phase 4 - 分析 + 回放]] | +| Phase 5 | 缓冲周 | 打磨 + 演示 | COMPLETED (2026-03-31) | [[Smart Support/Phase 5 - 打磨 + 演示]] | + +## 项目数据 + +- 后端测试:516 个(单元 ~400 + 集成 ~7 + E2E ~3) +- 前端测试:~23 个(vitest + happy-dom) +- 代码覆盖率:92.88% +- 应用版本:v0.5.0 +- Git 最新提交:`af53111` refactor: fix architectural issues ## 目标用户 @@ -67,43 +91,137 @@ AI 客服行动层框架。粘贴你的 API,获得一个能执行真实操作 ## 仓库 -- 代码:`ssh://git@git.colacoder.com:2200/kai/smart-support.git` +- 代码:`git@git.colacoder.com:kai/smart-support.git` - 分支:`main` -- 本地路径:`/Users/yiukai/Documents/git/smart-support` +- 本地路径(Windows):`C:\Users\yaoji\git\ColaCoder\smart-support` + +## WebSocket 协议 + +客户端 -> 服务器: +- `{"type": "message", "thread_id": "...", "content": "..."}` +- `{"type": "interrupt_response", "thread_id": "...", "interrupt_id": "...", "approved": true/false}` + +服务器 -> 客户端: +- `{"type": "token", "thread_id": "...", "content": "..."}` -- 流式 token +- `{"type": "interrupt", ...}` -- 人工确认提示(含 TTL) +- `{"type": "tool_call", ...}` / `{"type": "tool_result", ...}` -- 工具调用 +- `{"type": "message_complete", ...}` -- 消息完成 +- `{"type": "error", ...}` -- 错误 + +## REST API + +| 方法 | 路径 | 说明 | +|------|------|------| +| WS | `/ws` | WebSocket 聊天 | +| GET | `/api/health` | 健康检查 | +| GET | `/api/conversations` | 对话列表(分页) | +| GET | `/api/replay/{thread_id}` | 回放时间线(分页,默认 20 步) | +| GET | `/api/analytics?range=7d` | 分析摘要(1d/7d/30d/90d) | +| POST | `/api/openapi/import` | 开始 OpenAPI 导入 | +| GET | `/api/openapi/jobs/{id}` | 导入任务状态 | +| PUT | `/api/openapi/jobs/{id}/classifications/{idx}` | 修改端点分类 | +| POST | `/api/openapi/jobs/{id}/approve` | 审核通过,生成工具 | + +## 数据库表 + +| 表 | 用途 | +|----|----| +| checkpoints | LangGraph 状态快照(自动管理) | +| checkpoint_writes | 检查点写入记录 | +| conversations | 对话元数据(状态、解决类型、使用 Agent、Token、成本) | +| interrupts | 人工确认记录(pending/approved/rejected/expired) | +| analytics_events | 分析事件流(事件类型、Agent、工具、Token、成本、耗时) | + +## 架构决策(ADR) + +| ADR | 决策 | 理由 | +|-----|------|------| +| ADR-001 | LangGraph Supervisor 多 Agent | 内置编排,无需自定义 | +| ADR-002 | PostgresSaver 从第一天起 | Phase 4 分析需要可查询的检查点数据 | +| ADR-003 | WebSocket + astream_events() | 双向低延迟流式 | +| ADR-004 | YAML 声明式 Agent 注册 | 非开发者可配置 Agent | +| ADR-005 | LangGraph interrupt() HITL | 框架内置,深度集成检查点 | +| ADR-006 | OpenAPI: 解析 -> LLM 分类 -> 人工审核 | 平衡自动化与安全 | +| ADR-007 | SSRF 独立模块 | 可复用,可独立测试 | + +## 安全架构 + +- **L1 输入验证**:消息格式、长度限制(10k 字符)、Agent YAML 启动验证 +- **L2 SSRF 防护**:私有 IP 拦截、DNS 重绑定防御、重定向链验证 +- **L3 HITL**:写操作 interrupt()、30 分钟 TTL 自动取消 +- **L4 权限隔离**:Agent 级工具集、读 Agent 无法调写工具 +- **L5 审计追踪**:全操作记录、PostgreSQL 存储、回放 API ## 完整文档(已同步) -- [[Smart Support/Architecture]] - 系统架构文档(12 章,含 ADR、数据库设计、API 协议) -- [[Smart Support/Development Plan]] - 详细开发计划(6 Phase,任务清单 + 检查点 + 风险) -- [[Smart Support/Phase 1 Dev Log]] - Phase 1 开发日志(88% 覆盖率,82 个单元测试) +- [[Smart Support/Architecture]] -- 系统架构文档(12 章,含 ADR、数据库设计、API 协议) +- [[Smart Support/Development Plan]] -- 详细开发计划(5 Phase,任务清单 + 检查点 + 风险) +- [[Smart Support/Phase 1 Dev Log]] -- Phase 1 开发日志(88% 覆盖率,82 个单元测试) +- [[Smart Support/Phase 2 Dev Log]] -- Phase 2 开发日志(90% 覆盖率,153 个测试) +- [[Smart Support/Phase 3 Dev Log]] -- Phase 3 开发日志(93% 覆盖率,322 个测试) +- [[Smart Support/Phase 4 Dev Log]] -- Phase 4 开发日志(93% 覆盖率,399 个测试) +- [[Smart Support/Phase 5 Dev Log]] -- Phase 5 开发日志(93% 覆盖率,449 个测试) + +## 项目模块结构 + +``` +backend/app/ + main.py -- FastAPI 入口 (v0.5.0) + config.py -- Pydantic Settings + db.py -- AsyncPostgreSQL + AsyncPostgresSaver + llm.py -- LLM 提供商工厂(Anthropic/OpenAI/Google) + graph.py -- LangGraph Supervisor 构建 + ws_handler.py -- WebSocket 消息分发 + 流式 + 速率限制 + registry.py -- YAML Agent 注册表 + 模板支持 + intent.py -- LLM 意图分类器 + session_manager.py -- Session TTL(30m 滑动窗口) + interrupt_manager.py -- 中断 TTL 追踪 + 自动取消 + escalation.py -- Webhook 升级(指数退避) + conversation_tracker.py -- 对话生命周期追踪 + callbacks.py -- Token 用量回调 + agents/ -- Agent 定义(order_lookup, order_actions, discount, fallback) + openapi/ -- OpenAPI 解析 + 分类 + 生成(ssrf, fetcher, parser, classifier, generator) + replay/ -- 回放模型 + 转换器 + API + analytics/ -- 分析模型 + 事件记录 + 查询 + API + tools/ -- 错误处理(ErrorCategory, classify_error, with_retry) +``` ## 计划文档 项目根目录下: -- `design-doc.md` - 设计文档(问题定义、约束、方案选择) -- `ceo-plan.md` - CEO 计划(产品愿景、范围决策) -- `eng-review-plan.md` - 工程评审(架构决策、测试策略、失败模式) -- `eng-review-test-plan.md` - 测试计划(测试路径、边界情况、E2E 流程) -- `TODOS.md` - 待办事项 +- `design-doc.md` -- 设计文档(问题定义、约束、方案选择) +- `ceo-plan.md` -- CEO 计划(产品愿景、范围决策) +- `eng-review-plan.md` -- 工程评审(架构决策、测试策略、失败模式) +- `TODOS.md` -- 待办事项 -## 关键决策 +## 快速启动 -- 用 LangGraph 内置能力(supervisor、checkpointer、interrupt),不自己造轮子 -- PostgresSaver 从第一天起使用,为后期分析和回放打基础 -- OpenAPI 导入生成完整 MCP 服务器(非简单 @tool 函数),LLM 辅助端点分类 -- 路由错误时有 fallback agent 兜底 -- 解决率定义:成功工具调用 + 未升级 -- Token 用量从第一天起记录 +```bash +# 1. 克隆 + 配置 +git clone && cd smart-support +cp .env.example .env && cp backend/.env.example backend/.env +# 编辑 .env 设置 ANTHROPIC_API_KEY -## 待解决 +# 2. 启动 +docker compose up -d +# PostgreSQL: localhost:5433 | Backend: localhost:8000 | Frontend: localhost:80 + +# 3. 测试 +cd backend && pytest --cov=app --cov-report=term-missing +cd ../frontend && npm test +``` + +## 已知技术债务 - [ ] 认证/授权系统(生产部署前) - [ ] 多租户架构(第一个付费客户后) - [ ] CI/CD 流水线(原型阶段手动部署) -- [ ] 路由准确率评估数据集 -- [ ] 过期中断处理(Phase 2 实现) -- [ ] SSRF 防护模块(Phase 3 前构建) +- [ ] 速率限制进程全局状态 -- 多 Worker 需 Redis +- [ ] 中断清理未定时调度(cleanup_expired 存在但未触发) +- [ ] NoOpAnalyticsRecorder 已注册 -- PostgresAnalyticsRecorder 集成待完善 +- [ ] SaaS/Fintech 模板工具仅为桩(无实现) +- [ ] 工具生成基于字符串模板 -- 复杂场景可能需 AST ## Related -- [[Billo Release Agent]] - 另一个 AI Agent 项目 +- [[Billo Release Agent]] -- 另一个 AI Agent 项目 diff --git a/2 - Projects/Smart Support/Phase 1 - 核心框架.md b/2 - Projects/Smart Support/Phase 1 - 核心框架.md index 9d481ae..acfc6e4 100644 --- a/2 - Projects/Smart Support/Phase 1 - 核心框架.md +++ b/2 - Projects/Smart Support/Phase 1 - 核心框架.md @@ -1,5 +1,6 @@ --- created: 2026-03-29 +updated: 2026-04-06 type: project status: COMPLETED (2026-03-30) parent: "[[Smart Support]]" diff --git a/2 - Projects/Smart Support/Phase 2 - 多 Agent + 安全.md b/2 - Projects/Smart Support/Phase 2 - 多 Agent + 安全.md index d9b34c7..9236f2a 100644 --- a/2 - Projects/Smart Support/Phase 2 - 多 Agent + 安全.md +++ b/2 - Projects/Smart Support/Phase 2 - 多 Agent + 安全.md @@ -1,7 +1,8 @@ --- created: 2026-03-29 +updated: 2026-04-06 type: project -status: 未开始 +status: COMPLETED (2026-03-30) parent: "[[Smart Support]]" phase: 2 timeline: 第 3-4 周 @@ -20,161 +21,51 @@ tags: # Phase 2:多 Agent + 安全 +> Status: COMPLETED (2026-03-30) + ## 目标 -让 Supervisor 具备真正的多 Agent 路由能力,能根据用户意图选择正确的 Agent。同时完善安全机制:中断超时处理、Webhook 升级通知。这个阶段结束时,系统能处理多种类型的客服请求,并在无法解决时通过 Webhook 通知人工。 - -## 前置条件 - -- [[Smart Support/Phase 1 - 核心框架]] 完成 -- 核心聊天闭环端到端可用 -- PostgresSaver + interrupt() 基础流程工作正常 +让 Supervisor 具备真正的多 Agent 路由能力,能根据用户意图选择正确的 Agent。同时完善安全机制:中断超时处理、Webhook 升级通知。 ## 阶段产出 -- Supervisor 能准确路由不同类型的请求到对应 Agent -- 多意图请求(「取消订单并给我折扣」)能被拆分并按序处理 -- 无法解决的问题通过 Webhook 通知人工客服 -- 过期中断自动取消并提供重试选项 -- 2-3 个垂直行业模板开箱可用 +- Intent 分类器:LLM 结构化输出,支持单意图/多意图/模糊检测 +- Discount Agent:apply_discount(write + interrupt)+ generate_coupon(read) +- 中断管理器:30 分钟 TTL 自动过期,register/check/resolve/cleanup +- Webhook 升级:HTTP POST + 指数退避重试(最多 3 次) +- 增强 Supervisor 路由:动态 Agent 描述、多意图提示注入 +- 垂直行业模板:电商、SaaS、金融科技 +- 模板加载:load_template() / list_templates() -## 集成检查点 +## 新增文件 -第 4 周末验证: -1. 发送订单查询 → 路由到 order_lookup agent -2. 发送「取消订单并退款」→ 按序处理两个操作 -3. 发送无法处理的请求 → Webhook POST 发出 -4. 触发确认 → 30 分钟不操作 → 自动取消 → 重新发消息收到重试提示 -5. 加载电商模板 YAML → 相关 agents 自动注册 +| 文件 | 用途 | +|------|------| +| `app/intent.py` | 意图分类模型 + LLM 分类器 | +| `app/agents/discount.py` | 折扣 Agent 工具 | +| `app/interrupt_manager.py` | 中断 TTL 管理 | +| `app/escalation.py` | Webhook 升级 + 重试 | +| `templates/e-commerce.yaml` | 电商模板 | +| `templates/saas.yaml` | SaaS 模板 | +| `templates/fintech.yaml` | 金融科技模板 | ---- +## 测试覆盖 -## 任务清单 +- 总测试:153(Phase 1: 87 + Phase 2: 66) +- 覆盖率:90.18% +- 新模块覆盖:intent 100%, discount 96%, interrupt_manager 100%, escalation 100% -### 1. 完善 Supervisor 路由 +## 与计划的偏差 -- [ ] 优化 supervisor 的 agent 描述,使路由更准确 -- [ ] 多意图处理:supervisor 识别复合请求,拆分为多个子任务,按序执行 - - 例如「取消订单 1042 并给我一个 10% 折扣码」→ 先路由到 order_actions(取消),再路由到 discount(发码) -- [ ] 模糊/冲突意图处理:supervisor 无法判断时,返回澄清问题(「您是想查询订单还是取消订单?」) -- [ ] 路由失败日志:每次路由记录 `{intent, selected_agent, confidence}`,为后续评估提供数据 +- 多意图处理用 Supervisor 提示注入而非自定义预路由节点(更简单) +- Webhook 升级已接入 app.state 但未连接到具体 Agent 工具(模块就绪,集成推迟) +- `escalate_to_human` 工具未创建(升级模块可独立触发) -### 2. 过期中断处理 +## 技术债务 -- [ ] 中断触发时记录 `interrupt_timestamp` 到 graph state -- [ ] 用户恢复对话时检查:`current_time - interrupt_timestamp > 30 min` -- [ ] 超时行为: - 1. 将该操作标记为已取消(不执行) - 2. 返回消息:「您之前请求的[操作描述]已因超时取消。订单状态可能已变化,需要我重新查看吗?」 - 3. Agent 重新评估当前状态(重新调用查询工具),而不是直接重试旧操作 -- [ ] 未超时:正常恢复 interrupt 流程(approve/reject) - -### 3. Webhook 升级通知 - -- [ ] 配置项:`webhook_url`(在 agents.yaml 或环境变量中配置) -- [ ] 触发条件: - - Agent 明确表示无法处理(返回 escalation 标记) - - Supervisor 连续 3 次路由失败(用户重复同一问题) - - 用户主动请求人工客服 -- [ ] Webhook payload 格式: - -```json -{ - "event": "escalation", - "thread_id": "uuid", - "timestamp": "2026-04-10T14:30:00Z", - "reason": "agent_unable_to_resolve", - "conversation_summary": "客户询问关于批量退货的问题,order_lookup agent 无法找到相关功能", - "messages": [ - {"role": "user", "content": "..."}, - {"role": "assistant", "content": "..."} - ], - "customer_context": { - "resolved_entities": {"order_id": "1042"} - } -} -``` - -- [ ] HTTP POST 发送,设置 10 秒 timeout -- [ ] 失败重试:最多 3 次,指数退避(1s, 2s, 4s) -- [ ] 重试全部失败 → 记录日志(ERROR 级别),不阻塞聊天流程 -- [ ] 在聊天 UI 中通知用户:「已通知人工客服,他们会尽快联系您」 - -### 4. 垂直行业模板 - -- [ ] 创建模板目录 `backend/templates/` -- [ ] 电商模板 `ecommerce.yaml`: - -```yaml -name: ecommerce -description: 电商客服模板 - 订单管理、物流查询、退换货 -agents: - - name: order_lookup - description: 查询订单状态、物流跟踪、收货确认 - permission: read - personality: - tone: professional - greeting: "您好!我可以帮您查询订单相关信息。" - tools: [get_order, get_tracking, list_orders] - - - name: order_actions - description: 取消订单、修改地址、申请退换货 - permission: write - personality: - tone: careful - greeting: "我可以帮您处理订单变更,所有操作都会先确认。" - tools: [cancel_order, modify_address, request_return] - - - name: promotions - description: 查询优惠活动、发放折扣码 - permission: write - personality: - tone: enthusiastic - tools: [apply_discount, check_promotions] -``` - -- [ ] SaaS 模板 `saas.yaml`:账号管理、订阅变更、功能咨询 -- [ ] 金融科技模板 `fintech.yaml`:账户查询、交易记录、转账操作 -- [ ] 模板加载机制:启动时指定 `--template ecommerce` 或在配置中设置 `template: ecommerce` -- [ ] 模板与自定义 agents.yaml 合并:模板提供默认值,自定义配置覆盖 - -### 5. 新增演示 Agent - -在 Phase 1 的基础上增加写操作 Agent: - -- [ ] `order_actions` agent:取消订单(`cancel_order`)、修改地址(`modify_address`) -- [ ] `discount` agent:发放优惠券(`apply_discount`)、生成折扣码(`generate_coupon`) -- [ ] 所有写操作工具标记 `permission: write` → 自动触发 interrupt - -### 6. 测试 - -- [ ] **路由测试:** 「查询订单」→ order_lookup,「取消订单」→ order_actions,「给我折扣」→ discount -- [ ] **路由测试:** 模糊请求 → 返回澄清问题 -- [ ] **多意图测试:** 「取消订单并退款」→ 按序执行两个操作 -- [ ] **超时测试:** interrupt 后 mock 时间超过 30 分钟 → 自动取消 + 重试提示 -- [ ] **超时测试:** interrupt 后 mock 时间未超过 30 分钟 → 正常 approve/reject -- [ ] **Webhook 测试:** 升级触发 → HTTP POST 发出,payload 格式正确 -- [ ] **Webhook 测试:** 目标 URL 不可达 → 重试 3 次 → 记录日志 → 聊天不中断 -- [ ] **模板测试:** 加载电商模板 → agents 正确注册 -- [ ] **模板测试:** 自定义配置覆盖模板默认值 -- [ ] **E2E 测试:** 完整升级流程(无法处理 → webhook 发出 → 用户收到通知) - -## 技术要点 - -| 功能 | 实现方式 | -|------|---------| -| 多意图拆分 | Supervisor LLM 识别并按序调度 | -| 超时检测 | graph state 记录 timestamp,resume 时比较 | -| Webhook | httpx.AsyncClient POST,asyncio 重试 | -| 模板加载 | PyYAML 加载 + 与自定义 YAML 深度合并 | - -## 风险与缓解 - -| 风险 | 影响 | 缓解措施 | -|------|------|---------| -| 多意图拆分不准确 | 操作顺序错误或遗漏 | 先处理常见组合,复杂情况要求用户分步操作 | -| Webhook 目标服务不稳定 | 升级通知丢失 | 重试 + 日志 + 聊天内告知用户 | -| 超时时间 30 分钟不合适 | 过早或过晚取消 | 配置化,允许每个 agent 自定义 TTL | +- SaaS/Fintech 模板工具名称无实现(配置蓝图) +- 中断清理未定时调度 +- main.py 覆盖率 44%(需真实 DB) ## Related diff --git a/2 - Projects/Smart Support/Phase 2 Dev Log.md b/2 - Projects/Smart Support/Phase 2 Dev Log.md new file mode 100644 index 0000000..f1c0edd --- /dev/null +++ b/2 - Projects/Smart Support/Phase 2 Dev Log.md @@ -0,0 +1,43 @@ +--- +created: 2026-04-06 +type: log +project: "[[Smart Support]]" +source: docs/phases/phase-2-dev-log.md +tags: + - dev-log + - phase-2 + - intent-classification + - discount-agent + - interrupt-ttl + - webhook-escalation + - templates +--- + +# Phase 2: Multi-Agent Routing + Safety -- Development Log + +> Status: COMPLETED +> Phase branch: `phase-2/multi-agent-safety` +> Date started: 2026-03-30 +> Date completed: 2026-03-30 + +## What Was Built + +- **Intent Classification** (`app/intent.py`): LLM 结构化输出意图分类器,Pydantic 模型(IntentTarget, ClassificationResult)。支持单意图、多意图、模糊检测,可配置置信度阈值。 +- **Discount Agent** (`app/agents/discount.py`): Mock Agent,apply_discount(write + interrupt)和 generate_coupon(read)。验证折扣范围 1-100%。 +- **Interrupt Manager** (`app/interrupt_manager.py`): TTL 中断追踪,30 分钟自动过期。提供 register, check_status, resolve, cleanup_expired, generate_retry_prompt。 +- **Webhook Escalation** (`app/escalation.py`): HTTP POST 升级,指数退避重试(最多 3 次)。WebhookEscalator + NoOpEscalator,EscalationService Protocol。 +- **Enhanced Supervisor** (`app/graph.py`): 动态 Agent 描述 Supervisor 提示。意图分类器附加到 graph。多意图提示注入。 +- **Vertical Templates**: 三个行业 YAML 模板(电商、SaaS、金融科技)。 +- **Template Loading** (`app/registry.py`): load_template() 和 list_templates()。 +- **WebSocket Integration**: 模糊意图发送澄清消息。中断 TTL 检查 -- 过期中断返回重试提示。 + +## Test Coverage + +- Total: 153 tests (Phase 1: 87 + Phase 2: 66) +- Coverage: 90.18% +- intent.py: 100% | discount.py: 96% | interrupt_manager.py: 100% | escalation.py: 100% + +## Related + +- [[Smart Support]] +- [[Smart Support/Phase 2 - 多 Agent + 安全]] diff --git a/2 - Projects/Smart Support/Phase 3 - OpenAPI 自动发现.md b/2 - Projects/Smart Support/Phase 3 - OpenAPI 自动发现.md index e4f0d96..6114d8f 100644 --- a/2 - Projects/Smart Support/Phase 3 - OpenAPI 自动发现.md +++ b/2 - Projects/Smart Support/Phase 3 - OpenAPI 自动发现.md @@ -1,7 +1,8 @@ --- created: 2026-03-29 +updated: 2026-04-06 type: project -status: 未开始 +status: COMPLETED (2026-03-30) parent: "[[Smart Support]]" phase: 3 timeline: 第 4-6 周 @@ -19,177 +20,59 @@ tags: # Phase 3:OpenAPI 自动发现 +> Status: COMPLETED (2026-03-30) + ## 目标 -实现 Smart Support 的「10x 差异化功能」:用户粘贴 OpenAPI 规范 URL,系统自动生成 MCP 服务器和 Agent 配置。这个阶段结束时,用户无需写代码,只需提供 API 文档就能让 AI Agent 操作他们的系统。 - -## 前置条件 - -- [[Smart Support/Phase 2 - 多 Agent + 安全]] 完成 -- 多 Agent 路由 + interrupt 流程工作正常 -- YAML agent 注册表可以动态加载新 agent +实现 Smart Support 的「10x 差异化功能」:用户粘贴 OpenAPI 规范 URL,系统自动生成 @tool 函数和 Agent 配置。 ## 阶段产出 -- 粘贴 OpenAPI spec URL → 自动解析 + 生成 MCP 服务器 + 注册 Agent -- LLM 自动分类端点(读/写、客户参数、Agent 分组) -- 运维审核界面确认/修正 LLM 分类结果 -- SSRF 防护保障 URL 获取安全 -- 导入过程异步执行,WebSocket 实时推送进度 +- SSRF 防护模块:私有 IP 拦截、DNS 重绑定防御、重定向链验证 +- OpenAPI 获取器:SSRF 安全、JSON/YAML 自动检测、10MB 大小限制 +- 结构化 OpenAPI 验证器:3.0.x 和 3.1.x +- 端点解析器:$ref 解析、参数提取、自动生成 operationId +- 启发式 + LLM 端点分类器:GET=read, POST/PUT/PATCH/DELETE=write,LLM 失败回退启发式 +- 审核 API(/api/openapi):导入任务、分类审核、批准生成 +- @tool 代码生成器:async 函数 + httpx +- Agent YAML 生成器:按分类分组端点 +- 导入编排器:fetch -> validate -> parse -> classify 全流程 +- 内存任务存储:导入状态追踪 -## 集成检查点 +## 新增文件 -第 6 周末验证: -1. 粘贴一个真实的 OpenAPI 3.0 spec URL → 解析成功 -2. 生成的 MCP 服务器正确包装每个端点 -3. LLM 分类结果合理(GET = read,DELETE = write) -4. 运维审核后,agent 自动注册到 supervisor -5. 在聊天中使用新生成的工具完成操作 -6. SSRF 攻击被拦截(私有 IP、localhost) +| 文件 | 用途 | 行数 | +|------|------|------| +| `app/openapi/models.py` | 冻结数据类:EndpointInfo, ClassificationResult, ImportJob | 68 | +| `app/openapi/ssrf.py` | SSRF 防护(validate_url, safe_fetch, DNS 解析) | 162 | +| `app/openapi/fetcher.py` | SSRF 安全规范获取 | 94 | +| `app/openapi/validator.py` | 结构化规范验证 | 52 | +| `app/openapi/parser.py` | 端点提取 + $ref 解析 | 153 | +| `app/openapi/classifier.py` | 启发式 + LLM 分类器 | 164 | +| `app/openapi/review_api.py` | 导入/审核 API 路由 | 180 | +| `app/openapi/generator.py` | @tool 代码 + YAML 生成 | 157 | +| `app/openapi/importer.py` | 异步导入流水线 | 117 | ---- +## 测试覆盖 -## 任务清单 +- 新增测试:125 个(118 单元 + 7 集成) +- 总测试:322 +- 覆盖率:93.23% +- SSRF 测试最多:42 个 -### 1. SSRF 防护模块 +## 与计划的偏差 -> 独立模块 `backend/app/openapi/ssrf.py`,可与 Phase 1-2 并行开发 +- 未构建自定义工具基类(架构文档明确禁止) +- 使用轻量级结构化验证器而非包装外部库 +- 内存任务存储而非数据库(可后续迁移 PostgreSQL) +- 前端审核 UI 推迟到 Phase 5 -- [ ] URL 解析:提取 host,解析 DNS 获取 IP -- [ ] 屏蔽私有 IP 范围: - - `10.0.0.0/8` - - `172.16.0.0/12` - - `192.168.0.0/16` - - `127.0.0.0/8`(localhost) - - `169.254.0.0/16`(link-local,云元数据端点) - - `0.0.0.0/8` - - `::1`(IPv6 localhost) -- [ ] DNS 重绑定防护:解析 DNS → 检查 IP → 使用解析后的 IP 发起请求(不让 DNS 在检查和请求之间变化) -- [ ] URL 协议限制:仅允许 `http://` 和 `https://`,拒绝 `file://`, `ftp://`, `gopher://` 等 -- [ ] 可选 URL 白名单:通过配置限制只允许特定域名 -- [ ] 单元测试覆盖所有拦截场景 +## 技术债务 -### 2. OpenAPI 规范解析器 - -- [ ] 支持 OpenAPI 3.0+ 规范(JSON 和 YAML 格式) -- [ ] 使用 `openapi-spec-validator` 验证规范合法性 -- [ ] 通过 SSRF 安全模块获取远程 URL 内容 -- [ ] 解析每个端点提取: - - HTTP 方法 + 路径 - - 描述 / summary - - 请求参数(path params, query params, request body schema) - - 响应 schema - - 认证要求(API key, Bearer token, OAuth) -- [ ] 错误处理: - - 无效 URL → 「无法访问该地址,请检查 URL 是否正确」 - - 无效规范格式 → 「该文件不是有效的 OpenAPI 3.0 规范:[具体原因]」 - - 认证要求无法自动满足 → 提示用户提供 API key -- [ ] OpenAPI 2.0 (Swagger) → 返回明确提示:「检测到 Swagger 2.0 格式,请升级到 OpenAPI 3.0」 -- [ ] 大型规范(100+ 端点)→ 正常处理,不超时 - -### 3. MCP 服务器生成器 - -- [ ] 为每个解析到的端点生成 MCP tool 定义 -- [ ] Tool 名称:从路径 + 方法自动生成(如 `GET /orders/{id}` → `get_order_by_id`) -- [ ] Tool 描述:使用端点的 summary/description -- [ ] Tool 参数:从 path params + query params + request body 提取,保留类型信息 -- [ ] 生成可运行的 MCP 服务器代码(Python,使用 `mcp` SDK) -- [ ] 处理复杂 request body(嵌套对象、数组)→ 扁平化或保留 JSON 结构 -- [ ] 认证注入:生成的服务器支持在配置中设置 API key / Bearer token,自动添加到请求 header - -### 4. LLM 辅助端点分类 - -- [ ] 将解析后的端点信息(方法、路径、描述)发送给 LLM -- [ ] LLM 分类任务: - 1. **读/写分类**:每个端点标记为 `read`(不触发 interrupt)或 `write`(触发 interrupt) - 2. **客户参数识别**:哪些参数代表客户标识(customer_id, email, phone) - 3. **Agent 分组建议**:将端点按功能分组为不同 Agent(如「订单管理」「用户管理」「支付操作」) -- [ ] 分类提示模板: - -``` -你是一个 API 安全分析师。分析以下 API 端点列表,为每个端点提供: -1. 操作类型:read(查询/获取数据)或 write(创建/修改/删除数据) -2. 客户参数:哪些参数代表客户身份标识 -3. 建议的 Agent 分组名称 - -规则: -- GET 请求通常是 read,但要看描述(如 GET /export 可能是 write) -- POST/PUT/PATCH/DELETE 通常是 write -- 涉及金钱、订单状态变更、账号操作的必须标记为 write -``` - -- [ ] 分类结果缓存:同一规范不重复分类 -- [ ] 成本控制:使用 prompt caching 减少重复输入成本 - -### 5. 运维审核/修正 UI - -- [ ] API 端点:`GET /api/openapi/review/{import_id}` → 返回 LLM 分类结果 -- [ ] API 端点:`POST /api/openapi/review/{import_id}` → 提交修正后的分类 -- [ ] 前端审核界面: - - 端点列表,每行显示:方法、路径、描述、LLM 分类(read/write)、Agent 分组 - - 每个分类可以点击修改(下拉选择) - - 「全部确认」按钮 → 生成最终 MCP 服务器 + Agent YAML -- [ ] 修正后重新生成不需要再次调用 LLM - -### 6. Agent YAML 自动生成 - -- [ ] 根据 LLM 分类 + 运维修正结果,生成 Agent YAML 配置 -- [ ] 每个 Agent 分组 → 一个 agent 条目 -- [ ] permission 根据分组内端点的最高权限决定(有一个 write 端点就标记为 write) -- [ ] 自动生成 agent description(基于分组内端点的描述汇总) -- [ ] 生成的 YAML 合并到 agent 注册表,热加载到 supervisor(不需要重启) - -### 7. 异步导入 + 进度更新 - -- [ ] 导入流程作为后台任务执行(`asyncio.create_task`) -- [ ] 通过 WebSocket 推送进度更新: - -```json -{"type": "import_progress", "step": "parsing", "message": "正在解析 OpenAPI 规范..."} -{"type": "import_progress", "step": "classifying", "message": "正在分析端点 12/50..."} -{"type": "import_progress", "step": "generating", "message": "正在生成 MCP 服务器..."} -{"type": "import_progress", "step": "review", "message": "分析完成,请审核分类结果", "review_url": "/review/abc123"} -{"type": "import_progress", "step": "done", "message": "导入完成!新增 3 个 Agent,15 个工具"} -``` - -- [ ] 导入期间聊天功能不受影响 -- [ ] 导入失败 → 推送错误消息 + 错误详情 - -### 8. 测试 - -- [ ] **SSRF 测试:** 私有 IP (10.x, 172.16.x, 192.168.x) → 拦截 -- [ ] **SSRF 测试:** localhost / 127.0.0.1 → 拦截 -- [ ] **SSRF 测试:** 169.254.169.254(云元数据)→ 拦截 -- [ ] **SSRF 测试:** 合法公网 URL → 放行 -- [ ] **SSRF 测试:** file:// 协议 → 拦截 -- [ ] **解析测试:** 有效 OpenAPI 3.0 JSON → 正确解析端点 -- [ ] **解析测试:** 有效 OpenAPI 3.0 YAML → 正确解析端点 -- [ ] **解析测试:** 无效规范 → 明确错误信息 -- [ ] **解析测试:** 大型规范(100+ 端点)→ 不超时 -- [ ] **生成测试:** 端点 → MCP tool 定义(名称、参数、描述匹配) -- [ ] **分类测试:** mock LLM 响应 → 正确解析分类结果 -- [ ] **分类测试:** GET 端点 → 默认 read,DELETE 端点 → 默认 write -- [ ] **集成测试:** 完整流程:URL → 解析 → 分类 → 生成 → 注册 -- [ ] **E2E 测试:** 粘贴 spec URL → 进度更新 → 审核 → 新工具在聊天中可用 - -## 技术要点 - -| 功能 | 技术选型 | 说明 | -|------|---------|------| -| 规范验证 | openapi-spec-validator | PyPI 包,支持 3.0+ | -| URL 获取 | httpx + SSRF 模块 | 异步 HTTP,IP 检查 | -| MCP 生成 | mcp SDK (Python) | 生成 stdio MCP 服务器 | -| LLM 分类 | ChatAnthropic structured output | JSON mode 确保输出格式 | -| 异步任务 | asyncio.create_task | FastAPI 内后台任务 | - -## 风险与缓解 - -| 风险 | 影响 | 缓解措施 | -|------|------|---------| -| LLM 分类不准确 | 读操作被标记为写(多余确认)或反之(危险) | 运维审核 UI 作为安全网,默认偏向标记为 write | -| 复杂 request body 无法处理 | 部分端点工具不可用 | 跳过无法处理的端点,在审核 UI 中标注 | -| DNS 重绑定绕过 SSRF | 安全漏洞 | 解析后绑定 IP 发请求,不二次解析 | -| 大规范生成慢 | 用户等待久 | 异步 + 进度条,分批生成 | +- 前端 ReviewPage 推迟(API 就绪) +- 代码生成基于字符串模板 +- LLM 分类提示可用真实案例调优 +- 审核 API 无速率限制 ## Related diff --git a/2 - Projects/Smart Support/Phase 3 Dev Log.md b/2 - Projects/Smart Support/Phase 3 Dev Log.md new file mode 100644 index 0000000..656fd34 --- /dev/null +++ b/2 - Projects/Smart Support/Phase 3 Dev Log.md @@ -0,0 +1,42 @@ +--- +created: 2026-04-06 +type: log +project: "[[Smart Support]]" +source: docs/phases/phase-3-dev-log.md +tags: + - dev-log + - phase-3 + - openapi + - ssrf + - code-generation + - llm-classification +--- + +# Phase 3: OpenAPI Auto-Discovery -- Development Log + +> Status: COMPLETED +> Phase branch: `phase-3/openapi-discovery` +> Date started: 2026-03-30 +> Date completed: 2026-03-30 + +## What Was Built + +- **SSRF 防护** (`openapi/ssrf.py`): 私有 IP 拦截、DNS 重绑定防御、重定向链验证。162 行,42 个测试。 +- **规范获取** (`openapi/fetcher.py`): SSRF 安全获取,JSON/YAML 自动检测,10MB 限制。 +- **规范验证** (`openapi/validator.py`): 结构化 OpenAPI 3.0.x/3.1.x 验证。 +- **端点解析** (`openapi/parser.py`): $ref 解析、参数提取、自动 operationId。 +- **端点分类** (`openapi/classifier.py`): 启发式(GET=read)+ LLM 分类器 + Protocol 接口。失败回退启发式。 +- **审核 API** (`openapi/review_api.py`): 导入任务管理、分类审核、批准生成。180 行。 +- **代码生成** (`openapi/generator.py`): @tool 装饰 async 函数 + httpx。157 行。 +- **导入编排** (`openapi/importer.py`): fetch -> validate -> parse -> classify 全流程。 + +## Test Coverage + +- New: 125 tests (118 unit + 7 integration) +- Total: 322 tests +- Coverage: 93.23% + +## Related + +- [[Smart Support]] +- [[Smart Support/Phase 3 - OpenAPI 自动发现]] diff --git a/2 - Projects/Smart Support/Phase 4 - 分析 + 回放.md b/2 - Projects/Smart Support/Phase 4 - 分析 + 回放.md index 095b9c9..4086507 100644 --- a/2 - Projects/Smart Support/Phase 4 - 分析 + 回放.md +++ b/2 - Projects/Smart Support/Phase 4 - 分析 + 回放.md @@ -1,7 +1,8 @@ --- created: 2026-03-29 +updated: 2026-04-06 type: project -status: 未开始 +status: COMPLETED (2026-03-31) parent: "[[Smart Support]]" phase: 4 timeline: 第 6-7 周 @@ -19,243 +20,57 @@ tags: # Phase 4:分析 + 回放 +> Status: COMPLETED (2026-03-31) + ## 目标 -让客户看到 AI 客服的 ROI。对话回放让客户信任系统(看到 AI 为什么做了某个决定),分析仪表盘用数据证明价值(自动解决了多少问题、省了多少成本)。这个阶段结束时,Smart Support 是一个完整可演示的产品。 - -## 前置条件 - -- [[Smart Support/Phase 1 - 核心框架]] 完成(PostgresSaver 已持久化所有 checkpoint 数据) -- [[Smart Support/Phase 3 - OpenAPI 自动发现]] 完成(有真实工具调用数据可分析) -- Token 用量统计回调已运行(Phase 1 实现) +让客户看到 AI 客服的 ROI。对话回放让客户信任系统,分析仪表盘用数据证明价值。 ## 阶段产出 -- 对话回放页面:逐步展示 Agent 的决策过程 -- 分析仪表盘:解决率、Agent 使用率、升级率、每对话成本 -- 数据驱动的 ROI 证明能力 +- 回放数据模型:StepType 枚举、ReplayStep、ReplayPage(冻结数据类) +- 检查点转换器:PostgresSaver JSONB -> 结构化 ReplayStep 时间线 +- 回放 API:GET /api/conversations(分页列表)、GET /api/replay/{thread_id}(分页时间线) +- 分析数据模型:AgentUsage、InterruptStats、AnalyticsResult +- 分析事件记录器:Protocol 接口 + PostgresAnalyticsRecorder + NoOpAnalyticsRecorder +- 分析查询:resolution_rate、agent_usage、escalation_rate、cost_per_conversation、interrupt_stats +- 分析 API:GET /api/analytics?range=Xd +- DB 迁移:analytics_events 表 + conversations 列扩展 -## 集成检查点 +## 新增文件 -第 7 周末验证: -1. 完成几轮对话后,打开回放页面 → 看到完整决策时间线 -2. 分析仪表盘显示正确的解决率和成本数据 -3. 零数据状态(新部署)→ 仪表盘显示空状态引导 -4. 200+ 轮对话的回放 → 分页正常,不卡顿 +| 文件 | 用途 | +|------|------| +| `app/replay/models.py` | StepType, ReplayStep, ReplayPage | +| `app/replay/transformer.py` | Checkpoint JSONB -> ReplayStep[] | +| `app/replay/api.py` | 回放 + 对话列表 API | +| `app/analytics/models.py` | AgentUsage, InterruptStats, AnalyticsResult | +| `app/analytics/event_recorder.py` | 记录器 Protocol + 实现 | +| `app/analytics/queries.py` | SQL 查询 + get_analytics 聚合 | +| `app/analytics/api.py` | 分析 API 路由 | ---- +## 分析指标 -## 任务清单 +| 指标 | 计算方式 | +|------|---------| +| 解决率 | 成功工具调用 + 未升级 / 总对话数 | +| Agent 使用率 | 每 Agent 路由次数占比 | +| 升级率 | 触发 Webhook 对话占比 | +| 每对话成本 | Token 用量 x 价格 | +| 中断统计 | approved/rejected/expired 分布 | -### 1. 对话回放 API +## 测试覆盖 -- [ ] 端点 `GET /api/conversations` → 对话列表(分页) - - 返回:`thread_id`, 开始时间, 消息数, 最终状态(resolved/escalated/abandoned) - - 支持筛选:按状态、按日期范围、按 agent - - 分页参数:`page`, `page_size`(默认 20) +- 新增测试:74 个 +- 总测试:399 +- 覆盖率:92.87% +- 所有新模块覆盖率 81-100% -- [ ] 端点 `GET /api/replay/{thread_id}` → 单个对话的回放数据(分页) - - 查询 PostgresSaver checkpoint 表,按 checkpoint_id 排序 - - 每个 checkpoint 解析为结构化时间线事件: +## 与计划的偏差 -```json -{ - "thread_id": "uuid", - "total_steps": 15, - "page": 1, - "page_size": 50, - "events": [ - { - "step": 1, - "timestamp": "2026-04-10T14:30:00Z", - "type": "user_message", - "content": "查询订单 1042 的状态" - }, - { - "step": 2, - "timestamp": "2026-04-10T14:30:01Z", - "type": "routing", - "agent": "order_lookup", - "reasoning": "用户请求查询订单状态" - }, - { - "step": 3, - "timestamp": "2026-04-10T14:30:02Z", - "type": "tool_call", - "agent": "order_lookup", - "tool": "get_order_status", - "input": {"order_id": "1042"}, - "output": {"status": "shipped", "tracking": "SF1234567"}, - "duration_ms": 230 - }, - { - "step": 4, - "timestamp": "2026-04-10T14:30:03Z", - "type": "agent_response", - "agent": "order_lookup", - "content": "您的订单 1042 已发货,运单号 SF1234567", - "tokens": {"input": 450, "output": 35} - } - ] -} -``` - - - 分页:`page` + `page_size` 控制每页 events 数量 - - thread 不存在 → 404 - -- [ ] 端点 `GET /api/replay/{thread_id}/summary` → 对话摘要 - - 总步骤数、涉及的 agents、工具调用次数、总 token 用量、总耗时、最终状态 - -### 2. 对话回放 UI - -- [ ] 对话列表页: - - 表格显示所有对话(时间、消息数、状态、涉及 agent) - - 状态标签:🟢 已解决 / 🟡 已升级 / ⚫ 已放弃 - - 点击进入回放详情 - -- [ ] 回放详情页: - - 左侧:原始聊天记录(用户消息 + AI 回复) - - 右侧:决策时间线(路由决策、工具调用、参数、返回值、耗时) - - 时间线高亮: - - 工具调用 → 蓝色 - - interrupt 确认 → 黄色 - - 错误/升级 → 红色 - - 每个步骤可展开查看详细信息(工具输入输出、token 用量) - - 支持键盘导航(上/下箭头逐步浏览) - -- [ ] 长对话分页加载(滚动加载或分页按钮) - -### 3. 分析数据查询 - -- [ ] 数据来源:PostgresSaver checkpoint 表 + token 用量表 -- [ ] 核心指标计算: - -**解决率** -```sql --- resolved = 至少一次成功工具调用 且 未触发升级 -resolved_count / total_conversations * 100 -``` - -**Agent 使用率** -```sql --- 每个 agent 被路由到的次数占总路由次数的百分比 -SELECT agent_name, COUNT(*) * 100.0 / total_routes AS usage_pct -``` - -**升级率** -```sql --- 触发 webhook 升级的对话占总对话的百分比 -escalated_count / total_conversations * 100 -``` - -**每对话成本** -```sql --- 基于 token 用量计算 -SELECT thread_id, - SUM(input_tokens) * input_price + SUM(output_tokens) * output_price AS cost -``` - -**对话量趋势** -```sql --- 按天/周/月聚合对话数量 -SELECT DATE(created_at) AS date, COUNT(DISTINCT thread_id) AS conversations -GROUP BY date ORDER BY date -``` - -- [ ] 时间范围筛选:今天 / 7 天 / 30 天 / 自定义 -- [ ] 所有查询加索引优化(checkpoint 表的 thread_id + timestamp) - -### 4. 分析仪表盘 API - -- [ ] 端点 `GET /api/analytics/overview` → 概览数据 - -```json -{ - "period": "last_7_days", - "total_conversations": 142, - "resolution_rate": 73.2, - "escalation_rate": 12.7, - "avg_cost_per_conversation": 0.045, - "total_cost": 6.39, - "avg_messages_per_conversation": 4.2, - "avg_resolution_time_seconds": 45 -} -``` - -- [ ] 端点 `GET /api/analytics/agents` → Agent 使用分布 - -```json -{ - "agents": [ - {"name": "order_lookup", "usage_pct": 45.3, "resolution_rate": 89.1}, - {"name": "order_actions", "usage_pct": 30.2, "resolution_rate": 72.5}, - {"name": "discount", "usage_pct": 15.8, "resolution_rate": 65.0}, - {"name": "fallback", "usage_pct": 8.7, "resolution_rate": 20.0} - ] -} -``` - -- [ ] 端点 `GET /api/analytics/trend` → 对话量趋势(按日) -- [ ] 端点 `GET /api/analytics/costs` → 成本趋势 + 按 agent 成本分布 -- [ ] 所有端点支持 `period` 参数(`today`, `7d`, `30d`, `custom`) - -### 5. 分析仪表盘 UI - -- [ ] 概览卡片(顶部): - - 解决率(百分比 + 趋势箭头) - - 总对话数 - - 升级率 - - 平均成本/对话 -- [ ] Agent 使用分布(饼图或条形图) -- [ ] 对话量趋势(折线图,按日) -- [ ] 成本趋势(折线图,按日) -- [ ] 零数据状态: - - 没有对话数据时,显示引导页面:「开始你的第一次对话,数据将在这里展示」 - - 卡片显示 "—" 而非 0 或 NaN - -### 6. 对话状态判定 - -- [ ] 实现对话最终状态判定逻辑: - - **resolved**:至少一次成功工具调用 + 未触发升级 webhook - - **escalated**:触发了升级 webhook - - **abandoned**:最后一条消息是用户发送的,且超过 30 分钟无后续(session TTL 过期) -- [ ] 状态写入 checkpoint metadata 或独立表 -- [ ] 状态判定在对话结束时(WebSocket 断开 或 TTL 过期)异步执行 - -### 7. 测试 - -- [ ] **回放 API 测试:** 有效 thread_id → 返回结构化时间线 -- [ ] **回放 API 测试:** 不存在的 thread_id → 404 -- [ ] **回放 API 测试:** 大对话(200+ 步骤)→ 分页正常 -- [ ] **回放 API 测试:** 时间线事件类型覆盖(user_message, routing, tool_call, agent_response, interrupt, error) -- [ ] **分析 API 测试:** overview 返回正确的解决率计算 -- [ ] **分析 API 测试:** agent 使用分布百分比之和 = 100% -- [ ] **分析 API 测试:** 成本计算准确(基于 token 用量 × 价格) -- [ ] **分析 API 测试:** 时间范围筛选正确 -- [ ] **零数据测试:** 无对话 → 所有指标返回合理默认值(非 NaN/null) -- [ ] **状态判定测试:** 成功工具调用 + 无升级 → resolved -- [ ] **状态判定测试:** 触发 webhook → escalated -- [ ] **状态判定测试:** 用户最后发言 + 超时 → abandoned -- [ ] **E2E 测试:** 完成对话 → 回放页面正确展示 → 仪表盘数据更新 - -## 技术要点 - -| 功能 | 实现方式 | 说明 | -|------|---------|------| -| 回放数据 | PostgresSaver checkpoint 表查询 | 按 thread_id + checkpoint_id 排序 | -| 分页 | OFFSET/LIMIT 或 cursor-based | 大数据量用 cursor | -| 图表 | Recharts 或 Chart.js | React 图表库 | -| 索引 | checkpoint 表加 thread_id + created_at 索引 | 保证查询性能 | -| 状态判定 | 异步任务 | WebSocket 断开或 TTL 到期时触发 | - -## 风险与缓解 - -| 风险 | 影响 | 缓解措施 | -|------|------|---------| -| Checkpoint 数据格式变化 | 回放解析失败 | 版本化 checkpoint 格式,解析失败降级显示原始数据 | -| 大量对话数据查询慢 | 仪表盘加载慢 | 加索引 + 预聚合热门查询(物化视图) | -| 解决率定义不准确 | 指标误导 | 可配置定义,后续加入客户满意度信号 | -| Token 价格变化 | 成本计算不准 | 价格配置化,支持不同模型不同价格 | +- 前端页面推迟到 Phase 5 +- ws_handler 事件记录推迟(注册 NoOpAnalyticsRecorder) +- conversations.agents_used 列未填充 ## Related diff --git a/2 - Projects/Smart Support/Phase 4 Dev Log.md b/2 - Projects/Smart Support/Phase 4 Dev Log.md new file mode 100644 index 0000000..9421246 --- /dev/null +++ b/2 - Projects/Smart Support/Phase 4 Dev Log.md @@ -0,0 +1,41 @@ +--- +created: 2026-04-06 +type: log +project: "[[Smart Support]]" +source: docs/phases/phase-4-dev-log.md +tags: + - dev-log + - phase-4 + - analytics + - replay + - postgresql +--- + +# Phase 4: Conversation Replay + Analytics -- Development Log + +> Status: COMPLETED +> Phase branch: `phase-4/analytics-replay` +> Date started: 2026-03-31 +> Date completed: 2026-03-31 + +## What Was Built + +- **回放模型**: StepType 枚举、ReplayStep、ReplayPage 冻结数据类。 +- **检查点转换器** (`replay/transformer.py`): PostgresSaver JSONB -> 结构化 ReplayStep 时间线。 +- **回放 API** (`replay/api.py`): GET /api/conversations(分页列表)、GET /api/replay/{thread_id}(分页时间线,默认 20 步)。 +- **分析模型**: AgentUsage、InterruptStats、AnalyticsResult。 +- **事件记录器** (`analytics/event_recorder.py`): AnalyticsRecorder Protocol + PostgresAnalyticsRecorder + NoOpAnalyticsRecorder。 +- **分析查询** (`analytics/queries.py`): resolution_rate, agent_usage, escalation_rate, cost_per_conversation, interrupt_stats。 +- **分析 API** (`analytics/api.py`): GET /api/analytics?range=Xd。 +- **DB 迁移**: analytics_events 表 + conversations 列扩展(resolution_type, agents_used, turn_count, ended_at)。 + +## Test Coverage + +- New: 74 tests +- Total: 399 tests +- Coverage: 92.87% + +## Related + +- [[Smart Support]] +- [[Smart Support/Phase 4 - 分析 + 回放]] diff --git a/2 - Projects/Smart Support/Phase 5 - 打磨 + 演示.md b/2 - Projects/Smart Support/Phase 5 - 打磨 + 演示.md index 15f13c7..339bbbe 100644 --- a/2 - Projects/Smart Support/Phase 5 - 打磨 + 演示.md +++ b/2 - Projects/Smart Support/Phase 5 - 打磨 + 演示.md @@ -1,7 +1,8 @@ --- created: 2026-03-29 +updated: 2026-04-06 type: project -status: 未开始 +status: COMPLETED (2026-03-31) parent: "[[Smart Support]]" phase: 5 timeline: 缓冲周 @@ -14,97 +15,78 @@ tags: - documentation - edge-cases - e2e-testing + - frontend + - rate-limiting --- # Phase 5:打磨 + 演示准备 +> Status: COMPLETED (2026-03-31) + ## 目标 -将 Smart Support 从「能跑」变成「能演示给客户看」。修复所有边界情况,准备演示数据和脚本,确保一键部署流程顺畅。这个阶段结束时,能录一个 90 秒的产品演示视频。 - -## 前置条件 - -- [[Smart Support/Phase 4 - 分析 + 回放]] 完成 -- 所有核心功能端到端可用 +将 Smart Support 从「能跑」变成「能演示给客户看」。修复所有边界情况,准备演示数据和脚本,确保一键部署流程顺畅。 ## 阶段产出 -- 错误处理覆盖所有已知边界情况 -- 演示脚本 + 真实感的示例数据 -- Docker Compose 全栈一键部署 -- 90 秒产品演示视频 +### 后端 ---- +- **对话追踪器** (`conversation_tracker.py`):Protocol + PostgresConversationTracker + NoOpConversationTracker,生命周期管理(ensure, record_turn, resolve) +- **错误处理** (`tools/error_handler.py`):ErrorCategory 枚举、classify_error()、with_retry() 指数退避(仅重试可重试错误) +- **WebSocket 加固** (`ws_handler.py`): + - analytics_recorder + conversation_tracker + pool 参数 + - _fire_and_forget_tracking 异步追踪 + - 速率限制(10 msg/10s per thread) + - 空白消息检查、JSON 数组拒绝、10000 字符限制 +- **健康检查**:GET /api/health +- **演示数据**:demo_data.py 种子脚本 + sample_openapi.yaml -## 任务清单 +### 前端(全部页面实现) -### 1. 错误处理加固 +- **API 客户端** (`api.ts`):fetchConversations, fetchReplay, fetchAnalytics 类型化封装 +- **导航** (`NavBar.tsx` + `Layout.tsx`):水平导航 + App Shell +- **错误提示** (`ErrorBanner.tsx`):断线状态 + 重连按钮 +- **分析组件** (`MetricCard.tsx`):可复用指标卡片 +- **回放组件** (`ReplayTimeline.tsx`):垂直时间线 + 可展开步骤详情 +- **页面**: + - `ChatPage.tsx` -- 聊天(集成 ErrorBanner) + - `ReplayListPage.tsx` -- 对话列表(分页) + - `ReplayPage.tsx` -- 回放时间线 + - `DashboardPage.tsx` -- 分析仪表盘(范围选择、零状态处理) + - `ReviewPage.tsx` -- OpenAPI 导入表单 + 任务轮询 + 可编辑分类表 -- [ ] 审查所有 API 端点,确保每个都有明确的错误响应 -- [ ] LLM API 超时 → 用户收到「AI 正在思考中,请稍候...」→ 15 秒后仍无响应 → 「抱歉,处理超时,请重试」 -- [ ] WebSocket 异常断开 → 前端自动重连(最多 3 次,间隔 1s/2s/4s)→ 重连失败 → 提示刷新页面 -- [ ] MCP 工具调用失败 → 「该操作暂时不可用,已通知技术团队」 -- [ ] 非预期错误 → 统一错误格式,不暴露堆栈信息 -- [ ] 所有错误记录详细日志(structlog / JSON 格式) +### 基础设施 -### 2. 演示数据 +- `frontend/Dockerfile` -- 多阶段构建(node:20-alpine -> nginx:alpine) +- `frontend/nginx.conf` -- SPA 路由 + WebSocket/API 代理 +- `docker-compose.yml` -- 新增 frontend 服务、健康检查、app_network +- `.env.example` -- Docker Compose 环境模板 -- [ ] 创建模拟电商数据集: - - 20 个订单(不同状态:待付款、已付款、已发货、已完成、已取消) - - 5 个客户(含姓名、邮箱、订单历史) - - 3 个优惠活动(满减、折扣码、新人券) - - 物流追踪信息(不同快递公司、不同状态) -- [ ] Mock 工具返回对应数据(根据 order_id 查表返回) -- [ ] 数据感觉真实(合理的金额、日期、商品名称) +### 文档 -### 3. 演示脚本 +- `docs/demo-script.md` -- 10 分钟演示脚本(5 个场景) +- `docs/agent-config-guide.md` -- agents.yaml 参考 +- `docs/openapi-import-guide.md` -- 导入工作流 + SSRF 防护 +- `docs/deployment.md` -- Docker Compose 部署 + 生产考虑 +- `README.md` -- 完整项目概述 + 快速启动 -- [ ] 编写演示对话脚本(覆盖核心功能): +## 测试覆盖 -**场景 1:订单查询(30 秒)** -> 用户:「我的订单 1042 到哪了?」 -> Agent:查询 → 返回物流信息 + 预计到达时间 +- 新增测试:42 个(conversation_tracker 13 + error_handler 19 + edge_cases 10) +- 总测试:449(后续工程审查后增至 516) +- 覆盖率:92.88% -**场景 2:取消订单 + 人工确认(30 秒)** -> 用户:「帮我取消订单 1043」 -> Agent:确认提示 → 用户批准 → 取消成功 +## 与计划的偏差 -**场景 3:OpenAPI 导入(30 秒)** -> 粘贴 OpenAPI URL → 进度条 → 审核分类 → 新工具可用 → 用新工具完成操作 +- MAX_CONTENT_LENGTH 从 8000 改为 10000(匹配计划规格) +- _thread_timestamps 模块级别,添加 autouse fixture 清理测试间状态 +- 异步追踪用 await 而非后台任务(WebSocket 循环已是 async) -- [ ] 准备一个公开可用的 OpenAPI spec URL 用于演示(或自建 mock API + spec) -- [ ] 录制脚本的文字版,标注每个步骤的预期画面 +## 技术债务 -### 4. Docker Compose 全栈部署 - -- [ ] 更新 `docker-compose.yml`: - - PostgreSQL 16(带数据持久化 volume) - - FastAPI 后端(含 uvicorn) - - React 前端(nginx 托管构建产物) - - 环境变量通过 `.env` 文件注入 -- [ ] 创建 `Dockerfile`(后端)和 `Dockerfile`(前端) -- [ ] 健康检查:PostgreSQL ready → 后端启动 → 前端可访问 -- [ ] `docker compose up` 一键启动,无需手动操作 -- [ ] 编写部署文档(README 中的快速开始部分) - -### 5. 90 秒演示视频 - -- [ ] 按演示脚本录制屏幕 -- [ ] 要点: - - 开头 5 秒:一句话说明产品(「粘贴你的 API,获得一个能执行操作的 AI 客服」) - - 展示速度:聊天流式输出的流畅感 - - 展示信任:人工确认流程 - - 展示魔法:OpenAPI 导入(粘贴 URL → 自动可用) - - 展示价值:分析仪表盘(解决率、成本) -- [ ] 视频放到可分享的位置(YouTube unlisted 或直接托管) - -### 6. 最终测试 - -- [ ] 全量 E2E 测试通过 -- [ ] `pytest --cov` → 80%+ 覆盖率 -- [ ] 全新环境 `docker compose up` → 所有功能正常 -- [ ] 在不同网络环境测试(本地、云服务器) -- [ ] 演示脚本完整跑通 3 次无报错 +- main.py 覆盖率 48%(启动路径需真实 DB) +- 速率限制进程全局(多 Worker 需 Redis) +- conversations 表 schema 假设已存在 ## Related diff --git a/2 - Projects/Smart Support/Phase 5 Dev Log.md b/2 - Projects/Smart Support/Phase 5 Dev Log.md new file mode 100644 index 0000000..2937529 --- /dev/null +++ b/2 - Projects/Smart Support/Phase 5 Dev Log.md @@ -0,0 +1,56 @@ +--- +created: 2026-04-06 +type: log +project: "[[Smart Support]]" +source: docs/phases/phase-5-dev-log.md +tags: + - dev-log + - phase-5 + - error-handling + - frontend + - docker + - demo + - rate-limiting +--- + +# Phase 5: Polish + Demo Prep -- Development Log + +> Status: COMPLETED +> Phase branch: `phase-5/polish-demo` +> Date started: 2026-03-30 +> Date completed: 2026-03-30 + +## What Was Built + +### 后端 +- **对话追踪器** (`conversation_tracker.py`): Protocol + PostgresConversationTracker + NoOpConversationTracker。ensure, record_turn, resolve 生命周期管理。 +- **错误处理** (`tools/error_handler.py`): ErrorCategory 枚举(RETRYABLE/PERMANENT/EXTERNAL/UNKNOWN)、classify_error()、with_retry() 指数退避。 +- **WebSocket 加固**: 速率限制 10 msg/10s、空白消息检查、JSON 数组拒绝、10000 字符限制、fire-and-forget 追踪。 +- **健康检查**: GET /api/health。 +- **演示数据**: demo_data.py + sample_openapi.yaml。 + +### 前端(完整实现) +- API 客户端、导航栏、App Shell +- 5 个页面:Chat、ReplayList、Replay、Dashboard、Review +- ErrorBanner 断线提示 + 重连 +- MetricCard + ReplayTimeline 组件 +- WebSocket reconnect() + onDisconnect/onReconnect 回调 + +### 基础设施 +- Frontend Dockerfile(多阶段构建) +- nginx.conf(SPA + WS/API 代理) +- Docker Compose 全栈(PostgreSQL + Backend + Frontend) + +### 文档 +- 演示脚本、Agent 配置指南、OpenAPI 导入指南、部署文档、README + +## Test Coverage + +- New: 42 tests +- Total: 449 (后续工程审查增至 516) +- Coverage: 92.88% + +## Related + +- [[Smart Support]] +- [[Smart Support/Phase 5 - 打磨 + 演示]]