From 407b455f19cd2659ac66debad47fb791d3a46fb1 Mon Sep 17 00:00:00 2001 From: Yaojia Wang Date: Sun, 29 Mar 2026 21:30:09 +0200 Subject: [PATCH] vault: split Smart Support phases into separate files with detailed tasks --- 2 - Projects/Smart Support.md | 65 +---- .../Smart Support/Phase 1 - 核心框架.md | 232 ++++++++++++++++ .../Phase 2 - 多 Agent + 安全.md | 172 ++++++++++++ .../Phase 3 - OpenAPI 自动发现.md | 188 +++++++++++++ .../Smart Support/Phase 4 - 分析 + 回放.md | 254 ++++++++++++++++++ .../Smart Support/Phase 5 - 打磨 + 演示.md | 103 +++++++ 6 files changed, 956 insertions(+), 58 deletions(-) create mode 100644 2 - Projects/Smart Support/Phase 1 - 核心框架.md create mode 100644 2 - Projects/Smart Support/Phase 2 - 多 Agent + 安全.md create mode 100644 2 - Projects/Smart Support/Phase 3 - OpenAPI 自动发现.md create mode 100644 2 - Projects/Smart Support/Phase 4 - 分析 + 回放.md create mode 100644 2 - Projects/Smart Support/Phase 5 - 打磨 + 演示.md diff --git a/2 - Projects/Smart Support.md b/2 - Projects/Smart Support.md index a02e002..84c8de2 100644 --- a/2 - Projects/Smart Support.md +++ b/2 - Projects/Smart Support.md @@ -42,64 +42,13 @@ AI 客服行动层框架。粘贴你的 API,获得一个能执行真实操作 ## 开发阶段 -| 阶段 | 周期 | 内容 | 状态 | -|------|------|------|------| -| Phase 1 | 第 1-3 周 | 核心框架:Chat UI + Supervisor + Agent 注册表 + 中断流程 | 未开始 | -| Phase 2 | 第 3-4 周 | 多 Agent 路由 + Webhook 升级 + 垂直模板 | 未开始 | -| Phase 3 | 第 4-6 周 | OpenAPI 自动发现 + MCP 服务器生成 + SSRF 防护 | 未开始 | -| Phase 4 | 第 6-7 周 | 对话回放 + 数据分析仪表盘 | 未开始 | - -### Phase 1:核心框架(第 1-3 周) - -- [ ] FastAPI 后端 + WebSocket 聊天端点 -- [ ] Docker Compose 配置(PostgreSQL 16 + 应用) -- [ ] PostgresSaver 检查点持久化(`.setup()` 初始化) -- [ ] LangGraph Supervisor 配置(2-3 个演示 Agent:订单查询、FAQ、升级) -- [ ] YAML Agent 注册表加载器(含验证,无效 YAML 报明确错误) -- [ ] Agent 人设配置(YAML 中 tone/greeting 字段) -- [ ] React 聊天 UI + WebSocket 连接 + 逐 token 流式渲染 -- [ ] 基础 `interrupt()` 流程(写操作触发确认提示) -- [ ] Fallback Agent(路由错误时兜底) -- [ ] Token 用量统计回调(LangChain callback,写入 PostgreSQL) -- [ ] DB 连接错误处理(try/except,返回用户友好错误) -- [ ] **集成检查点:** 第 3 周末,完整聊天闭环端到端可用 - -### Phase 2:多 Agent + 安全(第 3-4 周) - -- [ ] 完整 Supervisor 路由 + 意图分类 -- [ ] Webhook 升级通知(HTTP POST 到配置 URL,含完整对话上下文) -- [ ] Webhook 失败重试(指数退避) -- [ ] 垂直行业模板(电商、SaaS YAML 配置文件) -- [ ] 过期中断处理(30 分钟 TTL 自动取消 + 重试提示) -- [ ] **集成检查点:** 第 4 周末,多 Agent 路由 + 中断流程可用 - -### Phase 3:OpenAPI 自动发现(第 4-6 周) - -- [ ] SSRF 防护模块(屏蔽内网 IP、localhost、169.254.x,DNS 重绑定防护) -- [ ] OpenAPI 3.0 规范解析器(用 `openapi-spec-validator` 验证) -- [ ] 无效/格式错误规范 → 明确错误信息 -- [ ] 从规范生成完整 MCP 服务器(每个端点一个工具) -- [ ] LLM 辅助端点分类(读/写、客户参数识别、Agent 分组建议) -- [ ] 运维审核/修正 UI(确认 LLM 分类结果) -- [ ] 从分类结果自动生成 Agent YAML 配置 -- [ ] 异步导入 + WebSocket 进度更新(「解析规范...」「生成工具 3/50...」「完成!」) -- [ ] **集成检查点:** 第 6 周末,粘贴真实 API 规范 → 工具在聊天中可用 - -### Phase 4:分析 + 回放(第 6-7 周) - -- [ ] 自定义分页回放 API 端点(`/api/replay/{thread_id}`) -- [ ] 回放 UI(React 时间线组件,逐步展示 Agent 决策、工具调用、返回结果) -- [ ] 分析查询(解决率、Agent 使用率、升级率、每次对话成本) -- [ ] 解决率计算:成功工具调用 + 未触发升级 -- [ ] 分析仪表盘 UI + 零数据状态处理 -- [ ] **集成检查点:** 第 7 周末,完整产品演示就绪 - -### Phase 5:打磨 + 演示准备(缓冲) - -- [ ] 错误处理加固 -- [ ] 演示脚本 + 示例数据 -- [ ] Docker Compose 全栈部署配置 -- [ ] 90 秒屏幕录制 +| 阶段 | 周期 | 内容 | 状态 | 详情 | +|------|------|------|------|------| +| Phase 1 | 第 1-3 周 | 核心框架 | 未开始 | [[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 - 打磨 + 演示]] | ## 目标用户 diff --git a/2 - Projects/Smart Support/Phase 1 - 核心框架.md b/2 - Projects/Smart Support/Phase 1 - 核心框架.md new file mode 100644 index 0000000..eab455f --- /dev/null +++ b/2 - Projects/Smart Support/Phase 1 - 核心框架.md @@ -0,0 +1,232 @@ +--- +created: "2026-03-29" +type: project +status: 未开始 +parent: "[[Smart Support]]" +phase: 1 +timeline: "第 1-3 周" +--- + +# Phase 1:核心框架 + +## 目标 + +搭建 Smart Support 的核心闭环:客户发消息 → AI Agent 处理 → 流式回复。这个阶段结束时,应该有一个完整可运行的聊天应用,能通过 mock 工具回答问题,并在写操作时触发人工确认。 + +## 阶段产出 + +- 可运行的全栈应用(`docker compose up` 一键启动) +- 聊天界面能发消息、收到流式回复 +- 2-3 个演示 Agent 通过 mock 工具执行操作 +- 写操作自动触发确认提示 + +## 集成检查点 + +第 3 周末验证: +1. `docker compose up` → PostgreSQL + FastAPI 正常启动 +2. 打开 `http://localhost:8000` → 聊天界面加载 +3. 发送「查询订单 1042 的状态」→ 收到流式回复 +4. 发送「取消订单 1042」→ 收到确认提示 → 批准 → 确认取消 +5. `pytest --cov` → 80%+ 覆盖率 + +--- + +## 任务清单 + +### 1. 基础设施搭建 + +- [ ] 初始化 Python 项目(`pyproject.toml`,依赖:fastapi, uvicorn, langgraph, langchain-anthropic, langgraph-checkpoint-postgres, langchain-mcp-adapters) +- [ ] 创建 `docker-compose.yml`(PostgreSQL 16 + 应用容器) +- [ ] 配置环境变量(`.env.example`):`LLM_PROVIDER`, `LLM_MODEL`, `ANTHROPIC_API_KEY`, `DATABASE_URL` +- [ ] 创建项目目录结构: + +``` +backend/ +├── app/ +│ ├── __init__.py +│ ├── main.py +│ ├── graph.py +│ ├── registry.py +│ ├── callbacks.py +│ └── agents/ +│ ├── __init__.py +│ ├── order_lookup.py +│ ├── faq.py +│ └── fallback.py +├── agents.yaml +└── tests/ + ├── __init__.py + ├── test_graph.py + ├── test_registry.py + ├── test_websocket.py + └── conftest.py +``` + +### 2. PostgresSaver 检查点配置 + +- [ ] 在 `main.py` 启动时初始化 PostgresSaver(调用 `.setup()` 创建表结构) +- [ ] 配置连接池(asyncpg) +- [ ] 验证检查点持久化:重启应用后,之前的对话上下文仍可恢复 +- [ ] DB 连接错误处理:graph 调用外层 try/except,捕获 DB 异常时返回「抱歉,系统暂时无法保存对话,请稍后重试」 + +### 3. YAML Agent 注册表 + +- [ ] 定义 `agents.yaml` 配置格式: + +```yaml +agents: + - name: order_lookup + description: 查询订单状态、物流跟踪信息 + permission: read + personality: + tone: professional + greeting: "您好,我来帮您查询订单信息。" + tools: + - get_order_status + - get_tracking_info + + - name: faq + description: 回答常见问题(退货政策、运费、营业时间等) + permission: read + personality: + tone: friendly + greeting: "有什么可以帮您的?" + tools: [] + + - name: fallback + description: 通用兜底 Agent,处理无法路由的请求 + permission: read + personality: + tone: helpful + tools: [] +``` + +- [ ] 实现 `registry.py`:加载 YAML,验证必填字段(name, description, permission),缺失字段报明确错误(含文件名和字段名) +- [ ] 无效 YAML 语法 → 启动时抛出错误,包含行号 +- [ ] Agent personality 配置解析(tone, greeting, escalation_message) + +### 4. LangGraph Supervisor 配置 + +- [ ] 使用 `langgraph-supervisor` 创建 supervisor graph +- [ ] 从 agent 注册表动态注册 agents(注册表驱动,非硬编码) +- [ ] 每个 agent 配置对应的 mock 工具(`@tool` 装饰器) +- [ ] Mock 工具实现: + - `get_order_status(order_id: str)` → 返回模拟订单数据(状态、日期、金额) + - `get_tracking_info(order_id: str)` → 返回模拟物流数据 + - `cancel_order(order_id: str)` → 返回取消确认(触发 interrupt) +- [ ] Fallback agent:当 supervisor 路由失败或 agent 返回「无法处理」时,fallback agent 接管,尝试所有可用工具 +- [ ] Supervisor 使用 `ChatAnthropic`(Claude Sonnet 4.6),通过 `LLM_PROVIDER` + `LLM_MODEL` 环境变量可切换 + +### 5. interrupt() 人工确认流程 + +- [ ] 在 agent 调用写操作工具前触发 `interrupt()` +- [ ] 判断逻辑:agent YAML 中 `permission: write` 的 agent,其所有工具调用都触发确认 +- [ ] 确认提示格式:「即将执行:取消订单 #1042。确认执行?[是/否]」 +- [ ] 用户回复「是」→ `Command(resume="approved")` → 执行操作 +- [ ] 用户回复「否」→ `Command(resume="rejected")` → 返回「操作已取消」 +- [ ] 确认状态通过 PostgresSaver checkpoint 持久化 + +### 6. FastAPI WebSocket 端点 + +- [ ] `ws://localhost:8000/ws` WebSocket 端点 +- [ ] 连接时生成 `thread_id`(UUID),作为 PostgresSaver 的 thread 标识 +- [ ] 接收消息 → 调用 supervisor graph(`ainvoke` / `astream_events()`) +- [ ] 流式输出:通过 `astream_events()` 获取 LLM token,逐个通过 WebSocket 发送 +- [ ] 消息协议: + +```json +// 客户端 → 服务器 +{"type": "message", "content": "查询订单 1042"} + +// 服务器 → 客户端(流式 token) +{"type": "token", "content": "您"} +{"type": "token", "content": "的"} +{"type": "token", "content": "订单"} + +// 服务器 → 客户端(确认提示) +{"type": "interrupt", "action": "cancel_order", "params": {"order_id": "1042"}, "message": "即将取消订单 #1042,确认执行?"} + +// 客户端 → 服务器(确认回复) +{"type": "resume", "decision": "approved"} + +// 服务器 → 客户端(错误) +{"type": "error", "message": "系统暂时无法处理,请稍后重试"} +``` + +- [ ] 断线处理:WebSocket 关闭时清理资源,不影响其他连接 +- [ ] 无效 JSON → 返回 error 消息,不断开连接 + +### 7. React 聊天 UI + +- [ ] 基础聊天界面(消息列表 + 输入框 + 发送按钮) +- [ ] WebSocket 连接管理(连接、断线重连) +- [ ] 流式 token 渲染(逐字显示 AI 回复) +- [ ] 中断确认 UI:收到 `interrupt` 消息时,显示操作描述 + 「确认」/「取消」按钮 +- [ ] 错误提示:收到 `error` 消息时,显示红色提示 +- [ ] Agent 操作可视化:显示 agent 正在执行的工具调用(如「正在查询订单...」) + +### 8. Token 用量统计 + +- [ ] 实现 `callbacks.py`:LangChain callback handler,记录每次 LLM 调用的 input/output tokens +- [ ] 数据写入 PostgreSQL(独立表或利用 checkpoint metadata) +- [ ] 每条记录包含:`thread_id`, `agent_name`, `input_tokens`, `output_tokens`, `model`, `timestamp` + +### 9. 测试 + +- [ ] **Graph 测试:** supervisor 收到「查询订单」→ 路由到 order_lookup agent → 调用 get_order_status → 返回结果 +- [ ] **Graph 测试:** supervisor 收到模糊请求 → 路由到 fallback agent +- [ ] **Graph 测试:** agent 调用写操作 → interrupt 触发 → resume approved → 操作执行 +- [ ] **Graph 测试:** interrupt → resume rejected → 操作取消 +- [ ] **注册表测试:** 有效 YAML → agents 正确加载 +- [ ] **注册表测试:** 无效 YAML → 明确错误信息 +- [ ] **注册表测试:** 缺失必填字段 → validation error +- [ ] **WebSocket 测试:** 发送消息 → 收到流式 token +- [ ] **WebSocket 测试:** 发送无效 JSON → 收到 error,连接不断 +- [ ] **WebSocket 测试:** 断线 → 服务器清理资源 +- [ ] **DB 测试:** 连接正常 → checkpoint 持久化成功 +- [ ] **DB 测试:** 连接失败 → 用户收到友好错误 +- [ ] **E2E 测试:** 完整聊天流程(发消息 → 收回复) +- [ ] **E2E 测试:** 完整确认流程(写操作 → 确认 → 执行) + +## 技术要点 + +| 组件 | 技术选型 | 说明 | +|------|---------|------| +| Web 框架 | FastAPI | 原生 WebSocket + async 支持 | +| Agent 编排 | langgraph-supervisor v1.1 | 内置 supervisor + middleware | +| 状态持久化 | langgraph-checkpoint-postgres v3.0.5 | 需调用 `.setup()` 初始化 | +| LLM | ChatAnthropic (Claude Sonnet 4.6) | 通过 LangChain BaseChatModel 抽象 | +| 流式输出 | astream_events() | Messages 模式,逐 token 推送 | +| 前端 | React | WebSocket 连接 + 流式渲染 | +| 数据库 | PostgreSQL 16 | Docker Compose 部署 | +| 测试 | pytest + FastAPI TestClient | 80%+ 覆盖率 | + +## 依赖项 + +``` +langgraph>=1.1.0 +langgraph-supervisor +langgraph-checkpoint-postgres>=3.0.5 +langchain-anthropic +langchain-mcp-adapters +fastapi +uvicorn[standard] +asyncpg +pyyaml +pytest +httpx +``` + +## 风险与缓解 + +| 风险 | 影响 | 缓解措施 | +|------|------|---------| +| LangGraph supervisor 路由不准 | Agent 收到错误类型的请求 | Fallback agent 兜底 + agent description 写清楚 | +| PostgresSaver 初始化失败 | 应用无法启动 | 启动时检查连接,失败报明确错误 | +| WebSocket 连接不稳定 | 用户体验差 | 前端自动重连 + 断线提示 | +| LLM API 超时 | 用户等待无响应 | 设置 timeout + 返回错误消息 | + +## Related + +- [[Smart Support]] +- [[Smart Support/Phase 2 - 多 Agent + 安全]] diff --git a/2 - Projects/Smart Support/Phase 2 - 多 Agent + 安全.md b/2 - Projects/Smart Support/Phase 2 - 多 Agent + 安全.md new file mode 100644 index 0000000..84674f5 --- /dev/null +++ b/2 - Projects/Smart Support/Phase 2 - 多 Agent + 安全.md @@ -0,0 +1,172 @@ +--- +created: "2026-03-29" +type: project +status: 未开始 +parent: "[[Smart Support]]" +phase: 2 +timeline: "第 3-4 周" +--- + +# Phase 2:多 Agent + 安全 + +## 目标 + +让 Supervisor 具备真正的多 Agent 路由能力,能根据用户意图选择正确的 Agent。同时完善安全机制:中断超时处理、Webhook 升级通知。这个阶段结束时,系统能处理多种类型的客服请求,并在无法解决时通过 Webhook 通知人工。 + +## 前置条件 + +- [[Smart Support/Phase 1 - 核心框架]] 完成 +- 核心聊天闭环端到端可用 +- PostgresSaver + interrupt() 基础流程工作正常 + +## 阶段产出 + +- Supervisor 能准确路由不同类型的请求到对应 Agent +- 多意图请求(「取消订单并给我折扣」)能被拆分并按序处理 +- 无法解决的问题通过 Webhook 通知人工客服 +- 过期中断自动取消并提供重试选项 +- 2-3 个垂直行业模板开箱可用 + +## 集成检查点 + +第 4 周末验证: +1. 发送订单查询 → 路由到 order_lookup agent +2. 发送「取消订单并退款」→ 按序处理两个操作 +3. 发送无法处理的请求 → Webhook POST 发出 +4. 触发确认 → 30 分钟不操作 → 自动取消 → 重新发消息收到重试提示 +5. 加载电商模板 YAML → 相关 agents 自动注册 + +--- + +## 任务清单 + +### 1. 完善 Supervisor 路由 + +- [ ] 优化 supervisor 的 agent 描述,使路由更准确 +- [ ] 多意图处理:supervisor 识别复合请求,拆分为多个子任务,按序执行 + - 例如「取消订单 1042 并给我一个 10% 折扣码」→ 先路由到 order_actions(取消),再路由到 discount(发码) +- [ ] 模糊/冲突意图处理:supervisor 无法判断时,返回澄清问题(「您是想查询订单还是取消订单?」) +- [ ] 路由失败日志:每次路由记录 `{intent, selected_agent, confidence}`,为后续评估提供数据 + +### 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 | + +## Related + +- [[Smart Support/Phase 1 - 核心框架]] +- [[Smart Support/Phase 3 - OpenAPI 自动发现]] +- [[Smart Support]] diff --git a/2 - Projects/Smart Support/Phase 3 - OpenAPI 自动发现.md b/2 - Projects/Smart Support/Phase 3 - OpenAPI 自动发现.md new file mode 100644 index 0000000..fb74c88 --- /dev/null +++ b/2 - Projects/Smart Support/Phase 3 - OpenAPI 自动发现.md @@ -0,0 +1,188 @@ +--- +created: "2026-03-29" +type: project +status: 未开始 +parent: "[[Smart Support]]" +phase: 3 +timeline: "第 4-6 周" +--- + +# Phase 3:OpenAPI 自动发现 + +## 目标 + +实现 Smart Support 的「10x 差异化功能」:用户粘贴 OpenAPI 规范 URL,系统自动生成 MCP 服务器和 Agent 配置。这个阶段结束时,用户无需写代码,只需提供 API 文档就能让 AI Agent 操作他们的系统。 + +## 前置条件 + +- [[Smart Support/Phase 2 - 多 Agent + 安全]] 完成 +- 多 Agent 路由 + interrupt 流程工作正常 +- YAML agent 注册表可以动态加载新 agent + +## 阶段产出 + +- 粘贴 OpenAPI spec URL → 自动解析 + 生成 MCP 服务器 + 注册 Agent +- LLM 自动分类端点(读/写、客户参数、Agent 分组) +- 运维审核界面确认/修正 LLM 分类结果 +- SSRF 防护保障 URL 获取安全 +- 导入过程异步执行,WebSocket 实时推送进度 + +## 集成检查点 + +第 6 周末验证: +1. 粘贴一个真实的 OpenAPI 3.0 spec URL → 解析成功 +2. 生成的 MCP 服务器正确包装每个端点 +3. LLM 分类结果合理(GET = read,DELETE = write) +4. 运维审核后,agent 自动注册到 supervisor +5. 在聊天中使用新生成的工具完成操作 +6. SSRF 攻击被拦截(私有 IP、localhost) + +--- + +## 任务清单 + +### 1. SSRF 防护模块 + +> 独立模块 `backend/app/openapi/ssrf.py`,可与 Phase 1-2 并行开发 + +- [ ] 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 发请求,不二次解析 | +| 大规范生成慢 | 用户等待久 | 异步 + 进度条,分批生成 | + +## Related + +- [[Smart Support/Phase 2 - 多 Agent + 安全]] +- [[Smart Support/Phase 4 - 分析 + 回放]] +- [[Smart Support]] diff --git a/2 - Projects/Smart Support/Phase 4 - 分析 + 回放.md b/2 - Projects/Smart Support/Phase 4 - 分析 + 回放.md new file mode 100644 index 0000000..d785877 --- /dev/null +++ b/2 - Projects/Smart Support/Phase 4 - 分析 + 回放.md @@ -0,0 +1,254 @@ +--- +created: "2026-03-29" +type: project +status: 未开始 +parent: "[[Smart Support]]" +phase: 4 +timeline: "第 6-7 周" +--- + +# Phase 4:分析 + 回放 + +## 目标 + +让客户看到 AI 客服的 ROI。对话回放让客户信任系统(看到 AI 为什么做了某个决定),分析仪表盘用数据证明价值(自动解决了多少问题、省了多少成本)。这个阶段结束时,Smart Support 是一个完整可演示的产品。 + +## 前置条件 + +- [[Smart Support/Phase 1 - 核心框架]] 完成(PostgresSaver 已持久化所有 checkpoint 数据) +- [[Smart Support/Phase 3 - OpenAPI 自动发现]] 完成(有真实工具调用数据可分析) +- Token 用量统计回调已运行(Phase 1 实现) + +## 阶段产出 + +- 对话回放页面:逐步展示 Agent 的决策过程 +- 分析仪表盘:解决率、Agent 使用率、升级率、每对话成本 +- 数据驱动的 ROI 证明能力 + +## 集成检查点 + +第 7 周末验证: +1. 完成几轮对话后,打开回放页面 → 看到完整决策时间线 +2. 分析仪表盘显示正确的解决率和成本数据 +3. 零数据状态(新部署)→ 仪表盘显示空状态引导 +4. 200+ 轮对话的回放 → 分页正常,不卡顿 + +--- + +## 任务清单 + +### 1. 对话回放 API + +- [ ] 端点 `GET /api/conversations` → 对话列表(分页) + - 返回:`thread_id`, 开始时间, 消息数, 最终状态(resolved/escalated/abandoned) + - 支持筛选:按状态、按日期范围、按 agent + - 分页参数:`page`, `page_size`(默认 20) + +- [ ] 端点 `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 价格变化 | 成本计算不准 | 价格配置化,支持不同模型不同价格 | + +## Related + +- [[Smart Support/Phase 3 - OpenAPI 自动发现]] +- [[Smart Support/Phase 5 - 打磨 + 演示]] +- [[Smart Support]] diff --git a/2 - Projects/Smart Support/Phase 5 - 打磨 + 演示.md b/2 - Projects/Smart Support/Phase 5 - 打磨 + 演示.md new file mode 100644 index 0000000..acc021c --- /dev/null +++ b/2 - Projects/Smart Support/Phase 5 - 打磨 + 演示.md @@ -0,0 +1,103 @@ +--- +created: "2026-03-29" +type: project +status: 未开始 +parent: "[[Smart Support]]" +phase: 5 +timeline: "缓冲周" +--- + +# Phase 5:打磨 + 演示准备 + +## 目标 + +将 Smart Support 从「能跑」变成「能演示给客户看」。修复所有边界情况,准备演示数据和脚本,确保一键部署流程顺畅。这个阶段结束时,能录一个 90 秒的产品演示视频。 + +## 前置条件 + +- [[Smart Support/Phase 4 - 分析 + 回放]] 完成 +- 所有核心功能端到端可用 + +## 阶段产出 + +- 错误处理覆盖所有已知边界情况 +- 演示脚本 + 真实感的示例数据 +- Docker Compose 全栈一键部署 +- 90 秒产品演示视频 + +--- + +## 任务清单 + +### 1. 错误处理加固 + +- [ ] 审查所有 API 端点,确保每个都有明确的错误响应 +- [ ] LLM API 超时 → 用户收到「AI 正在思考中,请稍候...」→ 15 秒后仍无响应 → 「抱歉,处理超时,请重试」 +- [ ] WebSocket 异常断开 → 前端自动重连(最多 3 次,间隔 1s/2s/4s)→ 重连失败 → 提示刷新页面 +- [ ] MCP 工具调用失败 → 「该操作暂时不可用,已通知技术团队」 +- [ ] 非预期错误 → 统一错误格式,不暴露堆栈信息 +- [ ] 所有错误记录详细日志(structlog / JSON 格式) + +### 2. 演示数据 + +- [ ] 创建模拟电商数据集: + - 20 个订单(不同状态:待付款、已付款、已发货、已完成、已取消) + - 5 个客户(含姓名、邮箱、订单历史) + - 3 个优惠活动(满减、折扣码、新人券) + - 物流追踪信息(不同快递公司、不同状态) +- [ ] Mock 工具返回对应数据(根据 order_id 查表返回) +- [ ] 数据感觉真实(合理的金额、日期、商品名称) + +### 3. 演示脚本 + +- [ ] 编写演示对话脚本(覆盖核心功能): + +**场景 1:订单查询(30 秒)** +> 用户:「我的订单 1042 到哪了?」 +> Agent:查询 → 返回物流信息 + 预计到达时间 + +**场景 2:取消订单 + 人工确认(30 秒)** +> 用户:「帮我取消订单 1043」 +> Agent:确认提示 → 用户批准 → 取消成功 + +**场景 3:OpenAPI 导入(30 秒)** +> 粘贴 OpenAPI URL → 进度条 → 审核分类 → 新工具可用 → 用新工具完成操作 + +- [ ] 准备一个公开可用的 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 次无报错 + +## Related + +- [[Smart Support/Phase 4 - 分析 + 回放]] +- [[Smart Support]]