--- status: active date: 2026-06-05 origin: docs/brainstorms/2026-06-05-agentkit-architecture-gap-analysis-requirements.md --- # AgentKit v2 Phase 2: 架构完善实施计划 **类型**: refactor **文件**: `docs/plans/2026-06-05-006-refactor-agentkit-v2-phase2-plan.md` **深度**: Deep — 跨模块改造,涉及安全、异步、流式、进化 4 个层面 --- ## 问题框架 AgentKit v2 Phase 1 已实现 12 个核心模块、535 个测试通过,但存在 4 个关键缺口使其无法被称为"生产就绪的标准 Agent 框架": 1. **服务化安全缺失** — 无认证、无限流、CORS 配置不当、SSRF 风险 2. **异步任务占位符** — 任务状态查询返回 placeholder,同步阻塞调用 3. **流式输出不支持** — 长时间 ReAct 循环无中间进展反馈 4. **Evolution 未集成** — 自我进化代码完整但未接入 Agent 生命周期 本计划按 **B → D → C → A** 顺序补齐这 4 个缺口。(需求来源见 origin 文档) --- ## 架构总览 ``` +------------------------+ | User / Consumer | +-----------+------------+ | +-----------v------------+ | AgentKit Server | | [Auth + Rate Limit] | ← Phase B 新增 +-----------+------------+ | +-----------v------------+ | Task Manager | | [Async + Streaming] | ← Phase D + C 新增 +-----------+------------+ | +----------+----------+----------+----------+ | | | | | +------v---+ +---v----+ +---v----+ +---v----+ | | ReAct | | Skill | |Quality | | Intent | | | [Stream] | | System | | Gate | | Router | | +----+-----+ +--------+ +--------+ +--------+ | | | +----v------------------------------------------v----+ | ConfigDrivenAgent / BaseAgent | | [+ Evolution Hooks] | ← Phase A 新增 +------+---------+---------+---------+---------+------+ | | | | | +------v---+ +---v----+ +---v----+ +---v----+ +---v----+ | LLM | | Tool | | Memory | | MCP | |Pipeline| | [Stream] | | System | | System | | Bridge | |Engine | +----------+ +--------+ +--------+ +--------+ +--------+ ``` --- ## 关键技术决策(复用 origin 文档 KTD1-KTD5) | 决策 | 选择 | 理由 | |------|------|------| | 认证方案 | API Key(非 JWT/OAuth) | 服务间调用,API Key 足够简单有效 | | 速率限制 | 内存计数器(非 Redis) | 单实例足够,后续可升级 | | 异步存储 | Redis + 内存降级 | 已有 Redis 依赖 | | 流式协议 | SSE(非 WebSocket) | 单向推送足够,HTTP 兼容性好 | | Evolution | 可选集成 | 通过 YAML `evolution.enabled` 控制 | --- ## 高层次技术设计 ### 中间件链(Phase B) ``` Request → CORS Middleware → API Key Auth → Rate Limiter → Route Handler ↓ 401 ↓ 429 Unauthorized Too Many Requests ``` ### 异步任务流(Phase D) ``` POST /tasks → 生成 task_id → 存入 TaskStore(PENDING) → 后台 asyncio.create_task() 执行 → 更新 TaskStore(RUNNING → COMPLETED/FAILED) → 返回 {"task_id": "...", "status": "PENDING"} GET /tasks/{id} → 查询 TaskStore → 返回真实状态 GET /tasks/{id}/result → 查询 TaskStore → 返回结果或 404 ``` ### 流式输出流(Phase C) ``` POST /tasks/stream → SSE endpoint → 后台执行任务 → 每步发出事件: event: step data: {"type": "think|act|observe", "step": 1, "content": "..."} → 完成时发出: event: done data: {"status": "completed", "output": {...}} ``` ### Evolution 生命周期钩子(Phase A) ``` BaseAgent.execute(): on_task_start() handle_task() quality_gate → retry on_task_complete() └─→ [NEW] evolve_after_task() ← EvolutionMixin └─→ Reflector.reflect() └─→ PromptOptimizer.optimize() [if suggestions] └─→ ABTester.evaluate() [if optimized] └─→ EvolutionStore.apply/rollback() ``` --- ## 输出结构 ``` src/agentkit/ ├── server/ │ ├── middleware.py # NEW: Auth + Rate Limit 中间件 │ ├── task_store.py # NEW: 任务状态存储 │ ├── routes/ │ │ └── streaming.py # NEW: SSE 流式端点 │ ├── app.py # MODIFIED: 注册中间件 │ ├── client.py # MODIFIED: 添加流式 + 异步方法 │ └── routes/ │ └── tasks.py # MODIFIED: 异步任务 + 状态查询 ├── core/ │ ├── base.py # MODIFIED: 集成 Evolution │ ├── dispatcher.py # MODIFIED: Callback URL 验证 │ ├── config_driven.py # MODIFIED: handler 白名单 + evolution 配置 │ └── protocol.py # MODIFIED: 新增 TaskState 枚举 ├── llm/ │ ├── gateway.py # MODIFIED: 新增 stream() 方法 │ └── providers/ │ └── openai.py # MODIFIED: 支持 stream=True ├── skills/ │ └── base.py # MODIFIED: 添加 evolution 配置 ├── core/ │ └── react.py # MODIFIED: 新增 execute_streaming() └── evolution/ # 现有代码,无需修改 ``` --- ## Implementation Units ### U1. CORS 修复 + API Key 认证中间件 **Goal**: 修复 CORS 配置冲突,添加 API Key 认证保护所有 API 端点(健康检查除外)。 **Requirements**: R1, R3 **Dependencies**: 无 **Files**: - **Create**: `src/agentkit/server/middleware.py` - **Modify**: `src/agentkit/server/app.py` - **Test**: `tests/unit/test_server_middleware.py` **Approach**: 1. 新建 `middleware.py`,实现 `APIKeyAuthMiddleware` 类(Starlette middleware 接口) 2. 从环境变量 `AGENTKIT_API_KEY` 读取密钥,未设置时跳过认证(开发模式) 3. 验证 `X-API-Key` 请求头,不匹配时返回 401 4. 白名单路径:`/api/v1/health` 不需要认证 5. 修改 `app.py`: - 移除 `allow_credentials=True`(与 `allow_origins=["*"]` 冲突) - 添加 `app.add_middleware(APIKeyAuthMiddleware)` 6. 在 `create_app()` 中添加 `api_key: str | None = None` 参数,允许程序化配置 **Patterns to follow**: Starlette `BaseHTTPMiddleware` 模式,参考 FastAPI 中间件文档 **Test scenarios**: - 无 API Key 访问受保护端点 → 401 Unauthorized - 错误 API Key → 401 Unauthorized - 正确 API Key → 200 OK - 健康检查端点无需 API Key → 200 OK - AGENTKIT_API_KEY 未设置时 → 跳过认证(开发模式) - 程序化传入 api_key 参数 → 使用传入的值 **Verification**: `pytest tests/unit/test_server_middleware.py -v` 全部通过,现有测试不受影响 --- ### U2. 速率限制中间件 **Goal**: 添加基于固定窗口的速率限制,防止 LLM 成本耗尽。 **Requirements**: R2 **Dependencies**: U1(中间件基础设施) **Files**: - **Modify**: `src/agentkit/server/middleware.py` - **Test**: `tests/unit/test_server_middleware.py`(追加) **Approach**: 1. 在 `middleware.py` 中实现 `RateLimiter` 类 2. 使用 `time.time()` + `defaultdict(list)` 实现固定窗口计数器 3. 默认限制:60 requests/minute,通过环境变量 `AGENTKIT_RATE_LIMIT_PER_MINUTE` 配置 4. 基于请求 IP(`request.client.host`)或 API Key 进行独立计数 5. 超过限制时返回 429 Too Many Requests,响应头包含 `Retry-After` 6. 在 `app.py` 中注册速率限制中间件(在 Auth 之后) **Test scenarios**: - 请求在限制内 → 正常通过 - 超过限制 → 429 Too Many Requests - `Retry-After` 响应头正确设置 - 不同 IP 独立计数 - 时间窗口过后计数器重置 - 可配置 rate_limit_per_minute **Verification**: 新增测试通过,不影响现有路由测试 --- ### U3. Callback URL SSRF 防护 **Goal**: 验证 TaskDispatcher 的 callback URL,防止 SSRF 攻击。 **Requirements**: R4 **Dependencies**: 无 **Files**: - **Modify**: `src/agentkit/core/dispatcher.py` - **Test**: `tests/unit/test_dispatcher.py`(追加) **Approach**: 1. 在 `dispatcher.py` 中添加 `_validate_callback_url(url: str) -> bool` 函数 2. 使用 `urllib.parse.urlparse` 解析 URL 3. 校验规则: - 协议必须是 `http` 或 `https` - 主机不能是内网 IP(127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, ::1) - 主机不能是 `localhost` 4. 在 `_trigger_callback()` 中调用验证,无效 URL 记录 warning 并跳过 5. 对 `socket.gethostbyname()` 做 try/except 防止 DNS 解析失败崩溃 **Test scenarios**: - 合法公网 URL(如 `https://example.com/callback`)→ 验证通过 - localhost URL → 拒绝 - 127.0.0.1 URL → 拒绝 - 10.x.x.x 内网 URL → 拒绝 - 192.168.x.x 内网 URL → 拒绝 - ftp:// 协议 → 拒绝 - file:// 协议 → 拒绝 - 无效 URL 格式 → 拒绝 **Verification**: 新增测试通过,现有 dispatcher 测试不受影响 --- ### U4. custom_handler 模块前缀白名单 **Goal**: 为 `ConfigDrivenAgent._import_handler()` 添加模块前缀白名单,防止任意代码执行。 **Requirements**: R4(安全加固补充) **Dependencies**: 无 **Files**: - **Modify**: `src/agentkit/core/config_driven.py` - **Test**: `tests/unit/test_config_driven.py`(追加) **Approach**: 1. 在 `ConfigDrivenAgent` 类中添加 `_ALLOWED_HANDLER_PREFIXES = ("agentkit.", "app.agent_framework.")` 2. 在 `_import_handler()` 开头添加前缀校验 3. 不在白名单中的路径抛出 `ConfigValidationError` 4. 参考 `QualityGate._import_validator()` 的白名单实现模式 **Test scenarios**: - `agentkit.xxx.handler` → 允许 - `app.agent_framework.handlers.xxx` → 允许 - `os.system` → 拒绝(ConfigValidationError) - `subprocess.run` → 拒绝 - 空路径 → 拒绝 **Verification**: 新增测试通过 --- ### U5. 任务状态存储 **Goal**: 实现任务状态存储,支持 Redis 和内存两种后端。 **Requirements**: R5, R7 **Dependencies**: 无 **Files**: - **Create**: `src/agentkit/server/task_store.py` - **Test**: `tests/unit/test_task_store.py` **Approach**: 1. 定义 `TaskState` 枚举:`PENDING`, `RUNNING`, `COMPLETED`, `FAILED` 2. 定义 `TaskRecord` dataclass:`task_id`, `state`, `input_data`, `output_data`, `error_message`, `created_at`, `updated_at`, `started_at` 3. 定义 `TaskStore` ABC:`create()`, `update()`, `get()`, `list_tasks()`, `cleanup()` 4. 实现 `InMemoryTaskStore`:使用 `dict` + `asyncio.Lock` 保证线程安全 5. 实现 `RedisTaskStore`:使用 Redis hash 存储,TTL 24 小时自动清理 6. 提供 `create_task_store(redis_url: str | None = None) -> TaskStore` 工厂函数 7. Redis 不可用时自动降级到 InMemory **Patterns to follow**: 参考 `WorkingMemory` 的 Redis 模式和 `UsageTracker` 的内存模式 **Test scenarios**: - InMemoryTaskStore: create → get 返回正确记录 - InMemoryTaskStore: update 状态从 PENDING → RUNNING → COMPLETED - InMemoryTaskStore: get 不存在的 task_id 返回 None - InMemoryTaskStore: list_tasks 返回所有记录 - InMemoryTaskStore: 并发安全(asyncio.Lock) - RedisTaskStore: create → get 返回正确记录(skip if no Redis) - 工厂函数: Redis 可用时返回 RedisTaskStore - 工厂函数: Redis 不可用时降级到 InMemoryTaskStore **Verification**: `pytest tests/unit/test_task_store.py -v` 全部通过 --- ### U6. 异步任务执行 **Goal**: `POST /api/v1/tasks` 改为异步提交,100ms 内返回 task_id。 **Requirements**: R5, R6 **Dependencies**: U5 **Files**: - **Modify**: `src/agentkit/server/routes/tasks.py` - **Test**: `tests/unit/test_server_routes.py`(更新现有测试) - **Test**: `tests/integration/test_server_e2e.py`(更新) **Approach**: 1. 在 `tasks.py` 中注入 `TaskStore`(通过 `req.app.state.task_store`) 2. 在 `app.py` 的 `create_app()` 中初始化 `task_store` 并设置到 `app.state` 3. 修改 `submit_task` 路由: - 生成 `task_id`,创建 `TaskRecord(PENDING)` 存入 TaskStore - 使用 `asyncio.create_task()` 后台执行任务 - 立即返回 `{"task_id": task_id, "status": "PENDING"}` 4. 后台任务逻辑: - 更新 TaskStore 为 RUNNING - 执行 `agent.execute(task)` - 更新 TaskStore 为 COMPLETED/FAILED,存储 output_data - 运行 quality gate 和 output standardizer(存储结果) 5. 添加可选参数 `sync: bool = False`,当 `sync=true` 时保持原有同步行为 **Test scenarios**: - 提交任务 → 100ms 内返回 task_id + PENDING - 后台任务执行 → TaskStore 状态变为 COMPLETED - 后台任务失败 → TaskStore 状态变为 FAILED - sync=true 参数 → 同步执行(原有行为) - 输入验证失败 → 400/413 错误(同步返回) **Verification**: 路由测试通过,E2E 测试验证异步行为 --- ### U7. 任务状态查询 + 结果获取 **Goal**: `GET /api/v1/tasks/{task_id}` 返回真实状态,新增结果获取端点。 **Requirements**: R6, R7 **Dependencies**: U5, U6 **Files**: - **Modify**: `src/agentkit/server/routes/tasks.py` - **Test**: `tests/unit/test_server_routes.py`(追加) **Approach**: 1. 修改 `get_task_status` 路由: - 从 TaskStore 查询 task_id - 返回 `{"task_id": ..., "status": "...", "created_at": "...", "updated_at": "..."}` - 不存在时返回 404 2. 新增 `GET /api/v1/tasks/{task_id}/result` 路由: - 从 TaskStore 查询 task_id - 如果状态是 COMPLETED → 返回完整结果(含 quality_result, standard_output) - 如果状态是 PENDING/RUNNING → 返回 202 Accepted + `{"status": "..."}` - 如果状态是 FAILED → 返回错误信息 - 不存在时返回 404 **Test scenarios**: - 查询存在的 task_id → 返回正确状态 - 查询不存在的 task_id → 404 - PENDING 状态查询结果 → 202 Accepted - COMPLETED 状态查询结果 → 返回完整输出 - FAILED 状态查询结果 → 返回错误信息 **Verification**: 路由测试通过 --- ### U8. LLM Gateway 流式支持 **Goal**: LLM Gateway 支持 streaming 模式,逐 chunk 返回 LLM 响应。 **Requirements**: R8 **Dependencies**: 无 **Files**: - **Modify**: `src/agentkit/llm/gateway.py` - **Modify**: `src/agentkit/llm/protocol.py` - **Modify**: `src/agentkit/llm/providers/openai.py` - **Test**: `tests/unit/test_llm_gateway.py`(追加) - **Test**: `tests/unit/test_llm_provider.py`(追加) **Approach**: 1. 在 `protocol.py` 中添加 `LLMStreamChunk` dataclass: - `content: str`(增量文本) - `tool_calls: list[ToolCall] | None` - `finish_reason: str | None`(`stop`, `tool_calls`, `length`) - `usage: TokenUsage | None`(仅在最后一个 chunk 有值) 2. 在 `LLMProvider` ABC 中添加 `stream()` 抽象方法: - `async def stream(request: LLMRequest) -> AsyncIterator[LLMStreamChunk]` 3. 在 `OpenAICompatibleProvider` 中实现 `stream()`: - 使用 `httpx.AsyncClient.stream()` 发送请求 - 解析 SSE 格式响应(`data: {...}` 行) - yield `LLMStreamChunk` 对象 4. 在 `LLMGateway` 中添加 `stream()` 方法: - 解析模型别名和 provider - 调用 provider 的 `stream()` 方法 - 转发 chunk **Patterns to follow**: OpenAI Python SDK 的 streaming 模式,`response.iter_lines()` 解析 SSE **Test scenarios**: - OpenAICompatibleProvider.stream() 逐 chunk yield 内容 - 最后一个 chunk 包含 usage 信息 - finish_reason 为 stop 时流结束 - finish_reason 为 tool_calls 时包含 tool_calls 信息 - LLMGateway.stream() 正确转发 chunk - 网络错误时抛出 LLMProviderError **Verification**: 新增流式测试通过 --- ### U9. ReAct Engine 事件流 **Goal**: ReAct Engine 支持 streaming 事件输出,实时推送 Think/Act/Observe 进展。 **Requirements**: R9 **Dependencies**: U8 **Files**: - **Modify**: `src/agentkit/core/react.py` - **Modify**: `src/agentkit/core/protocol.py` - **Test**: `tests/unit/test_react_engine.py`(追加) **Approach**: 1. 在 `protocol.py` 中添加 `ReActEvent` dataclass: - `event_type: str`(`think_start`, `think_end`, `tool_call`, `tool_result`, `final_answer`) - `step: int` - `data: dict`(事件具体数据) - `timestamp: datetime` 2. 在 `ReActEngine` 中添加 `execute_streaming()` 方法: - 参数与 `execute()` 相同,返回 `AsyncIterator[ReActEvent]` - Think 前 yield `think_start` 事件 - 调用 LLM stream 后 yield `think_end` 事件 - 每个工具调用 yield `tool_call` 事件 - 工具执行完成后 yield `tool_result` 事件 - 最终答案 yield `final_answer` 事件 3. 保持原有 `execute()` 方法不变(向后兼容) **Test scenarios**: - execute_streaming() 按顺序 yield 事件 - Think → Act → Observe 事件顺序正确 - 最终 yield final_answer 事件 - 事件中包含 step 编号和 timestamp - 工具调用失败时 yield tool_result(含 error) - 与 execute() 结果一致(同一输入产生相同输出) **Verification**: 新增流式测试通过 --- ### U10. SSE 流式端点 + Client SDK **Goal**: Server 提供 SSE 流式端点,Client SDK 支持流式消费。 **Requirements**: R10 **Dependencies**: U8, U9 **Files**: - **Create**: `src/agentkit/server/routes/streaming.py` - **Modify**: `src/agentkit/server/app.py` - **Modify**: `src/agentkit/server/client.py` - **Test**: `tests/unit/test_streaming_routes.py` - **Test**: `tests/unit/test_client_streaming.py` **Approach**: 1. 新建 `streaming.py`,实现 `POST /api/v1/tasks/stream` 端点: - 使用 `StreamingResponse` + `text/event-stream` content type - 后台执行任务,调用 `react_engine.execute_streaming()` - 每个 `ReActEvent` 序列化为 SSE 格式:`event: \ndata: \n\n` - 完成后发送 `event: done\ndata: \n\n` 2. 在 `app.py` 中注册 streaming router 3. 在 `client.py` 中添加 `submit_task_streaming()` 方法: - 使用 `httpx.AsyncClient.stream()` 消费 SSE - yield `ReActEvent` 对象 - 支持 async iterator 协议 **Patterns to follow**: Starlette `EventSourceResponse` 或 `StreamingResponse`,参考 FastAPI SSE 文档 **Test scenarios**: - SSE 端点返回 text/event-stream content type - 事件按 Think → Act → Observe → done 顺序 - 每个事件包含正确的 event type 和 JSON data - Client SDK 消费 SSE 流 - Client SDK 正确解析 ReActEvent - 任务失败时发送 error 事件 **Verification**: 流式路由和客户端测试通过 --- ### U11. Evolution 生命周期钩子集成 **Goal**: 将 EvolutionMixin 集成到 BaseAgent,任务完成后自动触发进化流程。 **Requirements**: R11 **Dependencies**: 无 **Files**: - **Modify**: `src/agentkit/core/base.py` - **Modify**: `src/agentkit/evolution/lifecycle.py` - **Test**: `tests/unit/test_evolution_lifecycle.py`(更新) - **Test**: `tests/unit/test_base_agent_v2.py`(追加) **Approach**: 1. 在 `BaseAgent` 中添加 Evolution 相关属性: - `_reflector: Reflector | None` - `_prompt_optimizer: PromptOptimizer | None` - `_ab_tester: ABTester | None` - `_evolution_store: EvolutionStore | None` - `_evolution_enabled: bool = False` 2. 在 `BaseAgent` 中添加 `use_evolution()` 方法: - 接受 `reflector`, `prompt_optimizer`, `ab_tester`, `evolution_store` 参数 - 设置所有 Evolution 组件 - 设置 `_evolution_enabled = True` 3. 修改 `BaseAgent.execute()` 方法: - 在 `on_task_complete()` 之后,如果 `_evolution_enabled` 为 True: - 调用 `EvolutionMixin.evolve_after_task(task, result)`(非阻塞,`asyncio.create_task()`) 4. 在 `EvolutionMixin.evolve_after_task()` 中添加开关检查: - 如果任何组件为 None,跳过对应步骤并记录 debug 日志 **Patterns to follow**: 参考 `use_tool()`, `use_memory()` 的插件注入模式 **Test scenarios**: - evolution_enabled=False → 不触发进化流程 - evolution_enabled=True → evolve_after_task 被调用 - Reflector 为 None → 跳过反思 - 完整流程:Reflect → Optimize → AB Test → Apply - 进化流程非阻塞(不阻塞 execute 返回) - EvolutionMixin 混入 ConfigDrivenAgent 正常工作 **Verification**: Evolution 集成测试通过,现有测试不受影响 --- ### U12. Evolution 配置化 **Goal**: Agent 可通过 YAML 配置启用/禁用 Evolution 功能。 **Requirements**: R12 **Dependencies**: U11 **Files**: - **Modify**: `src/agentkit/core/config_driven.py` - **Modify**: `src/agentkit/skills/base.py` - **Test**: `tests/unit/test_config_driven.py`(追加) - **Test**: `tests/unit/test_skill_config.py`(追加) **Approach**: 1. 在 `AgentConfig` 中添加 `evolution: dict[str, Any] | None` 字段 2. 定义 `EvolutionConfig` dataclass: - `enabled: bool = False` - `reflect_after_task: bool = True` - `ab_test_threshold: float = 0.95` - `max_optimization_rounds: int = 3` 3. 在 `SkillConfig` 中继承 evolution 配置 4. 修改 `ConfigDrivenAgent.__init__()`: - 从 config.evolution 解析 EvolutionConfig - 如果 `evolution.enabled = True`,自动创建默认组件并调用 `use_evolution()` - 默认组件:Reflector(启发式评分)、PromptOptimizer、ABTester、EvolutionStore(内存模式) 5. YAML 配置示例文档化 **Test scenarios**: - YAML 中 evolution.enabled=true → Agent 自动启用进化 - YAML 中 evolution.enabled=false → Agent 不启用进化 - YAML 中无 evolution 字段 → 默认不启用 - EvolutionConfig 字段默认值正确 - SkillConfig 继承 evolution 配置 **Verification**: 配置化测试通过 --- ## 范围和边界 ### 包含 - Phase B:服务化安全(R1-R4)→ U1-U4 - Phase D:异步任务(R5-R7)→ U5-U7 - Phase C:流式输出(R8-R10)→ U8-U10 - Phase A:Evolution 集成(R11-R12)→ U11-U12 ### 不包含 - GEO 项目的任何改动 - 新的 LLM Provider 实现 - 前端 UI 开发 - 生产环境部署配置(K8s、Prometheus 等) - pgvector 向量检索实现 ### 推迟到后续工作 - WebSocket 推送(当前使用 SSE) - Redis 滑动窗口速率限制(当前使用内存计数器) - Anthropic/Google 原生 Provider - Evolution 的分布式 A/B 测试 - 任务优先级队列 --- ## 风险和缓解 | 风险 | 影响 | 缓解 | |------|------|------| | 流式输出改动大 | ReAct Engine 需要重构 | 保持原有同步接口不变,新增 streaming 接口 | | 异步任务需要 Redis | 测试环境可能没有 Redis | InMemoryTaskStore 降级方案 | | API Key 认证破坏现有测试 | 测试需要传递 API Key | 测试环境不设置 AGENTKIT_API_KEY(跳过认证) | | Evolution 集成后 Agent 变慢 | 反思和优化增加延迟 | 异步执行(asyncio.create_task),可配置关闭 | | SSE 端点与现有同步端点冲突 | 路由冲突 | 使用不同路径 `/tasks/stream` | --- ## 测试策略 - **TDD 原则**:每个单元先写测试,再写实现 - **测试覆盖目标**:总测试数 600+(当前 535) - **分层测试**: - 单元测试:mock 外部依赖,验证逻辑 - 集成测试:使用真实 Redis/PostgreSQL(docker-compose.test.yml) - E2E 测试:验证完整链路 - **回归保护**:每次修改后运行全量测试 --- ## 执行顺序 ``` Phase B(安全) Phase D(异步任务) Phase C(流式输出) Phase A(Evolution) ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ U1 │ │ U5 │ │ U8 │ │ U11 │ │ Auth│ │Store│ │LLM │ │Hooks│ └──┬──┘ └──┬──┘ └──┬──┘ └──┬──┘ │ └──┬──┘ └──┬──┘ └──┬──┘ ┌──▼──┐ ┌▼────┐ ┌─▼───┐ ┌──▼──┐ │ U2 │ │ U6 │ │ U9 │ │ U12 │ │Rate │ │Async│ │React│ │Config│ └─────┘ └──┬──┘ └──┬──┘ └─────┘ └──┬──┘ └──┬──┘ ┌────▼────┐ ┌───▼────┐ │ U7 │ │ U10 │ │Status │ │SSE+SDK │ └─────────┘ └────────┘ 可并行:U3 + U4(无依赖,可与任何单元并行) ```