vault backup: 2026-04-06 16:23:54

This commit is contained in:
Yaojia Wang
2026-04-06 16:23:54 +02:00
parent e4cee2f21d
commit 7ab3575374
10 changed files with 507 additions and 635 deletions

View File

@@ -1,7 +1,8 @@
--- ---
created: 2026-03-29 created: 2026-03-29
updated: 2026-04-06
type: project type: project
status: active status: completed
deadline: "" deadline: ""
tags: tags:
- ai-agent - ai-agent
@@ -14,6 +15,8 @@ tags:
- customer-support - customer-support
- websocket - websocket
- postgresql - postgresql
- react
- docker
--- ---
# Smart Support # Smart Support
@@ -31,35 +34,56 @@ AI 客服行动层框架。粘贴你的 API获得一个能执行真实操作
``` ```
核心组件: 核心组件:
- **langgraph-supervisor** v1.1 - 多 Agent 编排 - **langgraph-supervisor** v0.0.31 -- 多 Agent 编排
- **langchain-mcp-adapters** - MCP 工具集成 - **langchain-mcp-adapters** -- MCP 工具集成
- **PostgresSaver** - 会话状态持久化 - **langgraph-checkpoint-postgres** v3.0.5 -- 会话状态持久化
- **interrupt()** - 写操作人工确认 - **interrupt()** -- 写操作人工确认30 分钟 TTL 自动取消)
## 技术栈 ## 技术栈
- Python 3.11+, FastAPI, LangGraph v1.1 | 组件 | 技术 | 版本/说明 |
- React前端, PostgreSQLDocker 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 驱动配置 - 多 Agent 协作YAML 驱动配置
- OpenAPI 规范自动生成 MCP 服务器 + Agent 配置LLM 辅助分类 + 人工审核) - 意图分类(单意图/多意图/模糊检测LLM 结构化输出
- 写操作人工确认30 分钟超时自动取消 - OpenAPI 规范自动生成 @tool 函数 + Agent YAMLLLM 辅助分类 + 人工审核
- 对话回放 + 数据分析仪表盘 - 写操作人工确认interrupt()30 分钟 TTL 超时自动取消)
- Webhook 升级通知 - 对话回放 + 数据分析仪表盘解决率、Agent 使用率、升级率、成本)
- Webhook 升级通知(指数退避重试)
- 垂直行业模板电商、SaaS、金融科技 - 垂直行业模板电商、SaaS、金融科技
- SSRF 防护(私有 IP 拦截、DNS 重绑定防御、重定向链验证)
- WebSocket 流式输出 + 速率限制10 msg/10s per thread
- 错误分类 + 自动重试ErrorCategory 枚举,可重试错误指数退避)
## 开发阶段 ## 开发阶段
| 阶段 | 周期 | 内容 | 状态 | 详情 | | 阶段 | 周期 | 内容 | 状态 | 详情 |
|------|------|------|------|------| |------|------|------|------|------|
| Phase 1 | 第 1-3 周 | 核心框架 | COMPLETED (2026-03-30) | [[Smart Support/Phase 1 - 核心框架]] | | Phase 1 | 第 1-3 周 | 核心框架 | COMPLETED (2026-03-30) | [[Smart Support/Phase 1 - 核心框架]] |
| Phase 2 | 第 3-4 周 | 多 Agent + 安全 | 未开始 | [[Smart Support/Phase 2 - 多 Agent + 安全]] | | Phase 2 | 第 3-4 周 | 多 Agent + 安全 | COMPLETED (2026-03-30) | [[Smart Support/Phase 2 - 多 Agent + 安全]] |
| Phase 3 | 第 4-6 周 | OpenAPI 自动发现 | 未开始 | [[Smart Support/Phase 3 - OpenAPI 自动发现]] | | Phase 3 | 第 4-6 周 | OpenAPI 自动发现 | COMPLETED (2026-03-30) | [[Smart Support/Phase 3 - OpenAPI 自动发现]] |
| Phase 4 | 第 6-7 周 | 分析 + 回放 | 未开始 | [[Smart Support/Phase 4 - 分析 + 回放]] | | Phase 4 | 第 6-7 周 | 分析 + 回放 | COMPLETED (2026-03-31) | [[Smart Support/Phase 4 - 分析 + 回放]] |
| Phase 5 | 缓冲周 | 打磨 + 演示 | 未开始 | [[Smart Support/Phase 5 - 打磨 + 演示]] | | 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` - 分支:`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/Architecture]] -- 系统架构文档12 章,含 ADR、数据库设计、API 协议)
- [[Smart Support/Development Plan]] - 详细开发计划(6 Phase任务清单 + 检查点 + 风险) - [[Smart Support/Development Plan]] -- 详细开发计划(5 Phase任务清单 + 检查点 + 风险)
- [[Smart Support/Phase 1 Dev Log]] - Phase 1 开发日志88% 覆盖率82 个单元测试) - [[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 TTL30m 滑动窗口)
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` - 设计文档(问题定义、约束、方案选择) - `design-doc.md` -- 设计文档(问题定义、约束、方案选择)
- `ceo-plan.md` - CEO 计划(产品愿景、范围决策) - `ceo-plan.md` -- CEO 计划(产品愿景、范围决策)
- `eng-review-plan.md` - 工程评审(架构决策、测试策略、失败模式) - `eng-review-plan.md` -- 工程评审(架构决策、测试策略、失败模式)
- `eng-review-test-plan.md` - 测试计划测试路径、边界情况、E2E 流程) - `TODOS.md` -- 待办事项
- `TODOS.md` - 待办事项
## 关键决策 ## 快速启动
- 用 LangGraph 内置能力supervisor、checkpointer、interrupt不自己造轮子 ```bash
- PostgresSaver 从第一天起使用,为后期分析和回放打基础 # 1. 克隆 + 配置
- OpenAPI 导入生成完整 MCP 服务器(非简单 @tool 函数LLM 辅助端点分类 git clone <repo-url> && cd smart-support
- 路由错误时有 fallback agent 兜底 cp .env.example .env && cp backend/.env.example backend/.env
- 解决率定义:成功工具调用 + 未升级 # 编辑 .env 设置 ANTHROPIC_API_KEY
- Token 用量从第一天起记录
## 待解决 # 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 流水线(原型阶段手动部署) - [ ] CI/CD 流水线(原型阶段手动部署)
- [ ] 路由准确率评估数据集 - [ ] 速率限制进程全局状态 -- 多 Worker 需 Redis
- [ ] 过期中断处理Phase 2 实现 - [ ] 中断清理未定时调度cleanup_expired 存在但未触发
- [ ] SSRF 防护模块Phase 3 前构建) - [ ] NoOpAnalyticsRecorder 已注册 -- PostgresAnalyticsRecorder 集成待完善
- [ ] SaaS/Fintech 模板工具仅为桩(无实现)
- [ ] 工具生成基于字符串模板 -- 复杂场景可能需 AST
## Related ## Related
- [[Billo Release Agent]] - 另一个 AI Agent 项目 - [[Billo Release Agent]] -- 另一个 AI Agent 项目

View File

@@ -1,5 +1,6 @@
--- ---
created: 2026-03-29 created: 2026-03-29
updated: 2026-04-06
type: project type: project
status: COMPLETED (2026-03-30) status: COMPLETED (2026-03-30)
parent: "[[Smart Support]]" parent: "[[Smart Support]]"

View File

@@ -1,7 +1,8 @@
--- ---
created: 2026-03-29 created: 2026-03-29
updated: 2026-04-06
type: project type: project
status: 未开始 status: COMPLETED (2026-03-30)
parent: "[[Smart Support]]" parent: "[[Smart Support]]"
phase: 2 phase: 2
timeline: 第 3-4 周 timeline: 第 3-4 周
@@ -20,161 +21,51 @@ tags:
# Phase 2多 Agent + 安全 # Phase 2多 Agent + 安全
> Status: COMPLETED (2026-03-30)
## 目标 ## 目标
让 Supervisor 具备真正的多 Agent 路由能力,能根据用户意图选择正确的 Agent。同时完善安全机制中断超时处理、Webhook 升级通知。这个阶段结束时,系统能处理多种类型的客服请求,并在无法解决时通过 Webhook 通知人工。 让 Supervisor 具备真正的多 Agent 路由能力,能根据用户意图选择正确的 Agent。同时完善安全机制中断超时处理、Webhook 升级通知。
## 前置条件
- [[Smart Support/Phase 1 - 核心框架]] 完成
- 核心聊天闭环端到端可用
- PostgresSaver + interrupt() 基础流程工作正常
## 阶段产出 ## 阶段产出
- Supervisor 能准确路由不同类型的请求到对应 Agent - Intent 分类器LLM 结构化输出,支持单意图/多意图/模糊检测
- 多意图请求(「取消订单并给我折扣」)能被拆分并按序处理 - Discount Agentapply_discountwrite + interrupt+ generate_couponread
- 无法解决的问题通过 Webhook 通知人工客服 - 中断管理器30 分钟 TTL 自动过期register/check/resolve/cleanup
- 过期中断自动取消并提供重试选项 - Webhook 升级HTTP POST + 指数退避重试(最多 3 次)
- 2-3 个垂直行业模板开箱可用 - 增强 Supervisor 路由:动态 Agent 描述、多意图提示注入
- 垂直行业模板电商、SaaS、金融科技
- 模板加载load_template() / list_templates()
## 集成检查点 ## 新增文件
第 4 周末验证: | 文件 | 用途 |
1. 发送订单查询 → 路由到 order_lookup agent |------|------|
2. 发送「取消订单并退款」→ 按序处理两个操作 | `app/intent.py` | 意图分类模型 + LLM 分类器 |
3. 发送无法处理的请求 → Webhook POST 发出 | `app/agents/discount.py` | 折扣 Agent 工具 |
4. 触发确认 → 30 分钟不操作 → 自动取消 → 重新发消息收到重试提示 | `app/interrupt_manager.py` | 中断 TTL 管理 |
5. 加载电商模板 YAML → 相关 agents 自动注册 | `app/escalation.py` | Webhook 升级 + 重试 |
| `templates/e-commerce.yaml` | 电商模板 |
| `templates/saas.yaml` | SaaS 模板 |
| `templates/fintech.yaml` | 金融科技模板 |
--- ## 测试覆盖
## 任务清单 - 总测试153Phase 1: 87 + Phase 2: 66
- 覆盖率90.18%
- 新模块覆盖intent 100%, discount 96%, interrupt_manager 100%, escalation 100%
### 1. 完善 Supervisor 路由 ## 与计划的偏差
- [ ] 优化 supervisor 的 agent 描述,使路由更准确 - 多意图处理用 Supervisor 提示注入而非自定义预路由节点(更简单)
- [ ] 多意图处理supervisor 识别复合请求,拆分为多个子任务,按序执行 - Webhook 升级已接入 app.state 但未连接到具体 Agent 工具(模块就绪,集成推迟)
- 例如「取消订单 1042 并给我一个 10% 折扣码」→ 先路由到 order_actions取消再路由到 discount发码 - `escalate_to_human` 工具未创建(升级模块可独立触发
- [ ] 模糊/冲突意图处理supervisor 无法判断时,返回澄清问题(「您是想查询订单还是取消订单?」)
- [ ] 路由失败日志:每次路由记录 `{intent, selected_agent, confidence}`,为后续评估提供数据
### 2. 过期中断处理 ## 技术债务
- [ ] 中断触发时记录 `interrupt_timestamp` 到 graph state - SaaS/Fintech 模板工具名称无实现(配置蓝图)
- [ ] 用户恢复对话时检查:`current_time - interrupt_timestamp > 30 min` - 中断清理未定时调度
- [ ] 超时行为: - main.py 覆盖率 44%(需真实 DB
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 记录 timestampresume 时比较 |
| Webhook | httpx.AsyncClient POSTasyncio 重试 |
| 模板加载 | PyYAML 加载 + 与自定义 YAML 深度合并 |
## 风险与缓解
| 风险 | 影响 | 缓解措施 |
|------|------|---------|
| 多意图拆分不准确 | 操作顺序错误或遗漏 | 先处理常见组合,复杂情况要求用户分步操作 |
| Webhook 目标服务不稳定 | 升级通知丢失 | 重试 + 日志 + 聊天内告知用户 |
| 超时时间 30 分钟不合适 | 过早或过晚取消 | 配置化,允许每个 agent 自定义 TTL |
## Related ## Related

View File

@@ -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 Agentapply_discountwrite + interrupt和 generate_couponread。验证折扣范围 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 + NoOpEscalatorEscalationService 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 + 安全]]

View File

@@ -1,7 +1,8 @@
--- ---
created: 2026-03-29 created: 2026-03-29
updated: 2026-04-06
type: project type: project
status: 未开始 status: COMPLETED (2026-03-30)
parent: "[[Smart Support]]" parent: "[[Smart Support]]"
phase: 3 phase: 3
timeline: 第 4-6 周 timeline: 第 4-6 周
@@ -19,177 +20,59 @@ tags:
# Phase 3OpenAPI 自动发现 # Phase 3OpenAPI 自动发现
> Status: COMPLETED (2026-03-30)
## 目标 ## 目标
实现 Smart Support 的「10x 差异化功能」:用户粘贴 OpenAPI 规范 URL系统自动生成 MCP 服务器和 Agent 配置。这个阶段结束时,用户无需写代码,只需提供 API 文档就能让 AI Agent 操作他们的系统。 实现 Smart Support 的「10x 差异化功能」:用户粘贴 OpenAPI 规范 URL系统自动生成 @tool 函数和 Agent 配置。
## 前置条件
- [[Smart Support/Phase 2 - 多 Agent + 安全]] 完成
- 多 Agent 路由 + interrupt 流程工作正常
- YAML agent 注册表可以动态加载新 agent
## 阶段产出 ## 阶段产出
- 粘贴 OpenAPI spec URL → 自动解析 + 生成 MCP 服务器 + 注册 Agent - SSRF 防护模块:私有 IP 拦截、DNS 重绑定防御、重定向链验证
- LLM 自动分类端点(读/写、客户参数、Agent 分组) - OpenAPI 获取器SSRF 安全、JSON/YAML 自动检测、10MB 大小限制
- 运维审核界面确认/修正 LLM 分类结果 - 结构化 OpenAPI 验证器3.0.x 和 3.1.x
- SSRF 防护保障 URL 获取安全 - 端点解析器:$ref 解析、参数提取、自动生成 operationId
- 导入过程异步执行WebSocket 实时推送进度 - 启发式 + LLM 端点分类器GET=read, POST/PUT/PATCH/DELETE=writeLLM 失败回退启发式
- 审核 API/api/openapi导入任务、分类审核、批准生成
- @tool 代码生成器async 函数 + httpx
- Agent YAML 生成器:按分类分组端点
- 导入编排器fetch -> validate -> parse -> classify 全流程
- 内存任务存储:导入状态追踪
## 集成检查点 ## 新增文件
第 6 周末验证: | 文件 | 用途 | 行数 |
1. 粘贴一个真实的 OpenAPI 3.0 spec URL → 解析成功 |------|------|------|
2. 生成的 MCP 服务器正确包装每个端点 | `app/openapi/models.py` | 冻结数据类EndpointInfo, ClassificationResult, ImportJob | 68 |
3. LLM 分类结果合理GET = readDELETE = write | `app/openapi/ssrf.py` | SSRF 防护validate_url, safe_fetch, DNS 解析) | 162 |
4. 运维审核后agent 自动注册到 supervisor | `app/openapi/fetcher.py` | SSRF 安全规范获取 | 94 |
5. 在聊天中使用新生成的工具完成操作 | `app/openapi/validator.py` | 结构化规范验证 | 52 |
6. SSRF 攻击被拦截(私有 IP、localhost | `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 规范解析器 - 前端 ReviewPage 推迟API 就绪)
- 代码生成基于字符串模板
- [ ] 支持 OpenAPI 3.0+ 规范JSON 和 YAML 格式) - LLM 分类提示可用真实案例调优
- [ ] 使用 `openapi-spec-validator` 验证规范合法性 - 审核 API 无速率限制
- [ ] 通过 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 个 Agent15 个工具"}
```
- [ ] 导入期间聊天功能不受影响
- [ ] 导入失败 → 推送错误消息 + 错误详情
### 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 端点 → 默认 readDELETE 端点 → 默认 write
- [ ] **集成测试:** 完整流程URL → 解析 → 分类 → 生成 → 注册
- [ ] **E2E 测试:** 粘贴 spec URL → 进度更新 → 审核 → 新工具在聊天中可用
## 技术要点
| 功能 | 技术选型 | 说明 |
|------|---------|------|
| 规范验证 | openapi-spec-validator | PyPI 包,支持 3.0+ |
| URL 获取 | httpx + SSRF 模块 | 异步 HTTPIP 检查 |
| 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 发请求,不二次解析 |
| 大规范生成慢 | 用户等待久 | 异步 + 进度条,分批生成 |
## Related ## Related

View File

@@ -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 自动发现]]

View File

@@ -1,7 +1,8 @@
--- ---
created: 2026-03-29 created: 2026-03-29
updated: 2026-04-06
type: project type: project
status: 未开始 status: COMPLETED (2026-03-31)
parent: "[[Smart Support]]" parent: "[[Smart Support]]"
phase: 4 phase: 4
timeline: 第 6-7 周 timeline: 第 6-7 周
@@ -19,243 +20,57 @@ tags:
# Phase 4分析 + 回放 # Phase 4分析 + 回放
> Status: COMPLETED (2026-03-31)
## 目标 ## 目标
让客户看到 AI 客服的 ROI。对话回放让客户信任系统(看到 AI 为什么做了某个决定分析仪表盘用数据证明价值自动解决了多少问题、省了多少成本。这个阶段结束时Smart Support 是一个完整可演示的产品 让客户看到 AI 客服的 ROI。对话回放让客户信任系统,分析仪表盘用数据证明价值
## 前置条件
- [[Smart Support/Phase 1 - 核心框架]] 完成PostgresSaver 已持久化所有 checkpoint 数据)
- [[Smart Support/Phase 3 - OpenAPI 自动发现]] 完成(有真实工具调用数据可分析)
- Token 用量统计回调已运行Phase 1 实现)
## 阶段产出 ## 阶段产出
- 对话回放页面:逐步展示 Agent 的决策过程 - 回放数据模型StepType 枚举、ReplayStep、ReplayPage冻结数据类
- 分析仪表盘解决率、Agent 使用率、升级率、每对话成本 - 检查点转换器PostgresSaver JSONB -> 结构化 ReplayStep 时间线
- 数据驱动的 ROI 证明能力 - 回放 APIGET /api/conversations分页列表、GET /api/replay/{thread_id}(分页时间线)
- 分析数据模型AgentUsage、InterruptStats、AnalyticsResult
- 分析事件记录器Protocol 接口 + PostgresAnalyticsRecorder + NoOpAnalyticsRecorder
- 分析查询resolution_rate、agent_usage、escalation_rate、cost_per_conversation、interrupt_stats
- 分析 APIGET /api/analytics?range=Xd
- DB 迁移analytics_events 表 + conversations 列扩展
## 集成检查点 ## 新增文件
第 7 周末验证: | 文件 | 用途 |
1. 完成几轮对话后,打开回放页面 → 看到完整决策时间线 |------|------|
2. 分析仪表盘显示正确的解决率和成本数据 | `app/replay/models.py` | StepType, ReplayStep, ReplayPage |
3. 零数据状态(新部署)→ 仪表盘显示空状态引导 | `app/replay/transformer.py` | Checkpoint JSONB -> ReplayStep[] |
4. 200+ 对话的回放 → 分页正常,不卡顿 | `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` → 对话列表(分页) - 新增测试74 个
- 返回:`thread_id`, 开始时间, 消息数, 最终状态resolved/escalated/abandoned - 总测试399
- 支持筛选:按状态、按日期范围、按 agent - 覆盖率92.87%
- 分页参数:`page`, `page_size`(默认 20 - 所有新模块覆盖率 81-100%
- [ ] 端点 `GET /api/replay/{thread_id}` → 单个对话的回放数据(分页) ## 与计划的偏差
- 查询 PostgresSaver checkpoint 表,按 checkpoint_id 排序
- 每个 checkpoint 解析为结构化时间线事件:
```json - 前端页面推迟到 Phase 5
{ - ws_handler 事件记录推迟(注册 NoOpAnalyticsRecorder
"thread_id": "uuid", - conversations.agents_used 列未填充
"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 价格变化 | 成本计算不准 | 价格配置化,支持不同模型不同价格 |
## Related ## Related

View File

@@ -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 - 分析 + 回放]]

View File

@@ -1,7 +1,8 @@
--- ---
created: 2026-03-29 created: 2026-03-29
updated: 2026-04-06
type: project type: project
status: 未开始 status: COMPLETED (2026-03-31)
parent: "[[Smart Support]]" parent: "[[Smart Support]]"
phase: 5 phase: 5
timeline: 缓冲周 timeline: 缓冲周
@@ -14,97 +15,78 @@ tags:
- documentation - documentation
- edge-cases - edge-cases
- e2e-testing - e2e-testing
- frontend
- rate-limiting
--- ---
# Phase 5打磨 + 演示准备 # Phase 5打磨 + 演示准备
> Status: COMPLETED (2026-03-31)
## 目标 ## 目标
将 Smart Support 从「能跑」变成「能演示给客户看」。修复所有边界情况,准备演示数据和脚本,确保一键部署流程顺畅。这个阶段结束时,能录一个 90 秒的产品演示视频。 将 Smart Support 从「能跑」变成「能演示给客户看」。修复所有边界情况,准备演示数据和脚本,确保一键部署流程顺畅。
## 前置条件
- [[Smart Support/Phase 4 - 分析 + 回放]] 完成
- 所有核心功能端到端可用
## 阶段产出 ## 阶段产出
- 错误处理覆盖所有已知边界情况 ### 后端
- 演示脚本 + 真实感的示例数据
- 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 秒)** - 新增测试42 个conversation_tracker 13 + error_handler 19 + edge_cases 10
> 用户:「我的订单 1042 到哪了?」 - 总测试449后续工程审查后增至 516
> Agent查询 → 返回物流信息 + 预计到达时间 - 覆盖率92.88%
**场景 2取消订单 + 人工确认30 秒)** ## 与计划的偏差
> 用户:「帮我取消订单 1043」
> Agent确认提示 → 用户批准 → 取消成功
**场景 3OpenAPI 导入30 秒)** - MAX_CONTENT_LENGTH 从 8000 改为 10000匹配计划规格
> 粘贴 OpenAPI URL → 进度条 → 审核分类 → 新工具可用 → 用新工具完成操作 - _thread_timestamps 模块级别,添加 autouse fixture 清理测试间状态
- 异步追踪用 await 而非后台任务WebSocket 循环已是 async
- [ ] 准备一个公开可用的 OpenAPI spec URL 用于演示(或自建 mock API + spec ## 技术债务
- [ ] 录制脚本的文字版,标注每个步骤的预期画面
### 4. Docker Compose 全栈部署 - main.py 覆盖率 48%(启动路径需真实 DB
- 速率限制进程全局(多 Worker 需 Redis
- [ ] 更新 `docker-compose.yml` - conversations 表 schema 假设已存在
- 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 次无报错
## Related ## Related

View File

@@ -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.confSPA + 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 - 打磨 + 演示]]