本项目实现了两种多智能体协调方式:
orchestrator.simple.ts) - 函数式调用orchestrator.langgraph.ts) - 状态图编排 ⭐️文件: src/agents/multi-agent/orchestrator.simple.ts
特点:
代码示例:
async execute(userQuestion: string) {
// 1. 接待员分析
const decision = await this.receptionistAgent.routeQuestion(userQuestion);
// 2. 根据决策路由
if (decision.targetAgent === AgentType.TECH_SUPPORT) {
return await this.techSupportAgent.handleQuestion(userQuestion);
} else if (decision.targetAgent === AgentType.SALES) {
return await this.salesAgent.handleQuestion(userQuestion);
} else {
return await this.answerWithDirectLLM(userQuestion);
}
}
文件: src/agents/multi-agent/orchestrator.langgraph.ts
特点:
代码示例:
// 1. 定义状态图
const workflow = new StateGraph(StateAnnotation);
// 2. 添加节点
workflow.addNode('receptionist', async (state) => {...});
workflow.addNode('tech_support', async (state) => {...});
workflow.addNode('sales', async (state) => {...});
workflow.addNode('direct_llm', async (state) => {...});
// 3. 定义边(流程)
workflow.addEdge(START, 'receptionist');
workflow.addConditionalEdges('receptionist', routingLogic);
workflow.addEdge('tech_support', END);
workflow.addEdge('sales', END);
workflow.addEdge('direct_llm', END);
// 4. 编译并执行
const graph = workflow.compile();
const result = await graph.invoke(initialState);
编辑 .env 文件:
# 使用 LangGraph 版本
USE_LANGGRAPH=true
# 使用简化版本
USE_LANGGRAPH=false
// 在服务中切换
multiAgentService.switchMode(true); // 切换到 LangGraph
multiAgentService.switchMode(false); // 切换到简化版
状态图是LangGraph的核心,定义了智能体的执行流程。
const workflow = new StateGraph(StateAnnotation);
定义状态的结构和更新规则:
const StateAnnotation = Annotation.Root({
messages: Annotation<any[]>({
reducer: (left, right) => left.concat(right), // 合并消息
default: () => [],
}),
userQuestion: Annotation<string>({
reducer: (left, right) => right || left, // 保留最新值
default: () => '',
}),
// ... 更多字段
});
Reducer的作用:
left: 旧值right: 新值节点是工作流中的处理单元,每个节点执行特定任务:
// @ts-ignore - LangGraph 1.0 类型定义不完善
workflow.addNode('receptionist', async (state: AgentState) => {
// 处理逻辑
const decision = await this.receptionistAgent.routeQuestion(state.userQuestion);
// 返回状态更新
return {
currentAgent: decision.targetAgent,
routingReason: decision.reason,
processingSteps: [{
agent: AgentType.RECEPTIONIST,
action: '路由决策',
timestamp: Date.now(),
}],
};
});
节点特点:
边定义节点之间的连接关系:
// @ts-ignore
workflow.addEdge(START, 'receptionist'); // START → 接待员
// @ts-ignore
workflow.addEdge('tech_support', END); // 技术支持 → END
// @ts-ignore
workflow.addConditionalEdges(
'receptionist', // 来源节点
(state: AgentState) => {
// 路由逻辑
if (state.currentAgent === AgentType.TECH_SUPPORT) {
return 'tech_support';
} else if (state.currentAgent === AgentType.SALES) {
return 'sales';
}
return 'direct_llm';
},
// 映射表:返回值 → 目标节点
{
tech_support: 'tech_support',
sales: 'sales',
direct_llm: 'direct_llm',
}
);
const result = await graph.invoke(initialState);
console.log(result.finalAnswer);
const stream = await graph.stream(initialState);
for await (const chunk of stream) {
console.log('状态更新:', chunk);
}
LangGraph 1.0 的TypeScript类型定义还不完善,我们使用 @ts-ignore 来绕过:
// @ts-ignore - LangGraph 1.0 类型定义不完善
workflow.addNode('receptionist', async (state: AgentState) => {...});
为什么使用 @ts-ignore 而不是 @ts-expect-error?
@ts-expect-error: 期望有错误,如果没错误会报警@ts-ignore: 无条件忽略下一行的类型检查@ts-ignore 更稳定假设用户问题: "我的账号登录不上去了"
1. START └─> 初始状态: { userQuestion: "我的账号登录不上去了", messages: [...] } 2. receptionist 节点 └─> 分析问题 → 决策: tech_support └─> 状态更新: { currentAgent: 'tech_support', routingReason: '...' } 3. 条件路由 └─> 根据 currentAgent 选择 → tech_support 节点 4. tech_support 节点 └─> 调用技术支持智能体处理 └─> 状态更新: { finalAnswer: '...', messages: [...] } 5. END └─> 返回最终结果
yarn install
# 编辑 .env 文件
USE_LANGGRAPH=true # 使用LangGraph版本
PORT=4005 yarn start:dev
http://localhost:4005/multi-agent
试试这些问题:
src/agents/multi-agent/ ├── orchestrator.simple.ts # 简化版协调器 ├── orchestrator.langgraph.ts # LangGraph版协调器 ⭐️ ├── orchestrator.ts.bak # 原始LangGraph版本(备份) ├── multi-agent.service.ts # NestJS服务(支持两种模式) ├── types.ts # 类型定义 └── agents/ ├── receptionist.agent.ts # 接待员智能体 ├── tech-support.agent.ts # 技术支持智能体 └── sales.agent.ts # 销售智能体
理解简化版 (orchestrator.simple.ts)
学习LangGraph版 (orchestrator.langgraph.ts)
对比两种实现
扩展功能
A: LangGraph 1.0 的TypeScript类型定义还不完善,使用 @ts-ignore 可以绕过类型检查。
A: 可以!服务会同时初始化两个协调器,通过 USE_LANGGRAPH 环境变量或 switchMode() 方法切换。
A: LangGraph增加了一层抽象,但对于AI应用来说,性能瓶颈通常在LLM调用上,状态图的开销可以忽略不计。
A:
LangGraph的核心优势:
适用场景:
开始你的LangGraph学习之旅吧!🚀