工具开发
工具是场景的核心能力,定义了 AI 可以执行的操作。
工具定义
typescript
interface ScenarioToolDefinition {
/** 工具名称(唯一标识) */
name: string
/** 工具定义 */
definition: {
name: string
description: string
descriptionZh?: string
parameters: {
type: string
properties: Record<string, ToolParameter>
required?: string[]
}
}
/** 工具执行器 */
executor: ToolExecutor
}参数定义
typescript
interface ToolParameter {
type: 'string' | 'number' | 'boolean' | 'array' | 'object'
description: string
descriptionZh?: string
required?: boolean
default?: unknown
enum?: string[]
items?: ToolParameter // 用于 array 类型
properties?: Record<string, ToolParameter> // 用于 object 类型
}执行器
typescript
type ToolExecutor = (
args: Record<string, unknown>,
context: ToolExecutionContext,
) => Promise<ToolExecutionResult>
interface ToolExecutionContext {
scenarioId: string
workspacePath: string
logger: ScenarioLogger
publishData: (channel: string, data: unknown) => void
getSharedData: (key: string) => unknown
querySql: (query: string) => Promise<ScenarioSqlResult>
}
interface ToolExecutionResult {
success: boolean
data?: unknown
error?: string
}开发示例
简单工具
typescript
{
name: 'get_current_time',
definition: {
name: 'get_current_time',
description: '获取当前时间',
descriptionZh: '获取当前系统时间',
parameters: {
type: 'object',
properties: {
timezone: {
type: 'string',
description: '时区',
descriptionZh: '时区,如 Asia/Shanghai',
default: 'Asia/Shanghai',
},
format: {
type: 'string',
description: '时间格式',
descriptionZh: '时间格式',
enum: ['iso', 'readable', 'timestamp'],
default: 'readable',
},
},
},
},
executor: async (args) => {
const now = new Date()
const { format } = args
switch (format) {
case 'iso':
return { success: true, data: now.toISOString() }
case 'timestamp':
return { success: true, data: now.getTime() }
default:
return { success: true, data: now.toLocaleString('zh-CN') }
}
},
}数据库操作工具
typescript
{
name: 'query_tasks',
definition: {
name: 'query_tasks',
description: '查询任务列表',
descriptionZh: '查询任务列表',
parameters: {
type: 'object',
properties: {
status: {
type: 'string',
description: '按状态筛选',
descriptionZh: '按状态筛选',
enum: ['pending', 'in_progress', 'completed'],
},
limit: {
type: 'number',
description: '最大结果数',
descriptionZh: '最大返回数量',
default: 20,
},
},
},
},
executor: async (args, context) => {
try {
const { status, limit = 20 } = args
let query = 'SELECT * FROM tasks'
const conditions: string[] = []
if (status) {
conditions.push(`status = '${status}'`)
}
if (conditions.length > 0) {
query += ' WHERE ' + conditions.join(' AND ')
}
query += ` ORDER BY created_at DESC LIMIT ${limit}`
const result = await context.querySql(query)
return {
success: true,
data: result.data,
total: result.data.length,
}
} catch (error) {
context.logger.error('查询任务失败', error)
return {
success: false,
error: `查询失败: ${error instanceof Error ? error.message : '未知错误'}`,
}
}
},
}外部 API 调用工具
typescript
{
name: 'fetch_news',
definition: {
name: 'fetch_news',
description: '获取最新新闻',
descriptionZh: '获取最新新闻',
parameters: {
type: 'object',
properties: {
category: {
type: 'string',
description: '新闻分类',
descriptionZh: '新闻分类',
enum: ['technology', 'business', 'science', 'health'],
},
count: {
type: 'number',
description: '新闻数量',
descriptionZh: '获取数量',
default: 5,
},
},
required: ['category'],
},
},
executor: async (args, context) => {
try {
const { category, count = 5 } = args
const response = await fetch(
`https://api.example.com/news?category=${category}&limit=${count}`,
{
headers: { 'Authorization': `Bearer ${context.getSharedData('api_key')}` },
},
)
if (!response.ok) {
throw new Error(`HTTP ${response.status}`)
}
const data = await response.json()
return { success: true, data: data.articles }
} catch (error) {
context.logger.error('获取新闻失败', error)
return {
success: false,
error: `获取失败: ${error instanceof Error ? error.message : '未知错误'}`,
}
}
},
}工具注册
工具的 getTools() 返回所有工具定义:
typescript
getTools(): ScenarioToolDefinition[] {
return [
tool1,
tool2,
tool3,
]
}最佳实践
- 命名规范:使用
snake_case,清晰描述功能 - 参数校验:在 executor 内部校验参数
- 错误处理:始终捕获异常,返回有意义的错误
- 日志记录:记录关键操作和错误
- 超时控制:长时间操作设置超时
- 幂等性:尽量保证操作幂等
- 返回结构化数据:便于 AI 理解和处理

