工具开发

创建自定义工具来扩展 Gemini CLI 的功能。学习如何设计、实现、测试和部署与 AI 对话无缝集成的工具。

开发流程

创建自定义工具的分步指南

1

定义工具接口

创建包含参数和描述的工具定义

示例:

const toolDefinition = {
  name: 'calculate_age',
  description: 'Calculate age based on birth date',
  parameters: {
    type: 'object',
    properties: {
      birthDate: {
        type: 'string',
        format: 'date',
        description: 'Birth date in YYYY-MM-DD format'
      },
      currentDate: {
        type: 'string',
        format: 'date',
        description: 'Current date (optional, defaults to today)'
      }
    },
    required: ['birthDate']
  }
};
2

实现工具逻辑

编写执行工具任务的执行函数

示例:

const executeFunction = async ({ birthDate, currentDate }) => {
  try {
    const birth = new Date(birthDate);
    const current = currentDate ? new Date(currentDate) : new Date();
    
    if (birth > current) {
      throw new Error('Birth date cannot be in the future');
    }
    
    const ageMs = current.getTime() - birth.getTime();
    const ageYears = Math.floor(ageMs / (1000 * 60 * 60 * 24 * 365.25));
    
    return `Age: ${ageYears} years old`;
  } catch (error) {
    return `Error: ${error.message}`;
  }
};
3

注册工具

将工具添加到 Gemini CLI 的工具注册表

示例:

import { GeminiCLI } from '@google/generative-ai-cli';

const cli = new GeminiCLI();

// Create complete tool
const ageTool = {
  ...toolDefinition,
  execute: executeFunction
};

// Register the tool
cli.registerTool(ageTool);

// Verify registration
console.log('Registered tools:', cli.listTools().map(t => t.name));
4

测试工具

测试您的工具以确保其正常工作

示例:

// Test the tool directly
const result = await cli.executeTool('calculate_age', {
  birthDate: '1990-05-15'
});
console.log(result); // "Age: 34 years old"

// Test with AI
const response = await cli.ask(
  "How old would someone born on May 15, 1990 be today?",
  { tools: ['calculate_age'] }
);

工具模板

使用此模板快速开始您的自定义工具开发

基础工具模板

复制此模板并根据您的需求进行修改。确保更新名称、描述、参数和执行逻辑。

import { Tool, ToolDefinition } from '@google/generative-ai-cli';

export const myCustomTool: ToolDefinition = {
  name: 'my_custom_tool',
  description: 'Description of what this tool does',
  parameters: {
    type: 'object',
    properties: {
      // Define your parameters here
      input: {
        type: 'string',
        description: 'Input parameter description'
      }
    },
    required: ['input']
  },
  execute: async (params) => {
    try {
      // Your tool logic here
      const { input } = params;
      
      // Process the input
      const result = processInput(input);
      
      // Return the result
      return result;
    } catch (error) {
      // Handle errors gracefully
      return `Error: ${error.message}`;
    }
  }
};

function processInput(input: string): string {
  // Your processing logic
  return `Processed: ${input}`;
}

最佳实践

遵循这些指导原则创建高质量、可靠的工具

工具设计

  • 保持工具专注于单一职责
  • 使用清晰、描述性的名称和描述
  • 定义全面的参数模式
  • 在参数描述中包含示例
  • 优雅地处理边缘情况

错误处理

  • 始终在 try-catch 块中包装执行
  • 返回有意义的错误消息
  • 验证输入参数
  • 处理网络超时和失败
  • 记录错误以便调试

性能

  • 正确实现异步操作
  • 为长时间操作添加超时处理
  • 在适当时缓存结果
  • 最小化外部依赖
  • 对大响应使用流式传输

安全

  • 验证和清理所有输入
  • 避免执行任意代码
  • 限制文件系统访问
  • 使用安全的 API 端点
  • 小心处理敏感数据

测试您的工具

确保您的工具在部署前正常工作

单元测试

// 直接测试工具执行
import { myCustomTool } from './my-tool';

describe('myCustomTool', () => {
  test('应该正确处理输入', async () => {
    const result = await myCustomTool.execute({
      input: 'test data'
    });

    expect(result).toBe('已处理: test data');
  });

  test('应该优雅地处理错误', async () => {
    const result = await myCustomTool.execute({
      input: null
    });

    expect(result).toMatch(/错误:/);
  });
});

集成测试

// 使用 Gemini CLI 测试工具
import { GeminiCLI } from '@google/generative-ai-cli';

const cli = new GeminiCLI();
cli.registerTool(myCustomTool);

// 测试工具注册
const tools = cli.listTools();
expect(tools.find(t => t.name === 'my_custom_tool')).toBeDefined();

// 测试工具执行
const result = await cli.executeTool('my_custom_tool', {
  input: 'test'
});
expect(result).toBeDefined();

测试和调试

确保您的工具可靠运行的技巧

测试策略

  • 单独测试工具函数
  • 使用各种输入参数进行测试
  • 测试错误条件和边缘情况
  • 验证与 AI 的集成

调试技巧

  • 添加详细的日志记录
  • 使用 console.log 进行调试
  • 检查参数验证
  • 监控性能指标

常见工具模式

不同类型工具的可重用模式

API 集成工具

与外部 API 集成的工具模式

const apiTool = {
  name: 'api_call',
  description: '调用外部服务的 API',
  parameters: {
    type: 'object',
    properties: {
      endpoint: { type: 'string', description: 'API 端点 URL' },
      method: { type: 'string', enum: ['GET', 'POST'], default: 'GET' },
      data: { type: 'object', description: '请求负载' }
    },
    required: ['endpoint']
  },
  execute: async ({ endpoint, method = 'GET', data }) => {
    try {
      const response = await fetch(endpoint, {
        method,
        headers: { 'Content-Type': 'application/json' },
        body: data ? JSON.stringify(data) : undefined
      });

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }

      return await response.json();
    } catch (error) {
      return `API 错误: ${error.message}`;
    }
  }
};

数据处理工具

处理和转换数据的工具模式

const processingTool = {
  name: 'data_processor',
  description: '处理和转换数据',
  parameters: {
    type: 'object',
    properties: {
      data: { type: 'array', description: '要处理的数据' },
      operation: {
        type: 'string',
        enum: ['sort', 'filter', 'map', 'reduce'],
        description: '要执行的操作'
      },
      criteria: { type: 'string', description: '处理条件' }
    },
    required: ['data', 'operation']
  },
  execute: async ({ data, operation, criteria }) => {
    try {
      switch (operation) {
        case 'sort':
          return data.sort();
        case 'filter':
          return data.filter(item => item.includes(criteria));
        case 'map':
          return data.map(item => `${criteria}: ${item}`);
        case 'reduce':
          return data.reduce((acc, item) => acc + item, '');
        default:
          throw new Error(`未知操作: ${operation}`);
      }
    } catch (error) {
      return `处理错误: ${error.message}`;
    }
  }
};

相关资源

深入了解工具开发和 API 集成