fischer-agentkit/docs/plans/2026-06-05-001-feat-agentki...

605 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.

---
title: "feat: fischer-agentkit TDD 验证与补全计划"
type: feat
status: active
date: 2026-06-05
origin: geo/docs/plans/2026-06-04-010-refactor-unified-agent-framework-plan.md
execution_posture: tdd
---
## Summary
对 fischer-agentkit 已实现的 6 大模块进行 TDD 验证先补全缺失的单元测试覆盖6 个零覆盖模块 + 4 个薄弱模块再修复测试中发现的问题pgvector 向量检索、datetime 弃用、测试基础设施缺失),最后补全 4 个集成测试验证端到端流程。采用真实 Redis/PostgreSQL 服务进行测试,确保验证结果可靠。
## Problem Frame
fischer-agentkit 的 6 大模块Core/Tools/Memory/Evolution/Orchestrator/MCP代码已全部实现189 个现有测试全部通过,但存在以下结构性问题:
1. **6 个模块完全无测试**dispatcher、registry、mcp/server、evolution_store、agent_tool、prompts — 代码存在但行为未验证
2. **4 个模块测试薄弱**working_memory无 Redis mock、episodic_memory仅测试衰减公式、mcp/client仅间接测试、handoff仅无 Redis 场景)
3. **集成测试完全缺失**`tests/integration/` 目录为空,无法验证端到端流程
4. **代码质量问题**21 处 `datetime.utcnow()` 弃用警告、EpisodicMemory pgvector 向量检索标记为 TODO
5. **测试基础设施缺失**:无 conftest.py、fixture 在 4 个文件中重复定义
这些问题意味着:虽然代码"能跑"但核心功能任务调度、Agent 注册、MCP 服务端、进化持久化)从未被自动化测试验证过。
---
## Requirements
本计划追溯至原始需求文档的以下条目:
| 需求 ID | 需求描述 | 验证状态 |
|---------|---------|---------|
| R2 | BaseAgent 统一生命周期 | 部分验证(缺 dispatcher/registry |
| R6 | Tool 三种类型Function/Agent/MCP | AgentTool 未验证 |
| R7 | ToolRegistry 注册发现版本管理 | 基本验证 |
| R8 | MCP Server 暴露 Agent 能力 | **未验证** |
| R9 | MCP Client 调用外部工具 | 仅间接验证 |
| R11 | Working Memory Redis | **未验证** |
| R12 | Episodic Memory 向量检索 | **未验证**TODO |
| R13 | Semantic Memory RAG+Graph | 基本验证 |
| R14 | 混合检索策略 | 部分验证 |
| R15 | 经验积累自动记录 | 部分验证 |
| R20 | Handoff 任务转交 | 仅无 Redis 场景 |
| R22 | 事件驱动替代轮询 | **未实现**(不在本计划范围) |
---
## Key Technical Decisions
KTD1. **真实服务测试策略**:单元测试和集成测试均使用真实 Redis 和 PostgreSQLpgvector服务通过 docker-compose 启动测试专用容器。理由fakeredis 不支持所有 Redis 命令(如 Pub/Sub 的完整行为mock SQLAlchemy session 无法验证真实 SQL 和 pgvector 查询。真实服务测试更可靠,且 GEO 项目已有 pgvector/pg15 和 Redis 7 的 docker 镜像。
KTD2. **测试基础设施先行**:先创建 conftest.py 提取公共 fixture再逐模块补全测试。理由4 个文件重复定义 `_make_task()` 等辅助函数,不统一会导致后续测试继续重复。
KTD3. **TDD 红绿循环**:每个模块先写测试定义期望行为(可能失败),再修复代码使测试通过。对于 EpisodicMemory 的 pgvector TODO先写测试定义向量检索的期望行为再实现 cosine distance 排序。
KTD4. **datetime.utcnow() 统一修复**:在补全测试之前先修复 21 处弃用警告,避免新测试继承技术债务。替换为 `datetime.now(timezone.utc)`与项目后期代码agent_tool.py、pipeline_engine.py 等)保持一致。
KTD5. **测试风格统一为类式**:新测试统一使用 `class TestXxx` 分组 + `async def` 方法(依赖 `asyncio_mode = "auto"`),不再使用 `@pytest.mark.asyncio` 装饰器。与项目较新的测试文件风格一致。
---
## High-Level Technical Design
### 测试分层架构
```mermaid
flowchart TB
subgraph Infrastructure["测试基础设施"]
DC["docker-compose.test.yml<br/>Redis 7 + pgvector/pg15"]
Conf["conftest.py<br/>公共 fixture"]
Env[".env.test<br/>测试环境变量"]
end
subgraph UnitTests["单元测试 (tests/unit/)"]
P0["P0: 零覆盖模块<br/>dispatcher, registry<br/>mcp/server, evolution_store<br/>agent_tool, prompts"]
P1["P1: 薄弱模块<br/>working_memory, episodic_memory<br/>mcp/client, handoff"]
Fix["代码修复<br/>datetime.utcnow, pgvector TODO"]
end
subgraph IntegrationTests["集成测试 (tests/integration/)"]
AL["test_agent_lifecycle.py<br/>完整生命周期"]
TC["test_tool_composition.py<br/>工具组合端到端"]
EL["test_evolution_loop.py<br/>进化闭环"]
MR["test_mcp_roundtrip.py<br/>MCP 往返"]
end
Infrastructure --> UnitTests
P0 --> Fix
P1 --> Fix
UnitTests --> IntegrationTests
```
### 测试执行流程
```mermaid
stateDiagram-v2
[*] --> SetupInfra: 启动测试容器
SetupInfra --> WriteTests: 编写测试RED
WriteTests --> RunTests: 运行测试
RunTests --> FixCode: 测试失败 → 修复代码GREEN
FixCode --> RunTests: 重新运行
RunTests --> WriteTests: 全部通过 → 下一模块
RunTests --> Integration: 单元测试全部通过
Integration --> [*]: 集成测试通过
```
---
## Implementation Units
### U1. 测试基础设施搭建
**Goal:** 创建 docker-compose 测试配置、conftest.py 公共 fixture、.env.test 环境变量,为后续 TDD 提供可靠基础。
**Requirements:** R2, R11, R12
**Dependencies:**
**Files:**
- `fischer-agentkit/docker-compose.test.yml`(新建)
- `fischer-agentkit/.env.test`(新建)
- `fischer-agentkit/tests/conftest.py`(新建)
- `fischer-agentkit/tests/unit/conftest.py`(新建)
- `fischer-agentkit/tests/integration/conftest.py`(新建)
- `fischer-agentkit/pyproject.toml`(修改:添加 pytest-docker 或 testcontainers 依赖)
**Approach:**
1. 创建 `docker-compose.test.yml`,包含 Redis 7 和 pgvector/pg15 服务,端口避免与 GEO 项目冲突Redis 6379 → 6381PostgreSQL 5432 → 5434
2. 创建 `.env.test` 声明测试环境变量
3. 创建 `tests/conftest.py`,提取公共 fixture
- `make_task()` — 构建 TaskMessage
- `make_result()` — 构建 TaskResult
- `redis_client` — 连接测试 Redis 的 async fixture
- `pg_session_factory` — 连接测试 PostgreSQL 的 async fixture
- `clean_redis` — 每个测试前清空 Redis
- `clean_db` — 每个测试前清空数据库
4. 创建 `tests/unit/conftest.py``tests/integration/conftest.py`,分别提供各自层级的 fixture
5. 在 pyproject.toml 的 dev 依赖中添加 `pytest-docker>=0.4``testcontainers[postgres,redis]>=4.0`
6. 添加 `pytest` 配置的 `env_file = ".env.test"` 或通过 fixture 管理环境变量
**Patterns to follow:** GEO 项目的 `geo/docker-compose.yml` 中 Redis 和 PostgreSQL 的配置模式
**Test scenarios:**
- docker-compose.test.yml 启动后 Redis 可连接并执行 PING
- docker-compose.test.yml 启动后 PostgreSQL 可连接并查询 pgvector 扩展
- conftest.py 的 redis_client fixture 可正常执行 set/get 操作
- conftest.py 的 pg_session_factory fixture 可创建表并执行查询
- make_task() fixture 生成的 TaskMessage 可被 BaseAgent.execute() 接受
- clean_redis fixture 在测试间正确隔离数据
**Verification:** `docker compose -f docker-compose.test.yml up -d && pytest tests/ -v` 全部通过
---
### U2. datetime.utcnow() 弃用修复
**Goal:** 将项目中 21 处 `datetime.utcnow()` 全部替换为 `datetime.now(timezone.utc)`,消除 DeprecationWarning。
**Requirements:** 代码质量(非功能性需求)
**Dependencies:** 无(可与 U1 并行)
**Files:**
- `fischer-agentkit/src/agentkit/core/protocol.py`7 处)
- `fischer-agentkit/src/agentkit/memory/base.py`1 处)
- `fischer-agentkit/src/agentkit/memory/working.py`3 处)
- `fischer-agentkit/src/agentkit/memory/episodic.py`2 处)
- `fischer-agentkit/src/agentkit/evolution/reflector.py`1 处)
- `fischer-agentkit/src/agentkit/evolution/lifecycle.py`2 处)
- `fischer-agentkit/tests/unit/test_memory_system.py`4 处)
- `fischer-agentkit/tests/unit/test_protocol.py`1 处)
**Approach:**
1. 在每个文件的 import 区域添加 `from datetime import timezone`(如尚未导入)
2.`datetime.utcnow()` 替换为 `datetime.now(timezone.utc)`
3.`field(default_factory=lambda: datetime.utcnow())` 替换为 `field(default_factory=lambda: datetime.now(timezone.utc))`
4. 运行现有 189 个测试确认无回归
**Execution note:** 先运行测试确认当前基线通过,修改后重新运行确认无回归且无 DeprecationWarning。
**Patterns to follow:** 项目中已正确使用 `datetime.now(timezone.utc)` 的文件agent_tool.py、pipeline_engine.py、registry.py、dispatcher.py、base.py
**Test scenarios:**
- 修改后 `pytest tests/ -W error::DeprecationWarning` 无弃用警告
- 修改后 189 个现有测试全部通过
- TaskMessage.from_dict() 反序列化包含 UTC 时间戳的 JSON 正确
**Verification:** `pytest tests/ -W error::DeprecationWarning -v` 全部通过,零警告
---
### U3. 零覆盖模块单元测试Core 层)
**Goal:**`core/dispatcher.py``core/registry.py` 补全单元测试,验证任务调度和 Agent 注册发现的核心逻辑。
**Requirements:** R2
**Dependencies:** U1
**Files:**
- `fischer-agentkit/tests/unit/test_dispatcher.py`(新建)
- `fischer-agentkit/tests/unit/test_registry.py`(新建)
**Approach:**
1. **test_dispatcher.py**
- 测试 TaskDispatcher 在本地模式(无 Redis下的任务分发
- 测试任务队列的 FIFO 顺序
- 测试任务重试逻辑
- 测试任务取消
- 测试回调机制
- 测试并发分发(多个任务同时入队)
2. **test_registry.py**
- 测试 AgentRegistry 动态注册新 AgentType
- 测试注册重复 AgentType 的处理
- 测试 get_available_agent 的轮询策略
- 测试 Agent 心跳和过期清理
- 测试按能力查询 Agent
**Execution note:** TDD — 先写测试定义期望行为,运行确认结果,再根据需要调整。
**Patterns to follow:** 现有 test_base_agent.py 的类式测试风格
**Test scenarios:**
test_dispatcher.py:
- 本地模式分发任务到指定 Agent返回 TaskResult
- 任务队列按 FIFO 顺序处理
- 任务执行失败时重试指定次数
- 取消正在等待的任务返回取消状态
- 回调函数在任务完成后被调用
- 多个任务并发分发,结果正确返回
test_registry.py:
- 动态注册新 AgentType 不报错
- 注册重复 AgentType 覆盖旧配置
- get_available_agent 轮询策略返回不同 Agent
- Agent 心跳超时后从可用列表移除
- 按 supported_tasks 查询匹配的 Agent
- 空注册表查询返回空列表
**Verification:** `pytest tests/unit/test_dispatcher.py tests/unit/test_registry.py -v` 全部通过
---
### U4. 零覆盖模块单元测试Tools + Prompts 层)
**Goal:**`tools/agent_tool.py``prompts/` 模块补全单元测试,验证 Agent 包装为 Tool 和模板渲染的逻辑。
**Requirements:** R6
**Dependencies:** U1
**Files:**
- `fischer-agentkit/tests/unit/test_agent_tool.py`(新建)
- `fischer-agentkit/tests/unit/test_prompt_template.py`(新建)
- `fischer-agentkit/tests/unit/test_prompt_section.py`(新建)
**Approach:**
1. **test_agent_tool.py**
- 测试 AgentTool 的输入映射input_mapping
- 测试 AgentTool 的输出映射output_mapping
- 测试 AgentTool 通过 Dispatcher 分发任务
- 测试 AgentTool 超时处理
- 测试 AgentTool 的 schema 自动生成
2. **test_prompt_template.py**
- 测试 PromptTemplate 变量替换 `${key}`
- 测试缺失变量的处理
- 测试模板渲染结果
3. **test_prompt_section.py**
- 测试 PromptSection 的条件渲染
- 测试多 Section 组合渲染
**Execution note:** TDD — AgentTool 的轮询等待机制1 秒间隔)在测试中需要 mock asyncio.sleep 加速。
**Patterns to follow:** 现有 test_tool_composition.py 的 Mock 模式
**Test scenarios:**
test_agent_tool.py:
- AgentTool 正确映射输入参数到 TaskMessage
- AgentTool 正确映射 TaskResult 到输出 dict
- AgentTool 通过 Dispatcher 分发任务并等待结果
- AgentTool 超时后抛出 TimeoutError
- AgentTool 的 input_schema 从 input_mapping 推断
- AgentTool 的 output_schema 从 output_mapping 推断
test_prompt_template.py:
- `${name}` 变量替换为实际值
- 缺失变量时抛出 KeyError 或保留原始占位符
- 多变量模板正确替换所有变量
- 空模板渲染返回空字符串
test_prompt_section.py:
- 条件为 True 的 Section 包含在渲染结果中
- 条件为 False 的 Section 排除在渲染结果外
- 多 Section 按顺序组合渲染
- 无条件 Section 始终包含
**Verification:** `pytest tests/unit/test_agent_tool.py tests/unit/test_prompt_template.py tests/unit/test_prompt_section.py -v` 全部通过
---
### U5. 零覆盖模块单元测试MCP Server + Evolution Store
**Goal:**`mcp/server.py``evolution/evolution_store.py` 补全单元测试,验证 MCP 服务端点和进化持久化逻辑。
**Requirements:** R8, R15
**Dependencies:** U1
**Files:**
- `fischer-agentkit/tests/unit/test_mcp_server.py`(新建)
- `fischer-agentkit/tests/unit/test_evolution_store.py`(新建)
**Approach:**
1. **test_mcp_server.py**
- 使用 `httpx.AsyncClient` + `ASGITransport` 测试 FastAPI 端点
- 测试 `/tools/list` 返回 ToolRegistry 中注册的工具
- 测试 `/tools/call` 调用指定工具并返回结果
- 测试调用不存在的工具返回错误
- 测试 `/resources/read` 端点
- 测试 JSON-RPC 2.0 协议格式
2. **test_evolution_store.py**
- 测试 EvolutionStore 记录进化变更
- 测试按 agent_name 查询变更历史
- 测试回滚操作
- 测试变更状态管理active/rolled_back
**Execution note:** MCP Server 测试使用 httpx.AsyncClient + ASGITransport无需启动真实 HTTP 服务器。
**Patterns to follow:** 现有 test_mcp_transport.py 的 httpx_mock 模式FastAPI 官方推荐的 AsyncClient 测试模式
**Test scenarios:**
test_mcp_server.py:
- `/tools/list` 返回已注册工具的名称和 schema
- `/tools/call` 调用 FunctionTool 返回正确结果
- `/tools/call` 调用不存在的工具返回 JSON-RPC 错误
- `/resources/read` 返回可用资源列表
- JSON-RPC 2.0 请求格式正确解析
- JSON-RPC 2.0 响应包含 jsonrpc/version/id 字段
test_evolution_store.py:
- 记录 prompt 类型的进化变更
- 记录 strategy 类型的进化变更
- 按 agent_name 查询返回该 Agent 的所有变更
- 回滚操作将变更状态设为 rolled_back
- 回滚后查询返回 rolled_back 状态
- 空存储查询返回空列表
**Verification:** `pytest tests/unit/test_mcp_server.py tests/unit/test_evolution_store.py -v` 全部通过
---
### U6. 薄弱模块补强测试Memory 层)
**Goal:** 为 WorkingMemory 和 EpisodicMemory 补全真实服务测试,验证 Redis 存取和 pgvector 向量检索。实现 EpisodicMemory 的 pgvector cosine distance 排序(当前标记为 TODO
**Requirements:** R11, R12, R14
**Dependencies:** U1, U2
**Files:**
- `fischer-agentkit/tests/unit/test_working_memory.py`(新建)
- `fischer-agentkit/tests/unit/test_episodic_memory.py`(新建)
- `fischer-agentkit/tests/unit/test_memory_retriever.py`(新建)
- `fischer-agentkit/src/agentkit/memory/episodic.py`(修改:实现 pgvector cosine distance
**Approach:**
1. **test_working_memory.py**(真实 Redis
- 测试 store/retrieve/delete 基本操作
- 测试 TTL 自动过期
- 测试 get_context() 格式化输出
- 测试不同 Agent 实例的 key 隔离
- 测试 Redis 连接失败时的降级处理
2. **test_episodic_memory.py**(真实 pgvector
- 测试 store 写入任务经验并生成 embedding
- 测试 search 按语义相似度检索pgvector cosine distance
- 测试 search 按时间衰减排序
- 测试 search 混合排序(语义 + 时间衰减)
- 测试 delete 删除指定记录
3. **test_memory_retriever.py**
- 测试三层记忆并行检索
- 测试权重融合排序
- 测试 Token 预算管理(截断超限结果)
4. **实现 pgvector cosine distance**
-`episodic.py` 的 search 方法中,将 `# TODO: 使用 pgvector 的 cosine distance 排序` 替换为真实的 pgvector 查询
- 使用 `embedding <=> :query_embedding` 操作符进行 cosine distance 排序
- 结合时间衰减因子:最终得分 = 语义相似度 × 时间衰减
**Execution note:** TDD — 先写 EpisodicMemory 的向量检索测试期望行为运行确认失败TODO 未实现),再实现 pgvector cosine distance 排序使测试通过。
**Patterns to follow:** GEO 项目的 `backend/app/services/knowledge/retriever.py` 中 HybridRetriever 的 RRF 融合排序模式
**Test scenarios:**
test_working_memory.py:
- store + retrieve 返回相同值
- TTL 过期后 retrieve 返回空
- get_context() 返回格式化的上下文字符串
- 不同 Agent 的 working_memory key 互不干扰
- delete 后 retrieve 返回空
- 存储复杂对象(嵌套 dict正确序列化/反序列化
test_episodic_memory.py:
- store 写入记录后可按 agent_name 查询
- search 按语义相似度返回最相关记录cosine distance
- search 时间衰减:近期记录排名高于远期
- search 混合排序:语义相似 + 时间衰减综合排序
- delete 删除指定 ID 的记录
- 空 store 的 search 返回空列表
test_memory_retriever.py:
- 并行查询三层记忆,结果合并
- 按权重融合排序(向量 0.5 + 关键词 0.2 + 图谱 0.3
- Token 预算管理:总 token 不超过预算时保留所有结果
- Token 预算管理:超过预算时截断低分结果
- 某层记忆无结果时不影响其他层
**Verification:** `pytest tests/unit/test_working_memory.py tests/unit/test_episodic_memory.py tests/unit/test_memory_retriever.py -v` 全部通过,且 EpisodicMemory 的 TODO 已实现
---
### U7. 薄弱模块补强测试MCP Client + Handoff
**Goal:** 为 MCPClient 和 HandoffManager 补全测试,验证 MCP 客户端工具发现和 Handoff 的 Redis Pub/Sub 机制。
**Requirements:** R9, R20
**Dependencies:** U1, U2
**Files:**
- `fischer-agentkit/tests/unit/test_mcp_client.py`(新建)
- `fischer-agentkit/tests/unit/test_handoff.py`(新建)
**Approach:**
1. **test_mcp_client.py**
- 测试 MCPClient 通过 Transport 连接远程 Server
- 测试 list_tools() 返回工具列表
- 测试 call_tool() 调用远程工具
- 测试 MCPClient 直接 HTTP 模式(无 Transport
- 测试连接失败时的错误处理
2. **test_handoff.py**(真实 Redis
- 测试 HandoffManager 通过 Redis Pub/Sub 发送转交请求
- 测试目标 Agent 监听并接收转交消息
- 测试转交消息携带上下文
- 测试无 Redis 时的降级处理(本地模式)
- 测试多个 Agent 同时监听不同频道
**Execution note:** Handoff 测试使用真实 Redis Pub/Sub需要确保测试间频道隔离。
**Patterns to follow:** 现有 test_mcp_transport.py 的 HTTP mock 模式
**Test scenarios:**
test_mcp_client.py:
- 通过 Transport 调用 list_tools 返回工具名称列表
- 通过 Transport 调用 call_tool 返回工具执行结果
- 直接 HTTP 模式调用工具
- 连接不存在的 Server 抛出连接错误
- call_tool 传入无效参数返回错误响应
- JSON-RPC 2.0 请求格式正确
test_handoff.py:
- send_handoff 通过 Redis Pub/Sub 发送消息
- listen_for_handoffs 接收到转交消息
- 转交消息包含 source_agent、target_agent、context、reason
- 无 Redis 时 HandoffManager 降级为本地调用
- 不同 Agent 监听不同频道互不干扰
- 转交消息序列化/反序列化正确
**Verification:** `pytest tests/unit/test_mcp_client.py tests/unit/test_handoff.py -v` 全部通过
---
### U8. 集成测试补全
**Goal:** 补全 4 个集成测试文件验证端到端流程Agent 完整生命周期、工具组合、进化闭环、MCP 往返。
**Requirements:** R2, R6, R8, R9, R15, R16, R18, R20
**Dependencies:** U1, U3, U4, U5, U6, U7
**Files:**
- `fischer-agentkit/tests/integration/test_agent_lifecycle.py`(新建)
- `fischer-agentkit/tests/integration/test_tool_composition.py`(新建)
- `fischer-agentkit/tests/integration/test_evolution_loop.py`(新建)
- `fischer-agentkit/tests/integration/test_mcp_roundtrip.py`(新建)
**Approach:**
1. **test_agent_lifecycle.py**
- 启动 Agent → 发送任务 → 接收结果 → 停止 Agent 的完整流程
- 验证 on_task_start/on_task_complete 钩子调用顺序
- 验证任务失败时 on_task_failed 钩子触发
- 验证 Memory 在任务执行中的存取
2. **test_tool_composition.py**
- SequentialChain两个工具顺序执行前一个输出作为后一个输入
- ParallelFanOut三个工具并行执行结果合并
- DynamicSelectorLLM 根据任务选择工具
- AgentTool将 Agent 包装为 Tool 并调用
3. **test_evolution_loop.py**
- 反思 → 优化 → A/B 测试 → 应用/回滚 完整闭环
- 验证 EvolutionStore 持久化进化记录
- 验证 A/B 测试效果提升后自动应用
- 验证 A/B 测试效果下降后自动回滚
4. **test_mcp_roundtrip.py**
- 启动 MCP Server → MCP Client 连接 → list_tools → call_tool → 结果返回
- 验证 Server 暴露的 Tool 与 ToolRegistry 一致
- 验证 Client 调用的结果与直接调用 Tool 一致
**Execution note:** 集成测试使用真实 Redis 和 PostgreSQL标记为 `@pytest.mark.integration`,可通过 `pytest -m "not integration"` 跳过。
**Patterns to follow:** 现有 test_u8_geo_integration.py 的端到端测试模式
**Test scenarios:**
test_agent_lifecycle.py:
- ConfigDrivenAgent 从 YAML 加载 → 启动 → 执行任务 → 返回 TaskResult → 停止
- BaseAgent 生命周期钩子按序调用start → on_task_start → handle_task → on_task_complete → stop
- 任务执行失败时 on_task_failed 触发TaskResult 状态为 FAILED
- Agent 执行任务时 WorkingMemory 自动存取上下文
- Agent 执行任务后 EpisodicMemory 自动记录经验
test_tool_composition.py:
- SequentialChain 顺序执行两个 FunctionTool第二个接收第一个的输出
- ParallelFanOut 并行执行三个 FunctionTool结果合并
- DynamicSelector 根据 LLM 判断选择合适工具
- AgentTool 包装 Agent 并通过 Dispatcher 分发任务
test_evolution_loop.py:
- 执行 5 次任务后 Reflector 生成反思
- PromptOptimizer 从成功案例生成 few-shot 示例
- ABTester 分流测试,实验组效果提升后自动应用
- ABTester 分流测试,实验组效果下降后自动回滚
- EvolutionStore 记录所有变更,支持查询历史
test_mcp_roundtrip.py:
- MCP Server 启动后 Client 可 list_tools
- Client call_tool 返回与直接调用 Tool 相同的结果
- Server 暴露的工具列表与 ToolRegistry 注册一致
- JSON-RPC 2.0 协议端到端正确
**Verification:** `pytest tests/integration/ -v` 全部通过
---
## Scope Boundaries
### In Scope
- 补全 6 个零覆盖模块的单元测试
- 补强 4 个薄弱模块的单元测试
- 实现 EpisodicMemory 的 pgvector cosine distance 排序(当前 TODO
- 修复 21 处 datetime.utcnow() 弃用警告
- 创建测试基础设施docker-compose.test.yml、conftest.py
- 补全 4 个集成测试文件
### Deferred for Later
- MIPROv2 多目标 Prompt 优化R16 高级特性)
- Bayesian Optimization 策略调优R17 高级特性)
- Pipeline 事件驱动替代轮询R22
- MCP Client 自动发现远程工具并注册到本地 ToolRegistryR9 高级特性)
- MCP Server SSE 流式响应R8 高级特性)
- EvolutionMixin 与 BaseAgent 的自动集成R15 增强)
- AgentTool 轮询改为事件驱动
- CI/CD 配置
- mypy/pyright 类型检查配置
### Outside This Project's Identity
- GEO 业务系统的完整迁移U8
- 前端 Agent 管理界面
- A2A Protocol 支持
---
## Risks & Dependencies
| Risk | Impact | Mitigation |
|------|--------|------------|
| pgvector cosine distance 实现可能需要调整表结构 | 需要数据库迁移 | 先写测试定义期望行为,实现时如需迁移则同步更新 docker-compose.test.yml 的 init-db 脚本 |
| 真实服务测试需要 docker 环境 | CI 环境可能无 docker | 提供 pytest marker 标记集成测试,无 docker 时可跳过;单元测试中 Redis/PG 相关测试也用 marker 标记 |
| AgentTool 轮询等待在测试中耗时 | 测试执行缓慢 | mock asyncio.sleep 加速,或设置短超时 |
| 现有测试可能因 conftest.py 重构而受影响 | fixture 命名冲突 | conftest.py 使用新 fixture 名,逐步迁移旧测试 |
| pytest-httpx 未在 pyproject.toml 中声明 | 依赖缺失 | 在 U1 中添加到 dev 依赖 |
---
## System-Wide Impact
- **测试执行时间**:从当前 ~3 秒增加到预计 ~30 秒(真实服务 + 集成测试)
- **开发依赖**:新增 pytest-docker/testcontainers、pytest-httpx
- **Docker 需求**:开发环境需安装 Docker 以运行测试
- **CI/CD**:后续需配置 GitHub Actions 运行 docker-compose 启动测试服务