外观
buildAgentTools
将 AgentCard 数组转换为 LLM Tool Calling 格式,支持 OpenAI、Anthropic、LangChain。
核心函数
| 函数 | 说明 |
|---|---|
buildAgentTools | 将 AgentCard 数组转换为通用 Tool 格式 |
toOpenAITools | 转换为 OpenAI SDK 格式 |
toAnthropicTools | 转换为 Anthropic SDK 格式 |
toLangChainTools | 转换为 LangChain DynamicStructuredTool |
executeOpenAIToolCall | 执行 OpenAI tool_call(自动调用 Agent) |
executeAnthropicToolUse | 执行 Anthropic tool_use(自动调用 Agent) |
基本流程
1. 获取 AgentCard
typescript
import { createAgentClient } from '@multi-agent/a2a'
const client = createAgentClient({
agentId: 'tool-agent',
address: 'a2a://localhost:50055',
})
const agentCard = await client.getAgentCard()2. 构建 Tools
typescript
import { buildAgentTools } from '@multi-agent/a2a'
// 支持多个 Agent
const { tools, toolInfoMap } = buildAgentTools([agentCard1, agentCard2])3. 转换为目标格式
typescript
import { toOpenAITools, toAnthropicTools, toLangChainTools } from '@multi-agent/a2a'
const openaiTools = toOpenAITools(tools) // OpenAI SDK 格式
const anthropicTools = toAnthropicTools(tools) // Anthropic SDK 格式
const langchainTools = toLangChainTools(tools) // LangChain DynamicStructuredToolOpenAI
typescript
import { createAgentClient } from '@multi-agent/a2a'
import { buildAgentTools, toOpenAITools, executeOpenAIToolCall } from '@multi-agent/a2a'
import OpenAI from 'openai'
// 1. 获取 AgentCard
const client = createAgentClient({ agentId: 'tool-agent', address: 'a2a://localhost:50055' })
const agentCard = await client.getAgentCard()
// 2. 构建 Tools
const { tools } = buildAgentTools([agentCard])
const openaiTools = toOpenAITools(tools)
// 3. 调用 OpenAI
const openai = new OpenAI()
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: '读取 package.json 文件' }],
tools: openaiTools,
})
// 4. 执行 tool_call(自动调用对应 Agent)
const toolCalls = response.choices[0].message.tool_calls
if (toolCalls) {
for (const toolCall of toolCalls) {
const result = await executeOpenAIToolCall(tools, toolCall)
console.log(result)
}
}Anthropic
typescript
import { createAgentClient } from '@multi-agent/a2a'
import { buildAgentTools, toAnthropicTools, executeAnthropicToolUse } from '@multi-agent/a2a'
import Anthropic from '@anthropic-ai/sdk'
// 1. 获取 AgentCard
const client = createAgentClient({ agentId: 'tool-agent', address: 'a2a://localhost:50055' })
const agentCard = await client.getAgentCard()
// 2. 构建 Tools
const { tools } = buildAgentTools([agentCard])
const anthropicTools = toAnthropicTools(tools)
// 3. 调用 Anthropic
const anthropic = new Anthropic()
const response = await anthropic.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 1024,
messages: [{ role: 'user', content: '读取 package.json 文件' }],
tools: anthropicTools,
})
// 4. 执行 tool_use(自动调用对应 Agent)
const toolUse = response.content.find(c => c.type === 'tool_use')
if (toolUse) {
const result = await executeAnthropicToolUse(tools, toolUse)
console.log(result)
}LangChain
typescript
import { createAgentClient } from '@multi-agent/a2a'
import { buildAgentTools, toLangChainTools } from '@multi-agent/a2a'
import { ChatOpenAI } from '@langchain/openai'
// 1. 获取 AgentCard
const client = createAgentClient({ agentId: 'tool-agent', address: 'a2a://localhost:50055' })
const agentCard = await client.getAgentCard()
// 2. 构建 Tools
const { tools } = buildAgentTools([agentCard])
const langchainTools = toLangChainTools(tools)
// 3. 绑定到 LLM
const llm = new ChatOpenAI({ model: 'gpt-4o' })
const llmWithTools = llm.bindTools(langchainTools)
// 4. 调用(LangChain 自动处理 tool_call)
const response = await llmWithTools.invoke('读取 package.json 文件')配置选项
typescript
interface BuildAgentToolsOptions {
excludeAgentIds?: string[] // 排除的 Agent ID
metadata?: Record<string, string> // 传递给 Agent 的 metadata
signal?: AbortSignal // 取消信号
timeout?: number // 超时时间(默认 120000ms)
parentStream?: MessageStream // 父级消息流
}excludeAgentIds
排除特定 Agent,常用于排除自己避免递归调用:
typescript
const { tools } = buildAgentTools(agentCards, {
excludeAgentIds: ['chat-agent'], // 排除 chat-agent
})metadata
传递 traceId 等上下文信息给被调用的 Agent:
typescript
const { tools } = buildAgentTools(agentCards, {
metadata: { 'x-trace-id': traceId },
})signal
传递取消信号,用户取消时中断 Agent 调用:
typescript
const controller = new AbortController()
const { tools } = buildAgentTools(agentCards, {
signal: controller.signal,
})
// 取消
controller.abort()parentStream
转发子 Agent 的 progress 消息给用户:
typescript
const { tools } = buildAgentTools(agentCards, {
parentStream: ctx.stream, // 自动转发 progress 消息
})在 Handler 中使用
完整示例,展示在 Agent Handler 中使用:
typescript
import { buildAgentTools, toOpenAITools } from '@multi-agent/a2a'
import type { AgentCard, Context } from '@multi-agent/a2a'
interface Params {
message: string
teamContext: { members: AgentCard[] }
}
async function handler(params: Params, ctx: Context) {
const { tools } = buildAgentTools(params.teamContext.members, {
excludeAgentIds: [ctx.agentId], // 排除自己
metadata: ctx.metadata.getMap(), // 传递 traceId 等
signal: ctx.signal, // 取消信号
parentStream: ctx.stream, // 转发 progress
})
const openaiTools = toOpenAITools(tools)
// 调用 LLM...
}toolInfoMap
buildAgentTools 返回的 toolInfoMap 用于获取工具的友好名称:
typescript
const { tools, toolInfoMap } = buildAgentTools([agentCard])
// toolInfoMap: Map<string, ToolInfo>
interface ToolInfo {
agentId: string // Agent ID
agentName: string // Agent 名称
skillName: string // 技能名称
}
// 示例
for (const [toolName, info] of toolInfoMap) {
console.log(`${toolName} -> ${info.agentName}.${info.skillName}`)
}
// tool-agent_readFile -> Tool Agent.readFile
// tool-agent_writeFile -> Tool Agent.writeFile可用于在 UI 中显示更友好的工具名称。