fischer-agentkit/docs/plans/2026-06-05-006-refactor-age...

689 lines
25 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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`
- 主机不能是内网 IP127.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: <type>\ndata: <json>\n\n`
- 完成后发送 `event: done\ndata: <json>\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 AEvolution 集成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/PostgreSQLdocker-compose.test.yml
- E2E 测试:验证完整链路
- **回归保护**:每次修改后运行全量测试
---
## 执行顺序
```
Phase B安全 Phase D异步任务 Phase C流式输出 Phase AEvolution
┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐
│ U1 │ │ U5 │ │ U8 │ │ U11 │
│ Auth│ │Store│ │LLM │ │Hooks│
└──┬──┘ └──┬──┘ └──┬──┘ └──┬──┘
│ └──┬──┘ └──┬──┘ └──┬──┘
┌──▼──┐ ┌▼────┐ ┌─▼───┐ ┌──▼──┐
│ U2 │ │ U6 │ │ U9 │ │ U12 │
│Rate │ │Async│ │React│ │Config│
└─────┘ └──┬──┘ └──┬──┘ └─────┘
└──┬──┘ └──┬──┘
┌────▼────┐ ┌───▼────┐
│ U7 │ │ U10 │
│Status │ │SSE+SDK │
└─────────┘ └────────┘
可并行U3 + U4无依赖可与任何单元并行
```