fischer-agentkit/docs/plans/2026-06-16-006-refactor-arc...

16 KiB
Raw Blame History

title: "refactor: AgentKit 架构优化演进 — 对齐业界最佳实践"
status: active
plan_id: "2026-06-16-006"
created: 2026-06-16
depth: deep
origin: "基于对 Codex/Claude Code/Trae/Qoder 的深入分析,优化 AgentKit 架构"

AgentKit 架构优化演进计划

Summary

基于对 Codex CLI、Claude Code、Trae Agent 2.0、Qoder 的深入分析,对 AgentKit 进行架构优化演进。核心变更:(1) 消除"路由"概念改为请求预处理,(2) 专家团从去中心化协作简化为 hub-and-spoke(3) PlanExec 简化为 Spec-Driven 模式,(4) 聊天记录 SQLite 持久化,(5) 删除旧路由层代码,(6) 新增可验证执行和工具描述精简。

Problem Frame

AgentKit 当前架构存在三类问题:

  1. 概念误导SimpleRouter 仍暗示"路由层"存在,但实际只做 @skill 前缀解析 + greeting fast-path核心决策已交给 REACT agent loop 中的 LLM
  2. 过度设计ExpertTeam 的去中心化协作CollaborationPlan + HandoffTransport + SharedWorkspace + 3 种 MergeStrategy远超业界实践增加 ~1500 行代码但无对应价值
  3. 能力缺口PlanExecEngine 默认使用 _LLMStepExecutor纯 LLM 调用无工具),聊天记录不持久化,无自动验证循环

Requirements

  • R1: 消除"路由"概念SimpleRouter 重命名为 RequestPreprocessor语义从"路由决策"变为"请求预处理"
  • R2: 专家团简化为 hub-and-spoke 模式Lead Expert + 并行 Task深度=1删除 CollaborationPlan/HandoffTransport/SharedWorkspace 的 ExpertTeam 专用逻辑
  • R3: PlanExecEngine 默认使用 ReActStepExecutor删除 _LLMStepExecutor
  • R4: 聊天记录 SQLite 持久化(参考 Codex 的 Thread 持久化)
  • R5: 删除 CostAwareRouter 及相关代码HeuristicClassifier、IntentRouter、QualityGate、SemanticRouter
  • R6: 新增可验证执行Test-and-Verify 循环,参考 Codex Cloud
  • R7: 工具描述分层注入(核心工具全量 + 扩展工具一行描述 + tool_search 按需获取)
  • R8: 默认启用上下文压缩
  • R9: 新增 Spec 文档作为一等公民(参考 Qoder Quest Mode
  • R10: 统一事件模型SQ/EQ 双队列,参考 Codex

Key Technical Decisions

KTD1: SimpleRouter 重命名为 RequestPreprocessor

决策:将 SimpleRouter 重命名为 RequestPreprocessorroute() 方法重命名为 preprocess()

依据

  • Codex 无路由层Claude Code 无路由层Trae 移除了 Proposal 阶段——业界共识是没有路由层
  • SimpleRouter 的 3 个功能(@skill 前缀、greeting regex、default REACT都是预处理而非路由决策
  • "路由"概念误导开发者认为存在意图预测层,实际上 LLM 在 agent loop 中自主决策

替代方案:完全删除 SimpleRouter所有请求直接进入 REACT loop。被否决——greeting fast-path 每次请求节省 ~100 tokens + 500ms@skill 前缀是用户显式指令需要代码级解析

KTD2: 专家团 hub-and-spoke 模式

决策ExpertTeam 从去中心化协作简化为 Lead Expert + 并行 Task深度=1

依据

  • Claude CodeTask 工具深度=1子 Agent 不能再生子 Agent
  • Codexspawn_agent 层级式,结果返回父 Agent
  • Qoder多专家并行独立执行主 Agent 汇总
  • 去中心化协作的通信复杂度 O(N²)hub-and-spoke 为 O(N)
  • 同一 LLM 扮演不同"专家"不产生真正的观点多样性,等价于多次采样+合并

保留ExpertConfig/ExpertTemplate/Registry定义专家 persona、BEST 合并策略Lead Agent 选择最佳结果)

删除CollaborationPlan 的 phase 依赖图、HandoffTransport 的 Agent 间通信、SharedWorkspace 的跨阶段状态共享、VOTE/FUSION 合并策略

KTD3: PlanExec 默认 ReActStepExecutor + Spec-Driven

决策:默认使用 ReActStepExecutor已实现删除 _LLMStepExecutor新增 Spec 文档持久化

依据

  • _LLMStepExecutor 不支持工具调用 = 没有执行能力
  • ReActStepExecutor 已实现并使用 ReActEngine支持工具调用和多步推理
  • Qoder Quest ModeSpec First 是人和 AI 的契约,用户确认后再执行
  • 当前 PlanExec 的计划对用户不可见,用户无法在执行前纠正方向

KTD4: 聊天记录 SQLite 持久化

决策:使用 SQLite 做聊天记录持久化(参考 Codex 的 Thread 持久化)

依据

  • Codex 使用 SQLite轻量、零配置、跨平台支持 resume/fork/archive
  • Claude Code 使用 append-only JSONL更简单但搜索能力弱
  • 当前 ConversationStore 纯内存,服务重启后丢失
  • SQLite 支持会话搜索、分页加载,且无需额外服务

Implementation Units

U1. SimpleRouter 重命名为 RequestPreprocessor

Goal: 消除"路由"概念,将 SimpleRouter 重命名为 RequestPreprocessor

Dependencies: 无

Files:

  • src/agentkit/chat/simple_router.py → 重命名为 src/agentkit/chat/request_preprocessor.py
  • src/agentkit/chat/skill_routing.py — 更新引用
  • src/agentkit/server/routes/portal.py — 更新 import 和调用
  • src/agentkit/server/routes/chat.py — 更新 import 和调用
  • src/agentkit/server/app.py — 更新 import 和调用
  • tests/unit/chat/test_simple_router.py → 重命名并更新

Approach:

  1. 创建 request_preprocessor.py,类名 RequestPreprocessor,方法 route()preprocess()
  2. _is_direct_chat() 重命名为 _is_trivial_input()
  3. SkillRoutingResult 保留(它是数据结构,不涉及路由概念)
  4. 更新所有调用点
  5. 删除旧文件

Patterns to follow: 现有 SimpleRouter 的代码结构

Test scenarios:

  • @skill:xxx 前缀正确解析为 SKILL_REACT 模式
  • Greeting regex 匹配返回 DIRECT_CHAT
  • 默认输入返回 REACT 模式
  • 未知 skill 回退到 REACT
  • preprocess() 方法签名与 route() 兼容

Verification: ruff check src/ && pytest tests/unit/chat/ -v


U2. 删除 CostAwareRouter 及相关代码

Goal: 删除已被 SimpleRouter 替代的旧路由层代码

Dependencies: U1

Files:

  • src/agentkit/router/ 目录下大部分文件(保留 init.py 和必要的导出)
  • src/agentkit/server/app.py — 清理注释掉的引用
  • src/agentkit/chat/cost_aware_router.py — 删除

Approach:

  1. 确认 CostAwareRouter 在代码中无活跃引用app.py 已注释)
  2. 删除 cost_aware_router.pyheuristic_classifier.pyintent.pyIntentRouterquality_gate.pysemantic_router.py
  3. 保留 router/__init__.py 导出必要的类型(如 ExecutionMode如果前端依赖
  4. 清理 app.py 中的注释引用
  5. 更新 router/ 目录的 __init__.py

Test scenarios:

  • 删除后 ruff check 无错误
  • pytest -m "not integration" 全部通过
  • 无 import 错误

Verification: ruff check src/ && pytest -m "not integration" -x


U3. 专家团简化为 hub-and-spoke

Goal: 将 ExpertTeam 从去中心化协作简化为 Lead Expert + 并行 Task 模式

Dependencies: 无(可与 U1/U2 并行)

Files:

  • src/agentkit/experts/orchestrator.py — 重写为 hub-and-spoke
  • src/agentkit/experts/team.py — 简化,移除 CollaborationPlan 依赖
  • src/agentkit/experts/plan.py — 简化,保留 MergeStrategy.BEST
  • src/agentkit/core/handoff_transport.py — 移除 ExpertTeam 专用逻辑
  • src/agentkit/core/shared_workspace.py — 移除 ExpertTeam 专用逻辑
  • src/agentkit/experts/router.py — 简化为 @team 前缀 + RequestPreprocessor 集成
  • tests/unit/experts/test_orchestrator.py — 更新

Approach:

  1. 重写 TeamOrchestratorLead Expert 自主规划 + 并行 spawn Task
  2. 删除 CollaborationPlan 的 phase 依赖图Lead Expert 自主决定执行顺序
  3. 删除 HandoffTransport 的 Agent 间通信Task 结果直接返回 Lead Expert
  4. 删除 SharedWorkspace 的跨阶段状态共享Lead Expert 持有所有状态
  5. 保留 MergeStrategy.BESTLead Agent 选择最佳结果),删除 VOTE/FUSION
  6. 简化 ExpertTeamRouter 为 @team 前缀触发
  7. 保留 ExpertConfig/ExpertTemplate/Registry 不变

Technical design:

新 TeamOrchestrator 流程:
1. 用户输入 → @team:xxx 前缀 → ExpertTeamMode
2. Lead Expert 接收任务,自主分解为子任务
3. 并行 spawn Task每个 Task 是独立 ReActEngine 实例)
4. 等待所有 Task 完成
5. Lead Expert 汇总结果BEST 策略)
6. 返回最终结果

约束:
- Task 深度=1Task 不能再 spawn Task
- Task 之间无通信
- Lead Expert 持有所有状态

Test scenarios:

  • Lead Expert 正确分解任务为子任务
  • 并行 Task 独立执行并返回结果
  • Lead Expert 汇总结果
  • 单个 Task 失败不影响其他 Task
  • 所有 Task 失败时回退到 Lead Expert 单独执行
  • @team 前缀正确触发 ExpertTeamMode

Verification: ruff check src/ && pytest tests/unit/experts/ -v


U4. PlanExec 默认 ReActStepExecutor + 删除 _LLMStepExecutor

Goal: PlanExecEngine 默认使用 ReActStepExecutor删除 _LLMStepExecutor

Dependencies: 无

Files:

  • src/agentkit/core/plan_exec_engine.py — 删除 _LLMStepExecutor 和 _LLMStepAgent默认 step_executor_type="react"
  • tests/unit/core/test_plan_exec_engine.py — 更新

Approach:

  1. 删除 _LLMStepExecutor_LLMStepAgent
  2. _create_executor() 方法移除 step_executor_type 参数,始终使用 ReActStepExecutor
  3. 清理相关 import

Test scenarios:

  • PlanExecEngine 默认创建 ReActStepExecutor
  • ReActStepExecutor 正确执行带工具调用的步骤
  • 步骤失败时触发重规划

Verification: ruff check src/ && pytest tests/unit/core/test_plan_exec_engine.py -v


U5. 聊天记录 SQLite 持久化

Goal: 使用 SQLite 持久化聊天记录,服务重启后不丢失

Dependencies: U1RequestPreprocessor 重命名完成后更新调用点)

Files:

  • src/agentkit/chat/sqlite_conversation_store.py — 新建
  • src/agentkit/server/routes/portal.py — 替换 ConversationStore
  • src/agentkit/chat/conversation_store.py — 保留作为接口/内存实现

Approach:

  1. 新建 SqliteConversationStore,实现与 ConversationStore 相同接口
  2. SQLite 表结构conversations(id, session_id, role, content, timestamp, metadata)
  3. 支持按 session_id 查询、分页加载、搜索
  4. 数据库文件路径:~/.agentkit/conversations.db
  5. 在 portal.py 中替换 ConversationStore 为 SqliteConversationStore
  6. 保留 ConversationStore 作为内存实现(测试用)

Test scenarios:

  • 消息正确持久化到 SQLite
  • 按 session_id 查询返回完整对话
  • 分页加载正确
  • 服务重启后数据不丢失
  • SQLite 文件不存在时自动创建

Verification: ruff check src/ && pytest tests/unit/chat/test_sqlite_conversation_store.py -v


U6. 可验证执行Test-and-Verify 循环)

Goal: ReActEngine 执行后可选自动运行项目测试验证结果

Dependencies: U4

Files:

  • src/agentkit/core/verification_loop.py — 新建
  • src/agentkit/core/react.py — 集成验证循环
  • src/agentkit/tools/builtin.py — 新增 run_tests 工具

Approach:

  1. 新建 VerificationLoop:执行后运行 pytest/ruff/typecheck失败则自动重试
  2. 最大重试次数可配置(默认 2
  3. 验证结果附加到 ReActResult
  4. 新增 run_tests 内置工具LLM 可主动调用
  5. 验证循环默认关闭,通过参数 verification_enabled=True 启用

Test scenarios:

  • 验证循环关闭时行为不变
  • 验证循环开启时,执行后自动运行测试
  • 测试通过时返回成功
  • 测试失败时自动重试
  • 达到最大重试次数后返回失败结果

Verification: ruff check src/ && pytest tests/unit/core/test_verification_loop.py -v


Goal: 核心工具全量注入,扩展工具只注入名称+一行描述LLM 可通过 tool_search 获取完整描述

Dependencies: 无

Files:

  • src/agentkit/core/react.py — 修改 _build_tool_use_prompt
  • src/agentkit/tools/builtin.py — 新增 tool_search 工具
  • src/agentkit/tools/search.py — 新建BM25 工具搜索

Approach:

  1. 工具分为 coreread/write/bash/search和 extended其余
  2. core 工具全量注入 prompt
  3. extended 工具只注入 name + one-line description
  4. 新增 tool_search 工具BM25 搜索工具描述,返回完整描述
  5. LLM 在 agent loop 中按需调用 tool_search

Test scenarios:

  • core 工具全量出现在 prompt 中
  • extended 工具只出现名称和一行描述
  • tool_search 正确返回工具完整描述
  • BM25 搜索相关性排序

Verification: ruff check src/ && pytest tests/unit/tools/test_tool_search.py -v


U8. 默认启用上下文压缩

Goal: ReActEngine 默认启用滑动窗口压缩

Dependencies: 无

Files:

  • src/agentkit/core/react.py — 修改默认 compressor 参数
  • src/agentkit/core/compressor.py — 确认滑动窗口实现

Approach:

  1. ReActEngine 的 __init__ 中 compressor 默认值从 None 改为 SlidingWindowCompressor
  2. 保留最近 N 轮 + 系统提示 + 工具描述
  3. N 可配置(默认 10

Test scenarios:

  • 长对话自动压缩
  • 压缩后系统提示和工具描述保留
  • 压缩不影响最近 N 轮对话

Verification: ruff check src/ && pytest tests/unit/core/test_compressor.py -v


U9. Spec 文档作为一等公民

Goal: PlanExec 生成的计划持久化为 Spec 文档,用户可查看、编辑、确认后再执行

Dependencies: U4

Files:

  • src/agentkit/core/spec_manager.py — 新建
  • src/agentkit/core/plan_exec_engine.py — 集成 SpecManager
  • src/agentkit/server/routes/tasks.py — 新增 Spec 相关 API

Approach:

  1. 新建 SpecManager:管理 Spec 文档的 CRUD
  2. Spec 文件路径:.agentkit/specs/<plan_id>.yaml
  3. PlanExecEngine 生成计划后,先持久化为 Spec
  4. 新增 APIGET /api/v1/specsGET /api/v1/specs/{id}PUT /api/v1/specs/{id}POST /api/v1/specs/{id}/confirm
  5. 用户确认后才开始执行

Test scenarios:

  • 计划正确持久化为 Spec 文件
  • Spec 文件可读取和编辑
  • 未确认的 Spec 不会执行
  • 确认后触发执行

Verification: ruff check src/ && pytest tests/unit/core/test_spec_manager.py -v


U10. 统一事件模型SQ/EQ 双队列)

Goal: 统一 CLI 和 WebSocket 的事件模型为 SQ/EQ 双队列

Dependencies: U3

Files:

  • src/agentkit/core/protocol.py — 新增 SQ/EQ 事件类型
  • src/agentkit/server/routes/portal.py — 对接 EQ
  • src/agentkit/cli/chat.py — 对接 EQ

Approach:

  1. 定义 SubmissionQueue用户输入和 EventQueueAgent 输出)
  2. 事件类型Session/Task/Turn 三级模型
  3. Portal WebSocket 和 CLI 共享同一事件流
  4. 前端可以统一渲染

Test scenarios:

  • SQ 正确接收用户输入
  • EQ 正确推送 Agent 事件
  • WebSocket 和 CLI 共享事件流
  • 事件类型正确分类

Verification: ruff check src/ && pytest tests/unit/core/test_protocol.py -v


Scope Boundaries

In Scope

  • 上述 10 个 Implementation Unit
  • 单元测试覆盖

Out of Scope

  • DockerComputerUseSession 实现P3等用户需求验证
  • 前端组件更新(后续迭代)
  • Agent 配置热重载P4
  • 渐进式上下文加载P4
  • Soul 演变多维度触发(关闭)
  • OTel 埋点(延后)

Deferred to Follow-Up Work

  • 前端 ExpertTeamView 接入真实数据
  • SWE-bench 端到端验证
  • 性能监控和成本追踪

Risks & Dependencies

Risk Impact Mitigation
U3 专家团重写可能影响现有 @team 功能 保留 ExpertConfig/ExpertTemplate/Registry只重写 Orchestrator
U5 SQLite 在高并发下可能有锁竞争 聊天场景写频率低SQLite WAL 模式足够
U7 tool_search 可能增加 LLM 调用轮次 核心工具全量注入,只有扩展工具需要搜索
U9 Spec 文档可能增加用户操作步骤 默认自动确认(可配置),不阻塞自动化流程

Phased Delivery

Phase 1清理收尾: U1 → U2 → U4 → U8 Phase 2核心能力: U5 → U6 → U9 Phase 3多 Agent: U3 → U7 → U10