--- 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 和 PostgreSQL(pgvector)服务,通过 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
Redis 7 + pgvector/pg15"] Conf["conftest.py
公共 fixture"] Env[".env.test
测试环境变量"] end subgraph UnitTests["单元测试 (tests/unit/)"] P0["P0: 零覆盖模块
dispatcher, registry
mcp/server, evolution_store
agent_tool, prompts"] P1["P1: 薄弱模块
working_memory, episodic_memory
mcp/client, handoff"] Fix["代码修复
datetime.utcnow, pgvector TODO"] end subgraph IntegrationTests["集成测试 (tests/integration/)"] AL["test_agent_lifecycle.py
完整生命周期"] TC["test_tool_composition.py
工具组合端到端"] EL["test_evolution_loop.py
进化闭环"] MR["test_mcp_roundtrip.py
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 → 6381,PostgreSQL 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:三个工具并行执行,结果合并 - DynamicSelector:LLM 根据任务选择工具 - 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 自动发现远程工具并注册到本地 ToolRegistry(R9 高级特性) - 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 启动测试服务