738 lines
30 KiB
Markdown
738 lines
30 KiB
Markdown
---
|
||
title: "feat: AgentKit Phase 4 — 企业级生产化升级"
|
||
status: completed
|
||
created: 2026-06-06
|
||
plan_type: feat
|
||
depth: deep
|
||
origin: AgentKit 全能力成熟度评估 + GEO 系统集成需求
|
||
branch: feat/agentkit-phase4-production
|
||
---
|
||
|
||
# AgentKit Phase 4 — 企业级生产化升级
|
||
|
||
## Summary
|
||
|
||
基于 AgentKit 全能力成熟度审计和 GEO 系统集成需求,本计划解决 5 大生产级差距:进化系统执行断裂、记忆系统不可扩展、LLM 单 Provider、核心引擎缺超时/取消、Server 缺实时通信。覆盖 12 个 Implementation Unit,分 3 个交付阶段,以"GEO 系统完美运行"为验收底线。
|
||
|
||
## Problem Frame
|
||
|
||
Phase 3 完成了基础设施搭建(持久化、记忆接入、进化设计、SKILL.md、可观测性),但审计发现多个"设计完整但执行断裂"的问题:
|
||
|
||
### 五大生产级差距
|
||
|
||
1. **进化系统名存实亡(35% 成熟度)**
|
||
- A/B 测试被禁用(lifecycle.py:172-188),整个验证循环被绕过
|
||
- `_current_module` 从未被设置(lifecycle.py:74),prompt 优化永远短路
|
||
- PromptOptimizer 仅注入 few-shot + 追加失败模式,无 LLM 驱动重写
|
||
- StrategyTuner 纯随机扰动,无代码路径调用
|
||
- ABTester 结果仅内存,进程重启丢失
|
||
|
||
2. **记忆系统不可扩展(65% 成熟度)**
|
||
- EpisodicMemory 客户端 O(N) 余弦(episodic.py:90-111),>1000 条不可用
|
||
- Episodic 未从配置初始化(app.py:173, config_driven.py:329-332 是 `pass`)
|
||
- 无嵌入缓存,每次 embed() 调 API
|
||
- Enhanced search 首个 KB 404 即全量降级(http_rag.py:198-202)
|
||
|
||
3. **LLM 仅单 Provider(60% 成熟度)**
|
||
- 仅 OpenAICompatibleProvider,Anthropic/Gemini/文心等无原生实现
|
||
- 无 Provider 级重试/熔断/退避
|
||
- chat_stream() 无 fallback 链
|
||
- HTTP 超时硬编码 60s
|
||
|
||
4. **核心引擎缺超时/取消(80% 成熟度)**
|
||
- ReAct 循环无超时强制执行,可无限运行
|
||
- 无 CancellationToken 支持
|
||
- BaseAgent.execute() 不读 timeout_seconds
|
||
- Agent 状态更新无锁,并发竞态
|
||
|
||
5. **Server 缺实时通信(75% 成熟度)**
|
||
- 无 WebSocket,流式响应仅 SSE
|
||
- SSE 创建新 ReActEngine 忽略 Agent 配置
|
||
- SSE 访问私有属性 `_tool_registry`/`_llm_model`
|
||
- 无 Evolution/Memory API 路由
|
||
|
||
### GEO 系统的关键依赖
|
||
|
||
GEO 系统以"Mode A"(纯 HTTP API)集成 AgentKit,关键路径:
|
||
|
||
- **内容生成**:`content_generator` skill → ReAct 引擎 → HttpRAGService 知识库检索 → LLM 生成
|
||
- **引用检测**:`citation_detector` skill → custom_handler → 回调 GEO 内部 API
|
||
- **GEO 优化**:`geo_optimizer` skill → ReAct 引擎 + 质量门控
|
||
- **监控/Schema/竞品/趋势**:各 skill → ReAct/custom 模式
|
||
|
||
**GEO 的容错模式**:AgentKit 不可用时降级到直接 LLM 调用。这意味着 AgentKit 的价值在于**质量提升**而非**功能可用**——如果 AgentKit 不比直接调用更好,就没有存在意义。
|
||
|
||
## Requirements
|
||
|
||
| ID | Requirement | Priority | Source |
|
||
|----|-------------|----------|--------|
|
||
| R1 | 进化系统可运行:A/B 测试启用、_current_module 自动设置、PromptOptimizer LLM 驱动 | P0 | 进化系统审计 |
|
||
| R2 | EpisodicMemory 使用 pgvector 原生搜索,支持百万级数据 | P0 | 记忆系统审计 |
|
||
| R3 | EpisodicMemory 从配置自动初始化,Server 和 ConfigDrivenAgent 统一接入 | P0 | 记忆系统审计 |
|
||
| R4 | 新增 Anthropic Provider(Messages API 原生实现) | P0 | LLM 审计 + GEO 需求 |
|
||
| R5 | ReAct 循环超时强制执行 + CancellationToken 支持 | P0 | 核心引擎审计 |
|
||
| R6 | Provider 级重试/熔断/指数退避 | P1 | LLM 审计 |
|
||
| R7 | chat_stream() 支持 fallback 链 | P1 | LLM 审计 |
|
||
| R8 | WebSocket 端点支持双向实时通信 | P1 | Server 审计 |
|
||
| R9 | SSE 流修复:使用 Agent 配置、不访问私有属性 | P1 | Server 审计 |
|
||
| R10 | Evolution/Memory API 路由 | P1 | Server 审计 |
|
||
| R11 | 嵌入缓存 + Enhanced Search 部分降级修复 | P1 | 记忆系统审计 |
|
||
| R12 | 新增 Gemini Provider | P2 | LLM 审计 |
|
||
| R13 | Agent 状态锁 + 配置热加载 | P2 | 核心引擎审计 |
|
||
|
||
## Key Technical Decisions
|
||
|
||
### KTD-1: 进化系统修复策略 — 修复而非重写
|
||
|
||
**决策**:在现有 EvolutionMixin 架构上修复断裂点,不引入 GEPA 式遗传算法。
|
||
|
||
**理由**:
|
||
- 现有管线设计完整(reflect → optimize → A/B test → apply/rollback),只需接通
|
||
- GEPA 需要"用自然语言反思替代梯度更新"的完整评估管线,当前无评估数据
|
||
- GEO 的 8 个 skill 都是 `llm_generate`/`custom` 模式,进化收益有限
|
||
- 修复后即可实现"执行轨迹 → LLM 反思 → 质量门控 → 安全应用"的最小闭环
|
||
|
||
**替代方案**:引入 GEPA 遗传算法 → 需要评估管线 + 统计显著 A/B + 大量执行数据,当前不具备条件
|
||
|
||
### KTD-2: EpisodicMemory pgvector 原生搜索 — 复用 GEO 数据库
|
||
|
||
**决策**:EpisodicMemory 直接使用 GEO 共享的 PostgreSQL + pgvector,通过 SQLAlchemy session 执行 `<=>` 操作符。
|
||
|
||
**理由**:
|
||
- docker-compose 已配置 AgentKit 与 GEO 共享 PostgreSQL
|
||
- GEO 的 `KnowledgeChunk` 已使用 pgvector `Vector(1536)` + HNSW 索引
|
||
- AgentKit 的 `EpisodicMemory` 模型(在 geo/backend/app/models/agent.py)已有 `embedding_id` 字段
|
||
- 无需引入新数据库,复用现有基础设施
|
||
|
||
**替代方案**:独立 pgvector 实例 → 增加运维复杂度,与 GEO 数据不共享
|
||
|
||
### KTD-3: LLM Provider 架构 — 抽象层 + 原生实现
|
||
|
||
**决策**:保留 `LLMProvider` ABC,新增 `AnthropicProvider` 和 `GeminiProvider` 原生实现,不依赖 OpenAI 兼容层。
|
||
|
||
**理由**:
|
||
- Anthropic Messages API 格式与 OpenAI 不同(`content` 数组 vs `content` 字符串,`tool_choice` 结构不同)
|
||
- Gemini 有独特的 `generateContent` API 和安全设置
|
||
- 通过 OpenAI 兼容层适配会丢失原生功能(如 Anthropic 的 extended thinking、Gemini 的 grounding)
|
||
- GEO 的 `content_generator` 和 `deai_agent` 对输出质量敏感,原生 API 更可靠
|
||
|
||
### KTD-4: 超时与取消 — asyncio.wait_for + CancellationToken
|
||
|
||
**决策**:ReAct 循环使用 `asyncio.wait_for()` 强制超时,新增 `CancellationToken` 支持优雅取消。
|
||
|
||
**理由**:
|
||
- `asyncio.wait_for()` 是 Python 标准库,无额外依赖
|
||
- CancellationToken 模式与 GEO 的 `agent_execution_context` 兼容
|
||
- Server 的 `cancel_task` 端点已有,只需 ReAct 循环配合
|
||
|
||
### KTD-5: WebSocket — FastAPI 原生 WebSocket
|
||
|
||
**决策**:使用 FastAPI 原生 `WebSocket` 端点,不引入 Socket.IO 等第三方库。
|
||
|
||
**理由**:
|
||
- GEO 前端已有 `agents.ts` API 客户端,WebSocket 原生支持即可
|
||
- 减少依赖,降低安全风险
|
||
- FastAPI WebSocket 与现有路由体系一致
|
||
|
||
## Scope Boundaries
|
||
|
||
### In Scope
|
||
|
||
- 进化系统修复(A/B 测试启用、_current_module 接入、LLM PromptOptimizer)
|
||
- EpisodicMemory pgvector 原生搜索 + 配置初始化
|
||
- Anthropic Provider + Gemini Provider
|
||
- Provider 级重试/熔断
|
||
- ReAct 超时 + CancellationToken
|
||
- WebSocket 端点
|
||
- SSE 流修复
|
||
- Evolution/Memory API 路由
|
||
- 嵌入缓存 + Enhanced Search 部分降级
|
||
|
||
### Out of Scope
|
||
|
||
- GEPA 遗传算法(需评估管线,Phase 5)
|
||
- 多 Agent 协作编排(L4 级,Phase 5)
|
||
- RAG 自纠错循环(L5 级,Phase 5)
|
||
- 配置热加载(P2,可后续)
|
||
- Agent 状态锁(P2,可后续)
|
||
- 文心/豆包/元宝等国内 Provider(P2,可后续通过社区贡献)
|
||
|
||
### Deferred to Follow-Up Work
|
||
|
||
- Contextual Retrieval(Anthropic 2024 突破,需 chunk 处理层)
|
||
- 评估管线(Ragas + Phoenix 集成)
|
||
- 多 Agent RAG 编排(supervisor-worker 拓扑)
|
||
- 配置 Schema 验证(Pydantic 模型)
|
||
- 性能基准测试
|
||
|
||
## High-Level Technical Design
|
||
|
||
### 架构总览
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ GEO Frontend (Next.js) │
|
||
│ agents.ts → WebSocket + REST API │
|
||
└────────────────────────┬────────────────────────────────────┘
|
||
│ HTTP / WebSocket
|
||
┌────────────────────────▼────────────────────────────────────┐
|
||
│ AgentKit Server (:8001) │
|
||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
|
||
│ │ REST API │ │WebSocket │ │ SSE │ │ Evolution API │ │
|
||
│ │ (tasks, │ │ (real- │ │ (stream) │ │ (/evolution) │ │
|
||
│ │ agents) │ │ time) │ │ │ │ │ │
|
||
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └───────┬───────┘ │
|
||
│ │ │ │ │ │
|
||
│ ┌────▼────────────▼────────────▼────────────────▼───────┐ │
|
||
│ │ Core Engine │ │
|
||
│ │ ReActEngine (timeout + cancel) │ │
|
||
│ │ ConfigDrivenAgent (_current_module auto-set) │ │
|
||
│ │ EvolutionMixin (A/B test enabled + LLM PromptOptimizer)│ │
|
||
│ └────┬──────────┬──────────┬──────────┬─────────────────┘ │
|
||
│ │ │ │ │ │
|
||
│ ┌────▼───┐ ┌───▼────┐ ┌──▼───┐ ┌───▼──────┐ │
|
||
│ │Memory │ │LLM │ │Skills│ │Evolution │ │
|
||
│ │System │ │Gateway │ │System│ │System │ │
|
||
│ │ │ │ │ │ │ │ │ │
|
||
│ │Working │ │OpenAI │ │YAML │ │LLM │ │
|
||
│ │(Redis) │ │Anthropic│ │MD │ │Reflector │ │
|
||
│ │ │ │Gemini │ │Pipeline│ │ABTester │ │
|
||
│ │Episodic│ │+retry │ │ │ │(enabled) │ │
|
||
│ │(pgvec) │ │+breaker│ │ │ │PromptOpt │ │
|
||
│ │ │ │ │ │ │ │(LLM) │ │
|
||
│ │Semantic│ │ │ │ │ │Store │ │
|
||
│ │(RAG) │ │ │ │ │ │(SQLite) │ │
|
||
│ └────┬───┘ └────────┘ └──────┘ └──────────┘ │
|
||
│ │ │
|
||
│ ┌────▼──────────────────────────────────────────────────┐ │
|
||
│ │ PostgreSQL + pgvector (shared with GEO) │ │
|
||
│ │ Redis (shared with GEO) │ │
|
||
│ └───────────────────────────────────────────────────────┘ │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 进化系统修复后数据流
|
||
|
||
```
|
||
任务完成
|
||
→ TraceRecorder.end_trace() 生成 ExecutionTrace
|
||
→ EvolutionMixin.evolve_after_task()
|
||
→ Reflector.reflect(trace) → Reflection (LLM 或规则)
|
||
→ if reflection.outcome == "should_optimize":
|
||
→ PromptOptimizer.optimize(module, trace, reflection)
|
||
→ LLM 驱动重写 instruction (新增)
|
||
→ 注入 few-shot demos (已有)
|
||
→ ABTester.assign_group(task_id) → control/treatment
|
||
→ ABTester.record_result(task_id, group, score)
|
||
→ if ABTester.is_significant(test_id):
|
||
→ apply change (treatment wins) or rollback (control wins)
|
||
→ else:
|
||
→ keep current, log inconclusive
|
||
→ EvolutionStore.persist(event)
|
||
```
|
||
|
||
### EpisodicMemory pgvector 搜索流程
|
||
|
||
```
|
||
MemoryRetriever.retrieve(query)
|
||
→ EpisodicMemory.search(query, top_k=5)
|
||
→ Embedder.embed(query) → query_embedding (带缓存)
|
||
→ SQLAlchemy: SELECT * FROM episodic_memories
|
||
ORDER BY embedding <=> :query_embedding
|
||
LIMIT :top_k
|
||
→ 时间衰减混合评分: score = alpha * (1 - cosine_distance) + (1-alpha) * time_decay
|
||
→ 返回 top_k 结果
|
||
```
|
||
|
||
### LLM Provider 重试/熔断流程
|
||
|
||
```
|
||
LLMGateway.chat(request)
|
||
→ Provider.chat() (primary)
|
||
→ CircuitBreaker.allow? → yes
|
||
→ RetryPolicy.execute():
|
||
→ attempt 1 → fail → backoff 1s
|
||
→ attempt 2 → fail → backoff 2s
|
||
→ attempt 3 → fail → CircuitBreaker.record_failure()
|
||
→ if failures >= threshold: open circuit
|
||
→ CircuitBreaker.allow? → no (circuit open)
|
||
→ skip to fallback
|
||
→ Fallback: try next provider/model in chain
|
||
```
|
||
|
||
---
|
||
|
||
## Implementation Units
|
||
|
||
### Phase A: 核心修复(P0 — GEO 运行依赖)
|
||
|
||
---
|
||
|
||
### U1. EpisodicMemory pgvector 原生搜索 + 配置初始化
|
||
|
||
**Goal**: 将 EpisodicMemory 从客户端 O(N) 余弦切换到 pgvector `<=>` 操作符,支持百万级数据;从 Server 和 ConfigDrivenAgent 配置自动初始化。
|
||
|
||
**Requirements**: R2, R3
|
||
|
||
**Dependencies**: 无
|
||
|
||
**Files**:
|
||
- `src/agentkit/memory/episodic.py` — 重写 search/retrieve 使用 pgvector
|
||
- `src/agentkit/memory/embedder.py` — 新增嵌入缓存
|
||
- `src/agentkit/server/app.py` — EpisodicMemory 初始化
|
||
- `src/agentkit/core/config_driven.py` — EpisodicMemory 初始化
|
||
- `src/agentkit/server/config.py` — Episodic 配置段
|
||
- `tests/unit/test_episodic_vector_search.py` — 更新测试
|
||
- `tests/unit/test_memory_integration.py` — 更新测试
|
||
|
||
**Approach**:
|
||
1. EpisodicMemory 新增 `session_factory` 参数,search/retrieve 使用 `text("embedding <=> :query_vec")` 原生 pgvector 查询
|
||
2. 保留 `_alpha` 混合评分:pgvector 返回 top_k*3 候选,Python 端做时间衰减重排
|
||
3. 无 pgvector 时降级到客户端余弦(现有逻辑)
|
||
4. Embedder 新增 `EmbeddingCache`(LRU + TTL),避免重复 embed 调用
|
||
5. ServerConfig 新增 `memory.episodic` 配置段(session_factory、pgvector_enabled、table_name)
|
||
6. create_app() 和 ConfigDrivenAgent 从配置创建 EpisodicMemory
|
||
|
||
**Patterns to follow**: GEO 的 `HybridRetriever`(pgvector + ILIKE + RRF 融合)
|
||
|
||
**Test scenarios**:
|
||
- pgvector 搜索返回 top_k 结果按相似度排序
|
||
- 无 pgvector 时降级到客户端余弦
|
||
- 时间衰减重排:近期条目优先
|
||
- 嵌入缓存命中/未命中
|
||
- 配置初始化 EpisodicMemory 成功/失败降级
|
||
- 大数据量(10000+ 条)搜索性能
|
||
|
||
**Verification**: 全量测试通过 + EpisodicMemory 集成测试覆盖 pgvector 路径
|
||
|
||
---
|
||
|
||
### U2. ReAct 超时强制执行 + CancellationToken
|
||
|
||
**Goal**: ReAct 循环支持超时强制退出和优雅取消,防止任务无限运行。
|
||
|
||
**Requirements**: R5
|
||
|
||
**Dependencies**: 无
|
||
|
||
**Files**:
|
||
- `src/agentkit/core/react.py` — 超时 + 取消支持
|
||
- `src/agentkit/core/protocol.py` — CancellationToken 类型
|
||
- `src/agentkit/core/base.py` — 传递 timeout_seconds
|
||
- `src/agentkit/core/config_driven.py` — 传递 timeout
|
||
- `src/agentkit/server/routes/tasks.py` — cancel 端点传递 token
|
||
- `tests/unit/test_react_engine.py` — 更新测试
|
||
- `tests/unit/test_base_agent.py` — 更新测试
|
||
|
||
**Approach**:
|
||
1. 新增 `CancellationToken` 数据类:`is_cancelled: bool`,`cancel()` 方法,`check()` 抛 `TaskCancelledError`
|
||
2. ReActEngine.__init__ 新增 `default_timeout: float = 300.0`
|
||
3. execute() 用 `asyncio.wait_for()` 包裹主循环,超时抛 `TaskTimeoutError`
|
||
4. 每步循环开始检查 `token.check()`
|
||
5. BaseAgent.execute() 从 `TaskMessage.timeout_seconds` 读取超时
|
||
6. Server cancel 端点设置 CancellationToken
|
||
|
||
**Patterns to follow**: Python asyncio.wait_for + CancellationToken 模式
|
||
|
||
**Test scenarios**:
|
||
- 超时触发 TaskTimeoutError,返回部分结果
|
||
- CancellationToken 取消,返回已完成步骤
|
||
- 超时 0 表示无限(向后兼容)
|
||
- 正常完成不受超时影响
|
||
- 并发取消和超时竞争
|
||
|
||
**Verification**: 全量测试通过 + 超时/取消场景覆盖
|
||
|
||
---
|
||
|
||
### U3. 进化系统修复 — A/B 测试启用 + _current_module 接入
|
||
|
||
**Goal**: 修复进化系统的 3 个断裂点,使自我进化管线可运行。
|
||
|
||
**Requirements**: R1
|
||
|
||
**Dependencies**: U2(超时机制防止进化循环失控)
|
||
|
||
**Files**:
|
||
- `src/agentkit/evolution/lifecycle.py` — 启用 A/B 测试、自动设置 _current_module
|
||
- `src/agentkit/evolution/ab_tester.py` — 持久化、确定性分组
|
||
- `src/agentkit/evolution/prompt_optimizer.py` — LLM 驱动重写
|
||
- `src/agentkit/evolution/strategy_tuner.py` — 接入进化管线
|
||
- `src/agentkit/core/config_driven.py` — 自动 set_current_module
|
||
- `src/agentkit/skills/base.py` — EvolutionConfig 扩展
|
||
- `tests/unit/test_evolution_lifecycle.py` — 更新测试
|
||
- `tests/unit/test_ab_tester.py` — 新增测试
|
||
- `tests/unit/test_prompt_optimizer.py` — 新增测试
|
||
|
||
**Approach**:
|
||
1. **A/B 测试启用**:
|
||
- lifecycle.py: 移除 TODO bypass,调用 ABTester
|
||
- ABTester: 改用 hash-based 分组(`hash(task_id) % 2`),确定性可复现
|
||
- ABTester: 结果持久化到 EvolutionStore
|
||
- 最小样本量 10(从 30 降低,适配 GEO 低频场景)
|
||
- 样本不足时不应用变更,记录"insufficient data"
|
||
2. **_current_module 自动设置**:
|
||
- ConfigDrivenAgent._handle_react() 在执行前自动 `set_current_module()`
|
||
- 从 SkillConfig 提取当前 prompt 作为 module
|
||
3. **LLM PromptOptimizer**:
|
||
- 新增 `LLMPromptOptimizer`:用 LLM 分析失败模式,重写 instruction
|
||
- 保留 `BootstrapPromptOptimizer`(原 PromptOptimizer 重命名)作为 fallback
|
||
- 工厂函数 `create_prompt_optimizer(optimizer_type, llm_gateway)`
|
||
4. **StrategyTuner 接入**:
|
||
- EvolutionMixin.evolve_after_task() 在 prompt 优化后检查 strategy 优化
|
||
- StrategyTuner 改用贝叶斯优化(简化版:高斯过程 1D)
|
||
|
||
**Patterns to follow**: GEO 的 `EnhancedRAG`(LLM 驱动优化模式)
|
||
|
||
**Test scenarios**:
|
||
- A/B 测试:control/treatment 分组确定性
|
||
- A/B 测试:最小样本量不足时不应用
|
||
- A/B 测试:统计显著时应用/回滚
|
||
- _current_module 自动设置
|
||
- LLM PromptOptimizer 生成优化 instruction
|
||
- StrategyTuner 贝叶斯优化
|
||
- 进化管线端到端:reflect → optimize → A/B test → apply/rollback
|
||
|
||
**Verification**: 全量测试通过 + 进化端到端测试
|
||
|
||
---
|
||
|
||
### U4. Anthropic Provider 原生实现
|
||
|
||
**Goal**: 新增 AnthropicProvider,支持 Claude Messages API 原生调用。
|
||
|
||
**Requirements**: R4
|
||
|
||
**Dependencies**: 无
|
||
|
||
**Files**:
|
||
- `src/agentkit/llm/providers/anthropic.py` — 新增 AnthropicProvider
|
||
- `src/agentkit/llm/gateway.py` — 注册 Anthropic provider
|
||
- `src/agentkit/llm/config.py` — Anthropic 配置
|
||
- `tests/unit/test_anthropic_provider.py` — 新增测试
|
||
|
||
**Approach**:
|
||
1. AnthropicProvider 实现 LLMProvider ABC
|
||
2. 使用 httpx 直接调用 `https://api.anthropic.com/v1/messages`
|
||
3. 支持 Messages API 特有功能:
|
||
- `content` 数组格式(text + tool_use + tool_result)
|
||
- `tool_choice` 结构(`{"type": "auto"|"any"|"tool", "name": "..."}`)
|
||
- `system` 顶层参数
|
||
- `max_tokens` 必填
|
||
- extended thinking(可选)
|
||
4. 流式支持:SSE `event: content_block_delta`
|
||
5. 错误处理:429 rate limit / 529 overload / 500 server error
|
||
6. 配置:`api_key`、`model`、`max_tokens`、`thinking_enabled`
|
||
|
||
**Patterns to follow**: OpenAICompatibleProvider 的接口模式
|
||
|
||
**Test scenarios**:
|
||
- 标准 chat 请求/响应
|
||
- tool_calls 请求/响应
|
||
- 流式 chat(content_block_delta)
|
||
- 错误处理(429/529/500)
|
||
- API key 缺失报错
|
||
- 模型别名解析
|
||
|
||
**Verification**: 全量测试通过 + Anthropic Provider 单元测试覆盖
|
||
|
||
---
|
||
|
||
### Phase B: 增强能力(P1 — GEO 质量提升)
|
||
|
||
---
|
||
|
||
### U5. Provider 级重试/熔断/指数退避
|
||
|
||
**Goal**: 每个 Provider 内置重试策略和熔断器,提高 LLM 调用可靠性。
|
||
|
||
**Requirements**: R6
|
||
|
||
**Dependencies**: U4(Anthropic Provider 也需要重试)
|
||
|
||
**Files**:
|
||
- `src/agentkit/llm/retry.py` — 新增 RetryPolicy + CircuitBreaker
|
||
- `src/agentkit/llm/providers/openai.py` — 集成重试
|
||
- `src/agentkit/llm/providers/anthropic.py` — 集成重试
|
||
- `src/agentkit/llm/config.py` — 重试/熔断配置
|
||
- `tests/unit/test_llm_retry.py` — 新增测试
|
||
|
||
**Approach**:
|
||
1. `RetryPolicy`:max_retries=3, base_delay=1.0, max_delay=30.0, exponential_base=2
|
||
2. `CircuitBreaker`:failure_threshold=5, recovery_timeout=60.0, half_open_max=1
|
||
3. Provider.chat() 包裹在 RetryPolicy + CircuitBreaker 中
|
||
4. 可重试错误:429/529/500/网络超时;不可重试:400/401/403
|
||
5. 配置化:per-provider retry 和 circuit_breaker 配置
|
||
|
||
**Patterns to follow**: resilience4j / tenacity 模式
|
||
|
||
**Test scenarios**:
|
||
- 重试成功(第 2 次成功)
|
||
- 重试耗尽抛异常
|
||
- 指数退避延迟
|
||
- 熔断器打开/半开/关闭状态转换
|
||
- 不可重试错误立即抛出
|
||
- 配置化重试参数
|
||
|
||
**Verification**: 全量测试通过 + 重试/熔断单元测试
|
||
|
||
---
|
||
|
||
### U6. chat_stream() Fallback 链支持
|
||
|
||
**Goal**: LLMGateway.chat_stream() 支持 fallback 模型链,与 chat() 对齐。
|
||
|
||
**Requirements**: R7
|
||
|
||
**Dependencies**: U5(重试机制)
|
||
|
||
**Files**:
|
||
- `src/agentkit/llm/gateway.py` — stream fallback
|
||
- `tests/unit/test_llm_gateway.py` — 更新测试
|
||
|
||
**Approach**:
|
||
1. chat_stream() 在 provider 失败时切换到 fallback model
|
||
2. 流式失败的特殊处理:已发送 chunk 后无法切换,记录错误并终止
|
||
3. 未发送任何 chunk 时可安全切换到 fallback
|
||
|
||
**Test scenarios**:
|
||
- 首个 provider 失败,fallback 成功
|
||
- 已发送 chunk 后失败,终止并记录
|
||
- 所有 provider 失败,抛异常
|
||
|
||
**Verification**: 全量测试通过
|
||
|
||
---
|
||
|
||
### U7. WebSocket 端点
|
||
|
||
**Goal**: 新增 WebSocket 端点支持双向实时通信,客户端可发送取消/参数变更指令。
|
||
|
||
**Requirements**: R8
|
||
|
||
**Dependencies**: U2(CancellationToken)
|
||
|
||
**Files**:
|
||
- `src/agentkit/server/routes/ws.py` — 新增 WebSocket 路由
|
||
- `src/agentkit/server/app.py` — 注册 WebSocket 路由
|
||
- `tests/unit/test_websocket.py` — 新增测试
|
||
|
||
**Approach**:
|
||
1. `WS /api/v1/ws/tasks/{task_id}` — 任务执行实时推送
|
||
2. 客户端消息类型:`cancel`(取消任务)、`ping`(心跳)
|
||
3. 服务端消息类型:`step`(ReAct 步骤)、`result`(最终结果)、`error`、`pong`
|
||
4. 连接认证:URL 参数 `?api_key=xxx` 或首条消息认证
|
||
5. 多客户端订阅同一任务(fan-out)
|
||
6. 任务完成后自动关闭连接
|
||
|
||
**Patterns to follow**: FastAPI WebSocket 官方模式
|
||
|
||
**Test scenarios**:
|
||
- WebSocket 连接/认证
|
||
- 接收 ReAct 步骤实时推送
|
||
- 发送 cancel 取消任务
|
||
- 任务完成自动关闭
|
||
- 未认证连接拒绝
|
||
- 多客户端订阅
|
||
|
||
**Verification**: 全量测试通过 + WebSocket 集成测试
|
||
|
||
---
|
||
|
||
### U8. SSE 流修复
|
||
|
||
**Goal**: 修复 SSE 流端点的 3 个问题:忽略 Agent 配置、访问私有属性、无 fallback。
|
||
|
||
**Requirements**: R9
|
||
|
||
**Dependencies**: 无
|
||
|
||
**Files**:
|
||
- `src/agentkit/server/routes/tasks.py` — 修复 SSE 流
|
||
- `src/agentkit/core/react.py` — 暴露公共接口
|
||
- `tests/unit/test_server_routes.py` — 更新测试
|
||
|
||
**Approach**:
|
||
1. SSE 流使用 Agent 的公共方法获取配置(`get_tools()`, `get_model()`, `get_system_prompt()`)
|
||
2. ConfigDrivenAgent 新增 `get_react_config()` 返回 max_steps/timeout 等
|
||
3. SSE 流复用 Agent 已有的 ReActEngine 实例
|
||
4. 流式 fallback:provider 失败时尝试 fallback model
|
||
|
||
**Test scenarios**:
|
||
- SSE 流使用 Agent 配置的 max_steps
|
||
- SSE 流不访问私有属性
|
||
- SSE 流 fallback 到备选模型
|
||
|
||
**Verification**: 全量测试通过
|
||
|
||
---
|
||
|
||
### U9. Evolution + Memory API 路由
|
||
|
||
**Goal**: 新增 Evolution 和 Memory 管理 API,支持前端展示和运维操作。
|
||
|
||
**Requirements**: R10
|
||
|
||
**Dependencies**: U3(进化系统修复)
|
||
|
||
**Files**:
|
||
- `src/agentkit/server/routes/evolution.py` — 新增 Evolution API
|
||
- `src/agentkit/server/routes/memory.py` — 新增 Memory API
|
||
- `src/agentkit/server/app.py` — 注册路由
|
||
- `tests/unit/test_evolution_api.py` — 新增测试
|
||
- `tests/unit/test_memory_api.py` — 新增测试
|
||
|
||
**Approach**:
|
||
1. Evolution API:
|
||
- `GET /api/v1/evolution/events` — 进化事件列表(分页、过滤)
|
||
- `GET /api/v1/evolution/skills/{name}/versions` — Skill 版本历史
|
||
- `POST /api/v1/evolution/trigger` — 手动触发进化
|
||
- `GET /api/v1/evolution/ab-tests` — A/B 测试列表
|
||
2. Memory API:
|
||
- `GET /api/v1/memory/episodic` — 情景记忆搜索
|
||
- `GET /api/v1/memory/semantic/search` — 知识库搜索代理
|
||
- `DELETE /api/v1/memory/episodic/{key}` — 删除记忆条目
|
||
|
||
**Test scenarios**:
|
||
- Evolution 事件列表分页
|
||
- Skill 版本历史查询
|
||
- 手动触发进化
|
||
- 记忆搜索
|
||
- 未授权访问拒绝
|
||
|
||
**Verification**: 全量测试通过 + API 路由测试
|
||
|
||
---
|
||
|
||
### U10. 嵌入缓存 + Enhanced Search 部分降级修复
|
||
|
||
**Goal**: 嵌入结果缓存减少 API 调用;Enhanced Search 对每个 KB 独立降级而非全量降级。
|
||
|
||
**Requirements**: R11
|
||
|
||
**Dependencies**: U1(EpisodicMemory 重构)
|
||
|
||
**Files**:
|
||
- `src/agentkit/memory/embedder.py` — 嵌入缓存
|
||
- `src/agentkit/memory/http_rag.py` — 部分降级修复
|
||
- `tests/unit/test_episodic_vector_search.py` — 更新测试
|
||
- `tests/unit/test_http_rag_service.py` — 更新测试
|
||
|
||
**Approach**:
|
||
1. `EmbeddingCache`:LRU 缓存(max_size=1000, TTL=3600s),基于文本 SHA-256 哈希
|
||
2. OpenAIEmbedder.embed() 先查缓存,命中直接返回
|
||
3. HttpRAGService.enhanced_search():逐 KB 尝试 enhanced,单个 404 降级到 standard 仅该 KB
|
||
4. 合并所有 KB 结果后统一排序
|
||
|
||
**Test scenarios**:
|
||
- 缓存命中返回相同向量
|
||
- 缓存未命中调用 API
|
||
- 缓存 TTL 过期重新获取
|
||
- 部分 KB enhanced 404,其余 KB 仍用 enhanced
|
||
- 所有 KB 降级到 standard
|
||
|
||
**Verification**: 全量测试通过
|
||
|
||
---
|
||
|
||
### Phase C: 扩展能力(P2 — 未来准备)
|
||
|
||
---
|
||
|
||
### U11. Gemini Provider 原生实现
|
||
|
||
**Goal**: 新增 GeminiProvider,支持 Google Gemini API 原生调用。
|
||
|
||
**Requirements**: R12
|
||
|
||
**Dependencies**: U5(重试机制)
|
||
|
||
**Files**:
|
||
- `src/agentkit/llm/providers/gemini.py` — 新增 GeminiProvider
|
||
- `src/agentkit/llm/gateway.py` — 注册 Gemini provider
|
||
- `src/agentkit/llm/config.py` — Gemini 配置
|
||
- `tests/unit/test_gemini_provider.py` — 新增测试
|
||
|
||
**Approach**:
|
||
1. GeminiProvider 实现 LLMProvider ABC
|
||
2. 使用 httpx 调用 `https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent`
|
||
3. 支持 Gemini 特有功能:
|
||
- `contents` 数组格式
|
||
- `safetySettings` 配置
|
||
- `toolConfig`(function_calling 配置)
|
||
- 流式:`streamGenerateContent`
|
||
4. 认证:API key 作为 URL 参数 `?key=xxx`
|
||
|
||
**Test scenarios**:
|
||
- 标准 generateContent 请求/响应
|
||
- function_calling 请求/响应
|
||
- 流式 generateContent
|
||
- safetySettings 过滤
|
||
- API key 缺失报错
|
||
|
||
**Verification**: 全量测试通过
|
||
|
||
---
|
||
|
||
### U12. Agent 状态锁 + 配置热加载
|
||
|
||
**Goal**: Agent 状态更新加锁防竞态;配置文件变更自动热加载。
|
||
|
||
**Requirements**: R13
|
||
|
||
**Dependencies**: 无
|
||
|
||
**Files**:
|
||
- `src/agentkit/core/base.py` — asyncio.Lock 保护状态
|
||
- `src/agentkit/server/config.py` — 文件监听 + 热加载
|
||
- `src/agentkit/server/app.py` — 热加载集成
|
||
- `tests/unit/test_base_agent.py` — 更新测试
|
||
- `tests/unit/test_server_config.py` — 更新测试
|
||
|
||
**Approach**:
|
||
1. BaseAgent 新增 `_status_lock: asyncio.Lock`,所有状态更新在锁内
|
||
2. ServerConfig 新增 `watch_config()` 方法:使用 `watchfiles` 监听 YAML 变更
|
||
3. 变更时重新加载配置,更新 LLMGateway/SkillRegistry 等组件
|
||
4. 热加载期间拒绝新请求(drain 模式)
|
||
|
||
**Test scenarios**:
|
||
- 并发状态更新无竞态
|
||
- 配置文件变更触发重载
|
||
- 重载期间请求排队等待
|
||
- 无效配置不覆盖当前配置
|
||
|
||
**Verification**: 全量测试通过
|
||
|
||
---
|
||
|
||
## Phased Delivery
|
||
|
||
| Phase | Units | 交付物 | GEO 影响 |
|
||
|-------|-------|--------|----------|
|
||
| **A: 核心修复** | U1-U4 | pgvector 记忆 + 超时取消 + 进化修复 + Anthropic Provider | GEO 内容生成质量提升 + Claude 模型支持 |
|
||
| **B: 增强能力** | U5-U10 | 重试熔断 + stream fallback + WebSocket + SSE 修复 + API 路由 + 缓存 | GEO 系统稳定性 + 实时监控 + 运维可见 |
|
||
| **C: 扩展能力** | U11-U12 | Gemini Provider + 状态锁 + 热加载 | 多模型选择 + 运维友好 |
|
||
|
||
## Risks & Mitigations
|
||
|
||
| Risk | Likelihood | Impact | Mitigation |
|
||
|------|-----------|--------|------------|
|
||
| pgvector 查询与 GEO 数据库冲突 | Low | High | 使用独立 schema `agentkit.episodic_memories`,不影响 GEO 表 |
|
||
| Anthropic API 格式差异导致 tool_calls 解析错误 | Medium | Medium | 严格按 Messages API 文档实现,覆盖 tool_use/tool_result 测试 |
|
||
| A/B 测试样本不足导致进化无法应用 | High | Low | 设置低阈值 min_samples=10,不足时记录日志不阻塞 |
|
||
| WebSocket 连接泄漏 | Medium | Medium | 心跳检测 + 超时自动断开 + 连接数上限 |
|
||
| 进化应用有害变更 | Medium | High | A/B 测试统计显著才应用 + 自动回滚 + 质量门控 |
|
||
|
||
## Success Metrics
|
||
|
||
| Metric | Current | Target |
|
||
|--------|---------|--------|
|
||
| EpisodicMemory 搜索延迟(1 万条) | >2s (O(N) 客户端) | <100ms (pgvector ANN) |
|
||
| ReAct 循环超时保护 | 无 | 100% 任务有超时 |
|
||
| 进化系统可运行性 | A/B 测试禁用 | A/B 测试启用 + 统计显著才应用 |
|
||
| LLM Provider 覆盖 | 1 (OpenAI 兼容) | 3 (OpenAI + Anthropic + Gemini) |
|
||
| Provider 调用可靠性 | 无重试/熔断 | 3 次重试 + 熔断保护 |
|
||
| 实时通信 | 仅 SSE | WebSocket + SSE 双通道 |
|
||
| API 路由覆盖 | 无 Evolution/Memory | 完整 CRUD + 搜索 |
|
||
| 全量测试 | 1037 passed | 1200+ passed |
|