はじめに
今回、AI Agentを支える技術であるFunction CallingをローカルLLMから実装するために行った試行錯誤の記録をこちらで記載します。
Function Callingとは
Function Callingとは、AI(LLM)が外部のツール・API・関数などを「自ら判断して呼び出して使う」機構のことです。
例えばLangChainなどのフレームワークでは、ユーザの入力に応じて「検索エンジン」「計算関数」「データベース」「Pythonコード」などをツールとして登録しておき、AIがどのツールを使うべきかを考え、適切なツールの引数を生成 → 実行 → 結果を取り込み回答を生成する…という一連の流れを自動化できます。
今回の実現したいこと
ターミナルなどのCLIツールからプログラムに関するプロンプト(「/tmpフォルダ配下にHello Worldと出力するPythonファイルを作成して」など)を入力することで指定されたディレクトリ階層に指定したプログラムファイルを作成する。
使用環境
- PCスペック
- os: MacOS
- チップ:Apple M2
- メモリ:16 GB
- 使用モデル: phi-3, qwen2.5-coder, llama, gpt-oss:20B
- 使用ツール: ollama
- 使用言語: Python
- 使用ライブラリ/フレームワーク: Transformers, LangChain, LangGraph
今回使用したコード
今回使用したコードはGitHubでも公開させていただいております。
ご興味いただける方は以下のリンクからご確認いただけますと幸いです。
試行錯誤の記録
1. LLMの導入と立ち上げ
今回のプロジェクトでは、まずローカル環境で動作可能な複数のLLMモデルを検証しました。
検討したモデルはphi-3、qwen2.5-coder、llama、そしてgpt-oss:20Bです。
各モデルの導入はollamaを使い、MacOS上で問題なく起動できるか、パフォーマンスや応答の質を確認しました。
モデルによって応答の安定性やツール呼び出しへの適応度に差があり、立ち上げ初期から挙動の違いが見られました。
2. Function Callingに必要な設計を調査
LLMが外部ツールを適切に呼び出すためには、ツールのインターフェース設計や呼び出しルールの明確化が不可欠です。
LangChainやLangGraphのドキュメントを読み込み、どのようにLLMにツールを認識・利用させるかを学びました。
特に、ツール呼び出しの状態管理や、無限ループに陥らないように終了条件をどう設定するかが重要なポイントでした。
また、ツール実行結果をどのようにLLMに返すか、双方向のやり取り設計も念入りに検討しました。
3. 実装
設計を踏まえて、ファイル書き込み・ディレクトリ作成・Git操作のツールをPythonで実装し、@toolデコレータでLangChainツールとしてラップしました。
LLMにはChatOllamaを用いてツールバインドし、StateGraphで状態遷移を管理する自律型Agentを構築。
また、プロンプトに「完了したら’TERMINATE’と返す」という終了合図を明示することで、処理の自動終了を実装しました。
4. 動いた瞬間
初期は複数モデルでツール呼び出しが不安定だったり、ループが止まらなかったりしましたが、gpt-oss:20Bを用いたところ、ツール呼び出しが安定し、
指定したファイル作成やgit操作を自律的に完遂できる動作を確認できました。
LLMが明確に終了指示を出すため無限ループ問題も解消し、ようやくCLI上で実用的に動作するAI Agentが完成した瞬間でした。
苦労したポイントまとめ
- ローカルLLMごとにツール呼び出しの認識精度や動作の安定度に差があったこと。
- 無限ループや状態遷移の制御が難しく、終了条件の設計に試行錯誤したこと。
- ツールの引数形式(JSON文字列など)とLLMからの応答形式の整合性を取る部分。
終わりに
本プロジェクトを通じて、ローカルLLMによるFunction Callingの実装の難しさと可能性を実感しました。
特にgpt-ossモデルの安定動作は大きな成果であり、今後の開発の基盤となると確信しています。
この記事が同じ挑戦をする方の参考になれば幸いです。