多智能体架构范式
与具体业务无关的智能体分层与路由设计经验。
1. 基类抽象与消息模型
- 基类:用抽象类或接口定义统一接口(如
process(userInput: string, options?: Record<string, unknown>): Promise<string>),子类实现具体逻辑。系统提示词、对话历史、记忆可放在基类,由子类按需覆盖默认实现。 - 消息模型:使用 TypeScript
interface或class定义消息结构,便于序列化、日志与持久化:
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),使用 TypeScriptinterface定义。 - 路由按「问答 vs 技术/执行」分流,规则可配置、可测试。
- 多智能体各司其职:Q&A / Planner / Core / Summary。
- 智能体实例懒加载 + 缓存,依赖通过 NestJS 依赖注入管理。