工具執行器
AI 代理可以在伺服器端呼叫的自訂函式。
工具是 AI Agent 可以呼叫的自訂函式。它們定義在伺服器端,傳入 createAgentHandler。
兩種風格
1. 簡單函式
簡單風格
toolExecutors: {
weather: async (params, context) => {
const res = await fetch(`https://api.weather.com?city=${params.city}`);
return { success: true, result: await res.json() };
},
}2. 完整設定(推薦)
包含 metadata 用於 prompt 生成 — SDK 使用 description、whenToUse 和 schema 來告訴 LLM 何時以及如何呼叫工具。
完整設定風格
toolExecutors: {
product_search: {
description: '搜尋商品資料庫',
whenToUse: '當用戶想要尋找商品、比較商品或詢問特定商品時',
schema: {
query: { type: 'string', required: true, description: '搜尋關鍵字(1-3 個詞)' },
topK: { type: 'number', required: false, default: 10, description: '回傳數量' },
},
output: '包含 title、price、imageUrl、description 的商品陣列',
execute: async (params, context) => {
// context.userId — 已驗證的用戶
// context.sessionId — 當前 session
const res = await fetch('https://your-api.com/products/search', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ...params, userId: context?.userId }),
});
return await res.json();
},
},
}型別定義
型別
/** 簡單函式風格 */
type ToolExecutorFunction = (
params: any,
context?: SessionContext
) => Promise<ToolResult>;
/** 完整設定風格 */
interface ToolExecutorConfig {
execute: ToolExecutorFunction;
description?: string;
whenToUse?: string;
schema?: Record<string, {
type: string;
required?: boolean;
default?: any;
description?: string;
}>;
output?: string;
}
/** 傳入每個執行器的 context */
interface SessionContext {
sessionId: string;
userId: string;
currentUrl: string;
currentPage: PageState | null;
}
/** 工具回傳值 */
interface ToolResult {
success: boolean;
result?: any;
error?: string;
}工具優先順序
SDK 按以下順序解析工具:
優先順序
1. 手動 toolExecutors(傳入 createAgentHandler) ← 最高優先
2. CUSTOMER 模式(在 Lens OS 後台設定)
3. PLATFORM 模式(SDK 內建工具) ← 最低優先- 手動 toolExecutors — 在你的專案中以程式碼定義(最高優先)
- CUSTOMER 模式 — 透過 Lens OS 儀表板設定的外部端點
- PLATFORM 模式 — SDK 內建實作(最低優先)
組織工具執行器
當專案有多個工具時,建議抽出到獨立檔案:
src/lib/tools.ts
import type { ToolExecutorConfig, SessionContext } from '@lens-os/sdk';
export function buildToolExecutors(): Record<string, ToolExecutorConfig> {
return {
product_search: {
description: '搜尋商品',
schema: { query: { type: 'string', required: true } },
execute: async (params) => {
const res = await fetch('/api/products/search', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(params),
});
return await res.json();
},
},
user_orders: {
description: '查詢用戶訂單',
schema: {
action: { type: 'string', required: true, description: '"get" | "update"' },
orderId: { type: 'string', required: false },
},
execute: async (params, context?: SessionContext) => {
const res = await fetch('/api/orders', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ...params, userId: context?.userId }),
});
return await res.json();
},
},
};
}src/app/api/agent/chat/route.ts
import { createAgentHandler } from '@lens-os/sdk/server';
import { buildToolExecutors } from '@/lib/tools';
export const handler = createAgentHandler({
apiKey: process.env.LENS_API_KEY!,
openaiKey: process.env.OPENAI_API_KEY!,
toolExecutors: buildToolExecutors(),
});
export const { POST } = handler;Tip
你提供的 metadata 越多(
description、whenToUse、schema、output), LLM 就越知道何時以及如何使用工具。