Vercel AI SDKのツール分離設計パターン(静的・動的ツール)
TypeScript
Vercel AI SDK
知識
判断
認証が必要なツールと不要なツールを分離し、実行場所(クライアント/サーバー)を制御する設計
ツール分離の基本構造
typescript
import { tool } from "ai";
import { z } from "zod";
// 静的ツール(認証不要、クライアント実行)
export const staticTools = {
getAccessibilityTree: tool({
description: "画面上の要素一覧を取得",
inputSchema: z.object({}),
execute: async () => {
// クライアント側で実行される
// サーバーには送られない
}
}),
showNotification: tool({
description: "通知を表示",
inputSchema: z.object({
message: z.string()
}),
execute: async ({ message }) => {
// クライアント側のアクション
}
}),
};
// 動的ツール生成関数(認証付き、サーバー実行)
export const createAuthenticatedTool = (authToken: string) =>
tool({
description: "認証が必要なAPI呼び出し",
inputSchema: z.object({
query: z.string()
}),
execute: async ({ query }) => {
const response = await fetch("/api/data", {
headers: { Authorization: `Bearer ${authToken}` }
});
return response.json();
}
});
// すべてのツールを統合
export const createTools = (authToken: string) => ({
...staticTools,
authenticatedTool: createAuthenticatedTool(authToken),
});クライアント側でのツール実行制御
typescript
onToolCall: async ({ toolCall }) => {
// 動的ツールはスキップ(サーバー側で実行済み)
if (toolCall.dynamic) {
return;
}
// 静的ツールのみクライアントで処理
if (toolCall.toolName === "getAccessibilityTree") {
const tree = extractAccessibilityTree();
addToolResult({
toolCallId: toolCall.toolCallId,
tool: "getAccessibilityTree",
output: tree,
});
}
}設計の利点
- 認証トークンの管理が明確
- クライアント/サーバーの責務分離
- セキュリティ向上(センシティブな操作はサーバーのみ)
- ツールの再利用性向上