# 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**：
```typescript
// 核心 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**：
```typescript
// 流式事件类型

/** 所有可能的 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**：
- 详见 [08-context-injection.md](./08-context-injection.md) 第 3 节

**交付标准**：
- 所有类型文件通过 `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](./09-tool-execution.md) 第 4 节
- **关键依赖**: `tool-execution.types.ts`
- **单测覆盖**:
  - 纯并发批次（所有 safe 工具）
  - 纯串行批次（所有 unsafe 工具）
  - 混合批次（safe + unsafe 交替）
  - 单个工具超时
  - 批次中一个工具失败
  - 空请求
  - 结果排序正确性

```typescript
// 单测示例
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](./08-context-injection.md) 第 5 节
- **关键依赖**: `KnowledgeClientService`, `context.types.ts`
- **单测覆盖**:
  - 所有 8 种上下文的独立构建
  - 缓存命中/未命中
  - Token 预算裁剪
  - P0 上下文不被裁剪
  - 缓存失效
  - auto-compaction 触发条件

### 3.4 base-specialist.service.ts

- 完整实现详见 [09-tool-execution.md](./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 的独立测试策略

```typescript
// 以 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](./11-prompt-templates.md)。

关键结构：
```typescript
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](./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` 相同的接口：

```typescript
@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**：
```typescript
// 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**：
```typescript
// 在 claude.module.ts 中导入 AgentsModule
@Module({
  imports: [AgentsModule],  // 新增
  providers: [
    ClaudeAgentServiceV2,  // 保留旧服务（过渡期）
    // ...
  ],
  exports: [
    ClaudeAgentServiceV2,      // 保留旧导出
    CoordinatorAgentService,   // 新增导出
  ],
})
export class ClaudeModule {}
```

**修改 conversation.service.ts**：
```typescript
// 切换注入（使用 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**：
```typescript
// 新增 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 共享类型更新

```typescript
// 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 更新

```typescript
// 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 组件

```tsx
// 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 事件处理

```typescript
// 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)**
```typescript
// 不删除代码，只标记 @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
- [ ] 回滚计划验证通过
- [ ] 文档更新完成
