AIチャットでツールを自動実行するシステムの実装
Go
バックエンド
AI
Gemini
// AIツール管理クラス
type AITools struct {
tools map[string]aitool.Tool
}
// ツールの登録
func NewAITools(memoRepo, categoryRepo, userCategoryRepo, skillSheetRepo) *AITools {
tools := make(map[string]aitool.Tool)
// 各ツールをインスタンス化して登録
memoTool := NewMemoTool(memoRepo)
tools[memoTool.GetDefinition().Name] = memoTool
categoryTool := NewCategoryTool(categoryRepo, userCategoryRepo)
tools[categoryTool.GetDefinition().Name] = categoryTool
skillSheetTool := NewSkillSheetTool(skillSheetRepo)
tools[skillSheetTool.GetDefinition().Name] = skillSheetTool
return &AITools{tools: tools}
}
// ツール定義を取得(AIに渡すため)
func (m *AITools) GetToolDefinitions() []aitool.ToolDefinition {
definitions := make([]aitool.ToolDefinition, 0, len(m.tools))
for _, tool := range m.tools {
definitions = append(definitions, tool.GetDefinition())
}
return definitions
}
// ツールを実行
func (m *AITools) CallTool(ctx context.Context, userID uint, toolName string, args map[string]interface{}) (*aitool.ToolResult, error) {
tool, exists := m.tools[toolName]
if !exists {
return &aitool.ToolResult{
Success: false,
Error: fmt.Sprintf("ツール '%s' が見つかりません", toolName),
}, nil
}
return tool.Execute(ctx, userID, args)
}
// Geminiでツールを使用
func handleGeminiWithTools(ctx context.Context, userID uint, message string, aiToolDefs []aitool.ToolDefinition) {
// ツールをGemini形式に変換
geminiTools := ConvertAIToolsToGemini(aiToolDefs)
// ツール実行関数を定義
toolExecutor := func(ctx context.Context, fc *genai.FunctionCall) (map[string]any, error) {
result, err := aiTools.CallTool(ctx, userID, fc.Name, fc.Args)
if err != nil {
return nil, err
}
if result.Success && result.Data != nil {
return convertToolResultForGemini(result.Data), nil
}
return map[string]any{"error": result.Error}, nil
}
// Gemini APIを呼び出し(ツール実行も含めて自動処理)
response, err := geminiService.ExecuteToolsNonStreaming(
ctx, systemPrompt, message, history, geminiTools, toolExecutor,
)
}