multi-agent-orchestrator TypeScript 本地快速上手:用 MultiAgentOrchestrator 构建多智能体编排应用
2026/9/16 17:13:27 网站建设 项目流程

multi-agent-orchestrator TypeScript 本地快速上手:用 MultiAgentOrchestrator 构建多智能体编排应用

【免费下载链接】agent-squadFlexible and powerful framework for managing multiple AI agents and handling complex conversations项目地址: https://gitcode.com/GitHub_Trending/mu/agent-squad

本文是 TypeScript 本地 Demo 的实战指南,围绕multi-agent-orchestrator框架讲解如何在一个普通 Node.js 项目中通过MultiAgentOrchestrator初始化编排器、注册多个专业化BedrockLLMAgent、调用routeRequest完成意图分类与智能体路由,最终在本地终端跑通第一个多智能体问答应用。读完本文,你将掌握编排器的配置项含义、默认模型与默认存储行为,并能对照仓库中的交互式 Demo 扩展出流式输出、工具调用(Function Calling)与多类型智能体(Lex、Lambda、Bedrock Agent)混编的完整方案。

一、这份指南解决什么问题

多智能体应用的关键难点在于:如何把"哪个智能体来回答"这件事交给系统自动决策。multi-agent-orchestrator给出的答案是"编排器 + 意图分类器 + 智能体注册表"三层结构:用户输入先经过分类器判定意图并选出最合适的智能体,再由该智能体生成回答。

本文对应的官方入门文档(typescript-local-demo.md)给出了一个最小可运行示例:只用两个BedrockLLMAgent(Tech Agent 与 Health Agent),通过默认的 Bedrock 分类器实现"科技问题找技术智能体、健康问题找医疗智能体"的路由效果。仓库中的 本地交互式 Demo 则是该示例的超集版本,额外演示了流式输出、天气工具调用以及 Lex/Lambda/Bedrock Agent 的混编,两相结合即可从"能跑"走向"能用于生产场景"。

二、前置条件

在开始之前,请确保本地环境满足以下条件(与入门文档一致,并补充说明):

  • Node.js 与 npm:本示例通过npm init+npm install搭建工程,并依赖ts-node运行 TypeScript 文件,需要可用的 Node.js 环境。
  • AWS 账户与相应权限:分类器与智能体都通过 Amazon Bedrock 的Converse API发起推理请求,因此需要配置 AWS 凭证(如环境变量AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY/AWS_REGION,或本机~/.aws/credentials),并确保账户已开通所需模型(anthropic.claude-3-5-sonnet-20240620-v1:0anthropic.claude-3-haiku-20240307-v1:0)的访问权限。
  • TypeScript 与 async/await 基础:示例大量使用async functionawait与异步迭代器(for await),需要对此有基本了解。

三、快速初始化项目

按照入门文档,在本地任意目录新建工程并安装依赖:

mkdir test_multi_agent_orchestrator cd test_multi_agent_orchestrator npm init npm install multi-agent-orchestrator

安装完成后,在package.jsondependencies中会出现multi-agent-orchestrator依赖。仓库中的 examples/local-demo/package.json 使用了"multi-agent-orchestrator": "^0.0.17"并额外引入了dotenv,用于从.env文件加载环境变量。如果希望运行本文后面的交互式 Demo,建议同样安装dotenvts-node

npm install dotenv npm install -D ts-node typescript

四、编写第一个多智能体应用

4.1 初始化编排器

新建quickstart.ts,首先初始化MultiAgentOrchestrator

import { MultiAgentOrchestrator } from "multi-agent-orchestrator"; const orchestrator = new MultiAgentOrchestrator({ config: { LOG_AGENT_CHAT: true, LOG_CLASSIFIER_CHAT: true, LOG_CLASSIFIER_RAW_OUTPUT: false, LOG_CLASSIFIER_OUTPUT: true, LOG_EXECUTION_TIMES: true, } });

configOrchestratorConfig的部分配置,未显式给出的项会与DEFAULT_CONFIG合并。对照 orchestrator.ts 中的默认配置,可梳理出每个开关的真实含义与默认值:

配置项默认值作用
LOG_AGENT_CHATfalse是否记录与智能体的对话交互日志
LOG_CLASSIFIER_CHATfalse是否记录与分类器的对话交互日志
LOG_CLASSIFIER_RAW_OUTPUTfalse是否记录分类器未加工的原始输出
LOG_CLASSIFIER_OUTPUTfalse是否记录分类器处理后的输出(即最终意图判定结果)
LOG_EXECUTION_TIMESfalse是否记录"分类耗时""智能体处理耗时"等各阶段执行时间
MAX_RETRIES3分类器返回异常 XML 时的最大重试次数
USE_DEFAULT_AGENT_IF_NONE_IDENTIFIEDtrue分类器未识别出任何智能体时,是否回退到默认智能体;为false时向用户返回提示语
NO_SELECTED_AGENT_MESSAGE"I'm sorry, I couldn't determine how to handle your request..."未选中任何智能体时展示给用户的兜底消息
GENERAL_ROUTING_ERROR_MSG_MESSAGE未定义路由过程中发生异常时的通用错误消息
MAX_MESSAGE_PAIRS_PER_AGENT100每个智能体保留的最大"用户-助手"消息对数(实际存储量为该值 × 2 条消息)

需要说明的是:USE_DEFAULT_AGENT_IF_NONE_IDENTIFIED只有在通过setDefaultAgent或构造参数defaultAgent设置了默认智能体时才生效,该回退逻辑可在 orchestrator.ts 的 classifyRequest 方法 中看到。

4.2 添加专业化智能体

随后注册两个负责不同领域的BedrockLLMAgent

import { BedrockLLMAgent } from "multi-agent-orchestrator"; orchestrator.addAgent( new BedrockLLMAgent({ name: "Tech Agent", description: "Specializes in technology areas including software development, hardware, AI, cybersecurity, blockchain, cloud computing, emerging tech innovations, and pricing/costs related to technology products and services.", }) ); orchestrator.addAgent( new BedrockLLMAgent({ name: "Health Agent", description: "Focuses on health and medical topics such as general wellness, nutrition, diseases, treatments, mental health, fitness, healthcare systems, and medical terminology or concepts.", }) );

description不是装饰性字段,它同时服务于两条链路:

  • 分类阶段:分类器把全部智能体的name+description注入系统提示词,据此把用户输入路由到语义最匹配的智能体;
  • 生成阶段BedrockLLMAgent的默认系统提示词模板为You are a ${this.name}. ${this.description} ...,即智能体在回答时也会携带该描述作为角色设定(见 bedrockLLMAgent.ts 的构造函数)。

addAgent会以智能体name生成唯一 ID(去除非字母数字字符、空格转连字符、转小写),重复注册相同 ID 会抛出异常(见 orchestrator.ts 的 addAgent)。

BedrockLLMAgentname/description外还支持以下常用选项(bedrockLLMAgent.ts 的类型定义):

  • modelId:使用的 Bedrock 模型 ID,默认anthropic.claude-3-haiku-20240307-v1:0(常量定义见 types/index.ts);
  • region:Bedrock 服务区域,缺省时使用默认凭证链;
  • streaming:是否流式返回,默认false
  • inferenceConfigmaxTokenstemperaturetopPstopSequences等推理参数;
  • guardrailConfig:Bedrock Guardrails 的guardrailIdentifierguardrailVersion
  • retriever:接入向量检索器,自动把检索上下文拼入系统提示词;
  • toolConfigtool(工具定义)、useToolHandler(工具执行回调)、toolMaxRecursions(工具调用最大轮数,默认 20);
  • customSystemPrompt:自定义系统提示词模板与模板变量。

4.3 实现主逻辑并路由请求

接下来编写入口逻辑,向编排器提交一条用户查询:

const userId = "quickstart-user"; const sessionId = "quickstart-session"; const query = "What are the latest trends in AI?"; console.log(`\nUser Query: ${query}`); async function main() { try { const response = await orchestrator.routeRequest(query, userId, sessionId); console.log("\n** RESPONSE ** \n"); console.log(`> Agent ID: ${response.metadata.agentId}`); console.log(`> Agent Name: ${response.metadata.agentName}`); console.log(`> User Input: ${response.metadata.userInput}`); console.log(`> User ID: ${response.metadata.userId}`); console.log(`> Session ID: ${response.metadata.sessionId}`); console.log(`> Additional Parameters:`, response.metadata.additionalParams); console.log(`\n> Response: ${response.output}`); } catch (error) { console.error("An error occurred:", error); } } main();

这里值得展开说明routeRequest的完整调用链(实现在 orchestrator.ts 的 routeRequest):

  1. classifyRequest:先从存储中取出该userId + sessionId的聊天历史,再调用分类器classifier.classify(userInput, chatHistory)
  2. agentProcessRequest:把分类结果(selectedAgent)交给dispatchToAgent,后者从存储取回该智能体的历史对话后调用selectedAgent.processRequest(...)生成回答;
  3. 结果封装:若智能体返回的是异步可迭代对象(流式响应),则返回{ metadata, output: AccumulatorTransform, streaming: true };否则返回{ metadata, output: string, streaming: false },并在智能体saveChat开启时把本次问答写入存储;
  4. 异常兜底:分类失败时metadata.agentId"no_agent_selected"agentName"No Agent",输出为NO_SELECTED_AGENT_MESSAGE

response.metadata携带agentIdagentNameuserInputuserIdsessionIdadditionalParams等字段(接口定义见 orchestrator.ts 的 RequestMetadata),便于上层 UI 展示"由哪个智能体回答"。

4.4 运行应用

npx ts-node quickstart.ts

运行后终端会依次打印:User Query→ 分类与路由日志(取决于LOG_*开关)→RESPONSE块(含 Agent ID / Agent Name / 最终回答)。由于示例查询 "What are the latest trends in AI?" 属于技术话题,分类器应将其路由给 Tech Agent。

五、默认行为与底层机制解读

入门文档的"Implementation Notes"部分点明了三条默认行为,这里结合源码给出更完整的解释。

5.1 默认分类器:BedrockClassifier + Claude 3.5 Sonnet

未显式传入classifier时,编排器使用new BedrockClassifier()(见 orchestrator.ts 构造函数)。该分类器的默认模型为anthropic.claude-3-5-sonnet-20240620-v1:0(见 bedrockClassifier.ts)。

分类器的判定并非"纯文本提示",而是通过工具调用(Function Calling)约束结构化输出:它把analyzePrompt工具(输入 schema 含userinputselected_agentconfidence三个必填字段)注入ConverseCommand,强制模型返回结构化的分类结果,再据此查表定位智能体并解析置信度(见 bedrockClassifier.ts 的 processRequest)。若使用 Anthropic 或 Mistral Large 模型,还会额外设置toolChoice强制命中该工具。这解释了LOG_CLASSIFIER_RAW_OUTPUT(查看原始输出)与LOG_CLASSIFIER_OUTPUT(查看解析后的意图结果)两个开关的差异来源。

5.2 默认智能体:BedrockLLMAgent + Claude 3 Haiku

示例中的BedrockLLMAgent未指定modelId,因此使用默认的anthropic.claude-3-haiku-20240307-v1:0(见 bedrockLLMAgent.ts 的构造函数)。其底层通过 AWS SDK 的ConverseCommand/ConverseStreamCommand与 Bedrock 交互:非流式模式下会循环处理"模型输出 → 若含toolUse则执行工具 → 结果回填 → 再次调用",直到end_turn或达到toolMaxRecursions上限;流式模式下则逐 chunkyield文本增量(见 bedrockLLMAgent.ts 的 processRequest 与 handleStreamingResponse)。

5.3 默认存储:InMemoryChatStorage

未传入storage时使用new InMemoryChatStorage()(见 orchestrator.ts 构造函数)。它的实现基于内存Map,以${userId}#${sessionId}#${agentId}为键保存按时间戳排序的消息列表,并提供连续消息去重、maxHistorySize截断、跨智能体历史合并(供分类器参考)等能力(见 memoryChatStorage.ts)。这意味着服务重启后对话历史即丢失,生产环境应按需替换为 DynamoDB 或 SQL 存储。

六、进阶:仓库中的交互式本地 Demo

入门文档只覆盖了"单次请求",而仓库的 local-orchestrator.ts 是一个完整的终端交互式版本:通过readline循环接收用户输入,直到键入exit退出。它在快速入门示例基础上叠加了四类能力,非常适合作为下一步的参考实现。

6.1 多类型智能体混编

Demo 同时注册了四类智能体,展示了编排器对异构智能体的统一抽象(它们都继承自 agent.ts 的 Agent 基类):

  • BedrockLLMAgent(Tech Agent):开启streaming: true,并设置inferenceConfig.temperature: 0.1以获得更确定性的回答;
  • LexBotAgent:接入 Amazon Lex 机器人,需要botIdbotAliasIdlocaleId(必填,缺失会抛异常),底层通过RecognizeTextCommand调用 Lex Runtime V2(见 lexBotAgent.ts);
  • AmazonBedrockAgent:接入 Bedrock 中已创建的 Agent,需要agentIdagentAliasId,支持enableTracestreaming(见 amazonBedrockAgent.ts);
  • LambdaAgent:把请求转发给 AWS Lambda 函数,支持自定义inputPayloadEncoder/outputPayloadDecoder编解码载荷(见 lambdaAgent.ts)。

Lex、Bedrock Agent、Lambda 三者的占位符({{REPLACE_WITH_...}})需要替换为你实际的 AWS 资源 ID 才能运行。

6.2 工具调用:天气智能体

Demo 中最具实战价值的是 Weather Agent:它通过toolConfig注册了一个Weather_Tool(输入为 WGS84 经纬度),并配套weatherToolHanlder回调与自定义系统提示词:

const weatherAgent = new BedrockLLMAgent({ name: "Weather Agent", description: "Specialized agent for giving weather condition from a city.", streaming: true, inferenceConfig: { temperature: 0.1 }, toolConfig: { tool: weatherToolDescription, useToolHandler: weatherToolHanlder, toolMaxRecursions: 5, } }); weatherAgent.setSystemPrompt(WEATHER_PROMPT); orchestrator.addAgent(weatherAgent);

其中WEATHER_PROMPT明确约束"只调用 Weather_Tool、绝不编造数据、按经纬度推断城市位置"等行为(见 weather_tool.ts),而weatherToolHanlder在收到模型的toolUse请求后调用 Open-Meteo 公共天气 API,并把结果以toolResult消息回填给模型。这正是BedrockLLMAgent内部"工具调用循环"(见 5.2 节)的完整落地样例。

6.3 流式响应的消费方式

Demo 通过response.streaming标志区分两种响应:流式时用for await (const chunk of response.output)逐块写出文本,并先打印 metadata 再输出内容流;非流式时直接打印response.output字符串(见 local-orchestrator.ts)。该判断与编排器内部"输出是否为异步可迭代对象"的判定一一对应。

6.4 智能体注册表与重叠分析

Demo 还演示了两个实用 API:

  • orchestrator.getAllAgents():遍历已注册智能体的namedescription
  • orchestrator.analyzeAgentOverlap():调用AgentOverlapAnalyzer对智能体描述做语义重叠分析,帮助开发者发现描述过于相似的智能体(可能引发错误路由),实现位于 agentOverlapAnalyzer.ts。

6.5 运行交互式 Demo

在仓库 examples/local-demo 目录下执行:

npm install # 配置 AWS 凭证与 REGION(可通过 .env 文件) npx ts-node local-orchestrator.ts

启动后会打印全部已注册智能体并进入对话循环,输入问题后回车即可看到对应智能体的流式回答。注意:除 Tech Agent 与 Weather Agent 外,其余智能体需先替换占位符为真实 AWS 资源 ID;分类器所在区域通过REGION环境变量读取(见 bedrockClassifier.ts 构造函数)。

七、下一步:从 Demo 走向生产

入门文档的"Next Steps"给出了四条演进路径,这里补充对应的仓库依据:

  1. 添加更多专业化智能体:继续用addAgent注册新的BedrockLLMAgent,并通过analyzeAgentOverlap()验证描述区分度;描述写得越具体、越不重叠,分类准确率越高;
  2. 实现持久化存储:将默认的InMemoryChatStorage替换为 DynamoDB 存储(storage/dynamoDbChatStorage.ts)或 SQL 存储(storage/sqlChatStorage.ts),在构造MultiAgentOrchestrator时通过storage参数注入,即可在服务重启后保留对话上下文;
  3. 自定义错误处理:通过config中的CLASSIFICATION_ERROR_MESSAGENO_SELECTED_AGENT_MESSAGEGENERAL_ROUTING_ERROR_MSG_MESSAGE定制面向用户的兜底文案,并借助MAX_RETRIESUSE_DEFAULT_AGENT_IF_NONE_IDENTIFIED调节容错行为;
  4. 实现流式响应:为BedrockLLMAgent开启streaming: true,按 6.3 节的模式在服务端逐 chunk 消费response.output,即可向前端提供类打字机效果。

若想对比 Python 侧的实现,可参考仓库中的 python-local-demo.md,其 API 设计与 TypeScript 版本一一对应。至此,从入门文档的最小示例到仓库的交互式 Demo,你已经掌握了multi-agent-orchestrator在 TypeScript 本地环境下的完整实践路径。

【免费下载链接】agent-squadFlexible and powerful framework for managing multiple AI agents and handling complex conversations项目地址: https://gitcode.com/GitHub_Trending/mu/agent-squad

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询