如何通过单一 API 为 AI 代理提供真实工具
通过 REST API 或 MCP 将 AI 代理连接到 150 多个开发人员工具。 Claude 工具使用、OpenAI 函数调用以及基于 MCP 的架构以及代码示例。
您正在构建一个人工智能代理来帮助用户完成技术任务。 代理需要查找 DNS 记录、验证电子邮件、生成 QR 代码并检查 SSL 证书。 法学硕士可以推理这些任务,但他们无法进行网络调用或生成图像。 您的代理需要工具。
典型的道路是痛苦的。 您连接一个用于 DNS 的库,另一个用于电子邮件验证,第三个用于 QR 码。 每个都有自己的身份验证、自己的响应格式、自己的错误处理。 您的代理的工具执行层变成了 API 客户端的拼凑而成。
更好的方法:让代理访问涵盖所有这些功能的单个 API。 一个身份验证令牌。 一种响应格式。 要跟踪的一种速率限制。 这篇文章展示了如何连接 博托伊API (150+开发者工具端点)分为三种代理架构:Claude工具使用、OpenAI函数调用和MCP。
30秒内的工具使用模式
每个主要的 LLM 提供商现在都支持工具使用(也称为函数调用)。 所有这些模式都是相同的:
- 您可以定义一组带有名称、描述和输入模式的工具。
- 您将用户消息连同工具定义一起发送给法学硕士。
- 法学硕士决定调用哪个工具以及使用什么参数。
- 您的代码执行工具调用(HTTP 请求、数据库查询、文件读取)。
- 您将工具结果发送回法学硕士。
- 法学硕士使用结果来制定最终答案。
该循环的伪代码如下所示:
// The tool-use loop: LLM reasons, picks a tool, you execute it
while (true) {
const response = await llm.chat(messages);
if (response.stop_reason === "tool_use") {
const toolCall = response.tool_calls[0];
const result = await executeToolCall(toolCall);
messages.push({ role: "tool", content: result });
} else {
return response.content; // Final answer
}
}
法学硕士本身从不执行该工具。 它产生结构化输出(工具名称+参数),并且您的代码执行。 这意味着工具可以是任何东西:shell 命令、数据库查询或 API 调用。
为什么 botoi 的 API 能够很好地映射到工具使用模式
每个 botoi 端点的形状都类似于工具定义。 每个端点都接受 JSON 输入并返回具有一致结构的 JSON 输出。 DNS 查找工具定义如下:
// Each botoi endpoint maps to a tool definition
// The OpenAPI spec at /openapi.json provides this automatically
{
"name": "dns_lookup",
"description": "Look up DNS records for a domain",
"parameters": {
"type": "object",
"properties": {
"domain": { "type": "string", "description": "Domain to query" },
"type": { "type": "string", "enum": ["A", "AAAA", "MX", "TXT", "CNAME", "NS"] }
},
"required": ["domain"]
}
}
三个因素使得这对于代理来说非常有效:
- 清晰的输入模式。 每个端点都接受一个小的、定义良好的 JSON 主体。 当架构很紧张时,LLM 擅长生成结构化 JSON。
-
一致的输出格式。 所有端点返回
{"{ success: true, data: { ... } }"}或者{"{ success: false, message: '...' }"}。 您的代理的工具结果解析器以相同的方式处理每个端点。 - 用于自动发现的 OpenAPI 规范。 规格位于 api.botoi.com/openapi.json 包含所有 150 多个端点的完整架构。 您可以通过编程方式从中生成工具定义,而不是手动编写它们。
架构 1:Claude 工具与 Anthropic SDK 结合使用
Claude 的工具使用 API 允许您将工具定义与消息一起传递。 当 Claude 决定调用一个工具时,它会返回一个 tool_use 包含工具名称和输入的内容块。 您执行调用并将结果作为 tool_result。
这是一个工作代理,可以查找 DNS 记录、检查 SSL 证书并使用 botoi 验证电子邮件:
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const BOTOI_KEY = process.env.BOTOI_API_KEY;
// Define botoi endpoints as Claude tools
const tools = [
{
name: "dns_lookup",
description: "Look up DNS records (A, MX, TXT, etc.) for a domain",
input_schema: {
type: "object",
properties: {
domain: { type: "string", description: "Domain to query" },
type: { type: "string", enum: ["A", "AAAA", "MX", "TXT", "CNAME", "NS"] },
},
required: ["domain"],
},
},
{
name: "ssl_check",
description: "Check SSL certificate and security headers for a domain",
input_schema: {
type: "object",
properties: {
url: { type: "string", description: "Domain or URL to check" },
},
required: ["url"],
},
},
{
name: "email_validate",
description: "Validate an email address (syntax, MX, disposable check)",
input_schema: {
type: "object",
properties: {
email: { type: "string", description: "Email address to validate" },
},
required: ["email"],
},
},
];
// Map tool names to botoi API endpoints
const toolEndpoints = {
dns_lookup: "/v1/dns/lookup",
ssl_check: "/v1/ssl",
email_validate: "/v1/email/validate",
};
async function callBotoiTool(name, input) {
const endpoint = toolEndpoints[name];
const res = await fetch(\`https://api.botoi.com\${endpoint}\`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": \`Bearer \${BOTOI_KEY}\`,
},
body: JSON.stringify(input),
});
return await res.json();
}
async function runAgent(userMessage) {
const messages = [{ role: "user", content: userMessage }];
while (true) {
const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
tools,
messages,
});
// If Claude wants to use a tool, execute it and feed the result back
if (response.stop_reason === "tool_use") {
const toolBlock = response.content.find((b) => b.type === "tool_use");
const result = await callBotoiTool(toolBlock.name, toolBlock.input);
messages.push({ role: "assistant", content: response.content });
messages.push({
role: "user",
content: [
{
type: "tool_result",
tool_use_id: toolBlock.id,
content: JSON.stringify(result),
},
],
});
} else {
// Claude is done; return the final text
return response.content[0].text;
}
}
}
// Usage
const answer = await runAgent(
"Check the DNS records and SSL certificate for stripe.com"
);
console.log(answer);
询问该代理“检查 stripe.com 的 DNS 记录和 SSL 证书”,Claude 将依次调用两个工具,然后将结果合成为可读的摘要。 Agent自动处理多步推理; Claude 根据用户的问题选择调用哪些工具以及按什么顺序。
架构2:OpenAI函数调用
OpenAI 的函数调用遵循相同的模式,但字段名称不同。 工具定义在 tools 数组与 type: "function"。 模型返回 tool_calls 当它想要执行一个函数时。
区别之一:GPT 可以在单个响应中请求多个工具调用。 下面的代码处理并行工具执行:
import OpenAI from "openai";
const openai = new OpenAI();
const BOTOI_KEY = process.env.BOTOI_API_KEY;
const tools = [
{
type: "function",
function: {
name: "dns_lookup",
description: "Look up DNS records for a domain",
parameters: {
type: "object",
properties: {
domain: { type: "string" },
type: { type: "string", enum: ["A", "AAAA", "MX", "TXT", "CNAME", "NS"] },
},
required: ["domain"],
},
},
},
{
type: "function",
function: {
name: "qr_generate",
description: "Generate a QR code SVG from text or a URL",
parameters: {
type: "object",
properties: {
text: { type: "string", description: "Content to encode" },
size: { type: "number", description: "Size in pixels (100-1000)" },
},
required: ["text"],
},
},
},
];
const toolEndpoints = {
dns_lookup: "/v1/dns/lookup",
qr_generate: "/v1/qr/generate",
};
async function callBotoiTool(name, args) {
const endpoint = toolEndpoints[name];
const res = await fetch(\`https://api.botoi.com\${endpoint}\`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": \`Bearer \${BOTOI_KEY}\`,
},
body: JSON.stringify(args),
});
return await res.json();
}
async function runAgent(userMessage) {
const messages = [{ role: "user", content: userMessage }];
while (true) {
const response = await openai.chat.completions.create({
model: "gpt-4o",
tools,
messages,
});
const choice = response.choices[0];
if (choice.finish_reason === "tool_calls") {
messages.push(choice.message);
for (const call of choice.message.tool_calls) {
const args = JSON.parse(call.function.arguments);
const result = await callBotoiTool(call.function.name, args);
messages.push({
role: "tool",
tool_call_id: call.id,
content: JSON.stringify(result),
});
}
} else {
return choice.message.content;
}
}
}
const answer = await runAgent(
"Generate a QR code for https://botoi.com and look up the MX records"
);
console.log(answer);
GPT-4o 可以同时调用 dns_lookup 和 qr_generate 当任务独立时并行。 该循环在将结果发送回模型之前处理所有工具调用。
架构3:基于MCP的代理
模型上下文协议 (MCP) 是一种不同的方法。 代理在运行时从 MCP 服务器发现工具,而不是在代码中定义工具。 Botoi 在以下位置运行 MCP 服务器: api.botoi.com/mcp 包含 44 个精选工具。
这是零代码选项。 无需编写工具定义。 无需构建执行层。 MCP 客户端(Claude Desktop、Cursor、Claude Code、VS Code)连接到服务器、发现工具并处理执行。
// Claude Desktop, Cursor, or VS Code: add to your MCP config
{
"mcpServers": {
"botoi": {
"type": "streamable-http",
"url": "https://api.botoi.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
// Claude Code: one command
// claude mcp add botoi --transport streamable-http https://api.botoi.com/mcp
添加此配置后,您的 AI 助手可以通过名称调用 44 个工具中的任何一个。 询问“查找 github.com 的 MX 记录”,助理会致电 lookup_dns 工具,传递域和记录类型,并返回结构化 JSON。
当您以交互方式(在 IDE 或聊天客户端中)使用 AI 助手时,MCP 是正确的选择。 当您构建自主运行的编程代理时,函数调用是正确的选择。
为什么单个 API 对代理很重要
当您为代理连接工具时,工具执行层是生产中中断的部分。 您添加的每个外部 API 都会引入其自己的故障模式。 考虑一下当您的代理使用五种不同的 API 时会发生什么:
- 五个可安全轮换和存储的 API 密钥。
- 独立跟踪的五个速率限制。
- 在将结果反馈给法学硕士之前需要标准化的五种响应格式。
- 具有不同状态代码和错误形状的五个错误处理路径。
- 五个要监控的计费仪表板。
使用单个 API,您的工具执行函数可以简化为一种模式:
// Shared helper: route any tool call to the right botoi endpoint
async function executeBotoiTool(name, input) {
const ENDPOINTS = {
dns_lookup: "/v1/dns/lookup",
ssl_check: "/v1/ssl",
email_validate: "/v1/email/validate",
qr_generate: "/v1/qr/generate",
ip_lookup: "/v1/ip/lookup",
hash_generate: "/v1/hash",
jwt_decode: "/v1/jwt/decode",
pii_detect: "/v1/pii/detect",
whois_lookup: "/v1/whois",
token_count: "/v1/token/count",
};
const path = ENDPOINTS[name];
if (!path) throw new Error("Unknown tool: " + name);
const res = await fetch(\`https://api.botoi.com\${path}\`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": \`Bearer \${process.env.BOTOI_API_KEY}\`,
},
body: JSON.stringify(input),
});
if (!res.ok) {
const err = await res.json();
return { error: err.message || "API call failed" };
}
return await res.json();
}
每个工具调用都会经历相同的身份验证标头、相同的错误形状、相同的速率限制。 添加一个新工具意味着向其中添加一行 ENDPOINTS 地图。 没有新的依赖项,没有新的凭据。
为您的代理选择合适的工具
不要将所有 150 多个端点注册为工具。 当工具列表很长时,法学硕士的表现会更差,因为他们必须推理更多的选择。 选择您的代理针对其特定用例所需的 5-15 种工具。
一些代理原型和适合它们的工具:
- 基础设施监控代理: DNS 查找、SSL 检查、HTTP 标头、站点性能检查、正常运行时间检查、IP 查找
- 电子邮件安全审核员: SPF 检查、DMARC 检查、DKIM 检查、MX 记录检查、电子邮件验证、一次性电子邮件检查
- 数据处理代理: JSON 格式、CSV 转 JSON、XML 转 JSON、Base64 编码/解码、HTML 转 Markdown、PII 检测
- 开发助理: JWT 解码、哈希生成、UUID 生成、cron 解析、正则表达式测试、令牌计数
开始狭窄。 当代理的用户请求其无法处理的功能时添加工具。 监视哪些工具被调用并删除那些从不触发的工具。
要点
- 法学硕士理由; 工具法。 工具使用模式将法学硕士的规划与现实世界行动的执行分开。 您的代理需要可靠的工具来弥补这一差距。
- 一个API,一个执行路径。 具有一致的身份验证、响应格式和错误处理功能的单一 API 简化了每个代理所需的工具执行层。
- 三种架构,相同的 API。 Claude 工具使用、OpenAI 函数调用和 MCP 都可与 botoi 端点配合使用。 选择与您的部署模型相匹配的一个。
- 保持工具列表较小。 每个代理注册 5-15 个工具。 太多的选择会降低法学硕士工具选择的准确性。
- 用于交互式使用的 MCP,用于自主代理的函数调用。 MCP 为您处理工具发现和执行。 函数调用使您可以完全控制循环。
这 API文档 列出带有请求/响应模式的每个端点。 这 OpenAPI 规范 允许您以编程方式生成工具定义。 这 MCP 工具清单 显示了通过 MCP 提供的 44 个精选工具。
FAQ
- 我可以将 botoi API 与任何 LLM 一起使用,而不仅仅是 Claude 和 GPT 吗?
- 是的。 该 API 是返回 JSON 的标准 REST API。 任何支持函数调用或工具使用的LLM框架(LangChain、LlamaIndex、Vercel AI SDK、CrewAI)都可以将botoi端点作为工具调用。 /openapi.json 中的 OpenAPI 规范提供了架构定义。
- 代理可以通过 botoi 访问多少种工具?
- REST API 有 150 多个端点。 MCP 服务器公开了 44 个精选工具。 对于使用 Claude 或 GPT 进行函数调用,您可以根据代理的用例选择将哪些端点注册为工具。
- 代理使用 API 是否需要身份验证?
- 匿名访问的速度为每分钟 5 个请求和每天 100 个请求,速率受 IP 限制。 对于生产代理,请从 botoi.com/api 获取 API 密钥。 免费套餐不需要信用卡。
- 什么是 MCP?它与函数调用有何不同?
- MCP(模型上下文协议)是用于将 AI 助手连接到外部工具的标准。 助手从 MCP 服务器发现可用工具并按名称调用它们。 函数调用要求您在代码中定义工具架构。 MCP 自动处理发现和调用。
- 我可以自行托管 botoi API 以降低延迟吗?
- 该 API 在边缘的 Cloudflare Workers 上运行,因此请求路由到全球最近的数据中心。 对于纯计算工具,响应时间低于 50 毫秒。 自托管不可用,但边缘部署意味着延迟与自托管解决方案相当。
开始使用 botoi 构建
150+ 个 API 端点,涵盖查询、文本处理、图片生成和开发者工具。免费套餐,无需信用卡。