Go Microを使用したAIエージェントCLIの構築
AIエージェントのCLIは、ツール発見、モデル統合、会話メモリ、および実行ループという4つのコアコンポーネントに焦点を当てることで、およそ150行のコードで実装できます。このアプローチでは、ユーザーのリクエストを特定のサービスにルーティングするための手動の「if-then」ロジックを必要とせず、代わりに大規模言語モデル(LLM)が提供された説明に基づいてどのツールを呼び出すべきかを判断するようにします。
ツール呼び出しエージェントの4つのコンポーネント
機能的なAIエージェントを構築するには、3つの主要な問題を解決する必要があります。LLMに利用可能なツールのリストを提供すること、リクエストされたときにそれらのツールを実行すること、および会話メモリを通じてコンテキストを維持することです。
1. ツール発見
LLMは、どの関数が呼び出し可能であるかを知っておく必要があります。Go Microフレームワークでは、サービスはリクエストタイプやフィールドのメタデータを含むリクエストをレジストリに登録します。これにより、エージェントは、各ツールが名前、説明(ハンドラーのdocコメントから派生)、およびパラメータスキーマ(リクエスト構造体のフィールドから派生)を含むツールリストを自動的に生成できるようになります。
Go Microを使用していない場合は、このステップではエンドポイントを個別に列挙し、LLM用の {name, description, parameters} のリストを構築する必要があります。
2. モデル統合と実行
LLMを統合するには、プロバイダーに依存しないインターフェースが必要です。統一された ai.Model インターフェースを使用することで、開発者は単一の文字列を変更するだけで、Anthropic、OpenAI、Gemini、Groq、Mistral、Together、または Atlas Cloud のようなプロバイダーを切り替えることができます。
実行は、ツールリストをモデルに接続することで処理されます。モデルが特定のツール(例: users_Users_Create)を呼び出すと決定した場合、ハンドラーはリクエストを適切なRPCにルーティングし、結果をモデルに返します。
3. 会話メモリ
フォローアップの質問をサポートするために、エージェントにはメッセージ蓄積器が必要です。単純な History オブジェクト(Add、Messages、および Reset メソッドを持つメッセージのスライス)が、ユーザーのプロンプトとアシスタントの返答を追跡します。この蓄積された履歴は、コンテキストを維持するために、その後のすべての呼び出しでLLMに渡されます。
4. 実行ループ
エージェントのコアロジックは、以下のシーケンスを実行するループです:
- プロンプトを記録する: ユーザーの入力は履歴に追加されます。
- モデルを呼び出す: プロンプト、システム指示、ツールリスト、および会話履歴がLLMに送信されます。
- 返答を処理する: アシスタントの最初の返答は表示され、履歴に記録されます。
- ツールを実行する: モデルはどのツールを呼び出すべきかを決定します。ハンドラーはそれらを実行し、結果が報告されます。
- 最終的な回答: モデルはツールの出力に基づいて最終的な回答を生成し、それが表示され、記録されます。
実装が簡潔である理由
実装の簡潔さは、3つのアーキテクチャ上の選択によって実現されています:
- 自己記述型サービス: コード内のdocコメントや
@exampleタグを使用することで、LLMは開発者が個別にツールスキーマを記述することなく、使用方法のヒントを受け取ることができます。 - 統一されたプロバイダーインターフェース: 複数のLLMプロバイダーのための単一のインターフェースは、プロバイダー固有の結合コードの必要性を排除します。
- 自動実行配線: ツール呼び出しとRPCディスパッチの接続は、
ai.WithTools(tools)を介して自動的に処理されるため、手動のルーティングロジックは不要です。
AIエージェントの拡張
基本的なループが確立されたら、エージェントはいくつかの強化機能で拡張できます:
- 安全性: 破壊的なツール呼び出しの前に確認ステップを追加する。
- Observability: 監査トレイルにすべてのツール呼び出しをログ出力する。
- Observability: ツールリストをフィルタリングして、エージェントのアクセスを特定のサービスに制限する。
- Interface: REPL (Read-Eval-Print Loop) を Slack bot や
micro flowを介したイベント駆動型トリガーに置き換える。