🚀 使用AI SDK进行编程工具调用
适用于任何模型的通用LLM优化POC
程序化工具调用 是一种新颖的方法,通过用代码生成和沙盒执行取代传统的多往返工具调用,大大降低了LLM推理成本和延迟。
💡 源于 Anthropic的beta功能 2025年11月宣布。这个项目扩展了这种范式,以与 LLM 的 通过Vercel AI SDK,包括通过AI网关的100多个模型。
______________________________________________________________________
🎯 问题
传统的LLM工具调用是 固有低效尤其是对于MCP:
User: "Get data for users 1-5 and find the highest scorer"
Traditional Approach (N round-trips):
┌─────────────────────────────────────────────────────────────┐
│ Round 1: LLM → getUser(1) → result → LLM (context grows) │
│ Round 2: LLM → getUser(2) → result → LLM (context grows) │
│ Round 3: LLM → getUser(3) → result → LLM (context grows) │
│ Round 4: LLM → getUser(4) → result → LLM (context grows) │
│ Round 5: LLM → getUser(5) → result → LLM (context grows) │
│ Round 6: LLM → final answer │
└─────────────────────────────────────────────────────────────┘
⬇️
6 LLM calls × full context each
Accumulated results pollute context
High latency, high token cost✨ 解决方案
PTC将工具编排转换为单个代码生成+执行:
Programmatic Approach (1 round-trip):
┌─────────────────────────────────────────────────────────────┐
│ Round 1: LLM generates JavaScript: │
│ const users = await Promise.all([ │
│ getUser({ id: '1' }), getUser({ id: '2' }), │
│ getUser({ id: '3' }), getUser({ id: '4' }), │
│ getUser({ id: '5' }) │
│ ]); │
│ return users.sort((a,b) => b.score - a.score)[0]; │
│ │
│ → Execute in Sandbox → Return final result only │
│ │
│ Round 2: LLM receives final answer, responds to user │
└─────────────────────────────────────────────────────────────┘
⬇️
2 LLM calls total
Intermediate results never enter context
Parallel execution, massive savings______________________________________________________________________
📊 经验证的效率提升
| 度量 | 传统 | PTC | 改进 |
|---|---|---|---|
| LLM往返 | N(每个工具) | 2(固定) | 90%减少 |
| 上下文增长 | 指数 | 常数 | 85%效率 |
| 令牌使用 | 约70000(10个工具) | 约14000 | 节省80% |
| 延迟 | 顺序 | 并行 | 快3-5倍 |
| MCP工具调用 | N次往返 | 1次代码执行 | 节省60-80% |
______________________________________________________________________
🏗️ 建筑
┌──────────────────────────────────────────────────────────────────┐
│ User Request │
└──────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ Vercel AI SDK 5.0 + Programmatic Tool Wrapper │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ withProgrammaticCalling(tools) │ │
│ │ ├── Wraps local tools (Zod schemas) │ │
│ │ ├── Wraps MCP tools (JSON Schema) │ │
│ │ └── Injects code_execution meta-tool │ │
│ └────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ LLM (Any Provider via AI Gateway) │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Generates JavaScript code orchestrating N tool calls │ │
│ │ Uses defensive helpers (toArray, safeGet, isSuccess...) │ │
│ └────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ Vercel Sandbox (Isolated Cloud Execution) │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ ┌─────────────┐ ┌─────────────────────────────────┐ │ │
│ │ │ Local Tools │ │ MCP Bridge (File-based IPC) │ │ │
│ │ │ getUser() │ │ mcp_firecrawl_scrape() │ │ │
│ │ │ calculate() │ │ mcp_github_search() │ │ │
│ │ └─────────────┘ └─────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ Main Process (MCP Tool Bridge Monitor) │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ - Routes sandbox MCP requests to real MCP servers │ │
│ │ - Supports HTTP, SSE, and Stdio transports │ │
│ │ - Normalizes responses for predictable code access │ │
│ │ - Parallel batch execution for efficiency │ │
│ └────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ Final Result Only → Back to LLM → User Response │
└──────────────────────────────────────────────────────────────────┘______________________________________________________________________
🌟 主要特点
🔧 通用模型支持
- 直接提供者:克洛德,OpenAI GPT
- Vercel人工智能网关:100多种型号(双子座、米斯特拉尔、Groq、DeepSeek、Meta等)
- 适用于任何支持工具调用的模型
🧪 Vercel沙盒执行
- LLM生成代码的隔离云环境
- Node.js 22运行时完全支持async/await
- 执行前自动语法验证
- 成本优化的Singleton模式
🔌 MCP协议集成
- 一流的支持 模型上下文协议
- HTTP、SSE和Stdio传输支持
- 小说 MCP电桥 沙盒架构↔MCP通信
- 参数归一化和响应变换
📈 实时效率指标
- 代币节省明细(中间、上下文、开销、决策)
- 执行时间跟踪
- UI中显示视觉指标
- 每次执行成本分析
🛡️ 防御性运行时助手
用于处理不可预测的MCP响应的内置实用程序:
toArray(value) // Safe array conversion
safeGet(obj, 'path') // Safe nested property access
safeMap(value, fn) // Safe iteration
isSuccess(response) // Check MCP response success
extractText(response) // Extract string output
getCommandOutput(resp) // Parse command results______________________________________________________________________
🚀 入门指南
先决条件
- Node.js 18+
- Vercel帐户(用于沙盒)
- 至少一个人工智能提供商API密钥
安装
选项1:使用已发布的软件包(推荐)
安装已发布的npm包:
npm install @task-orchestrator/programmatic-tools对等依赖关系 (必填):
npm install ai@^5.0.0 @vercel/sandbox@^1.0.0 zod@^3.0.0 ms@^2.1.0可选依赖关系 (用于MCP支持):
npm install @ai-sdk/mcp@^0.0.11选项2:克隆和开发
# Clone the repository
git clone https://github.com/your-repo/vercel-ptc-next.git
cd vercel-ptc-next
# Install dependencies
npm install
# Set up environment variables
cp .env.example .env环境配置
# Required: At least one AI provider
ANTHROPIC_API_KEY=sk-ant-...
# OR
OPENAI_API_KEY=sk-...
# Optional: Vercel AI Gateway (100+ models)
AI_GATEWAY_API_KEY=your_gateway_api_key
# Vercel Sandbox (run `vercel link` or set token)
VERCEL_TOKEN=your_vercel_token运行开发服务器
npm run dev
# Open http://localhost:3000______________________________________________________________________
📖 用法
在项目中使用该包
基本设置
import { streamText } from 'ai';
import { withProgrammaticCalling } from '@task-orchestrator/programmatic-tools';
import { tool } from 'ai';
import { z } from 'zod';
// Define your tools
const myTools = {
getUser: tool({
description: 'Get user by ID',
inputSchema: z.object({ id: z.string() }),
execute: async ({ id }) => ({ id, name: `User ${id}`, score: Math.random() * 100 }),
}),
calculateAverage: tool({
description: 'Calculate average of numbers',
inputSchema: z.object({ numbers: z.array(z.number()) }),
execute: async ({ numbers }) => ({
average: numbers.reduce((a, b) => a + b, 0) / numbers.length
}),
}),
};
// Wrap tools for programmatic calling
const { tools } = withProgrammaticCalling(myTools);
// Use with streamText or generateText
const result = await streamText({
model: yourModel,
tools,
messages: [{
role: 'user',
content: 'Get users 1, 2, 3 and calculate their average score'
}],
});与MCP集成
import { withProgrammaticCalling } from '@task-orchestrator/programmatic-tools';
import { createMCPManager } from '@task-orchestrator/programmatic-tools/mcp';
// Initialize MCP servers
const mcpManager = createMCPManager({
servers: [
{
name: 'firecrawl',
type: 'http',
url: 'https://mcp.firecrawl.dev/your-key/v2/mcp',
},
],
});
await mcpManager.initialize();
const mcpTools = mcpManager.getTools();
// Combine with your local tools
const allTools = { ...myTools, ...mcpTools };
// Wrap for programmatic calling
const { tools } = withProgrammaticCalling(allTools);使用上下文管理(令牌优化)
import { ContextManager, withContextManagement } from '@task-orchestrator/programmatic-tools';
const contextManager = new ContextManager();
const result = await streamText({
model,
tools,
messages,
...withContextManagement({
contextManager,
onStepFinish: (step) => {
// Your custom step handling
},
}),
});
// Get token savings
const tokensSaved = contextManager.getTokensSaved();
console.log(`Saved ${tokensSaved.totalSaved} tokens`);使用演示应用程序
如果你已经克隆了存储库,你可以运行完整的演示:
基本聊天
- 从下拉列表中选择您的型号(⌘K打开)
- 键入需要多个操作的提示
- 观看PTC生成代码并高效执行
示例提示
"Get 5 users and calculate their average score"
→ Generates Promise.all() with 5 getUser calls + calculation
"Scrape 3 URLs and summarize their content"
→ Parallel mcp_firecrawl_scrape calls + aggregation
"Find top products on ProductHunt today"
→ MCP scraping with filtering and formatting调试面板
点击“调试”查看:
- 生成的代码
- 单个工具调用结果
- 代币储蓄明细
- 执行时间表
______________________________________________________________________
🔌 MCP服务器配置
通过配置文件(推荐)
编辑 lib/mcp/mcp-config.ts:
export const mcpServers: MCPServerConfig[] = [
// HTTP transport
{
name: "Firecrawl MCP",
type: "http",
url: "https://mcp.firecrawl.dev/your-key/v2/mcp"
},
// Stdio transport (local process)
{
name: "GitHub MCP",
type: "stdio",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-github"]
},
// SSE transport
{
name: "Streaming MCP",
type: "sse",
url: "https://example.com/sse"
}
];
export const enableMCP: boolean = true;MCP桥:工作原理
MCP桥使沙盒代码能够调用外部MCP工具:
┌─────────────────────────────────────────────────────────────┐
│ Vercel Sandbox │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ // LLM-generated code │ │
│ │ const results = await Promise.all([ │ │
│ │ mcp_firecrawl_scrape({ url: '...' }), │ │
│ │ mcp_firecrawl_scrape({ url: '...' }) │ │
│ │ ]); │ │
│ │ │ │
│ │ // Writes to /tmp/mcp_call_*.json │ │
│ │ // Polls /tmp/mcp_result_*.json │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Main Process (Bridge Monitor) │
│ - Watches for MCP request files │
│ - Routes to real MCP client (HTTP/SSE/Stdio) │
│ - Normalizes responses │
│ - Writes results back to sandbox filesystem │
└─────────────────────────────────────────────────────────────┘______________________________________________________________________
📁 项目结构
vercel-ptc-next/
├── app/
│ ├── api/
│ │ ├── chat/route.ts # Main chat endpoint with PTC
│ │ ├── mcp/route.ts # MCP server management
│ │ └── models/route.ts # Gateway model discovery
│ ├── layout.tsx
│ ├── page.tsx
│ └── globals.css
├── components/
│ ├── ChatInterface.tsx # Main UI with AI Elements
│ ├── DebugPanel.tsx # Tool call inspection
│ ├── EfficiencyMetrics.tsx # Token savings display
│ ├── MCPServerManager.tsx # MCP configuration UI
│ └── ai-elements/ # Modular AI UI components
│ ├── conversation.tsx
│ ├── message.tsx
│ ├── tool.tsx
│ ├── code-block.tsx
│ ├── chain-of-thought.tsx
│ └── ...
├── lib/
│ ├── tool-wrapper.ts # 🔑 Core PTC implementation
│ ├── sandbox.ts # Vercel Sandbox orchestration
│ ├── mcp-bridge.ts # MCP ↔ Sandbox communication
│ ├── mcp/
│ │ ├── client.ts # MCP client implementation
│ │ ├── adapter.ts # MCP → AI SDK conversion
│ │ ├── manager.ts # Multi-server management
│ │ └── mcp-config.ts # Server configuration
│ ├── providers.ts # AI provider factory
│ ├── tools.ts # Example tool definitions
│ └── context-manager.ts # Token optimization
└── types/
└── chat.ts # TypeScript definitions______________________________________________________________________
💰 成本分析
Vercel沙盒定价
| 度量 | 费率 | 免费等级(爱好) |
|---|---|---|
| 活动CPU时间 | 0.128美元/小时 | 5小时/月 |
| 预留内存 | 0.0106美元/GB小时 | 420 GB小时 |
| 网络带宽 | 0.15美元/GB | 20 GB |
| 沙盒创意 | 60美元/百万 | 5000 |
每次执行成本(2 vCPU,4GB RAM)
| 场景 | 持续时间 | 估计。成本 |
|---|---|---|
| 快速(3-5个工具) | 10秒 | ~0.0004美元 |
| 中等(5-10个工具) | 30秒 | ~0.001美元 |
| 重型(MCP重型) | 2分钟 | ~0.003美元 |
投资回报分析
| 度量 | 传统(10种工具) | PTC |
|---|---|---|
| 法学硕士往返 | 10 | 2 |
| 上下文标记 | ~70000 | ~14000 |
| LLM成本(GPT-4) | 0.70-2.10美元 | 0.14-0.42美元 |
| 沙盒成本 | 0美元 | ~0.002美元 |
| 净储蓄 | - | $0.50-$1.70 |
结果:约0.002美元的沙盒管理费用为每个复杂工作流程节省了0.50-1.70美元的LLM成本。
______________________________________________________________________
🔮 代币储蓄是如何计算的
PTC追踪四类节省:
{
// 1. Intermediate Results (never sent to LLM)
intermediateResultTokens: 12500,
// 2. Context Re-sends (base context × N-1 calls avoided)
roundTripContextTokens: 35000,
// 3. Tool Call Overhead (JSON structure per call)
toolCallOverheadTokens: 400,
// 4. LLM Decision Outputs (reasoning per step avoided)
llmDecisionTokens: 720,
// Total
totalSaved: 48620
}______________________________________________________________________
🛠️ 扩展PTC
添加本地工具
使用该软件包时:
import { tool } from 'ai';
import { z } from 'zod';
const myTools = {
myCustomTool: tool({
description: 'Description for LLM',
inputSchema: z.object({
param: z.string().describe('Parameter description'),
}),
execute: async ({ param }) => {
// Your implementation
return { result: '...' };
},
}),
};
const { tools } = withProgrammaticCalling(myTools);在本地开发时(在这个仓库中):
// lib/tools.ts
export const tools = {
myCustomTool: tool({
description: 'Description for LLM',
inputSchema: z.object({
param: z.string().describe('Parameter description'),
}),
execute: async ({ param }) => {
// Your implementation
return { result: '...' };
},
}),
};添加MCP服务器
使用该软件包时:
import { createMCPManager } from '@task-orchestrator/programmatic-tools/mcp';
const mcpManager = createMCPManager({
servers: [
{
name: "Your MCP Server",
type: "http",
url: "https://your-mcp-server.com/mcp"
},
],
});在本地开发时(在这个仓库中):
// lib/mcp/mcp-config.ts
export const mcpServers: MCPServerConfig[] = [
{
name: "Your MCP Server",
type: "http",
url: "https://your-mcp-server.com/mcp"
},
];______________________________________________________________________
🧪 发展
# Run development server
npm run dev
# Type checking
npm run build
# Linting
npm run lint______________________________________________________________________
📦 包裹信息
核心功能以npm包的形式提供:
包裹: @task-orchestrator/programmatic-tools
安装:
npm install @task-orchestrator/programmatic-tools文档: 请参阅 包README API的详细文档。
特征:
- ✅ 具有代码生成功能的程序化工具调用
- ✅ MCP(模型上下文协议)集成
- ✅ 令牌优化的上下文管理
- ✅ 效率指标跟踪
- ✅ 防御性辅助函数,实现稳健执行
📚 资源
- 包文档 -API详细参考
- -在项目中安装和使用
- Vercel AI SDK文档
- 模型上下文协议规范
- Vercel沙盒文档
- Vercel沙盒定价
- MCP服务器示例
______________________________________________________________________
🤝 贡献
欢迎投稿!这是一种新颖的模式,有以下空间:
- 其他MCP服务器集成
- 性能优化
- 新的防御辅助功能
- 特定于提供商的优化
- UI/UX改进
______________________________________________________________________
📄 许可证
麻省理工学院
______________________________________________________________________
Built with ❤️ using Vercel AI SDK, Vercel Sandbox, and MCP
First-of-its-kind LLM optimization for the modern AI stack
