iconsulting/docs/architecture/10-implementation-plan.md

30 KiB
Raw Permalink Blame History

10 - 实施计划详解 (Implementation Plan)

1. 总体时间线

Week 1          Week 2          Week 2-3        Week 3          Week 4          Week 5
┌──────────┐   ┌──────────┐   ┌──────────┐   ┌──────────┐   ┌──────────┐   ┌──────────┐
│ Phase 1  │   │ Phase 2  │   │ Phase 3  │   │ Phase 4  │   │ Phase 5+6│   │ Phase 7  │
│          │   │          │   │          │   │          │   │          │   │          │
│ 架构文档 │──→│ 基础设施  │──→│ 专家Agent│──→│ Coordinator│──→│ 集成+前端│──→│ 测试+优化│
│ + 类型   │   │          │   │          │   │          │   │          │   │          │
│ 定义     │   │ Queue    │   │ 6个Agent │   │ 核心Loop  │   │ Module   │   │ 场景测试 │
│          │   │ Context  │   │ 6份Prompt│   │ 主Prompt  │   │ Gateway  │   │ 性能优化 │
│          │   │ Base     │   │          │   │          │   │ Frontend │   │ 旧代码清理│
└──────────┘   └──────────┘   └──────────┘   └──────────┘   └──────────┘   └──────────┘

2. Phase 1: 架构文档 + 类型定义 (Week 1)

2.1 架构文档12份

序号 文件 内容 状态
00 00-overview.md 总览 + 架构图 已完成
01 01-coordinator-agent.md Coordinator 设计 已完成
02 02-specialist-agents.md 6 个专家 Agent 设计 待完成
03 03-agent-communication.md Agent 间通信协议 待完成
04 04-streaming-protocol.md 流式传输协议 待完成
05 05-frontend-integration.md 前端集成方案 待完成
06 06-token-cost-management.md Token 与成本管理 待完成
07 07-testing-strategy.md 测试策略 待完成
08 08-context-injection.md 动态上下文注入 已完成
09 09-tool-execution.md 工具并发执行 已完成
10 10-implementation-plan.md 实施计划(本文档) 已完成
11 11-prompt-templates.md 所有 Prompt 模板 已完成

2.2 类型定义文件

需要创建以下类型定义文件:

packages/services/conversation-service/src/infrastructure/agents/
├── types/
│   ├── agent.types.ts          # Agent 相关类型
│   ├── stream.types.ts         # 流式事件类型
│   └── context.types.ts        # 上下文注入类型

agent.types.ts

// 核心 Agent 类型定义

/** Agent 名称枚举 */
export enum AgentName {
  COORDINATOR = 'coordinator',
  POLICY_EXPERT = 'policy_expert',
  ASSESSMENT_EXPERT = 'assessment_expert',
  STRATEGIST = 'strategist',
  OBJECTION_HANDLER = 'objection_handler',
  CASE_ANALYST = 'case_analyst',
  MEMORY_MANAGER = 'memory_manager',
}

/** Agent 使用的模型 */
export enum AgentModel {
  SONNET = 'claude-sonnet-4-20250514',
  HAIKU = 'claude-haiku-4-20250514',
}

/** Agent 配置 */
export interface AgentConfig {
  name: AgentName;
  model: AgentModel;
  maxTokens: number;
  maxTurns: number;           // Agent mini-loop 最大轮次
  timeoutMs: number;          // 超时时间
  tools: string[];            // 可用工具名列表
  systemPromptFile: string;   // Prompt 文件路径
}

/** Agent 执行上下文 */
export interface AgentExecutionContext {
  userId: string;
  conversationId: string;
  coordinatorTurn: number;    // Coordinator 当前轮次
  parentToolUseId: string;    // 触发此 Agent 的 tool_use ID
}

/** Agent Loop 参数 */
export interface AgentLoopParams {
  messages: Anthropic.MessageParam[];
  systemPrompt: string[] | Anthropic.TextBlockParam[];
  tools: Anthropic.Tool[];
  maxTurns: number;
  maxBudgetUsd: number;
  conversationId: string;
  userId: string;
  abortSignal?: AbortSignal;
}

/** 咨询状态(从 consulting_state XML tag 提取) */
export interface ConsultingStateReport {
  currentStage: string;
  collectedFields: string[];
  nextAction: string;
  confidenceLevel: 'low' | 'medium' | 'high';
  recommendedPrograms?: string[];
}

stream.types.ts

// 流式事件类型

/** 所有可能的 Stream 事件 */
export type StreamEvent =
  | TextStreamEvent
  | AgentStartEvent
  | AgentProgressEvent
  | AgentCompleteEvent
  | ToolStartEvent
  | ToolCompleteEvent
  | ToolErrorEvent
  | StateUpdateEvent
  | UsageEvent
  | ErrorEvent
  | EndEvent;

export interface TextStreamEvent {
  type: 'text';
  content: string;
}

export interface AgentStartEvent {
  type: 'agent_start';
  agentName: string;
  toolUseId: string;
}

export interface AgentProgressEvent {
  type: 'agent_progress';
  agentName: string;
  turn: number;
  maxTurns: number;
}

export interface AgentCompleteEvent {
  type: 'agent_complete';
  agentName: string;
  durationMs: number;
  tokensUsed?: { input: number; output: number };
}

export interface StateUpdateEvent {
  type: 'state_update';
  state: ConsultingStateReport;
}

export interface UsageEvent {
  type: 'usage';
  usage: { inputTokens: number; outputTokens: number };
  totalCostUsd: number;
}

export interface ErrorEvent {
  type: 'error';
  code: string;
  message: string;
}

export interface EndEvent {
  type: 'end';
  totalTokens: { input: number; output: number };
  totalCostUsd: number;
  turnsUsed: number;
  agentsCalled: string[];
}

context.types.ts

交付标准

  • 所有类型文件通过 tsc --noEmit 类型检查
  • 每个 interface 有 JSDoc 注释
  • 导出为 barrel file (types/index.ts)

3. Phase 2: 基础设施 (Week 2)

3.1 文件结构

packages/services/conversation-service/src/infrastructure/agents/
├── types/                          # Phase 1 产物
│   ├── agent.types.ts
│   ├── stream.types.ts
│   ├── context.types.ts
│   └── index.ts
├── core/                           # Phase 2 产物
│   ├── tool-execution-queue.ts     # 工具并发执行队列
│   ├── context-injector.service.ts # 上下文注入器
│   ├── base-specialist.service.ts  # 专家 Agent 基类
│   ├── agent-executor.ts           # Agent 执行器工厂
│   └── token-tracker.ts            # Token 追踪器

3.2 tool-execution-queue.ts

  • 完整实现详见 09-tool-execution.md 第 4 节
  • 关键依赖: tool-execution.types.ts
  • 单测覆盖:
    • 纯并发批次(所有 safe 工具)
    • 纯串行批次(所有 unsafe 工具)
    • 混合批次safe + unsafe 交替)
    • 单个工具超时
    • 批次中一个工具失败
    • 空请求
    • 结果排序正确性
// 单测示例
describe('ToolExecutionQueue', () => {
  it('should execute concurrent-safe tools in parallel', async () => {
    const queue = new ToolExecutionQueue();
    const executionOrder: string[] = [];

    queue.registerTool('tool_a', {
      isConcurrencySafe: true,
      executor: async () => {
        executionOrder.push('a_start');
        await sleep(100);
        executionOrder.push('a_end');
        return { content: 'a', success: true };
      },
      // ...
    });

    queue.registerTool('tool_b', {
      isConcurrencySafe: true,
      executor: async () => {
        executionOrder.push('b_start');
        await sleep(50);
        executionOrder.push('b_end');
        return { content: 'b', success: true };
      },
      // ...
    });

    const results = await queue.executeAll([
      { toolUseId: '1', toolName: 'tool_a', input: {}, originalIndex: 0 },
      { toolUseId: '2', toolName: 'tool_b', input: {}, originalIndex: 1 },
    ]);

    // 两个工具应该几乎同时开始
    expect(executionOrder[0]).toBe('a_start');
    expect(executionOrder[1]).toBe('b_start');
    // b 先完成50ms vs 100ms
    expect(executionOrder[2]).toBe('b_end');
    expect(executionOrder[3]).toBe('a_end');
    // 结果按 originalIndex 排序
    expect(results[0].toolName).toBe('tool_a');
    expect(results[1].toolName).toBe('tool_b');
  });
});

3.3 context-injector.service.ts

  • 完整实现详见 08-context-injection.md 第 5 节
  • 关键依赖: KnowledgeClientService, context.types.ts
  • 单测覆盖:
    • 所有 8 种上下文的独立构建
    • 缓存命中/未命中
    • Token 预算裁剪
    • P0 上下文不被裁剪
    • 缓存失效
    • auto-compaction 触发条件

3.4 base-specialist.service.ts

  • 完整实现详见 09-tool-execution.md 第 6 节
  • 关键依赖: @anthropic-ai/sdk
  • 单测覆盖:
    • Mini-loop 正常完成1轮无工具调用
    • Mini-loop 有工具调用2轮
    • 达到 maxTurns 强制终止
    • API 错误处理
    • Token 追踪回调

3.5 交付标准

  • 所有基础设施组件可以独立运行单测
  • 不依赖具体的 Specialist Agent 实现
  • 使用 mock 的 Claude API 进行测试

4. Phase 3: 专家 Agent (Week 2-3)

4.1 文件结构

packages/services/conversation-service/src/infrastructure/agents/
├── specialists/
│   ├── policy-expert.service.ts        # 政策专家
│   ├── assessment-expert.service.ts    # 评估专家
│   ├── strategist.service.ts           # 策略顾问
│   ├── objection-handler.service.ts    # 异议处理
│   ├── case-analyst.service.ts         # 案例分析
│   └── memory-manager.service.ts       # 记忆管理
├── prompts/
│   ├── coordinator-system-prompt.ts    # Phase 4
│   ├── policy-expert-prompt.ts
│   ├── assessment-expert-prompt.ts
│   ├── strategist-prompt.ts
│   ├── objection-handler-prompt.ts
│   ├── case-analyst-prompt.ts
│   └── memory-manager-prompt.ts

4.2 各 Agent 实现计划

Agent 继承 Model 工具 预估代码量 优先级
PolicyExpertService BaseSpecialistService Sonnet search_knowledge ~120 行 P0
AssessmentExpertService BaseSpecialistService Sonnet search_knowledge, get_user_context ~200 行 P0
MemoryManagerService BaseSpecialistService Haiku save_user_memory, get_user_context ~150 行 P0
StrategistService BaseSpecialistService Sonnet get_user_context ~100 行 P1
ObjectionHandlerService BaseSpecialistService Sonnet search_knowledge, get_user_context ~120 行 P1
CaseAnalystService BaseSpecialistService Haiku search_knowledge, get_user_context ~100 行 P2

4.3 开发顺序

建议按以下顺序开发(优先级 + 依赖关系):

1. MemoryManagerService     → 最简单,验证 BaseSpecialist + 工具执行
   ↓
2. PolicyExpertService      → 最常用,验证 knowledge-service 集成
   ↓
3. AssessmentExpertService  → 核心业务,需要 knowledge + 用户上下文
   ↓
4. StrategistService        → 辅助 Coordinator 决策
   ↓
5. ObjectionHandlerService  → 异议处理,依赖 knowledge
   ↓
6. CaseAnalystService       → 最后实现,依赖度最低

4.4 每个 Agent 的独立测试策略

// 以 PolicyExpertService 为例的独立测试

describe('PolicyExpertService', () => {
  let service: PolicyExpertService;
  let mockAnthropicClient: jest.Mocked<Anthropic>;
  let mockKnowledgeClient: jest.Mocked<KnowledgeClientService>;

  beforeEach(() => {
    mockAnthropicClient = createMockAnthropicClient();
    mockKnowledgeClient = createMockKnowledgeClient();
    service = new PolicyExpertService(mockAnthropicClient, mockKnowledgeClient);
  });

  it('should answer policy questions without tool calls', async () => {
    // Mock: Claude 直接回答,不调用工具
    mockAnthropicClient.messages.create.mockResolvedValue({
      content: [{ type: 'text', text: '高才通B类要求...' }],
      usage: { input_tokens: 500, output_tokens: 200 },
      stop_reason: 'end_turn',
    });

    const result = await service.execute({
      input: { query: '高才通B类条件是什么' },
      maxTurns: 3,
    });

    expect(result.output).toContain('高才通');
    expect(result.turnsUsed).toBe(1);
  });

  it('should use search_knowledge tool when needed', async () => {
    // Mock: Claude 调用 search_knowledge再用结果生成回答
    mockAnthropicClient.messages.create
      .mockResolvedValueOnce({
        content: [
          { type: 'tool_use', id: 't1', name: 'search_knowledge', input: { query: 'TTPS B类 条件' } },
        ],
        usage: { input_tokens: 500, output_tokens: 100 },
        stop_reason: 'tool_use',
      })
      .mockResolvedValueOnce({
        content: [{ type: 'text', text: '根据查询结果高才通B类...' }],
        usage: { input_tokens: 800, output_tokens: 300 },
        stop_reason: 'end_turn',
      });

    mockKnowledgeClient.retrieveKnowledge.mockResolvedValue({
      content: '高才通B类要求全球百强大学学士学位...',
      sources: [{ articleId: '1', title: '高才通指南', similarity: 0.92 }],
    });

    const result = await service.execute({
      input: { query: '高才通B类条件' },
      maxTurns: 3,
      onToolCall: jest.fn(),
    });

    expect(result.output).toContain('根据查询结果');
    expect(result.turnsUsed).toBe(2);
    expect(mockKnowledgeClient.retrieveKnowledge).toHaveBeenCalled();
  });
});

4.5 交付标准

  • 每个 Agent 有独立的单元测试mock Claude API + mock 外部服务)
  • 每个 Agent 的 Prompt 是独立文件,可以独立调整
  • 所有 Agent 通过 BaseSpecialistService.execute() 统一调用

5. Phase 4: Coordinator (Week 3)

5.1 文件结构

packages/services/conversation-service/src/infrastructure/agents/
├── coordinator/
│   ├── coordinator-agent.service.ts    # 主服务
│   ├── agent-loop.ts                   # 核心递归循环
│   └── state-extractor.ts             # 从回复中提取 consulting_state
├── prompts/
│   └── coordinator-system-prompt.ts    # 500+ 行 Prompt

5.2 coordinator-system-prompt.ts

这是整个系统最重要的文件,详见 11-prompt-templates.md

关键结构:

export function buildCoordinatorSystemPrompt(config: {
  expertContact: { wechat: string; phone: string; workingHours: string };
  paidServices: { assessmentPrice: number; description: string };
  currentDate: string;
}): string {
  return `
# 身份定义
...(约 30 行)

# 你的专家团队
...(约 80 行)

# 六大移民类别
...(约 200 行)

# 对话策略
...(约 100 行)

# 回复规范
...(约 40 行)

# 状态报告格式
...(约 30 行)

# 业务规则
...(约 20 行)
  `;
}

5.3 agent-loop.ts

核心递归循环,详见 01-coordinator-agent.md 第 4 节。

关键特性:

  • async function* agentLoop(): AsyncGenerator 模式
  • 递归调用自身tool_results → 再次调用 Claude
  • 集成 ContextInjector
  • 集成 ToolExecutionQueue
  • 集成 state extractor
  • abort 信号支持

5.4 coordinator-agent.service.ts

NestJS 服务,封装 agent-loop对外暴露与旧 ClaudeAgentServiceV2 相同的接口:

@Injectable()
export class CoordinatorAgentService {
  constructor(
    private contextInjector: ContextInjectorService,
    private toolExecutionQueue: ToolExecutionQueue,
    // ... 各 Specialist Agent
  ) {}

  async *sendMessage(params: {
    conversationContext: ConversationContext;
    userMessage: string;
    attachments?: FileAttachment[];
    userId: string;
    conversationId: string;
    deviceInfo?: DeviceInfo;
  }): AsyncGenerator<StreamEvent> {
    // 委托给 agentLoop
    yield* agentLoop({
      messages: this.buildMessages(params),
      systemPrompt: this.buildSystemPrompt(),
      tools: this.toolExecutionQueue.getClaudeTools(),
      maxTurns: 15,
      maxBudgetUsd: 0.50,
      conversationId: params.conversationId,
      userId: params.userId,
    });
  }
}

5.5 交付标准

  • Coordinator 可以独立运行集成测试(使用真实 Claude API
  • agent-loop 有完整的单元测试mock API
  • System Prompt 经过人工审查
  • 通过 5 个核心对话场景的 E2E 测试

6. Phase 5: 集成 (Week 4 前半)

6.1 NestJS Module 集成

新增 agents.module.ts

// packages/services/conversation-service/src/infrastructure/agents/agents.module.ts

@Module({
  imports: [KnowledgeModule],  // 依赖 KnowledgeClientService
  providers: [
    // Core
    ToolExecutionQueue,
    ContextInjectorService,
    // Specialists
    PolicyExpertService,
    AssessmentExpertService,
    StrategistService,
    ObjectionHandlerService,
    CaseAnalystService,
    MemoryManagerService,
    // Coordinator
    CoordinatorAgentService,
  ],
  exports: [CoordinatorAgentService],
})
export class AgentsModule {}

修改 claude.module.ts

// 在 claude.module.ts 中导入 AgentsModule
@Module({
  imports: [AgentsModule],  // 新增
  providers: [
    ClaudeAgentServiceV2,  // 保留旧服务(过渡期)
    // ...
  ],
  exports: [
    ClaudeAgentServiceV2,      // 保留旧导出
    CoordinatorAgentService,   // 新增导出
  ],
})
export class ClaudeModule {}

修改 conversation.service.ts

// 切换注入(使用 feature flag
@Injectable()
export class ConversationService {
  constructor(
    @Inject(CONVERSATION_REPOSITORY)
    private readonly conversationRepo: IConversationRepository,
    @Inject(MESSAGE_REPOSITORY)
    private readonly messageRepo: IMessageRepository,
    // 旧服务(过渡期保留)
    private readonly claudeAgentService: ClaudeAgentServiceV2,
    // 新服务
    private readonly coordinatorAgentService: CoordinatorAgentService,
    private readonly configService: ConfigService,
  ) {}

  private get useNewArchitecture(): boolean {
    return this.configService.get<boolean>('USE_MULTI_AGENT', false);
  }

  async *sendMessage(params: SendMessageParams): AsyncGenerator<StreamChunk> {
    if (this.useNewArchitecture) {
      yield* this.sendMessageV3(params);  // 新架构
    } else {
      yield* this.sendMessageV2(params);  // 旧架构
    }
  }
}

更新 conversation.gateway.ts

// 新增 Agent 相关的 WebSocket 事件
// stream_chunk 保持不变
// 新增:
//   agent_start  { agentName, conversationId }
//   agent_progress { agentName, turn, maxTurns, conversationId }
//   agent_complete { agentName, durationMs, conversationId }

6.2 Feature Flag 策略

环境变量: USE_MULTI_AGENT=true/false

开发环境: true  (直接使用新架构)
测试环境: true  (测试新架构)
生产环境: false (等全部测试通过后切换)

6.3 共享类型更新

// packages/shared/types/src/conversation.ts
// 新增 StreamEvent 类型供前端使用

export interface AgentStatusEvent {
  type: 'agent_start' | 'agent_progress' | 'agent_complete';
  agentName: string;
  conversationId: string;
  // agent_progress only
  turn?: number;
  maxTurns?: number;
  // agent_complete only
  durationMs?: number;
}

6.4 交付标准

  • Feature flag 可以在不重启服务的情况下切换
  • 旧架构在 USE_MULTI_AGENT=false 时完全不受影响
  • WebSocket 事件向后兼容(新事件是追加的,不修改已有事件)

7. Phase 6: 前端 (Week 4 后半)

7.1 前端文件修改

packages/clients/web-client/src/
├── stores/
│   └── chatStore.ts            # 新增 agentStatus 状态
├── components/
│   ├── chat/
│   │   ├── ChatWindow.tsx      # 处理新的 WebSocket 事件
│   │   ├── MessageBubble.tsx   # 可能需要微调
│   │   └── AgentStatus.tsx     # 新增Agent 工作状态组件
│   └── shared/
│       └── AgentBadge.tsx      # 新增Agent 名称+状态徽章

7.2 chatStore 更新

// chatStore.ts (Zustand)

interface AgentStatus {
  name: string;
  displayName: string;       // 中文显示名
  status: 'idle' | 'working' | 'completed';
  startedAt?: number;
  completedAt?: number;
  durationMs?: number;
}

interface ChatState {
  // 已有状态...
  messages: Message[];
  isStreaming: boolean;

  // 新增Agent 状态
  activeAgents: AgentStatus[];
  agentHistory: AgentStatus[];  // 本次对话中所有 Agent 调用记录
}

// Agent 名称映射
const AGENT_DISPLAY_NAMES: Record<string, string> = {
  policy_expert: '政策专家',
  assessment_expert: '评估专家',
  strategist: '策略顾问',
  objection_handler: '异议处理',
  case_analyst: '案例分析',
  memory_manager: '记忆管理',
};

7.3 AgentStatus 组件

// AgentStatus.tsx
// 显示在聊天窗口中,消息气泡和输入框之间

function AgentStatus({ agents }: { agents: AgentStatus[] }) {
  const workingAgents = agents.filter(a => a.status === 'working');

  if (workingAgents.length === 0) return null;

  return (
    <div className="agent-status-bar">
      {workingAgents.map(agent => (
        <div key={agent.name} className="agent-badge working">
          <span className="agent-icon">🔄</span>
          <span className="agent-name">{agent.displayName}</span>
          <span className="agent-time">
            {formatElapsedTime(Date.now() - (agent.startedAt || 0))}
          </span>
        </div>
      ))}
      <span className="agent-hint">正在分析中...</span>
    </div>
  );
}

7.4 ChatWindow 事件处理

// ChatWindow.tsx - WebSocket 事件处理更新

socket.on('agent_start', (data: { agentName: string; conversationId: string }) => {
  chatStore.addActiveAgent({
    name: data.agentName,
    displayName: AGENT_DISPLAY_NAMES[data.agentName] || data.agentName,
    status: 'working',
    startedAt: Date.now(),
  });
});

socket.on('agent_complete', (data: { agentName: string; durationMs: number }) => {
  chatStore.completeAgent(data.agentName, data.durationMs);
});

socket.on('stream_end', () => {
  chatStore.clearActiveAgents();  // 清除所有工作中的 Agent 状态
});

7.5 交付标准

  • Agent 状态在 UI 中实时显示
  • Agent 完成后自动消失(带淡出动画)
  • 在弱网环境下不会出现 Agent 状态 "卡住" 的问题(超时自动清除)
  • 旧架构模式下不显示 Agent 状态

8. Phase 7: 测试 + 优化 + 清理 (Week 5)

8.1 测试场景矩阵

场景编号 场景描述 涉及 Agent 预期行为
S01 新用户首次咨询 Coordinator + Memory 破冰 → 收集信息 → 保存记忆
S02 询问高才通条件 Coordinator + Policy 检索知识库 → 准确回答
S03 信息收集后评估 Coordinator + Assessment + Memory 评估资格 → 推荐方案
S04 用户表示犹豫 Coordinator + Objection + Strategist 识别异议 → 策略回应
S05 用户要求付费评估 Coordinator + (Payment tool) 生成支付链接
S06 老用户回访 Coordinator + Memory 加载历史记忆 → 个性化问候
S07 并发工具调用 Coordinator + Policy + Case 并行执行两个 Agent
S08 超长对话 (30+ 轮) All Auto-compaction 触发
S09 API 错误恢复 Coordinator 降级到 Haiku / 友好错误
S10 用户中途取消 Coordinator AbortSignal 生效

8.2 性能优化清单

优化项 目标 方法
首次回复延迟 < 3s Prompt Caching + 预热
并发 Agent 延迟 < 5s (3 个 Agent 并行) ToolExecutionQueue 并行
Context Injection 延迟 < 200ms 缓存 + 并行获取
Auto-compaction 延迟 < 2s Haiku 摘要
Token 成本 (每对话) < $0.30 Haiku for 辅助 Agent + Caching
内存使用 < 100MB per 1000 并发对话 对话结束清理缓存

8.3 旧代码清理计划

阶段 A: 标记废弃 (Week 5)

// 不删除代码,只标记 @deprecated
/** @deprecated Use CoordinatorAgentService instead. Will be removed in v4. */
export class ClaudeAgentServiceV2 { ... }

/** @deprecated Replaced by Coordinator Prompt. */
export class StrategyEngineService { ... }

/** @deprecated Intent classification now handled by LLM. */
export const intentClassifier = { ... };

/** @deprecated Response quality now handled by Prompt. */
export const responseGate = { ... };

阶段 B: 删除代码 (Week 6+, after 1 week in production)

  • 删除 strategy-engine.service.ts
  • 删除 intent-classifier.ts
  • 删除 response-gate.ts
  • 删除 default-strategy.ts
  • 删除 claude-agent-v2.service.ts
  • 移除 feature flag

8.4 Rollback 计划

如果新架构在生产中出现严重问题:

1. 即时回滚 (< 1 分钟):
   设置环境变量 USE_MULTI_AGENT=false
   → 自动切回 ClaudeAgentServiceV2
   → 不需要重新部署

2. 部署回滚 (< 5 分钟):
   git revert 到 Phase 5 之前的 commit
   → 重新部署 conversation-service

3. 数据恢复:
   新架构不修改数据库 schema
   ConsultingState 格式向后兼容
   → 无需数据迁移

9. 组件依赖图

                              ┌─────────────────┐
                              │   agents.module  │
                              └────────┬────────┘
                                       │ exports
                          ┌────────────▼────────────┐
                          │ CoordinatorAgentService  │
                          └────────────┬────────────┘
                                       │ depends on
                    ┌──────────────────┼──────────────────┐
                    │                  │                   │
          ┌────────▼───────┐ ┌────────▼────────┐ ┌───────▼────────┐
          │ ContextInjector │ │ ToolExecution   │ │ agentLoop()    │
          │ Service         │ │ Queue           │ │ (function)     │
          └────────┬───────┘ └────────┬────────┘ └───────┬────────┘
                   │                  │                   │
          ┌────────▼───────┐ ┌────────▼────────┐         │
          │ Knowledge      │ │ Agent Executors  │         │
          │ ClientService  │ │ (factory)        │         │
          └────────────────┘ └────────┬────────┘         │
                                      │                   │
                              ┌───────▼───────────────────┘
                              │
                    ┌─────────▼─────────┐
                    │ BaseSpecialist     │
                    │ Service (abstract) │
                    └─────────┬─────────┘
                              │ extends
          ┌───────┬───────┬───┴───┬───────┬───────┐
          │       │       │       │       │       │
        Policy  Assess  Strat  Object  Case   Memory
        Expert  Expert  gist   Handler  Analyst Manager

10. 风险与缓解

风险 概率 影响 缓解措施
Coordinator Prompt 效果不佳 Phase 4 投入大量时间测试 Prompt准备多个版本 A/B 测试
Token 成本超预期 监控每次对话成本,设置 maxBudgetUsd 硬上限
并发 Agent 导致 Rate Limit 实现指数退避重试,降级到 Haiku
Context Window 不够用 Auto-compaction + 严格的 token 预算
前端 Agent 状态同步问题 WebSocket 事件超时自动清理
旧代码删除导致回归 Feature flag 过渡期,完善的回滚计划

11. 交付 Checklist

Phase 1 Checklist

  • 12 份架构文档全部完成
  • agent.types.ts 通过类型检查
  • stream.types.ts 通过类型检查
  • context.types.ts 通过类型检查
  • 所有类型有 JSDoc 注释

Phase 2 Checklist

  • ToolExecutionQueue 通过所有单元测试
  • ContextInjectorService 通过所有单元测试
  • BaseSpecialistService 通过所有单元测试
  • 所有组件可以独立测试(不依赖 Claude API

Phase 3 Checklist

  • 6 个 Specialist Agent 全部实现
  • 6 份 Prompt 文件全部编写
  • 每个 Agent 有独立的单元测试
  • 每个 Agent 使用真实 API 的集成测试(可选,按需运行)

Phase 4 Checklist

  • Coordinator System Prompt 完成500+ 行)
  • agent-loop 通过所有单元测试
  • CoordinatorAgentService 通过集成测试
  • 5 个核心场景 E2E 测试通过

Phase 5 Checklist

  • agents.module.ts 编写完成
  • Feature flag 切换工作正常
  • 旧架构在 flag=false 时不受影响
  • WebSocket 事件向后兼容

Phase 6 Checklist

  • chatStore 更新完成
  • AgentStatus 组件实现
  • ChatWindow 处理新事件
  • 前端无 regression

Phase 7 Checklist

  • 10 个测试场景全部通过
  • 性能指标达标
  • 旧代码标记 @deprecated
  • 回滚计划验证通过
  • 文档更新完成