多智能体架构范式

与具体业务无关的智能体分层与路由设计经验。

1. 基类抽象与消息模型

  • 基类:用抽象类或接口定义统一接口(如 process(userInput: string, options?: Record<string, unknown>): Promise<string>),子类实现具体逻辑。系统提示词、对话历史、记忆可放在基类,由子类按需覆盖默认实现。
  • 消息模型:使用 TypeScript interfaceclass 定义消息结构,便于序列化、日志与持久化:
interface AgentMessage {
  role: 'user' | 'assistant' | 'system';
  content: string;
  metadata?: Record<string, unknown>;
}
  • 历史与记忆分离:对话历史(当前会话轮次)与长期记忆(跨会话)建议用不同字段或不同管理器,避免混用导致难以做记忆摘要或裁剪。

2. 路由分发

  • 职责:根据用户输入决定走「简单问答」还是「需要规划/工具执行」等分支,而不是把所有请求都交给同一个重型流水线。
  • 实现方式
    • 关键词列表:问候、帮助、介绍类 → 轻量 Q&A;操作类动词(扫描、执行、分析等)→ 规划/执行流。
    • 规则顺序:先匹配问候/再见,再匹配问答类关键词,再根据长度与操作词判定;短句且无操作词可默认走 Q&A,减少误判。
  • 类型:路由结果用 TypeScript 字面量联合类型(如 type RouteResult = 'qa' | 'technical')明确表达,便于上层分支与测试。

3. 多智能体分工

  • Q&A Agent:只做对话、介绍、帮助,不调用工具,响应快、成本低。
  • Planner Agent:解析意图、拆解步骤、产出待办(Todo),不直接执行。
  • Core Agent:带工具调用的主智能体,执行具体动作,可复用 ReAct/function calling。
  • Summary Agent:对当轮工具执行结果做摘要,便于用户与审计。

路由只决定「走 Q&A 还是走 Planner → Core → Summary」;各 Agent 之间通过会话上下文或事件总线传递数据,避免紧耦合。

4. 依赖注入与获取智能体

  • 上层(TUI / API)通过 NestJS 的依赖注入获取 Agent 实例,内部按类型懒加载并缓存,避免进程内重复创建。
@Injectable()
export class AgentFactory {
  private agents = new Map<string, BaseAgent>();

  getAgent(agentType: string): BaseAgent {
    if (!this.agents.has(agentType)) {
      this.agents.set(agentType, this.createAgent(agentType));
    }
    return this.agents.get(agentType)!;
  }

  private createAgent(agentType: string): BaseAgent {
    // 按类型创建对应的 Agent 实例
  }
}
  • 审计、记忆、DB 等可通过 NestJS 模块注入到 Agent 构造函数,便于测试时替换为 mock。

5. 可复用要点小结

  • 抽象基类 / 接口 + 统一 process 方法。
  • 消息模型标准化(role / content / metadata),使用 TypeScript interface 定义。
  • 路由按「问答 vs 技术/执行」分流,规则可配置、可测试。
  • 多智能体各司其职:Q&A / Planner / Core / Summary。
  • 智能体实例懒加载 + 缓存,依赖通过 NestJS 依赖注入管理。