From e4f08576a95d0708ae6ec33cfa2daff6b1c8c9fc Mon Sep 17 00:00:00 2001 From: Yaojia Wang Date: Mon, 30 Mar 2026 00:26:50 +0200 Subject: [PATCH] docs: add CLAUDE.md project instructions and architecture docs - CLAUDE.md with phase execution workflow and project conventions - ARCHITECTURE.md with system design, data flow, and component breakdown - DEVELOPMENT-PLAN.md with detailed 5-phase task breakdown --- CLAUDE.md | 293 +++++++++ docs/ARCHITECTURE.md | 1241 ++++++++++++++++++++++++++++++++++++++ docs/DEVELOPMENT-PLAN.md | 1040 ++++++++++++++++++++++++++++++++ 3 files changed, 2574 insertions(+) create mode 100644 CLAUDE.md create mode 100644 docs/ARCHITECTURE.md create mode 100644 docs/DEVELOPMENT-PLAN.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..64c1138 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,293 @@ +# Smart Support -- Project Instructions + +## Project Overview + +AI customer support action-layer framework. Core value: "Paste your API, get an AI agent that executes real actions." + +- **Tech Stack:** Python 3.11+, FastAPI, LangGraph v1.1, React, PostgreSQL 16, Docker Compose +- **Planning Docs:** `docs/DEVELOPMENT-PLAN.md`, `docs/ARCHITECTURE.md`, `eng-review-plan.md` +- **Phases:** 5 phases (see `docs/DEVELOPMENT-PLAN.md`) + +--- + +## Phase Execution Workflow (MANDATORY) + +Every phase MUST follow this exact workflow. No exceptions. + +### Step 0: Pre-flight Checks, Checkpoint, and Branch + +Before starting ANY phase work: + +```bash +# 1. Verify ECC hooks are working +# - ECC plugin provides all hooks (quality-gate, security, session management) +# - Controlled by ECC_HOOK_PROFILE env var (standard/strict) in ~/.claude/settings.json +# - Run a test edit on a .py file to confirm quality-gate.js fires (ruff auto-format) +# - If hooks are broken, check ECC plugin status before proceeding + +# 2. Run full test suite to confirm main is green (regression gate) +pytest --cov=app --cov-report=term-missing +# - If any test fails, fix it before starting the new phase + +# 3. Create checkpoint to snapshot the starting state +/everything-claude-code:checkpoint create [phase name] + +# 4. Create the phase branch +git checkout main +git pull origin main +git checkout -b phase-{N}/{short-description} +# Example: phase-1/core-framework + +# 5. Mark phase as IN PROGRESS +# Update the Phase Summary table in this CLAUDE.md: +# change Status from `NOT STARTED` to `IN PROGRESS` +``` + +### Step 1: Read Plan and Prepare + +1. Read `docs/DEVELOPMENT-PLAN.md` -- locate the current phase section +2. Read `docs/ARCHITECTURE.md` -- understand relevant components +3. Identify all tasks, acceptance criteria, and dependencies for this phase +4. Create a phase dev log **skeleton** at `docs/phases/phase-{N}-dev-log.md` (date, branch name, plan link only -- content filled in Step 5) + +### Step 2: Develop Using Orchestrate Skill + +Route to the correct orchestration mode based on work type: + +| Work Type | Skill Command | +|-----------|---------------| +| New feature | `/everything-claude-code:orchestrate feature` | +| Bug fix | `/everything-claude-code:orchestrate bugfix` | +| Refactor | `/everything-claude-code:orchestrate refactor` | + +ALWAYS use the appropriate orchestrate skill. Never develop without it. + +A single phase may contain mixed work types (e.g., Phase 5 has feature + bugfix + refactor). Call the orchestrate skill **per sub-task** with the matching mode. Example: + +``` +# Within Phase 5: +/everything-claude-code:orchestrate feature # for demo script +/everything-claude-code:orchestrate bugfix # for error handling fixes +/everything-claude-code:orchestrate refactor # for code cleanup +``` + +### Step 3: Module Independence (CRITICAL) + +Every module MUST be independently runnable (with mocked deps) and independently testable. Use `Protocol` for interfaces and dependency injection for all external deps (see `~/.claude/rules/python/patterns.md`). No circular imports -- dependency graph must be a DAG. + +Module boundaries for this project: + +``` +backend/app/ + agents/ -- Agent definitions and tools (depends on: registry) + registry.py -- YAML agent registry (depends on: nothing) + graph.py -- LangGraph supervisor (depends on: agents, registry) + openapi/ -- OpenAPI parser + MCP gen (depends on: nothing) + replay/ -- Conversation replay API (depends on: nothing, reads DB) + analytics/ -- Analytics queries (depends on: nothing, reads DB) + callbacks.py -- Token usage logging (depends on: nothing) + main.py -- FastAPI entry point (composes all modules) +frontend/ -- React UI (depends on: backend API contract only) +``` + +### Step 4: Testing (MANDATORY -- 80%+ Coverage) + +Follow `~/.claude/rules/python/testing.md` for pytest patterns and `pytest.mark` categorization. Use these project-specific markers: + +```python +@pytest.mark.unit # per-module isolated tests +@pytest.mark.integration # cross-module with real PostgreSQL (Docker) +@pytest.mark.e2e # full-stack user flow tests +``` + +E2E scope by phase: +- **Phase 1:** Backend-only E2E via FastAPI TestClient (WebSocket chat loop). Frontend and backend develop in parallel, full-stack E2E not yet possible. +- **Phase 2+:** Full-stack E2E (frontend + backend) required for all critical user flows. + +Test file structure: + +``` +backend/tests/ + unit/ -- @pytest.mark.unit per module + integration/ -- @pytest.mark.integration with real DB + e2e/ -- @pytest.mark.e2e full-stack flows + conftest.py -- Shared fixtures, marker registration +``` + +**NOTE:** This project uses `--cov=app` (not `--cov=src` as in the global Python rules): + +```bash +pytest --cov=app --cov-report=term-missing +pytest -m unit # run only unit tests +pytest -m integration # run only integration tests +pytest -m e2e # run only e2e tests +``` + +### Step 5: Phase Development Documentation + +Fill in the dev log skeleton created in Step 1 (`docs/phases/phase-{N}-dev-log.md`): + +```markdown +# Phase {N}: {Title} -- Development Log + +> Status: IN PROGRESS | COMPLETED +> Phase branch: `phase-{N}/{short-description}` +> Date started: YYYY-MM-DD +> Date completed: YYYY-MM-DD +> Related plan section: [Phase {N} in DEVELOPMENT-PLAN](../DEVELOPMENT-PLAN.md#phase-{n}-xxx) + +## What Was Built + +- List of features/components implemented +- Architecture decisions made during development + +## Code Structure + +- New files created and their purposes +- Modified files and what changed +- Module dependency changes + +## Test Coverage + +- Unit test count and coverage % +- Integration test count +- E2E test count +- Overall coverage: XX% + +## Deviations from Plan + +- Any changes from the original plan and why + +## Known Issues / Tech Debt + +- Items deferred to future phases +``` + +Add a link to this dev log in `docs/DEVELOPMENT-PLAN.md` under the corresponding phase section. + +### Step 6: Verification and Checkpoint Verify + +After all development and testing, run verification in this exact order: + +``` +# 1. Run the verification skill -- must pass +/everything-claude-code:verify + +# 2. Verify the checkpoint -- validates all phase deliverables +/everything-claude-code:checkpoint verify [phase name] +``` + +The checkpoint verify validates: +- All tests passing (80%+ coverage) +- Phase dev log exists and is linked +- No unresolved TODOs for this phase +- Module independence constraints met +- Code quality checks pass + +Both MUST pass before proceeding. Fix any issues found. + +### Step 7: Mark Complete, Merge to Main + +After both verify steps pass: + +```bash +# Ensure all changes are committed on the phase branch +# IMPORTANT: Never use `git add -A`. Add specific files to avoid committing +# .env, __pycache__, IDE configs, or other untracked artifacts. +# Verify .gitignore covers all exclusions before staging. +git add backend/ frontend/ docs/ docker-compose.yml pyproject.toml +git status # review staged files before committing +git commit -m "feat: complete phase {N} -- {description}" + +# Tag the checkpoint +git tag checkpoint/phase-{N} + +# Merge to main +git checkout main +git merge phase-{N}/{short-description} + +# Push (after user confirmation) +git push origin main --tags +``` + +**Mark phase as completed (MANDATORY -- do ALL three):** + +1. **Update Phase Summary table** in this file (`CLAUDE.md`): change Status from `IN PROGRESS` to `COMPLETED (YYYY-MM-DD)` +2. **Update dev log** (`docs/phases/phase-{N}-dev-log.md`): fill in `Date completed` and set status to `COMPLETED` +3. **Check off tasks** in `docs/DEVELOPMENT-PLAN.md`: mark all completed task checkboxes `- [x]` under the current phase section + +All three markers must be consistent. If any is missed, the next phase's Step 0 regression gate will catch the discrepancy. + +A checkpoint includes: +- `/everything-claude-code:checkpoint create` at phase start +- `/everything-claude-code:checkpoint verify` at phase end +- All tests passing (80%+ coverage) +- Phase dev log written and linked +- `/everything-claude-code:verify` passed +- Git tag `checkpoint/phase-{N}` created +- Phase marked COMPLETED in three locations +- Branch merged to main + +--- + +## Phase Summary + +| Phase | Branch | Focus | Status | +|-------|--------|-------|--------| +| 1 | `phase-1/core-framework` | FastAPI + LangGraph + React chat loop + PostgresSaver | NOT STARTED | +| 2 | `phase-2/multi-agent-safety` | Supervisor routing + interrupts + templates | NOT STARTED | +| 3 | `phase-3/openapi-discovery` | OpenAPI parsing + MCP generation + SSRF protection | NOT STARTED | +| 4 | `phase-4/analytics-replay` | Replay API + analytics dashboard | NOT STARTED | +| 5 | `phase-5/polish-demo` | Error hardening + demo prep + Docker deploy | NOT STARTED | + +Status values: `NOT STARTED` -> `IN PROGRESS` -> `COMPLETED (YYYY-MM-DD)` + +--- + +## Rules Reference + +This project inherits from `~/.claude/rules/`. CLAUDE.md only contains project-specific overrides -- do NOT duplicate rules content here. + +| Rule File | Project Override | +|-----------|-----------------| +| `common/coding-style.md` | None -- follow as-is | +| `python/coding-style.md` | Use `ruff` only (not black + isort separately) | +| `python/patterns.md` | `Protocol` for all module interfaces. Module boundary map above | +| `python/testing.md` | `--cov=app` (not `--cov=src`). Add `@pytest.mark.e2e` marker | +| `python/security.md` | `bandit` scan recommended before phase merge | +| `python/hooks.md` | All hooks provided by ECC plugin (see below). Type checker deferred to Phase 2+ | +| `common/testing.md` | 80%+ coverage enforced by workflow Step 6 verify | +| `common/security.md` | ECC `governance-capture.js` + `block-no-verify` handle security checks | + +### Hooks (ECC Plugin -- No Custom Hooks) + +All hooks come from the ECC plugin (`everything-claude-code`). No project-level hooks in `.claude/settings.local.json`. + +| ECC Hook | Type | What It Does | +|----------|------|-------------| +| `quality-gate.js` | PostToolUse (Edit/Write) | Auto-runs ruff check + format on .py files | +| `post-edit-format.js` | PostToolUse (Edit) | Auto-format after edits | +| `block-no-verify` | PreToolUse (Bash) | Blocks `--no-verify` flag on git commits | +| `governance-capture.js` | Pre+Post (Bash/Edit/Write) | Captures secrets/policy violations (enable: `ECC_GOVERNANCE_CAPTURE=1`) | +| `pre-bash-git-push-reminder.js` | PreToolUse (Bash) | Confirms before git push | +| `suggest-compact.js` | PreToolUse (Edit/Write) | Suggests context compaction when needed | +| `session-end.js` | Stop | Persists session state | +| `evaluate-session.js` | Stop | Extracts reusable patterns | +| `cost-tracker.js` | Stop | Tracks token/cost metrics | +| `check-console-log.js` | Stop | Checks for debug statements | +| `mcp-health-check.js` | Pre + PostFailure | MCP server health monitoring | + +Controlled by `ECC_HOOK_PROFILE` env var in `~/.claude/settings.json` (currently: `standard`). + +--- + +## Quick Reference + +- Plan doc: `docs/DEVELOPMENT-PLAN.md` +- Architecture doc: `docs/ARCHITECTURE.md` +- Phase dev logs: `docs/phases/phase-{N}-dev-log.md` +- Test command: `pytest --cov=app --cov-report=term-missing` +- **Phase start:** `/everything-claude-code:checkpoint create [phase name]` +- **Phase end:** `/everything-claude-code:checkpoint verify [phase name]` +- Verify command: `/everything-claude-code:verify` +- Orchestrate: `/everything-claude-code:orchestrate {feature|bugfix|refactor}` diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..7d38498 --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,1241 @@ +# Smart Support -- 系统架构文档 + +> 版本: 1.0 | 日期: 2026-03-29 | 状态: APPROVED (CEO + ENG CLEARED) +> +> **配套文档:** 分阶段任务清单、检查点标准、风险登记册详见 [DEVELOPMENT-PLAN.md](DEVELOPMENT-PLAN.md) + +--- + +## 目录 + +1. [系统概览](#1-系统概览) +2. [组件职责分解](#2-组件职责分解) +3. [数据流图](#3-数据流图) +4. [技术栈决策](#4-技术栈决策) +5. [数据库设计](#5-数据库设计) +6. [API 设计](#6-api-设计) +7. [Agent 系统架构](#7-agent-系统架构) +8. [MCP 集成层](#8-mcp-集成层) +9. [安全架构](#9-安全架构) +10. [部署架构](#10-部署架构) +11. [架构决策记录 (ADR)](#11-架构决策记录-adr) +12. [非功能性需求](#12-非功能性需求) + +--- + +## 1. 系统概览 + +### 1.1 定位 + +Smart Support 是一个 AI 客服**行动层框架**。它不替代 Zendesk/Intercom 等现有客服平台, +而是补全这些平台缺失的能力 -- 让 AI 能直接调用内部系统完成操作(查订单、取消订单、发优惠券等)。 + +现有客服工具的自动化率卡在 20-30%,原因是它们只能回答问题,无法执行操作。 +Smart Support 通过 MCP 协议连接内部系统,将自动化率提升到 60%+。 + +### 1.2 核心价值 + +"粘贴你的 API,获得一个能执行真实操作的智能客服。" + +### 1.3 目标用户 + +中型电商公司(日均 500-5000 订单,5-20 名客服)的客户体验负责人。 + +### 1.4 高层架构图 + +``` ++------------------+ +| React Chat UI | (前端: 聊天 / 回放 / 分析仪表盘) ++--------+---------+ + | WebSocket (双向, 流式) + v ++--------+---------+ +| FastAPI Server | (HTTP + WebSocket 入口) +| main.py | ++--------+---------+ + | + v ++--------+---------+ +| Context Manager |<--- PostgresSaver (会话状态持久化) +| (LangGraph State)| langgraph-checkpoint-postgres ++--------+---------+ + | + v ++--------+--------------------+ +| LangGraph Supervisor | (Agent 编排 + 意图路由) +| langgraph-supervisor v1.1 | ++--------+--------------------+ + | + +----+----+----+----+ + | | | | | + v v v v v + Agent Agent Agent Agent Fallback + A B C D Agent + | | | | + v v v v + MCP MCP @tool CLI + Tools Tools Wrapper + | | | | + v v v v ++-------------------------------+ +| 客户内部系统 | +| (Shopify, REST API, gRPC 等) | ++-------------------------------+ + +横切关注点: ++-------------------------------------------+ +| interrupt() -- 写操作人工确认 (HITL) | +| callbacks.py -- Token 用量 / 成本统计 | +| analytics/ -- 解决率 / Agent 使用率 | +| replay/ -- 对话回放 API | +| openapi/ -- OpenAPI 自动发现 + SSRF 防护 | ++-------------------------------------------+ +``` + +### 1.5 项目结构 + +``` +smart-support/ +├── backend/ +│ ├── app/ +│ │ ├── main.py # FastAPI + WebSocket 入口 +│ │ ├── graph.py # LangGraph Supervisor 配置 +│ │ ├── agents/ # Agent 定义 + 工具绑定 +│ │ ├── registry.py # YAML Agent 注册表加载器 +│ │ ├── openapi/ # OpenAPI 解析 + MCP 服务器生成 +│ │ │ ├── parser.py # OpenAPI 3.0 规范解析 +│ │ │ ├── ssrf.py # SSRF 防护 (独立工具) +│ │ │ ├── classifier.py # LLM 端点分类 +│ │ │ └── generator.py # MCP 服务器代码生成 +│ │ ├── replay/ # 对话回放 API +│ │ ├── analytics/ # 数据分析查询 + API +│ │ └── callbacks.py # Token 用量统计 Callback +│ ├── agents.yaml # Agent 注册表配置 +│ ├── templates/ # 垂直行业模板 +│ │ ├── e-commerce.yaml +│ │ ├── saas.yaml +│ │ └── fintech.yaml +│ └── tests/ +├── frontend/ # React 聊天 UI + 回放 + 仪表盘 +├── docker-compose.yml # PostgreSQL + 应用 +└── pyproject.toml +``` + +--- + +## 2. 组件职责分解 + +### 2.1 前端层 (React) + +| 组件 | 职责 | +|------|------| +| Chat UI | 多轮对话界面, 流式 token 显示, interrupt 确认/拒绝交互 | +| Replay UI | 分步时间线回放 Agent 决策过程、工具调用和返回结果 | +| Analytics Dashboard | 解决率、Agent 使用率、升级率、对话成本等指标可视化 | +| OpenAPI Import UI | 粘贴 URL, 查看导入进度, 审核 LLM 分类结果 | + +### 2.2 API 层 (FastAPI) + +| 模块 | 职责 | +|------|------| +| main.py | 应用入口, WebSocket 端点, 静态文件服务 | +| WebSocket Handler | 双向通信: 接收用户消息, 流式返回 token, 处理 interrupt 响应 | + +### 2.3 Agent 编排层 (LangGraph) + +| 模块 | 职责 | +|------|------| +| graph.py | 初始化 LangGraph Supervisor, 绑定 Agent + 工具 + Checkpointer | +| registry.py | 从 YAML 文件加载 Agent 定义, 验证配置合法性 | +| agents/ | Agent 定义: 每个 Agent 拥有独立的 system prompt, 工具集, 权限边界 | + +### 2.4 工具集成层 + +| 模块 | 职责 | +|------|------| +| MCP Tools | 通过 `langchain-mcp-adapters` (MultiServerMCPClient) 连接 MCP 服务器 | +| @tool 装饰器 | 直接 REST/GraphQL HTTP 调用, 无 MCP 开销 | +| CLI Wrappers | 包装现有 CLI 工具 (Shopify CLI, AWS CLI 等), 解析 stdout/stderr | + +### 2.5 持久化层 + +| 模块 | 职责 | +|------|------| +| PostgresSaver | LangGraph checkpoint 持久化, 支持回放和分析查询 | +| PostgreSQL | 存储会话状态、对话历史、分析数据 | + +### 2.6 横切模块 + +| 模块 | 职责 | +|------|------| +| callbacks.py | LangChain callback, 统计每次对话的 token 用量和成本 | +| openapi/ | OpenAPI 规范解析 + SSRF 防护 + LLM 端点分类 + MCP 服务器生成 | +| replay/ | 自定义分页 API, 查询 checkpointer 状态历史 | +| analytics/ | 聚合查询: 解决率、Agent 使用率、升级率、成本 | + +--- + +## 3. 数据流图 + +### 3.1 消息处理流程 + +``` +用户输入消息 + | + v +[1] WebSocket 接收消息 + | + v +[2] 构造 LangGraph input (thread_id + message) + | + v +[3] Supervisor 收到消息 + | + +---> [3a] 意图分类 (LLM structured output) + | + v +[4] 路由到目标 Agent (基于 Agent 描述匹配) + | + +---> [4a] 无匹配 -> Fallback Agent -> 通用回复或澄清提问 + | + v +[5] Agent 执行 + | + +---> [5a] 读操作: 直接调用 MCP Tool -> 返回结果 + | + +---> [5b] 写操作: 触发 interrupt() -> 进入中断流程 (见 3.2) + | + v +[6] Agent 生成回复 + | + v +[7] astream_events() 流式推送 token + | + v +[8] WebSocket 发送给客户端 + | + v +[9] PostgresSaver 自动保存 checkpoint +``` + +### 3.2 中断 (Interrupt) 流程 + +``` +Agent 调用写操作工具 + | + v +[1] interrupt() 暂停图执行 + | + v +[2] 服务端通过 WebSocket 发送确认提示 + {type: "interrupt", action: "cancel_order", params: {...}} + | + v +[3] 客户端显示确认对话框 + | + +---> [3a] 用户批准 + | | + | v + | [4a] Command(resume=True) 恢复图执行 + | | + | v + | [5a] 工具执行操作 -> 返回结果 -> 流式回复 + | + +---> [3b] 用户拒绝 + | | + | v + | [4b] Command(resume=False) 恢复图执行 + | | + | v + | [5b] Agent 确认未执行 -> 流式回复 + | + +---> [3c] 30 分钟无响应 (TTL 超时) + | + v + [4c] 自动取消 + 重新评估当前状态 + | + v + [5c] 向用户发送过期通知 + 提供重试选项 + +会话 TTL 规则 (来源: design-doc.md): +- 会话采用 30 分钟滑动窗口 TTL, 每次用户消息重置计时器 +- 待审批的 interrupt 延长会话 TTL, 直到用户响应或 interrupt 超时 +- interrupt 自身有独立的 30 分钟固定 TTL (超时自动取消) +- WebSocket 断线重连时, 服务端重新发送未完成的 interrupt 提示 +``` + +### 3.3 OpenAPI 导入流程 + +``` +运维人员粘贴 OpenAPI 规范 URL + | + v +[1] SSRF 防护检查 + | + +---> 私有 IP / DNS 重绑定 -> 拒绝并返回错误 + | + v +[2] 获取 OpenAPI 规范文件 + | + v +[3] openapi-spec-validator 验证规范格式 + | + +---> 格式错误 -> 返回清晰的错误信息 + | + v +[4] 解析所有端点 (路径 + 方法 + 参数 + Schema) + | + v +[5] LLM 自动分类 (异步后台任务) + | - 读/写分类 + | - 客户参数识别 + | - Agent 分组建议 + | (通过 WebSocket 推送进度) + | + v +[6] 运维人员审核分类结果 + | - 修正错误分类 + | - 调整 Agent 分组 + | + v +[7] 生成 MCP 服务器 + Agent YAML 配置 + | + v +[8] 新工具注册到 Agent Registry + | + v +[9] 立即可在聊天中使用 +``` + +--- + +## 4. 技术栈决策 + +| 组件 | 选型 | 理由 | +|------|------|------| +| 语言 | Python 3.11+ | LangGraph/LangChain 生态首选语言, Agent 开发最成熟 | +| Web 框架 | FastAPI | 原生 async, WebSocket 支持, 性能优秀 | +| Agent 编排 | LangGraph v1.1 + langgraph-supervisor | 内置 supervisor 模式, 中间件支持, 不重复造轮子 | +| MCP 集成 | langchain-mcp-adapters | MultiServerMCPClient 管理多 MCP 连接 | +| 本地工具 | LangChain @tool 装饰器 | 简单 Python 函数即工具, 无 MCP 开销 | +| 状态持久化 | PostgresSaver (langgraph-checkpoint-postgres v3.0.5) | 从第一天起用 PostgreSQL, 支持回放/分析查询 | +| 数据库 | PostgreSQL 16 | 成熟稳定, jsonb 支持, checkpoint 兼容 | +| LLM | Claude Sonnet 4.6 (默认) | 通过 LangChain BaseChatModel 抽象, 支持切换 OpenAI/Google | +| 流式输出 | FastAPI WebSocket + astream_events() | 双向通信, 内置流式支持 | +| 前端 | React | 组件化, 生态成熟, 满足 Chat/Replay/Dashboard 三个 UI 面 | +| 部署 | Docker Compose | 单命令启动, PostgreSQL + 应用 | +| OpenAPI 验证 | openapi-spec-validator | 成熟的 Python OpenAPI 规范验证库 | +| 测试 | pytest + FastAPI TestClient | Python 测试标准, 支持 async | + +### LLM 提供商抽象 + +``` +环境变量: + LLM_PROVIDER=anthropic # anthropic | openai | google + LLM_MODEL=claude-sonnet-4-6-20250514 + +代码路径: + LangChain BaseChatModel -> ChatAnthropic / ChatOpenAI / ChatGoogleGenerativeAI +``` + +不构建自定义 wrapper。使用 LangChain 内置的提供商抽象。 + +--- + +## 5. 数据库设计 + +### 5.1 设计原则 + +- Phase 1 锁定 schema, 确保 Phase 4 分析/回放无需迁移 +- PostgresSaver 管理 checkpoint 表 (由 langgraph-checkpoint-postgres 自动创建) +- 分析数据通过查询 checkpoint 表 + 自定义表聚合 + +### 5.2 表结构 + +#### checkpoints (由 PostgresSaver 自动管理) + +```sql +-- langgraph-checkpoint-postgres 自动创建的表 +-- 存储 LangGraph 图的每一步状态快照 +CREATE TABLE checkpoints ( + thread_id TEXT NOT NULL, + checkpoint_ns TEXT NOT NULL DEFAULT '', + checkpoint_id TEXT NOT NULL, + parent_checkpoint_id TEXT, + type TEXT, + checkpoint JSONB NOT NULL, -- 图状态快照 + metadata JSONB DEFAULT '{}', -- 包含 step, source, writes 等 + created_at TIMESTAMPTZ DEFAULT NOW(), + PRIMARY KEY (thread_id, checkpoint_ns, checkpoint_id) +); + +-- checkpoint 写入记录 +CREATE TABLE checkpoint_writes ( + thread_id TEXT NOT NULL, + checkpoint_ns TEXT NOT NULL DEFAULT '', + checkpoint_id TEXT NOT NULL, + task_id TEXT NOT NULL, + idx INTEGER NOT NULL, + channel TEXT NOT NULL, + type TEXT, + blob BYTEA NOT NULL, + PRIMARY KEY (thread_id, checkpoint_ns, checkpoint_id, task_id, idx) +); +``` + +#### conversations (自定义 - 对话元数据) + +```sql +CREATE TABLE conversations ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + thread_id TEXT UNIQUE NOT NULL, -- 关联 checkpoints.thread_id + customer_id TEXT, -- 客户标识 (可选) + status TEXT NOT NULL DEFAULT 'active', -- active | resolved | escalated + resolution_type TEXT, -- auto | human | escalated + started_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + ended_at TIMESTAMPTZ, + turn_count INTEGER DEFAULT 0, + agents_used TEXT[] DEFAULT '{}', -- 使用过的 Agent 名称 + total_tokens INTEGER DEFAULT 0, + total_cost_usd NUMERIC(10,6) DEFAULT 0, + escalation_url TEXT, -- Webhook 升级目标 URL + metadata JSONB DEFAULT '{}' +); + +CREATE INDEX idx_conversations_status ON conversations(status); +CREATE INDEX idx_conversations_started_at ON conversations(started_at); +``` + +#### interrupts (自定义 - 中断审批记录) + +```sql +CREATE TABLE interrupts ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + thread_id TEXT NOT NULL REFERENCES conversations(thread_id), + agent_name TEXT NOT NULL, + action TEXT NOT NULL, -- cancel_order, apply_discount 等 + parameters JSONB NOT NULL, + status TEXT NOT NULL DEFAULT 'pending', -- pending | approved | rejected | expired + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + resolved_at TIMESTAMPTZ, + resolved_by TEXT, -- customer | operator | system(ttl) + ttl_expires_at TIMESTAMPTZ NOT NULL -- created_at + 30 min +); + +CREATE INDEX idx_interrupts_status ON interrupts(status); +CREATE INDEX idx_interrupts_ttl ON interrupts(ttl_expires_at) + WHERE status = 'pending'; +``` + +#### analytics_events (自定义 - 分析事件流) + +```sql +CREATE TABLE analytics_events ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + thread_id TEXT NOT NULL, + event_type TEXT NOT NULL, -- message | tool_call | interrupt | escalation | resolution + agent_name TEXT, + tool_name TEXT, + tokens_used INTEGER DEFAULT 0, + cost_usd NUMERIC(10,6) DEFAULT 0, + duration_ms INTEGER, + success BOOLEAN, + error_message TEXT, + metadata JSONB DEFAULT '{}', + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +CREATE INDEX idx_analytics_thread ON analytics_events(thread_id); +CREATE INDEX idx_analytics_type ON analytics_events(event_type); +CREATE INDEX idx_analytics_created ON analytics_events(created_at); +``` + +### 5.3 分析查询示例 + +```sql +-- 解决率 (成功工具调用 + 无升级) +SELECT + COUNT(*) FILTER (WHERE resolution_type = 'auto') * 100.0 / COUNT(*) AS resolution_rate +FROM conversations +WHERE started_at >= NOW() - INTERVAL '7 days'; + +-- Agent 使用率 +SELECT unnest(agents_used) AS agent, COUNT(*) AS usage_count +FROM conversations +WHERE started_at >= NOW() - INTERVAL '7 days' +GROUP BY agent ORDER BY usage_count DESC; + +-- 成本/对话 +SELECT AVG(total_cost_usd) AS avg_cost +FROM conversations +WHERE ended_at IS NOT NULL AND started_at >= NOW() - INTERVAL '7 days'; +``` + +--- + +## 6. API 设计 + +### 6.1 WebSocket 协议 + +**端点:** `ws://host:8000/ws` + +#### 客户端 -> 服务端 + +```json +// 发送消息 +{ + "type": "message", + "thread_id": "conv-abc-123", + "content": "取消订单 #1042" +} + +// 中断响应 (批准) +{ + "type": "interrupt_response", + "thread_id": "conv-abc-123", + "interrupt_id": "int-xyz-789", + "approved": true +} + +// 中断响应 (拒绝) +{ + "type": "interrupt_response", + "thread_id": "conv-abc-123", + "interrupt_id": "int-xyz-789", + "approved": false +} +``` + +#### 服务端 -> 客户端 + +```json +// 流式 token +{ + "type": "token", + "thread_id": "conv-abc-123", + "content": "正在" +} + +// 中断提示 (需要人工确认) +{ + "type": "interrupt", + "thread_id": "conv-abc-123", + "interrupt_id": "int-xyz-789", + "agent": "order_actions", + "action": "cancel_order", + "params": {"order_id": "1042"}, + "description": "取消订单 #1042", + "ttl_seconds": 1800 +} + +// 工具调用通知 (UI 展示用) +{ + "type": "tool_call", + "thread_id": "conv-abc-123", + "agent": "order_lookup", + "tool": "get_order_status", + "params": {"order_id": "1042"} +} + +// 工具结果 +{ + "type": "tool_result", + "thread_id": "conv-abc-123", + "tool": "get_order_status", + "result": {"status": "shipped", "tracking": "SF1234567"} +} + +// 消息完成 +{ + "type": "message_complete", + "thread_id": "conv-abc-123" +} + +// 错误 +{ + "type": "error", + "thread_id": "conv-abc-123", + "message": "LLM 服务暂时不可用,请稍后重试" +} + +// OpenAPI 导入进度 +{ + "type": "import_progress", + "task_id": "imp-456", + "stage": "classifying", + "progress": 0.6, + "message": "正在分类端点 (18/30)..." +} +``` + +#### 重连机制 + +WebSocket 断线后客户端重连: +1. 客户端使用相同 `thread_id` 重新连接 +2. 服务端从 PostgresSaver 恢复会话状态 +3. 如有未完成的 interrupt, 重新发送 interrupt 提示 + +### 6.2 REST 端点 + +| 方法 | 路径 | 描述 | +|------|------|------| +| GET | `/` | 聊天 UI 静态页面 | +| GET | `/api/replay/{thread_id}` | 对话回放 (分页) | +| GET | `/api/replay/{thread_id}?page=2&per_page=20` | 回放分页参数 | +| GET | `/api/analytics` | 分析仪表盘数据 | +| GET | `/api/analytics?range=7d` | 指定时间范围 | +| POST | `/api/openapi/import` | 提交 OpenAPI 规范 URL | +| GET | `/api/openapi/import/{task_id}` | 查询导入任务状态 | +| POST | `/api/openapi/import/{task_id}/review` | 提交分类审核结果 | + +### 6.3 回放 API 响应格式 + +```json +{ + "success": true, + "data": { + "thread_id": "conv-abc-123", + "total_steps": 42, + "page": 1, + "per_page": 20, + "steps": [ + { + "step": 1, + "type": "user_message", + "content": "查一下订单 1042 的状态", + "timestamp": "2026-03-29T10:00:00Z" + }, + { + "step": 2, + "type": "supervisor_routing", + "target_agent": "order_lookup", + "reasoning": "用户询问订单状态,路由到 order_lookup agent", + "timestamp": "2026-03-29T10:00:01Z" + }, + { + "step": 3, + "type": "tool_call", + "agent": "order_lookup", + "tool": "get_order_status", + "params": {"order_id": "1042"}, + "result": {"status": "shipped"}, + "duration_ms": 230, + "timestamp": "2026-03-29T10:00:02Z" + }, + { + "step": 4, + "type": "agent_response", + "agent": "order_lookup", + "content": "订单 #1042 已发货...", + "tokens": 87, + "timestamp": "2026-03-29T10:00:03Z" + } + ] + }, + "error": null +} +``` + +### 6.4 分析 API 响应格式 + +```json +{ + "success": true, + "data": { + "range": "7d", + "total_conversations": 342, + "resolution_rate": 0.62, + "escalation_rate": 0.15, + "avg_turns_per_conversation": 4.2, + "avg_cost_per_conversation_usd": 0.034, + "agent_usage": [ + {"agent": "order_lookup", "count": 198, "percentage": 0.42}, + {"agent": "order_actions", "count": 89, "percentage": 0.19}, + {"agent": "discount", "count": 55, "percentage": 0.12} + ], + "interrupt_stats": { + "total": 89, + "approved": 71, + "rejected": 12, + "expired": 6 + } + }, + "error": null +} +``` + +--- + +## 7. Agent 系统架构 + +### 7.1 Agent 注册表 (YAML 驱动) + +所有 Agent 通过 `agents.yaml` 声明式配置: + +```yaml +agents: + - name: order_lookup + description: "查询订单状态、物流信息、订单详情" + permission: read # read 操作不触发 interrupt + personality: + tone: professional + greeting: "您好,我来帮您查询订单信息。" + escalation_message: "这个问题需要人工客服介入,我来帮您转接。" + tools: + - get_order_status + - get_tracking_info + - get_order_details + + - name: order_actions + description: "取消订单、修改订单、变更收货地址" + permission: write # write 操作触发 interrupt + personality: + tone: careful + greeting: "我可以帮您处理订单变更,所有操作都会先经过您的确认。" + tools: + - cancel_order + - modify_order + - update_shipping_address + + - name: discount + description: "发放优惠券、应用折扣码、退款处理" + permission: write + personality: + tone: friendly + tools: + - apply_discount + - generate_coupon + - process_refund +``` + +### 7.2 注册表加载 (registry.py) + +``` +启动时: +[1] 读取 agents.yaml +[2] 验证配置合法性 (名称唯一, 工具存在, 权限合法) + - 失败: 清晰的错误信息 (文件名 + 行号) +[3] 为每个 Agent 构建 LangGraph node: + - 绑定 system prompt (含 personality 配置) + - 绑定工具集 + - 设置权限边界 +[4] 注册到 Supervisor +``` + +### 7.3 Supervisor 路由 + +``` + +---> order_lookup (读) + | +用户消息 --> Supervisor --> order_actions (写 + interrupt) + (意图分类) | + +---> discount (写 + interrupt) + | + +---> fallback_agent (兜底) +``` + +路由机制: +- Supervisor 使用 LLM structured output 进行意图分类 +- 基于 Agent 的 `description` 字段选择最佳匹配 +- 多意图请求 (如 "取消订单并给我优惠券") 由 Supervisor 顺序编排 +- 歧义意图 -> 澄清提问 +- 无匹配 -> Fallback Agent 处理 + +### 7.4 Fallback Agent + +专门处理路由失败的通用 Agent: +- 捕获所有未匹配的意图 +- 提供通用帮助信息 +- 引导用户更清晰地表述需求 +- 记录未匹配事件供后续分析路由准确率 + +### 7.5 垂直行业模板 + +预置 YAML 模板, 新客户 5 分钟内上手: + +| 模板 | 包含的 Agent | 典型工具 | +|------|-------------|---------| +| e-commerce.yaml | order_lookup, order_actions, discount, shipping | 订单查询, 取消, 退款, 物流追踪 | +| saas.yaml | account, billing, support | 账户管理, 订阅变更, 工单创建 | +| fintech.yaml | account_inquiry, transaction, dispute | 余额查询, 交易记录, 争议处理 | + +--- + +## 8. MCP 集成层 + +### 8.1 三层工具架构 + +``` +LangChain Tool Interface (统一 Python 函数) + | + +--- [1] MCP Tools (langchain-mcp-adapters) + | 用于复杂/有状态的集成 + | 通过 MCP 协议 (stdio/SSE) 连接 + | + +--- [2] Direct API Tools (@tool 装饰器) + | 简单 REST/GraphQL 调用 + | 无 MCP 开销 + | + +--- [3] CLI Wrappers (@tool 装饰器) + 包装 CLI 工具 (Shopify CLI, AWS CLI) + 解析 stdout/stderr +``` + +关键设计: LangChain 工具就是 Python 函数加描述 -- 后端实现细节对 Agent 透明。 +不构建自定义工具基类。 + +### 8.2 MCP 连接管理 + +```python +# 使用 langchain-mcp-adapters 的 MultiServerMCPClient +# 每个 MCP 服务器独立连接 +mcp_config = { + "shopify": { + "command": "python", + "args": ["mcp_servers/shopify_server.py"], + "transport": "stdio" + }, + "internal_api": { + "url": "http://mcp-server:3000/sse", + "transport": "sse" + } +} +``` + +### 8.3 OpenAPI 自动生成 MCP 服务器 + +Phase 3 核心功能: + +``` +OpenAPI 3.0 规范 + | + v +[解析] 提取端点 + 参数 + Schema + | + v +[分类] LLM 自动分类: + - read / write + - 客户参数 (order_id, customer_id 等) + - Agent 分组建议 + | + v +[审核] 运维人员修正分类结果 + | + v +[生成] 输出: + - MCP 服务器代码 (包装每个端点) + - agents.yaml 配置 (Agent 定义 + 工具绑定) + | + v +[注册] 热加载到 Agent Registry +``` + +### 8.4 工具故障处理 + +| 故障类型 | 处理策略 | +|---------|---------| +| 瞬时错误 (超时/限流) | 指数退避重试 (最多 3 次) | +| 认证失败 | 立即升级到人工, 不重试 | +| API 不可用 | 向用户显示错误 + 升级 | +| 响应格式异常 | 记录日志 + 返回友好错误消息 | + +--- + +## 9. 安全架构 + +### 9.1 安全层次 + +``` ++---------------------------------------+ +| [L1] 输入验证 | +| - WebSocket 消息格式校验 | +| - 消息长度限制 | +| - Agent YAML 配置验证 | ++---------------------------------------+ +| [L2] SSRF 防护 (openapi/ssrf.py) | +| - 屏蔽私有 IP (10.x, 172.16-31.x, | +| 192.168.x, 127.x, 169.254.x) | +| - DNS 重绑定攻击防护 | +| - URL 白名单 (可选) | ++---------------------------------------+ +| [L3] HITL 人工确认 | +| - 所有写操作需要人工批准 | +| - 30 分钟 TTL, 过期自动取消 | +| - 重新评估当前状态后才允许重试 | ++---------------------------------------+ +| [L4] 权限隔离 | +| - 每个 Agent 只能访问配置的工具集 | +| - read Agent 无法调用 write 工具 | +| - 工具级别的参数校验 | ++---------------------------------------+ +| [L5] 操作审计 | +| - 每个操作记录: Agent, 参数, 结果, | +| 时间戳, 操作 ID | +| - 全量存入 PostgreSQL | +| - 支持回放和事后审查 | ++---------------------------------------+ +``` + +### 9.2 SSRF 防护详细设计 + +`openapi/ssrf.py` 作为独立工具模块: + +``` +URL 输入 + | + v +[1] 解析 URL -> 提取 hostname + | + v +[2] DNS 解析 hostname -> IP 地址 + | + v +[3] 检查 IP 是否为私有地址: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 + - 127.0.0.0/8 + - 169.254.0.0/16 + - ::1, fe80::/10 + - 0.0.0.0 + | + +---> 私有 IP -> 拒绝, 返回明确错误 + | + v +[4] 发起 HTTP 请求 + | + v +[5] 二次检查: 验证实际连接的 IP (防 DNS 重绑定) + | + +---> 重绑定到私有 IP -> 中断连接, 返回错误 + | + v +[6] 返回响应内容 +``` + +### 9.3 未来安全增强 (NOT in scope, 记录于 TODOS.md) + +- API Key 认证 (WebSocket 连接) +- Session-based 认证 (Dashboard/Replay/Import) +- 全端点限流 +- 多租户隔离 + +--- + +## 10. 部署架构 + +### 10.1 Docker Compose + +``` ++-------------------------------------------+ +| Docker Compose | +| | +| +----------------+ +------------------+ | +| | smart-support | | PostgreSQL 16 | | +| | (Python App) | | | | +| | | | - checkpoints | | +| | FastAPI :8000 +--> - conversations | | +| | React (static) | | - interrupts | | +| | | | - analytics | | +| +----------------+ +------------------+ | +| | ++-------------------------------------------+ +``` + +```yaml +# docker-compose.yml (概念) +version: "3.9" +services: + app: + build: . + ports: + - "8000:8000" + environment: + - DATABASE_URL=postgresql://user:pass@db:5432/smartsupport + - LLM_PROVIDER=anthropic + - LLM_MODEL=claude-sonnet-4-6-20250514 + - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} + depends_on: + - db + + db: + image: postgres:16 + environment: + - POSTGRES_DB=smartsupport + - POSTGRES_USER=user + - POSTGRES_PASSWORD=pass + volumes: + - pgdata:/var/lib/postgresql/data + ports: + - "5432:5432" + +volumes: + pgdata: +``` + +### 10.2 环境变量 + +| 变量 | 用途 | 默认值 | +|------|------|--------| +| DATABASE_URL | PostgreSQL 连接串 | (必填) | +| LLM_PROVIDER | LLM 提供商 | anthropic | +| LLM_MODEL | 模型名称 | claude-sonnet-4-6-20250514 | +| ANTHROPIC_API_KEY | Anthropic API Key | (必填) | +| OPENAI_API_KEY | OpenAI API Key | (可选) | +| INTERRUPT_TTL_MINUTES | 中断超时时间 | 30 | +| WEBHOOK_RETRY_MAX | Webhook 最大重试次数 | 3 | + +### 10.3 单命令启动 + +```bash +# 设置 API Key +export ANTHROPIC_API_KEY=sk-xxx + +# 启动 +docker compose up + +# 访问 +open http://localhost:8000 +``` + +--- + +## 11. 架构决策记录 (ADR) + +### ADR-001: 使用 LangGraph Supervisor 进行多 Agent 编排 + +**背景:** 需要将不同类型的客服请求路由到不同的专业 Agent。 + +**决策:** 使用 `langgraph-supervisor` v1.1 内置的 supervisor 模式。 + +**正面影响:** +- 不同 Agent 拥有独立的权限边界和工具集 +- 不同操作有不同的失败模式和安全检查 +- 框架内置, 无需自建编排逻辑 +- 支持中间件扩展 + +**负面影响:** +- 每次请求增加一轮 LLM 调用 (supervisor 路由), 延迟 8-15 秒 +- 原型阶段可能过度工程化 (Cross-Model Review 的质疑) + +**缓解措施:** 全程流式输出 token, 降低用户感知延迟。 + +**替代方案:** +- 单 Agent + 工具路由: 更简单, 但权限隔离困难 +- 关键词路由: 无 LLM 开销, 但准确率低 + +**状态:** ACCEPTED (创始人明确选择, 理由: 不同操作需要不同权限边界) + +--- + +### ADR-002: 从第一天使用 PostgresSaver 而非 InMemorySaver + +**背景:** LangGraph 提供多种 checkpointer 实现。InMemorySaver 更简单, PostgresSaver 需要数据库。 + +**决策:** 从 Phase 1 起使用 PostgresSaver + Docker Compose。 + +**正面影响:** +- Phase 4 的回放和分析功能可直接查询, 无需迁移 +- 进程重启不丢失会话状态 +- 数据 schema 从第一天锁定 + +**负面影响:** +- 开发环境需要运行 PostgreSQL (通过 Docker Compose 缓解) +- 比 InMemorySaver 配置更复杂 + +**替代方案:** +- InMemorySaver: 更简单但重启丢数据, 迁移到 PostgresSaver 并非简单配置切换 +- SQLiteSaver: 中间方案, 但最终仍需迁移 + +**状态:** ACCEPTED + +--- + +### ADR-003: WebSocket 双向通信而非 HTTP 轮询 + +**背景:** 需要支持流式 token 输出 + interrupt 交互。 + +**决策:** FastAPI WebSocket + LangGraph astream_events()。 + +**正面影响:** +- 真正的双向通信: 服务端推送 token, 客户端发送 interrupt 响应 +- 延迟低, 无轮询开销 +- LangGraph 原生支持 astream_events() + +**负面影响:** +- WebSocket 连接管理复杂 (断线重连, 状态恢复) +- 不如 REST 易于调试 + +**替代方案:** +- SSE + REST: 服务端推送用 SSE, 客户端操作用 REST。更简单但需两个通道。 +- HTTP 轮询: 最简单但延迟高, 不适合流式场景。 + +**状态:** ACCEPTED + +--- + +### ADR-004: YAML 声明式 Agent 注册表 + +**背景:** 需要让客户和运维人员能配置 Agent, 而不需要修改代码。 + +**决策:** Agent 定义通过 YAML 文件配置, 启动时加载验证。 + +**正面影响:** +- 非开发人员可配置 Agent +- 新增 Agent = 新增配置条目 + 连接工具 +- 支持垂直行业模板 (预置 YAML) +- 配置可版本控制 + +**负面影响:** +- YAML 配置错误的调试体验不如代码 +- 需要构建配置验证逻辑 + +**缓解措施:** 启动时严格验证, 错误信息包含文件名和行号。 + +**状态:** ACCEPTED + +--- + +### ADR-005: LangGraph interrupt() 实现 HITL 而非自定义审批系统 + +**背景:** 写操作需要人工确认。 + +**决策:** 使用 LangGraph 内置的 `interrupt()` 函数暂停图执行, 等待用户响应。 + +**正面影响:** +- 框架内置, 无需自建状态机 +- 与 checkpointer 深度集成, 中断状态自动持久化 +- 使用 `Command(resume=value)` 恢复, API 简洁 + +**负面影响:** +- 需要自建 TTL 超时逻辑 (30 分钟) +- 需要处理 WebSocket 断线后重发 interrupt + +**状态:** ACCEPTED + +--- + +### ADR-006: OpenAPI 规范解析 + LLM 分类 + 人工审核三步流程 + +**背景:** 核心卖点 "粘贴 API, 获得客服" 需要自动理解 API 端点。 + +**决策:** 三步流程: 解析规范 -> LLM 自动分类 -> 人工审核修正。 + +**正面影响:** +- 自动化程度高: LLM 处理大部分分类工作 +- 人工审核兜底: 防止 LLM 错误分类导致安全问题 (将读操作误分为写) +- 异步执行 + WebSocket 进度推送, 不阻塞聊天 + +**负面影响:** +- LLM 分类成本 (大型 API 可能有 100+ 端点) +- 分类准确率取决于 API 文档质量 + +**替代方案:** +- 纯手动配置: 安全但耗时 +- 纯 LLM 自动化: 快但有安全风险 + +**状态:** ACCEPTED + +--- + +### ADR-007: SSRF 防护作为独立工具模块 + +**背景:** OpenAPI URL 导入功能允许用户提供任意 URL, 存在 SSRF 风险。 + +**决策:** 构建独立的 `openapi/ssrf.py` 工具, 屏蔽私有 IP + DNS 重绑定。 + +**正面影响:** +- 独立模块, 可在 Phase 3 前并行开发 +- 可复用于其他需要外部 URL 访问的场景 +- 双重检查 (DNS 解析前 + 实际连接后) + +**状态:** ACCEPTED + +--- + +## 12. 非功能性需求 + +### 12.1 性能 + +| 指标 | 目标 | 备注 | +|------|------|------| +| 首 token 延迟 | < 2 秒 | Supervisor 路由 + Agent 启动 | +| 端到端响应时间 | 8-15 秒 | 含 LLM 调用, 通过流式输出缓解感知延迟 | +| MCP 工具调用 | < 5 秒 | 取决于下游 API | +| 回放 API | < 500ms | 分页查询, 每页 20 步 | +| 分析查询 | < 2 秒 | PostgreSQL 聚合查询 + 索引 | +| WebSocket 消息 | < 100ms | 本地处理延迟 | + +### 12.2 可扩展性 + +**当前阶段 (原型):** +- 单实例部署, Docker Compose +- 单租户架构 +- 预期负载: 并发 10-50 个对话 + +**扩展路线图:** + +| 阶段 | 用户规模 | 架构变更 | +|------|---------|---------| +| 原型 | 1-10 并发 | 单实例 Docker Compose | +| 首个客户 | 10-50 并发 | 增加连接池, 优化查询 | +| 多客户 | 50-200 并发 | 多租户隔离, 水平扩展应用层 | +| 规模化 | 200+ 并发 | Redis 缓存层, 读写分离, CDN 静态资源 | + +### 12.3 可靠性 + +| 故障场景 | 处理策略 | +|---------|---------| +| LLM API 超时/限流 | 向用户返回错误消息, 建议重试 | +| MCP 工具调用失败 | 升级到人工 + 显示错误消息 | +| PostgreSQL 连接断开 | try/except 包裹图调用, 返回用户友好错误 | +| WebSocket 断线 | 客户端自动重连, 服务端恢复状态 | +| 中断 TTL 过期 | 自动取消 + 提供重试选项 | +| Webhook 目标不可达 | 指数退避重试 (最多 3 次) + 记录日志 | +| 无效 YAML 配置 | 启动时检查, 清晰报错 (文件+行号) | + +### 12.4 可测试性 + +| 测试类型 | 覆盖范围 | 工具 | +|---------|---------|------| +| 单元测试 | Agent 逻辑, SSRF 防护, YAML 解析 | pytest | +| 集成测试 | WebSocket 消息流, 图调用, Checkpoint | pytest + FastAPI TestClient | +| E2E 测试 | 6 个关键流程 (见下) | pytest | + +**6 个 E2E 关键流程:** +1. 快乐路径: 查询订单状态 -> 获得答案 +2. 取消+批准: 取消订单 -> interrupt -> 批准 -> 确认取消 +3. 取消+拒绝: 取消订单 -> interrupt -> 拒绝 -> 未执行 +4. 多轮上下文: "查订单1042" -> "取消那个" -> 正确解析指代 +5. OpenAPI 导入: 粘贴规范 URL -> 工具生成 -> 聊天中使用新工具 +6. 对话回放: 选择已完成对话 -> 分步回放正确渲染 + +**覆盖率目标:** 80%+ + +### 12.5 成本控制 + +| 措施 | 说明 | +|------|------| +| Prompt 缓存 | 从第一天启用 (Phase 1 任务 1.4.5), 减少重复 system prompt 的 LLM 成本。来源: TODOS.md 设计变更 | +| Token 用量统计 | LangChain callback 记录每次对话的 token 消耗 | +| 成本/对话指标 | 在分析仪表盘展示, 支持优化决策 | +| LLM 提供商可切换 | 可根据成本/性能在 Claude/GPT/Gemini 间切换 | + +### 12.6 NOT in Scope + +> 完整的范围外事项清单见 [DEVELOPMENT-PLAN.md 范围外事项](DEVELOPMENT-PLAN.md#范围外事项-来自工程评审)。 +> 关键排除项: 认证/授权、多租户、CI/CD、限流、Zendesk/Intercom 集成、移动端、i18n、计费。 + +--- + +## 附录: 关键参考文档 + +| 文档 | 路径 | 内容 | +|------|------|------| +| **开发计划** | [`docs/DEVELOPMENT-PLAN.md`](DEVELOPMENT-PLAN.md) | 分阶段任务清单、检查点标准、风险登记册、并行化策略 | +| 项目概览 | `README.md` | 技术栈, 项目结构, 快速开始 | +| CEO 计划 | `ceo-plan.md` | 产品愿景, 范围决策, 6 项扩展 | +| 设计文档 | `design-doc.md` | 问题定义, 约束, 方案选择 | +| 工程评审 | `eng-review-plan.md` | 架构决策, 测试策略, 失败模式 | +| 测试计划 | `eng-review-test-plan.md` | 测试路径, 边界情况, E2E 流程 | +| 待办事项 | `TODOS.md` | 延迟项, 设计变更记录 | diff --git a/docs/DEVELOPMENT-PLAN.md b/docs/DEVELOPMENT-PLAN.md new file mode 100644 index 0000000..468fba4 --- /dev/null +++ b/docs/DEVELOPMENT-PLAN.md @@ -0,0 +1,1040 @@ +# Smart Support -- 详细开发计划 + +> 基于 CEO 计划、设计文档、工程评审计划、测试计划和 TODOS 综合制定。 +> 生成日期: 2026-03-29 +> 预计总工期: 7-8 周 (1 名全职高级 Python 工程师) +> +> **配套文档:** 技术栈、项目结构、架构决策 (ADR)、数据库 schema、API 协议、安全架构等详见 [ARCHITECTURE.md](ARCHITECTURE.md) + +--- + +## 目录 + +1. [总览](#总览) +2. [Phase 1: 核心框架](#phase-1-核心框架-第-1-3-周) +3. [Phase 2: 多 Agent 路由 + 安全层](#phase-2-多-agent-路由--安全层-第-3-4-周) +4. [Phase 3: OpenAPI 自动发现](#phase-3-openapi-自动发现-第-4-6-周) +5. [Phase 4: 对话回放 + 数据分析](#phase-4-对话回放--数据分析-第-6-7-周) +6. [Phase 5: 打磨 + Demo 准备](#phase-5-打磨--demo-准备-第-7-8-周) +7. [Phase 6: 客户接入](#phase-6-客户接入-第-8-周起) +8. [并行化策略](#并行化策略) +9. [全局风险登记册](#全局风险登记册) +10. [验收标准总览](#验收标准总览) + +--- + +## 总览 + +Smart Support 是一个 AI 客服行动层框架。核心价值主张: "粘贴你的 API, 获得一个能执行真实操作的智能客服。" + +框架不替代 Zendesk/Intercom, 而是补全它们缺失的"行动层" -- 让 AI 能直接调用内部系统完成查询、取消、退款等操作。 + +> 技术栈、项目结构、架构决策详见 [ARCHITECTURE.md](ARCHITECTURE.md#4-技术栈决策)。 +> 本文档专注于 **什么时候做什么、怎么验证、有什么风险**。 + +--- + +## Phase 1: 核心框架 (第 1-3 周) + +### 目标 + +搭建完整的聊天回路: 用户在 React UI 发送消息 -> FastAPI WebSocket 接收 -> LangGraph Supervisor 处理 -> Mock Agent 响应 -> 流式返回给用户。所有会话状态通过 PostgresSaver 持久化。 + +### 任务清单 + +#### 1.1 项目初始化与基础设施 (预计 2 天) + +- [ ] **1.1.1** 初始化 Python 项目结构 (`pyproject.toml`, 依赖管理) + - 文件: `backend/pyproject.toml` + - 工作量: S (2 小时) + - 依赖: 无 + - 风险: 低 +- [ ] **1.1.2** 创建 Docker Compose 配置 (PostgreSQL 16 + 应用) + - 文件: `docker-compose.yml` + - 工作量: S (2 小时) + - 依赖: 无 + - 风险: 低 +- [ ] **1.1.3** 配置 PostgresSaver 检查点持久化 + - 文件: `backend/app/db.py` + - 工作量: M (4 小时) + - 依赖: 1.1.2 + - 风险: 中 -- PostgresSaver schema 初始化需要验证兼容性 +- [ ] **1.1.4** 设置 pytest + FastAPI TestClient 测试框架 + - 文件: `backend/tests/conftest.py`, `backend/pyproject.toml` + - 工作量: S (2 小时) + - 依赖: 1.1.1 + - 风险: 低 +- [ ] **1.1.5** 配置环境变量管理 (`LLM_PROVIDER`, `LLM_MODEL`, DB 连接等) + - 文件: `backend/app/config.py`, `.env.example` + - 工作量: S (1 小时) + - 依赖: 无 + - 风险: 低 + +#### 1.2 YAML Agent 注册表 (预计 2 天) + +- [ ] **1.2.1** 设计 Agent YAML 配置 schema (name, description, permission, personality, tools) + - 文件: `backend/agents.yaml` + - 工作量: S (2 小时) + - 依赖: 无 + - 风险: 低 +- [ ] **1.2.2** 实现 YAML 注册表加载器 + 校验 (无效 YAML 需给出文件/行号错误) + - 文件: `backend/app/registry.py` + - 工作量: M (4 小时) + - 依赖: 1.2.1 + - 风险: 中 -- 校验逻辑需覆盖各种畸形输入 +- [ ] **1.2.3** 实现 Agent 人格配置 (tone, greeting, escalation_style) + - 文件: `backend/app/registry.py` (扩展) + - 工作量: S (1 小时) + - 依赖: 1.2.2 + - 风险: 低 +- [ ] **1.2.4** 编写注册表加载器单元测试 (正常加载、空文件、无效 YAML、缺少必填字段) + - 文件: `backend/tests/test_registry.py` + - 工作量: S (2 小时) + - 依赖: 1.2.2 + - 风险: 低 + +#### 1.3 Mock Agent 与工具 (预计 1.5 天) + +- [ ] **1.3.1** 创建 Mock 订单查询 Agent + 工具 (get_order_status, get_tracking_info) + - 文件: `backend/app/agents/order_lookup.py` + - 工作量: M (3 小时) + - 依赖: 1.2.2 + - 风险: 低 +- [ ] **1.3.2** 创建 Mock 订单操作 Agent + 工具 (cancel_order -- 需要 interrupt) + - 文件: `backend/app/agents/order_actions.py` + - 工作量: M (3 小时) + - 依赖: 1.2.2 + - 风险: 低 +- [ ] **1.3.3** 创建通用回退 Agent (处理误路由和无法分类的意图) + - 文件: `backend/app/agents/fallback.py` + - 工作量: S (2 小时) + - 依赖: 1.2.2 + - 风险: 低 +- [ ] **1.3.4** 编写 Mock Agent 单元测试 + - 文件: `backend/tests/test_agents.py` + - 工作量: S (2 小时) + - 依赖: 1.3.1, 1.3.2, 1.3.3 + - 风险: 低 + +#### 1.4 LangGraph Supervisor 配置 (预计 2 天) + +- [ ] **1.4.1** 配置 LangGraph Supervisor (使用 langgraph-supervisor, 连接注册表中的 Agents) + - 文件: `backend/app/graph.py` + - 工作量: M (6 小时) + - 依赖: 1.2.2, 1.3.1, 1.3.2, 1.3.3 + - 风险: 高 -- LangGraph supervisor 配置是核心, 如果阻塞超过 5 天需回退到单 Agent +- [ ] **1.4.2** 实现基础 interrupt() 流程 (写操作触发人工确认) + - 文件: `backend/app/graph.py` (扩展) + - 工作量: M (4 小时) + - 依赖: 1.4.1 + - 风险: 中 -- interrupt/resume 状态管理需仔细测试 +- [ ] **1.4.3** 配置 LLM Provider 抽象 (BaseChatModel + 环境变量切换) + - 文件: `backend/app/llm.py` + - 工作量: S (2 小时) + - 依赖: 1.1.5 + - 风险: 低 +- [ ] **1.4.4** 实现 Token 用量统计回调 + - 文件: `backend/app/callbacks.py` + - 工作量: S (2 小时) + - 依赖: 1.4.1 + - 风险: 低 +- [ ] **1.4.5** 启用 Prompt Caching (从第一天减少重复 system prompt 的 LLM 成本) + - 文件: `backend/app/llm.py` (扩展) + - 工作量: S (1 小时) + - 依赖: 1.4.3 + - 风险: 低 + - 来源: TODOS.md 设计变更 -- "Prompt caching: 从第一天启用" +- [ ] **1.4.6** 实现会话滑动窗口 TTL (30 分钟, 每次消息重置; 待审批的 interrupt 延长 TTL 直到解决) + - 文件: `backend/app/session_manager.py` + - 工作量: M (3 小时) + - 依赖: 1.4.1, 1.1.3 + - 风险: 中 -- 需区分 session TTL (滑动窗口) 和 interrupt TTL (固定 30 分钟) + - 来源: design-doc.md -- "30-minute sliding window TTL (reset on each turn)" +- [ ] **1.4.7** 编写 Graph 单元测试 (supervisor 路由、mock 工具调用、状态断言、session TTL) + - 文件: `backend/tests/test_graph.py` + - 工作量: M (4 小时) + - 依赖: 1.4.1, 1.4.2 + - 风险: 中 + +#### 1.5 FastAPI WebSocket 后端 (预计 2 天) + +- [ ] **1.5.1** 实现 FastAPI 应用入口 + WebSocket `/ws` 端点 + - 文件: `backend/app/main.py` + - 工作量: M (4 小时) + - 依赖: 1.4.1 + - 风险: 低 +- [ ] **1.5.2** 实现 WebSocket 流式输出 (astream_events) + - 文件: `backend/app/main.py` (扩展) + - 工作量: M (4 小时) + - 依赖: 1.5.1 + - 风险: 中 -- 流式事件格式需与前端协议一致 +- [ ] **1.5.3** 实现 interrupt 响应处理 (WebSocket 接收审批/拒绝, 恢复 graph 执行) + - 文件: `backend/app/main.py` (扩展) + - 工作量: M (4 小时) + - 依赖: 1.5.2, 1.4.2 + - 风险: 高 -- 断线重连 + 重发 interrupt 提示是易出错点 +- [ ] **1.5.4** 实现 DB 错误处理 (try/except 包裹 graph 调用, 返回友好错误信息) + - 文件: `backend/app/main.py` (扩展) + - 工作量: S (1 小时) + - 依赖: 1.5.1 + - 风险: 低 +- [ ] **1.5.5** 编写 WebSocket 测试 (连接、消息流、流式输出、interrupt 响应、断线处理) + - 文件: `backend/tests/test_websocket.py` + - 工作量: M (4 小时) + - 依赖: 1.5.1, 1.5.2, 1.5.3 + - 风险: 中 + +#### 1.6 React 聊天 UI (预计 3 天) [可并行] + +- [ ] **1.6.1** 初始化 React 项目 (Vite 或 CRA) + - 文件: `frontend/` 目录 + - 工作量: S (1 小时) + - 依赖: 无 + - 风险: 低 +- [ ] **1.6.2** 实现聊天消息列表组件 (支持流式 token 渲染) + - 文件: `frontend/src/components/ChatMessages.tsx` + - 工作量: M (4 小时) + - 依赖: 1.6.1 + - 风险: 低 +- [ ] **1.6.3** 实现消息输入组件 + - 文件: `frontend/src/components/ChatInput.tsx` + - 工作量: S (2 小时) + - 依赖: 1.6.1 + - 风险: 低 +- [ ] **1.6.4** 实现 WebSocket 连接管理 (连接、断线重连、消息收发) + - 文件: `frontend/src/hooks/useWebSocket.ts` + - 工作量: M (4 小时) + - 依赖: 1.6.1 + - 风险: 中 -- 需处理断线重连逻辑 +- [ ] **1.6.5** 实现 interrupt 确认 UI (确认/拒绝按钮, 操作详情展示) + - 文件: `frontend/src/components/InterruptPrompt.tsx` + - 工作量: M (3 小时) + - 依赖: 1.6.4 + - 风险: 低 +- [ ] **1.6.6** 实现 Agent 操作内联展示 (工具调用过程可见) + - 文件: `frontend/src/components/AgentAction.tsx` + - 工作量: S (2 小时) + - 依赖: 1.6.2 + - 风险: 低 +- [ ] **1.6.7** 集成聊天页面主组件 + - 文件: `frontend/src/pages/ChatPage.tsx` + - 工作量: M (3 小时) + - 依赖: 1.6.2, 1.6.3, 1.6.4, 1.6.5, 1.6.6 + - 风险: 低 + +### Phase 1 检查点标准 + +通过以下全部验证才能进入 Phase 2: + +- [ ] `docker compose up` 成功启动 PostgreSQL + 应用 +- [ ] 打开 `http://localhost:8000` 聊天 UI 加载正常 +- [ ] 发送 "订单 1042 的状态" -> 收到 Mock Agent 的流式响应 +- [ ] 发送 "取消订单 1042" -> 收到 interrupt 确认提示 -> 批准 -> 收到确认消息 +- [ ] 发送 "取消订单 1042" -> 收到 interrupt 确认提示 -> 拒绝 -> 收到取消消息 +- [ ] 多轮对话上下文保持 (通过 PostgresSaver 验证) +- [ ] 会话 30 分钟无活动后过期; 每次消息重置 TTL; 待审批 interrupt 延长 TTL +- [ ] 无效 YAML 配置启动时给出清晰错误信息 +- [ ] `pytest --cov` 覆盖率 >= 80% (Phase 1 代码) + +### Phase 1 测试要求 + +| 类型 | 测试项 | 文件 | +|------|--------|------| +| 单元测试 | YAML 注册表加载/校验 | `tests/test_registry.py` | +| 单元测试 | Mock Agent 工具调用 | `tests/test_agents.py` | +| 单元测试 | Graph supervisor 路由 | `tests/test_graph.py` | +| 单元测试 | 会话滑动窗口 TTL (过期、重置、interrupt 延长) | `tests/test_graph.py` | +| 集成测试 | WebSocket 消息流 | `tests/test_websocket.py` | +| 集成测试 | interrupt 审批/拒绝流程 | `tests/test_websocket.py` | +| E2E | Happy path: 查询 -> 响应 | 手动验证 | +| E2E | 取消 + 批准: 写操作 -> interrupt -> 批准 | 手动验证 | +| E2E | 取消 + 拒绝: 写操作 -> interrupt -> 拒绝 | 手动验证 | + +### Phase 1 风险项 + +| 风险 | 严重度 | 缓解措施 | +|------|--------|----------| +| LangGraph supervisor 配置复杂度超预期 | 高 | 如果阻塞超过 5 天, 回退到单 Agent + 工具路由, 后续再重构为多 Agent | +| PostgresSaver schema 兼容性问题 | 中 | 提前阅读 langgraph-checkpoint-postgres 文档, 使用官方 migration | +| WebSocket interrupt/resume 状态管理 | 中 | 先实现最简版本 (无断线重连), 后续迭代增强 | +| 流式事件格式前后端不一致 | 中 | 提前定义 WebSocket 消息协议文档, 前后端同步开发 | + +### Phase 1 交付物 + +- FastAPI 后端 (WebSocket 聊天端点) +- LangGraph Supervisor + 3 个 Mock Agent +- YAML Agent 注册表加载器 +- PostgresSaver 检查点持久化 +- React 聊天 UI (流式输出 + interrupt 确认) +- Docker Compose 配置 +- 单元测试 + 集成测试 (覆盖率 >= 80%) + +--- + +## Phase 2: 多 Agent 路由 + 安全层 (第 3-4 周) + +### 目标 + +完善 Supervisor 的意图分类和多 Agent 路由能力, 实现 Webhook 升级、垂直行业模板、中断超时处理。 + +### 前置条件 + +- Phase 1 检查点全部通过 +- TODOS.md 中无阻塞 Phase 2 的待办项 + +### 任务清单 + +#### 2.1 Supervisor 路由增强 (预计 2 天) + +- [ ] **2.1.1** 实现 LLM 结构化输出的意图分类 (基于 Agent 描述选择) + - 文件: `backend/app/graph.py` (增强) + - 工作量: M (4 小时) + - 依赖: Phase 1 完成 + - 风险: 中 -- 路由准确率需要评估 +- [ ] **2.1.2** 实现多意图请求处理 ("取消订单并给我一个折扣" -> 顺序执行) + - 文件: `backend/app/graph.py` (增强) + - 工作量: M (6 小时) + - 依赖: 2.1.1 + - 风险: 高 -- 多意图原子性问题 (全部成功 vs. 部分失败升级) +- [ ] **2.1.3** 实现歧义意图处理 (无法分类时询问澄清问题) + - 文件: `backend/app/agents/fallback.py` (增强) + - 工作量: S (2 小时) + - 依赖: 2.1.1 + - 风险: 低 +- [ ] **2.1.4** 编写路由测试 (正确路由、多意图、歧义、回退) + - 文件: `backend/tests/test_routing.py` + - 工作量: M (4 小时) + - 依赖: 2.1.1, 2.1.2, 2.1.3 + - 风险: 低 + +#### 2.2 Mock 折扣 Agent (预计 0.5 天) + +- [ ] **2.2.1** 创建 Mock 折扣 Agent + 工具 (apply_discount, generate_coupon) + - 文件: `backend/app/agents/discount.py` + - 工作量: S (2 小时) + - 依赖: Phase 1 + - 风险: 低 +- [ ] **2.2.2** 更新 agents.yaml 添加折扣 Agent 配置 + - 文件: `backend/agents.yaml` + - 工作量: S (30 分钟) + - 依赖: 2.2.1 + - 风险: 低 + +#### 2.3 中断超时处理 (预计 1 天) + +- [ ] **2.3.1** 实现 30 分钟 TTL 自动取消机制 + - 文件: `backend/app/interrupt_manager.py` + - 工作量: M (4 小时) + - 依赖: Phase 1 (interrupt 基础) + - 风险: 中 -- 定时器精度和状态一致性 +- [ ] **2.3.2** 实现过期后重试提示 (重新评估当前状态后重新发起) + - 文件: `backend/app/interrupt_manager.py` (扩展) + - 工作量: M (3 小时) + - 依赖: 2.3.1 + - 风险: 中 +- [ ] **2.3.3** 编写中断超时测试 + - 文件: `backend/tests/test_interrupt.py` + - 工作量: S (2 小时) + - 依赖: 2.3.1, 2.3.2 + - 风险: 低 + +#### 2.4 Webhook 升级 (预计 1 天) + +- [ ] **2.4.1** 实现 Webhook 升级模块 (HTTP POST 到配置的 URL, 包含完整对话上下文) + - 文件: `backend/app/escalation.py` + - 工作量: M (3 小时) + - 依赖: Phase 1 + - 风险: 低 +- [ ] **2.4.2** 实现 Webhook 重试机制 (指数退避, 最多 3 次) + - 文件: `backend/app/escalation.py` (扩展) + - 工作量: S (2 小时) + - 依赖: 2.4.1 + - 风险: 低 +- [ ] **2.4.3** 编写 Webhook 测试 (成功发送、目标不可达、重试) + - 文件: `backend/tests/test_escalation.py` + - 工作量: S (2 小时) + - 依赖: 2.4.1, 2.4.2 + - 风险: 低 + +#### 2.5 垂直行业模板 (预计 0.5 天) + +- [ ] **2.5.1** 创建电商模板 YAML (订单查询、订单操作、折扣) + - 文件: `backend/templates/e-commerce.yaml` + - 工作量: S (1 小时) + - 依赖: 1.2.2 + - 风险: 低 +- [ ] **2.5.2** 创建 SaaS 模板 YAML (账户查询、订阅管理、计费) + - 文件: `backend/templates/saas.yaml` + - 工作量: S (1 小时) + - 依赖: 1.2.2 + - 风险: 低 +- [ ] **2.5.3** 创建 Fintech 模板 YAML (交易查询、争议处理) + - 文件: `backend/templates/fintech.yaml` + - 工作量: S (1 小时) + - 依赖: 1.2.2 + - 风险: 低 +- [ ] **2.5.4** 实现模板加载逻辑 (选择模板 -> 覆盖 agents.yaml) + - 文件: `backend/app/registry.py` (扩展) + - 工作量: S (2 小时) + - 依赖: 2.5.1, 2.5.2, 2.5.3 + - 风险: 低 + +### Phase 2 检查点标准 + +- [ ] 发送 "查询订单 1042" -> 路由到订单查询 Agent +- [ ] 发送 "取消订单 1042 并给我一个 10% 折扣" -> 顺序执行两个 Agent +- [ ] 发送模糊消息 -> 回退 Agent 请求澄清 +- [ ] interrupt 超过 30 分钟 -> 自动取消 + 提供重试选项 +- [ ] Agent 升级 -> Webhook POST 发送成功 (或重试后日志记录) +- [ ] 使用电商模板启动 -> 3 个预配置 Agent 正常工作 +- [ ] `pytest --cov` 覆盖率 >= 80% (Phase 1 + Phase 2 代码) + +### Phase 2 测试要求 + +| 类型 | 测试项 | 文件 | +|------|--------|------| +| 单元测试 | 意图分类准确性 | `tests/test_routing.py` | +| 单元测试 | 多意图顺序执行 | `tests/test_routing.py` | +| 单元测试 | 中断 TTL 超时 | `tests/test_interrupt.py` | +| 单元测试 | Webhook 发送/重试 | `tests/test_escalation.py` | +| 集成测试 | 完整多 Agent 路由流程 | `tests/test_routing.py` | +| E2E | 多轮上下文: "查询 1042" 然后 "取消那个" -> 正确实体解析 | 手动验证 | + +### Phase 2 风险项 + +| 风险 | 严重度 | 缓解措施 | +|------|--------|----------| +| 多意图原子性不清晰 | 高 | 采用 best-effort 模式: 部分失败时升级人工, 不回滚已完成操作 | +| Supervisor 路由准确率不足 | 中 | 编写路由准确率评估数据集, 设定基线 (>90% 准确率) | +| 30 分钟 TTL 定时器精度 | 低 | 使用数据库时间戳比对, 不依赖内存定时器 | + +### Phase 2 交付物 + +- 完善的多 Agent 路由 (意图分类 + 多意图 + 歧义处理) +- Mock 折扣 Agent +- interrupt 30 分钟 TTL 自动取消 + 重试 +- Webhook 升级模块 (带重试) +- 3 个垂直行业模板 (电商、SaaS、Fintech) +- 路由 + 中断 + 升级测试 + +--- + +## Phase 3: OpenAPI 自动发现 (第 4-6 周) + +### 目标 + +实现 "粘贴 API URL, 自动生成可用工具" 的核心差异化功能。解析 OpenAPI 3.0 规范, 生成 MCP 服务器, LLM 辅助分类端点, 运维审核后自动生成 Agent 配置。 + +### 前置条件 + +- Phase 2 检查点全部通过 +- **TODOS: 工具接口决策** (支持 MCP/CLI/直接 API 三种后端) 在此阶段开始前完成 (~2-3 小时研究) + +### 任务清单 + +#### 3.0 工具接口研究 (预计 0.5 天) [来自 TODOS.md] + +- [ ] **3.0.1** 研究 MCP Python SDK (`mcp` on PyPI), 确定 MCP/CLI/API 三种后端的抽象方式 + - 工作量: S (2-3 小时) + - 依赖: 无 + - 风险: 低 +- [ ] **3.0.2** 设计工具基类, 抽象多后端支持 (LangChain @tool 函数式封装) + - 文件: `backend/app/tools/base.py` + - 工作量: M (3 小时) + - 依赖: 3.0.1 + - 风险: 中 + +#### 3.1 SSRF 防护工具 (预计 1 天) [可提前并行开发] + +- [ ] **3.1.1** 实现 SSRF 防护模块 (屏蔽私有 IP: 10.x, 172.16-31.x, 192.168.x, 127.x, 169.254.x, ::1) + - 文件: `backend/app/openapi/ssrf.py` + - 工作量: M (3 小时) + - 依赖: 无 + - 风险: 低 +- [ ] **3.1.2** 实现 DNS 重绑定防护 (解析 DNS 后再验证 IP, 不信任域名) + - 文件: `backend/app/openapi/ssrf.py` (扩展) + - 工作量: M (3 小时) + - 依赖: 3.1.1 + - 风险: 中 -- 需覆盖 IPv6 和边界情况 +- [ ] **3.1.3** 编写 SSRF 防护测试 (私有 IP、localhost、169.254.x、DNS 重绑定、正常 URL) + - 文件: `backend/tests/test_ssrf.py` + - 工作量: S (2 小时) + - 依赖: 3.1.1, 3.1.2 + - 风险: 低 + +#### 3.2 OpenAPI 规范解析 (预计 2 天) + +- [ ] **3.2.1** 实现 OpenAPI 规范获取 (URL 下载, 经 SSRF 检查) + - 文件: `backend/app/openapi/fetcher.py` + - 工作量: M (3 小时) + - 依赖: 3.1.1 + - 风险: 低 +- [ ] **3.2.2** 实现 OpenAPI 规范校验 (使用 openapi-spec-validator) + - 文件: `backend/app/openapi/validator.py` + - 工作量: S (2 小时) + - 依赖: 3.2.1 + - 风险: 低 +- [ ] **3.2.3** 实现端点提取和结构化 (路径、方法、参数、请求体、响应) + - 文件: `backend/app/openapi/parser.py` + - 工作量: M (6 小时) + - 依赖: 3.2.2 + - 风险: 中 -- 真实 OpenAPI 规范的复杂度 (嵌套 $ref, allOf, etc.) +- [ ] **3.2.4** 编写解析器测试 (有效规范、无效规范、100+ 端点、边界 case) + - 文件: `backend/tests/test_openapi_parser.py` + - 工作量: M (3 小时) + - 依赖: 3.2.3 + - 风险: 低 + +#### 3.3 LLM 辅助分类 (预计 2 天) + +- [ ] **3.3.1** 实现 LLM 端点分类 (每个端点: 读/写、客户参数、推荐 Agent 分组) + - 文件: `backend/app/openapi/classifier.py` + - 工作量: M (6 小时) + - 依赖: 3.2.3 + - 风险: 中 -- LLM 分类质量依赖 prompt 设计 +- [ ] **3.3.2** 实现分类结果结构化输出 (JSON schema 约束) + - 文件: `backend/app/openapi/classifier.py` (扩展) + - 工作量: S (2 小时) + - 依赖: 3.3.1 + - 风险: 低 +- [ ] **3.3.3** 编写分类器测试 (Mock LLM 响应, 验证分类逻辑) + - 文件: `backend/tests/test_classifier.py` + - 工作量: M (3 小时) + - 依赖: 3.3.1 + - 风险: 低 + +#### 3.4 运维审核 UI (预计 1.5 天) + +- [ ] **3.4.1** 实现分类结果审核 API (GET 分类结果, POST 修正) + - 文件: `backend/app/openapi/review_api.py` + - 工作量: M (4 小时) + - 依赖: 3.3.1 + - 风险: 低 +- [ ] **3.4.2** 实现审核 UI 页面 (表格展示每个端点分类, 可编辑) + - 文件: `frontend/src/pages/ReviewPage.tsx` + - 工作量: M (6 小时) + - 依赖: 3.4.1 + - 风险: 低 + +#### 3.5 MCP 服务器生成 (预计 2 天) + +- [ ] **3.5.1** 实现 MCP 工具包装器生成 (每个端点 -> LangChain @tool 或 MCP server) + - 文件: `backend/app/openapi/generator.py` + - 工作量: L (8 小时) + - 依赖: 3.3.1, 3.0.2 + - 风险: 高 -- MCP 服务器生成是本项目最复杂的代码生成任务 +- [ ] **3.5.2** 实现 Agent YAML 自动生成 (基于分类结果生成 agents.yaml) + - 文件: `backend/app/openapi/generator.py` (扩展) + - 工作量: M (4 小时) + - 依赖: 3.5.1 + - 风险: 中 +- [ ] **3.5.3** 编写生成器测试 (生成的工具可调用, YAML 可加载) + - 文件: `backend/tests/test_generator.py` + - 工作量: M (4 小时) + - 依赖: 3.5.1, 3.5.2 + - 风险: 低 + +#### 3.6 异步导入流程 (预计 1 天) + +- [ ] **3.6.1** 实现后台异步任务 (不阻塞聊天) + - 文件: `backend/app/openapi/importer.py` + - 工作量: M (4 小时) + - 依赖: 3.5.1, 3.5.2 + - 风险: 中 +- [ ] **3.6.2** 实现 WebSocket 进度更新 (解析中 -> 分类中 -> 审核中 -> 完成) + - 文件: `backend/app/openapi/importer.py` (扩展) + - 工作量: M (3 小时) + - 依赖: 3.6.1 + - 风险: 低 +- [ ] **3.6.3** 编写导入流程集成测试 + - 文件: `backend/tests/test_importer.py` + - 工作量: M (3 小时) + - 依赖: 3.6.1, 3.6.2 + - 风险: 低 + +### Phase 3 检查点标准 + +- [ ] 粘贴一个真实 OpenAPI 规范 URL -> 端点被正确解析 +- [ ] LLM 分类结果展示在审核页面, 可编辑 +- [ ] 审核通过后, 自动生成的工具在聊天中可用 +- [ ] SSRF 尝试 (localhost, 私有 IP) 被阻止并返回清晰错误 +- [ ] 无效/畸形 OpenAPI 规范 -> 返回清晰错误信息 +- [ ] 100+ 端点的规范 -> 生成不超时 +- [ ] 导入过程不阻塞聊天, 进度通过 WebSocket 更新 +- [ ] `pytest --cov` 覆盖率 >= 80% + +### Phase 3 测试要求 + +| 类型 | 测试项 | 文件 | +|------|--------|------| +| 单元测试 | SSRF 防护 (各种 IP/域名) | `tests/test_ssrf.py` | +| 单元测试 | OpenAPI 解析 (有效/无效/复杂规范) | `tests/test_openapi_parser.py` | +| 单元测试 | LLM 分类 (Mock LLM) | `tests/test_classifier.py` | +| 单元测试 | MCP 工具/YAML 生成 | `tests/test_generator.py` | +| 集成测试 | 完整导入流程 | `tests/test_importer.py` | +| E2E | 粘贴规范 URL -> 工具生成 -> 在聊天中使用 | 手动验证 | + +### Phase 3 风险项 + +| 风险 | 严重度 | 缓解措施 | +|------|--------|----------| +| MCP 服务器代码生成质量不稳定 | 高 | 先支持简单 REST API (GET/POST), 复杂场景 (OAuth, 分页) 延后 | +| 真实 OpenAPI 规范的边界 case 超多 | 高 | 使用 openapi-spec-validator 做前置校验, 不支持的特性给出明确提示 | +| LLM 分类准确率不够 | 中 | 运维审核 UI 是安全网, LLM 只是建议 | +| DNS 重绑定防护遗漏 | 中 | 解析后缓存 IP, 请求时二次验证 | + +### Phase 3 交付物 + +- SSRF 防护独立模块 +- OpenAPI 规范解析器 +- LLM 辅助端点分类器 +- 运维审核 API + UI +- MCP 工具/Agent YAML 自动生成器 +- 异步导入流程 (带 WebSocket 进度) +- 完整测试套件 + +--- + +## Phase 4: 对话回放 + 数据分析 (第 6-7 周) + +### 目标 + +实现对话回放 UI (逐步查看 Agent 决策过程) 和数据分析仪表盘 (解决率、Agent 使用率、升级率、每次对话成本)。 + +### 前置条件 + +- Phase 1 检查点通过 (PostgresSaver 数据可查询) +- Phase 2 检查点通过 (有足够的对话数据类型) +- 注意: Phase 4 不依赖 Phase 3, 如果 Phase 3 延迟可提前启动 + +### 任务清单 + +#### 4.1 对话回放 API (预计 2 天) + +- [ ] **4.1.1** 设计回放数据模型 (步骤类型: agent_selection, tool_call, tool_result, interrupt, response) + - 文件: `backend/app/replay/models.py` + - 工作量: M (3 小时) + - 依赖: Phase 1 + - 风险: 低 +- [ ] **4.1.2** 实现分页回放 API (GET `/api/replay/{thread_id}`, 支持 200+ 轮次) + - 文件: `backend/app/replay/api.py` + - 工作量: M (6 小时) + - 依赖: 4.1.1 + - 风险: 中 -- PostgresSaver checkpoint 数据的查询性能 +- [ ] **4.1.3** 实现 checkpoint 数据 -> 结构化时间线 JSON 转换 + - 文件: `backend/app/replay/transformer.py` + - 工作量: M (4 小时) + - 依赖: 4.1.2 + - 风险: 中 -- checkpoint 内部结构可能随 LangGraph 版本变化 +- [ ] **4.1.4** 编写回放 API 测试 (正常回放、404、分页、空对话) + - 文件: `backend/tests/test_replay.py` + - 工作量: M (3 小时) + - 依赖: 4.1.2, 4.1.3 + - 风险: 低 + +#### 4.2 回放 UI (预计 2 天) + +- [ ] **4.2.1** 实现对话列表页面 (选择要回放的对话) + - 文件: `frontend/src/pages/ReplayListPage.tsx` + - 工作量: M (3 小时) + - 依赖: 4.1.2 + - 风险: 低 +- [ ] **4.2.2** 实现步骤时间线组件 (逐步展示 Agent 决策、工具调用、结果) + - 文件: `frontend/src/components/ReplayTimeline.tsx` + - 工作量: M (6 小时) + - 依赖: 4.1.3 + - 风险: 低 +- [ ] **4.2.3** 实现回放详情页面 (集成时间线 + 对话内容) + - 文件: `frontend/src/pages/ReplayPage.tsx` + - 工作量: M (4 小时) + - 依赖: 4.2.1, 4.2.2 + - 风险: 低 + +#### 4.3 数据分析 API (预计 2 天) + +- [ ] **4.3.1** 实现解决率查询 (成功工具调用 + 无升级) + - 文件: `backend/app/analytics/queries.py` + - 工作量: M (4 小时) + - 依赖: Phase 1 (callbacks.py) + - 风险: 中 -- 需要从 checkpoint 数据中提取结构化指标 +- [ ] **4.3.2** 实现 Agent 使用率查询 (每个 Agent 的调用次数和占比) + - 文件: `backend/app/analytics/queries.py` (扩展) + - 工作量: M (3 小时) + - 依赖: 4.3.1 + - 风险: 低 +- [ ] **4.3.3** 实现升级率查询 (升级到人工的对话占比) + - 文件: `backend/app/analytics/queries.py` (扩展) + - 工作量: S (2 小时) + - 依赖: 4.3.1 + - 风险: 低 +- [ ] **4.3.4** 实现每次对话成本查询 (基于 token 用量统计) + - 文件: `backend/app/analytics/queries.py` (扩展) + - 工作量: M (3 小时) + - 依赖: Phase 1 (callbacks.py) + - 风险: 低 +- [ ] **4.3.5** 实现分析 API 端点 (GET `/api/analytics`, 聚合所有指标) + - 文件: `backend/app/analytics/api.py` + - 工作量: M (3 小时) + - 依赖: 4.3.1, 4.3.2, 4.3.3, 4.3.4 + - 风险: 低 +- [ ] **4.3.6** 编写分析查询测试 (有数据、无数据零状态、大量数据) + - 文件: `backend/tests/test_analytics.py` + - 工作量: M (3 小时) + - 依赖: 4.3.5 + - 风险: 低 + +#### 4.4 分析仪表盘 UI (预计 1.5 天) + +- [ ] **4.4.1** 实现仪表盘页面 (解决率、Agent 使用率、升级率、成本) + - 文件: `frontend/src/pages/DashboardPage.tsx` + - 工作量: M (6 小时) + - 依赖: 4.3.5 + - 风险: 低 +- [ ] **4.4.2** 实现零状态处理 (无对话数据时的友好提示) + - 文件: `frontend/src/pages/DashboardPage.tsx` (扩展) + - 工作量: S (1 小时) + - 依赖: 4.4.1 + - 风险: 低 +- [ ] **4.4.3** 实现前端路由 (聊天 / 回放 / 仪表盘 导航) + - 文件: `frontend/src/App.tsx` + - 工作量: S (2 小时) + - 依赖: 4.4.1, 4.2.3 + - 风险: 低 + +### Phase 4 检查点标准 + +- [ ] 完成一次对话后, 在回放页面可以逐步查看 Agent 决策过程 +- [ ] 200+ 轮次的对话回放, 分页正常, 无慢查询 +- [ ] 仪表盘显示: 解决率、Agent 使用率、升级率、每次对话成本 +- [ ] 无对话数据时仪表盘显示零状态 +- [ ] 导航在聊天、回放、仪表盘之间切换正常 +- [ ] `pytest --cov` 覆盖率 >= 80% + +### Phase 4 测试要求 + +| 类型 | 测试项 | 文件 | +|------|--------|------| +| 单元测试 | 回放 API (分页、404、数据转换) | `tests/test_replay.py` | +| 单元测试 | 分析查询 (各指标、零状态) | `tests/test_analytics.py` | +| 集成测试 | 完整回放流程 (对话 -> 回放) | `tests/test_replay.py` | +| E2E | 选择已完成对话 -> 步骤回放正确渲染 | 手动验证 | + +### Phase 4 风险项 + +| 风险 | 严重度 | 缓解措施 | +|------|--------|----------| +| PostgresSaver checkpoint 数据结构变化 | 中 | 在 transformer 层做版本适配, 不直接耦合内部结构 | +| 200+ 轮次查询性能 | 中 | 使用分页 + 数据库索引, 必要时增加 SQL 查询优化 | +| 分析指标定义不够精确 | 低 | "解决率 = 成功工具调用 + 无升级" 作为初始定义, 后续加入客户满意度信号 | + +### Phase 4 交付物 + +- 分页回放 API + checkpoint -> 时间线转换 +- 回放列表 + 详情 UI +- 4 个分析指标查询 (解决率、Agent 使用率、升级率、成本) +- 分析仪表盘 UI (含零状态) +- 前端路由导航 +- 完整测试套件 + +--- + +## Phase 5: 打磨 + Demo 准备 (第 7-8 周) + +### 目标 + +错误处理加固、Demo 脚本和示例数据准备、Docker Compose 全栈部署验证、文档完善。为第一个客户演示做好准备。 + +### 前置条件 + +- Phase 1-4 检查点全部通过 + +### 任务清单 + +#### 5.1 错误处理加固 (预计 2 天) + +- [ ] **5.1.1** 审查所有 MCP 工具调用的错误处理 (超时、认证失败、网络错误) + - 文件: 全部 `backend/app/agents/*.py` + - 工作量: M (4 小时) + - 依赖: Phase 1-3 + - 风险: 低 +- [ ] **5.1.2** 实现 MCP 错误分类 (可重试 vs. 不可重试, 指数退避策略) + - 文件: `backend/app/tools/error_handler.py` + - 工作量: M (4 小时) + - 依赖: 5.1.1 + - 风险: 低 +- [ ] **5.1.3** 审查前端错误处理 (断线提示、服务端错误友好展示) + - 文件: `frontend/src/` 各组件 + - 工作量: M (3 小时) + - 依赖: Phase 1 前端 + - 风险: 低 +- [ ] **5.1.4** 处理边界情况 (空消息、超长消息 10K+、快速连发消息、取消已取消的订单、WebSocket 断线 mid-stream 清理) + - 文件: `backend/app/main.py`, `backend/app/agents/*.py`, `frontend/src/` + - 工作量: M (6 小时) + - 依赖: Phase 1-2 + - 风险: 低 + - 来源: eng-review-test-plan.md 边界 case 清单 +- [ ] **5.1.5** 编写边界情况测试 (含: 取消已取消订单返回合适错误、WebSocket 断线服务端清理、快速连发无竞态、歧义无上下文时澄清提问) + - 文件: `backend/tests/test_edge_cases.py` + - 工作量: M (4 小时) + - 依赖: 5.1.4 + - 风险: 低 + +#### 5.2 Demo 准备 (预计 1.5 天) + +- [ ] **5.2.1** 创建 Demo 脚本 (预设对话流程, 覆盖: 查询、取消+批准、多轮上下文、OpenAPI 导入) + - 文件: `docs/demo-script.md` + - 工作量: M (3 小时) + - 依赖: Phase 1-4 + - 风险: 低 +- [ ] **5.2.2** 准备示例数据 (Mock 订单数据, 预置对话用于回放演示) + - 文件: `backend/fixtures/demo_data.py` + - 工作量: M (3 小时) + - 依赖: 5.2.1 + - 风险: 低 +- [ ] **5.2.3** 准备示例 OpenAPI 规范 (用于 Phase 3 功能演示) + - 文件: `backend/fixtures/sample_openapi.yaml` + - 工作量: S (1 小时) + - 依赖: Phase 3 + - 风险: 低 +- [ ] **5.2.4** 录制 90 秒 Demo 视频 + - 工作量: M (3 小时) + - 依赖: 5.2.1, 5.2.2, 5.2.3 + - 风险: 低 + +#### 5.3 全栈部署验证 (预计 1 天) + +- [ ] **5.3.1** 验证 Docker Compose 一键启动 (PostgreSQL + 后端 + 前端) + - 文件: `docker-compose.yml` + - 工作量: M (4 小时) + - 依赖: Phase 1-4 + - 风险: 中 -- 多服务联调可能有端口/网络问题 +- [ ] **5.3.2** 验证环境变量配置文档完整性 + - 文件: `.env.example`, `docs/deployment.md` + - 工作量: S (1 小时) + - 依赖: 5.3.1 + - 风险: 低 +- [ ] **5.3.3** 端到端冒烟测试 (全部 6 条 E2E 关键路径) + - 工作量: M (3 小时) + - 依赖: 5.3.1 + - 风险: 低 + +#### 5.4 文档完善 (预计 1 天) + +- [ ] **5.4.1** 更新 README.md (快速开始、配置说明、架构图) + - 文件: `README.md` + - 工作量: M (3 小时) + - 依赖: Phase 1-4 + - 风险: 低 +- [ ] **5.4.2** 编写 Agent 配置指南 (如何添加新 Agent、如何配置工具) + - 文件: `docs/agent-config-guide.md` + - 工作量: M (3 小时) + - 依赖: Phase 1-2 + - 风险: 低 +- [ ] **5.4.3** 编写 OpenAPI 导入指南 + - 文件: `docs/openapi-import-guide.md` + - 工作量: S (2 小时) + - 依赖: Phase 3 + - 风险: 低 +- [ ] **5.4.4** 编写部署指南 + - 文件: `docs/deployment.md` + - 工作量: S (2 小时) + - 依赖: 5.3.1 + - 风险: 低 + +### Phase 5 检查点标准 + +- [ ] `docker compose up` 从零启动, 所有功能正常 +- [ ] 6 条 E2E 关键路径全部通过: + 1. Happy path: "订单 1042 的状态" -> 查询 -> 回答 + 2. 取消+批准: "取消订单 1042" -> interrupt -> 批准 -> 确认 + 3. 取消+拒绝: "取消订单 1042" -> interrupt -> 拒绝 -> 无操作 + 4. 多轮上下文: "查询 1042" 然后 "取消那个" -> 正确实体解析 + 5. OpenAPI 导入: 粘贴规范 URL -> 工具生成 -> 在聊天中使用 + 6. 对话回放: 选择已完成对话 -> 步骤回放正确渲染 +- [ ] Demo 视频录制完成 (90 秒) +- [ ] 文档完整 (README, Agent 配置, OpenAPI 导入, 部署) +- [ ] `pytest --cov` 全项目覆盖率 >= 80% + +### Phase 5 测试要求 + +| 类型 | 测试项 | 文件 | +|------|--------|------| +| 单元测试 | 边界情况 (空消息、超长消息、连发、取消已取消订单) | `tests/test_edge_cases.py` | +| 集成测试 | WebSocket 断线 mid-stream 服务端清理 | `tests/test_edge_cases.py` | +| 集成测试 | 快速连发消息无竞态 | `tests/test_edge_cases.py` | +| 集成测试 | 歧义无上下文意图 -> 澄清提问 | `tests/test_edge_cases.py` | +| E2E | 全部 6 条关键路径 | 手动冒烟测试 | + +### Phase 5 风险项 + +| 风险 | 严重度 | 缓解措施 | +|------|--------|----------| +| Docker 多服务联调问题 | 中 | 逐步添加服务, 不要一次全部配置 | +| Demo 演示时服务不稳定 | 中 | 准备离线录制的 Demo 视频作为备选 | + +### Phase 5 交付物 + +- 错误处理加固后的后端 + 前端 +- Demo 脚本 + 示例数据 + 示例 OpenAPI 规范 +- 90 秒 Demo 视频 +- 全栈 Docker Compose 部署 (验证通过) +- 完整文档集 (README, Agent 配置, OpenAPI 导入, 部署) + +--- + +## Phase 6: 客户接入 (第 8 周起) + +### 目标 + +为第一个真实客户构建 MCP 连接器, 将框架接入客户的内部系统。这是从 Demo 到真实产品的关键一步。 + +> 来源: ceo-plan.md Phase 5 -- "Real connectors for first client's systems" + +### 前置条件 + +- Phase 5 检查点全部通过 (完整 Demo 可运行) +- 已有至少 1 个设计合作伙伴 (来自业务验证) + +### 任务清单 + +#### 6.1 客户系统对接 (工期视客户系统复杂度而定) + +- [ ] **6.1.1** 分析客户 API 系统 (Shopify Admin API / 自定义 REST / 其他) + - 工作量: M (4-8 小时) + - 依赖: 客户提供 API 文档或 OpenAPI 规范 + - 风险: 中 -- 客户 API 文档质量不可控 +- [ ] **6.1.2** 构建客户专属 MCP 连接器 (或使用 Phase 3 OpenAPI 自动生成) + - 文件: `backend/mcp_servers/{client_name}/` + - 工作量: L (1-3 天, 视 API 复杂度) + - 依赖: 6.1.1 + - 风险: 高 -- OAuth、分页、速率限制等实际 API 问题 +- [ ] **6.1.3** 配置客户专属 agents.yaml (Agent 分组、权限、人设) + - 文件: `backend/agents.yaml` (客户版本) + - 工作量: S (2 小时) + - 依赖: 6.1.2 + - 风险: 低 +- [ ] **6.1.4** 端到端测试: 真实 API 调用 (查询真实订单、执行真实操作) + - 工作量: M (4 小时) + - 依赖: 6.1.2, 6.1.3 + - 风险: 高 -- 生产数据的边界 case + +#### 6.2 生产准备 (预计 2 天) + +- [ ] **6.2.1** 实现 Auth 系统 (API key 认证 WebSocket, session 认证 Dashboard) + - 文件: `backend/app/auth.py` + - 工作量: M (1 天) + - 依赖: Phase 4 完成 + - 风险: 中 + - 来源: TODOS.md -- "Auth system: P1 before production deployment" +- [ ] **6.2.2** 部署到云环境 (Fly.io / Railway / AWS) + - 工作量: M (4 小时) + - 依赖: 6.2.1 + - 风险: 中 + +### Phase 6 检查点标准 + +- [ ] 客户专属 MCP 连接器能调用真实 API +- [ ] 使用客户数据完成完整对话流程 (查询、操作、确认) +- [ ] Auth 系统保护所有端点 +- [ ] 部署到云环境, 客户可通过 URL 访问 + +### Phase 6 风险项 + +| 风险 | 严重度 | 缓解措施 | +|------|--------|----------| +| 客户 API 文档质量差或缺失 | 高 | 先用 Phase 3 OpenAPI 自动发现, 人工补充缺失部分 | +| OAuth / 速率限制等真实 API 问题 | 高 | Phase 5 的 MCP 错误分类 (5.1.2) 已实现重试/升级策略 | +| 客户数据边界 case 超预期 | 中 | 逐步上线: 先只读操作, 验证后再开放写操作 | + +### Phase 6 交付物 + +- 客户专属 MCP 连接器 +- 客户专属 Agent 配置 +- Auth 系统 (API key + session) +- 云端部署 + +--- + +## 并行化策略 + +| 通道 | 内容 | 模块 | 可并行阶段 | +|------|------|------|-----------| +| A | 后端核心 (Phase 1-2) | `backend/app/` | Phase 1-2 | +| B | 前端 UI | `frontend/` | Phase 1 与 A 并行 | +| C | SSRF 防护工具 (独立模块) | `backend/app/openapi/ssrf.py` | Phase 1 期间可提前开发 | + +- **Phase 1**: A (后端) + B (前端) + C (SSRF) 三路并行 +- **Phase 2**: 依赖 Phase 1 后端完成, 串行 +- **Phase 3**: 依赖 Phase 2, 串行 (但 C 的 SSRF 已完成) +- **Phase 4**: 不依赖 Phase 3, 可与 Phase 3 后半段并行启动 +- **Phase 5**: 依赖 Phase 1-4, 串行 +- **Phase 6**: 依赖 Phase 5 + 客户, 按客户节奏推进 + +--- + +## 全局风险登记册 + +| 编号 | 风险 | 严重度 | 阶段 | 缓解措施 | +|------|------|--------|------|----------| +| R1 | LangGraph supervisor 配置复杂度超预期 | 高 | Phase 1 | 5 天阻塞则回退单 Agent | +| R2 | MCP 服务器代码生成质量不稳定 | 高 | Phase 3 | 先支持简单 REST, 复杂场景延后 | +| R3 | 真实 OpenAPI 规范边界 case | 高 | Phase 3 | 前置校验, 不支持的特性明确提示 | +| R4 | 多意图原子性不清晰 | 高 | Phase 2 | Best-effort, 部分失败升级人工 | +| R5 | interrupt/resume 状态管理 | 中 | Phase 1 | 先实现最简版, 后续迭代 | +| R6 | PostgresSaver checkpoint 结构变化 | 中 | Phase 4 | transformer 层做版本适配 | +| R7 | LLM 分类准确率不够 | 中 | Phase 3 | 运维审核 UI 作为安全网 | +| R8 | DNS 重绑定防护遗漏 | 中 | Phase 3 | 解析后缓存 IP, 二次验证 | +| R9 | 无客户验证需求 | 高 | 全局 | Phase 1 完成后立即进行客户对话 | + +--- + +## 验收标准总览 + +### 工程完成标准 + +- [ ] 完整框架: Chat UI + Agent Router + Context Manager 端到端运行 +- [ ] 多 Agent 路由: 基于意图正确选择 Agent +- [ ] 会话上下文: Agent 正确解析跨轮次引用 ("取消那个") +- [ ] 人工确认: 写操作需要审批才能执行 +- [ ] 可插拔 MCP: 新工具可通过配置添加, 无需改代码 +- [ ] OpenAPI 自动发现: 粘贴 URL -> 工具可用 +- [ ] 对话回放: 逐步查看 Agent 决策过程 +- [ ] 数据分析: 解决率、Agent 使用率、升级率、成本 +- [ ] 90 秒 Demo 视频 +- [ ] 全项目测试覆盖率 >= 80% + +### 业务验证标准 + +- [ ] Demo 完成后 2 周内, 至少与 5 位真实电商运营者对话 +- [ ] Demo 完成后 4 周内, 至少 1 个付费试点 + +--- + +## 范围外事项 (来自工程评审) + +以下内容明确不在原型范围内: + +- 认证/授权系统 (延迟到预生产) +- 多租户架构 (延迟到第一个付费客户) +- CI/CD 管道 (原型阶段手动部署) +- 速率限制 (延迟到预生产) +- Zendesk/Intercom 市场集成 (延迟到验证后) +- 移动端响应式 UI (仅支持桌面端 Demo) +- 国际化 (i18n) +- 计费/定价基础设施 +- 分发管道 (手动 Docker Compose 部署) + +--- + +## 待办事项追踪 (来自 TODOS.md) + +| 待办 | 时间点 | 状态 | +|------|--------|------| +| 工具接口决策 (MCP/CLI/API 三后端) | Phase 3 开始前 | 待完成 -- 见任务 3.0 | +| Auth 系统 (API key + session) | Phase 6 任务 6.2.1 | 待完成 | +| Prompt Caching | Phase 1 任务 1.4.5 | 待完成 | +| Checkpointer 迁移计划 | 已解决 (PostgresSaver 从第一天开始) | 已完成 | + +--- + +> 本文档应随开发进展持续更新。每个 Phase 完成后, 勾选对应的检查点标准和任务清单。