簡介
人工智慧代理需要與外界互動的工具-網路搜尋、資料庫查詢、程式碼執行。工具註冊表管理所有工具的生命週期:註冊、驗證、執行和安全。
1.ToolHandler介面
// packages/core/src/tools/types.ts
export type ToolHandler = (
args: Record<string, unknown>,
context: ToolContext,
) => Promise<unknown>;
export interface ToolContext {
tenantId: string;
userId: string;
sessionId: string;
abortSignal?: AbortSignal;
}
工具處理程序是接收參數+上下文並傳回任何結果的函數。
2. 工具註冊表實現
// packages/core/src/tools/tool-registry.ts
export class ToolRegistry {
private tools = new Map<string, {
definition: ToolDefinition;
handler: ToolHandler;
}>();
register(definition: ToolDefinition, handler: ToolHandler) {
if (this.tools.has(definition.name)) {
throw new Error(`Tool "${definition.name}" already registered`);
}
this.tools.set(definition.name, { definition, handler });
}
unregister(name: string) {
this.tools.delete(name);
}
getDefinitions(): ToolDefinition[] {
return Array.from(this.tools.values()).map(t => t.definition);
}
async execute(
name: string,
args: Record<string, unknown>,
context: ToolContext,
): Promise<ToolResult> {
const tool = this.tools.get(name);
if (!tool) {
return {
toolCallId: '',
success: false,
result: null,
error: `Unknown tool: ${name}`,
duration: 0,
};
}
const start = performance.now();
try {
const result = await tool.handler(args, context);
return {
toolCallId: '',
success: true,
result,
duration: performance.now() - start,
};
} catch (error) {
return {
toolCallId: '',
success: false,
result: null,
error: error instanceof Error ? error.message : String(error),
duration: performance.now() - start,
};
}
}
// Execute all tool calls from LLM response
async executeAll(
toolCalls: ToolCall[],
context: ToolContext,
): Promise<ToolResult[]> {
return Promise.all(
toolCalls.map(async (call) => {
const result = await this.execute(call.name, call.arguments, context);
return { ...result, toolCallId: call.id };
}),
);
}
}
3.內建工具
// packages/core/src/tools/builtin/web-search.ts
export const webSearchTool: ToolDefinition = {
name: 'web_search',
description: 'Search the web for current information',
parameters: {
type: 'object',
properties: {
query: { type: 'string', description: 'Search query' },
maxResults: { type: 'number', description: 'Max results (1-10)' },
},
required: ['query'],
},
};
export const webSearchHandler: ToolHandler = async (args) => {
const { query, maxResults = 5 } = args as { query: string; maxResults?: number };
const results = await fetch(`https://api.search.example/search?q=${encodeURIComponent(query)}&limit=${maxResults}`);
return results.json();
};
// packages/core/src/tools/builtin/code-interpreter.ts
export const codeInterpreterTool: ToolDefinition = {
name: 'execute_code',
description: 'Execute JavaScript/TypeScript code in a sandbox',
parameters: {
type: 'object',
properties: {
code: { type: 'string', description: 'Code to execute' },
language: { type: 'string', enum: ['javascript', 'typescript', 'python'] },
},
required: ['code'],
},
sandbox: { required: true },
};
4. 沙盒執行
// packages/core/src/tools/sandbox.ts
import { runInNewContext } from 'node:vm';
export interface SandboxToolExecutor {
execute(code: string): Promise<unknown>;
}
export class VMSandbox implements SandboxToolExecutor {
async execute(code: string): Promise<unknown> {
const context = {
console: { log: (...args: unknown[]) => args },
Math,
JSON,
Date,
// NO access to: fs, process, require, import, fetch
};
return runInNewContext(code, context, {
timeout: 5000, // 5s max
displayErrors: true,
});
}
}
安全原理: 工具標記 sandbox: { required: true } 僅在虛擬機器沙箱中運作 - 無法存取檔案系統、網路或進程。
5. 總結
- ToolHandler — 簡單的功能介面:
(args, context) => Promise<result> - ToolRegistry — 用於註冊/取消註冊/執行的註冊表模式
- 並行執行 —
executeAll()並行運行工具 - 沙箱 — 針對不可信程式碼的基於虛擬機器的隔離
下一篇: 建築代理類-平台的協調中心。