AI・機械学習

AIエージェントを「使えるもの」にするFunction Callingの仕組みを徹底解説

「AIって文章を生成するのは得意だけど、実際に何かを実行してくれるわけじゃないよね…」

そう感じたことはありませんか?実はその「実行できる」を可能にするのが、今まさに注目されているFunction Calling(ファンクションコーリング)という仕組みなんです。

今回はFunction Callingの基本的な考え方と、Pythonを使った実装例、そしてAIエージェントのアーキテクチャについて、できるだけわかりやすく解説していきます 🚀

Function Callingってそもそも何?

AI agent function calling
AI agent function calling / Photo by Mikhail Nilov via Pexels

ざっくり一言で言うと、「AIが自分でツールを呼び出して、現実世界のアクションを起こせる仕組み」です。

イメージとしては、こんな感じです。

  • 📧 メールを送る
  • 📁 ファイルを確認する
  • 🗃️ データベースに問い合わせる
  • 🐙 GitHubにコードをプッシュする

普通のAIは「メールを送ってください」と言われても、文章を返すだけです。でもFunction Callingを使えば、AIが実際にメール送信の関数を呼び出せるようになります。テキスト生成と「実行」がつながる、それがFunction Callingの本質です 💡

仕組みをシンプルに理解しよう

大まかな流れはこんな感じです。

  1. ユーザーがAIに指示を出す(例:「明日の天気を調べて」)
  2. AIが「この指示にはどのツール(関数)が必要か」を判断する
  3. AIが関数名と引数を JSON 形式で返す
  4. アプリ側がその関数を実際に実行する
  5. 実行結果をAIに渡して、最終的な回答を生成する

ポイントは、AIが直接コードを実行しているわけではないという点です。AIは「何を呼び出せばよいか」を提案し、実行はあくまでアプリ側が担当します。これは意外と重要な設計思想で、セキュリティや制御のしやすさにも関わってきます 💡

Pythonで動かすFunction Callingの基本サンプル

OpenAIのAPIを使った、シンプルな実装例を見てみましょう。今回は「天気を取得する関数」をAIに呼び出させるサンプルです。

import openai
import json

client = openai.OpenAI()

# ── ① 利用可能なツールを定義する ──
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "指定した都市の現在の天気を取得する",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "都市名(例: Tokyo, Osaka)"
                    }
                },
                "required": ["city"]
            }
        }
    }
]

# ── ② 実際の関数(ここではダミー実装)──
def get_weather(city: str) -> str:
    # 本来はWeather APIなどを呼び出す
    return f"{city}の天気: 晴れ、気温23℃"

# ── ③ AIにメッセージを送る ──
messages = [
    {"role": "user", "content": "東京の天気を教えて"}
]

response = client.chat.completions.create(
    model="gpt-4o",
    messages=messages,
    tools=tools,
    tool_choice="auto"  # AIが自動でツール使用を判断
)

# ── ④ AIのレスポンスを確認する ──
response_message = response.choices[0].message
print("AIの判断:", response_message)

# ── ⑤ tool_callsがあれば関数を実行する ──
if response_message.tool_calls:
    for tool_call in response_message.tool_calls:
        func_name = tool_call.function.name
        func_args = json.loads(tool_call.function.arguments)

        # 関数名に応じて実行
        if func_name == "get_weather":
            result = get_weather(**func_args)

        # ── ⑥ 実行結果をAIに渡して最終回答を生成 ──
        messages.append(response_message)  # AIの提案を追加
        messages.append({
            "role": "tool",
            "tool_call_id": tool_call.id,
            "content": result
        })

    final_response = client.chat.completions.create(
        model="gpt-4o",
        messages=messages
    )
    print("最終回答:", final_response.choices[0].message.content)

実行すると、AIが「get_weatherを呼ぶべき」と判断し、関数の実行結果を踏まえた自然な回答を返してくれます。

コードの流れを図解でおさらい


上のコードをステップごとに整理すると、こんな流れになっています。

  • ① ツール定義:AIに「こんな関数が使えるよ」と教える
  • ② API呼び出し(1回目):AIがツールを使うかどうかを判断する
  • ③ 関数実行:アプリ側で実際に関数を動かす
  • ④ API呼び出し(2回目):関数の結果をAIに渡して最終回答を生成する

「APIを2回呼ぶ」という点が最初は戸惑いやすいポイントです。でも「AIが考える → 人間(アプリ)が動く → AIがまとめる」という流れだと思うと、自然な分業ですよね 😊

複数のツールを使わせるには?

Function Callingの本領発揮は、複数のツールを定義してAIに選ばせるときです。

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "指定した都市の天気を取得する",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string"}
                },
                "required": ["city"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "send_email",
            "description": "指定した宛先にメールを送信する",
            "parameters": {
                "type": "object",
                "properties": {
                    "to": {"type": "string", "description": "宛先メールアドレス"},
                    "subject": {"type": "string", "description": "件名"},
                    "body": {"type": "string", "description": "本文"}
                },
                "required": ["to", "subject", "body"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "search_database",
            "description": "社内データベースからキーワード検索する",
            "parameters": {
                "type": "object",
                "properties": {
                    "keyword": {"type": "string", "description": "検索キーワード"}
                },
                "required": ["keyword"]
            }
        }
    }
]

こうしておくと、ユーザーの指示に応じてAIが「今回はsend_emailが必要だ」「今回はsearch_databaseを使おう」と自動的に判断してくれます。これがAIエージェントの「賢さ」の正体です。

AIエージェントのアーキテクチャとFunction Calling

Function Callingは、AIエージェントを構成する中核の仕組みです。よく使われるアーキテクチャを整理しておきましょう。

ReAct(Reasoning + Acting)パターン

AIが「考える → 行動する → 観察する」を繰り返すループ構造です。

  • Reasoning(推論):次に何をすべきか考える
  • Acting(行動):Function Callingでツールを呼ぶ
  • Observation(観察):結果を受け取って次の判断に活かす

このループを繰り返すことで、複雑なタスクを段階的に解決できます。LangChainやLlamaIndexのエージェントも、基本的にはこのパターンで動いています。

Tool Use(ツール使用)パターン

OpenAIのFunction Callingがまさにこれです。事前に定義したツール群の中から、AIが必要なものを選んで呼び出します。シンプルなタスクには1回のツール呼び出しで済むことも多く、扱いやすいのが特徴です。

実装するときの注意点

Function Callingを実際に使うとき、気をつけたいポイントをまとめます。

① 関数のdescriptionは丁寧に書く

AIはdescriptionを読んで「どの関数を使うか」を決めます。説明が曖昧だと、意図しない関数が呼ばれることがあります。「いつ・何のために使う関数なのか」を明確に書くことがポイントです。

② 実行前に確認ステップを入れる

特にメール送信やファイル削除など、取り消しのできない操作は、AIの判断をそのまま実行するのは危険です。「本当に実行しますか?」という確認ステップを間に挟む設計にしましょう。

③ tool_choiceで制御できる

API呼び出し時に指定できるtool_choiceパラメータで、ツールの使用を制御できます。

  • "auto":AIが自動判断(通常はこれ)
  • "none":ツールを使わない(通常の回答のみ)
  • {"type": "function", "function": {"name": "get_weather"}}:特定の関数を強制的に呼ぶ

④ エラーハンドリングを忘れずに

関数の実行が失敗したとき、そのエラー内容もAIに渡してあげると、AIが「リトライする」「ユーザーに報告する」といった適切な対処を選べるようになります。

try:
    result = get_weather(**func_args)
except Exception as e:
    result = f"エラーが発生しました: {str(e)}"

# エラー内容もそのままAIに渡す
messages.append({
    "role": "tool",
    "tool_call_id": tool_call.id,
    "content": result
})

Function CallingとLangChainの関係


「LangChainのAgentって何が違うの?」と思う方もいるかもしれません。実はLangChainのToolやAgentも、内部的にはFunction Calling(またはそれに近い仕組み)を使っています。LangChainはそこにループ制御・メモリ管理・チェーン構造などを追加したフレームワークだと理解するとスッキリします 🙌

小規模なユースケースならOpenAI APIのFunction Callingを直接使うのがシンプルでおすすめです。複雑なマルチエージェント構成になってきたら、LangChainやLlamaIndexの導入を検討するとよいでしょう。

まとめ

Function Callingについて整理すると、こうなります。

  • ✅ AIにツール(関数)を「提案させる」仕組み
  • ✅ 実際の実行はアプリ側が担当する設計
  • ✅ 複数ツールを定義して、AIに選ばせることができる
  • ✅ ReActパターンと組み合わせることでエージェントが作れる
  • ✅ descriptionを丁寧に書くことが品質のカギ

「AIに文章を作らせる」から「AIに仕事をさせる」へ。Function Callingはその橋渡しをしてくれる、とても重要な技術です。まずは天気取得やメモ保存など、小さなツールを1つ作って試してみるのがおすすめです 🚀

📚 関連商品・おすすめ書籍

スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ)

もしも

スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ)

初心者に定番のPython入門書

Amazonで見る

ELEGOO Arduino用UNO R3スターターキット レベルアップ チュートリアル付 mega2560 r3 nanoと互換 [並行輸入品]

もしも

ELEGOO Arduino用UNO R3スターターキット レベルアップ チュートリアル付 mega2560 r3 nanoと互換 [並行輸入品]

チュートリアル付きのArduino入門セット

Amazonで見る

実践Claude Code入門―現場で活用するためのAIコーディングの思考法

もしも

実践Claude Code入門―現場で活用するためのAIコーディングの思考法

AIコーディングの現場活用法を学ぶ一冊

Amazonで見る

※本記事にはアフィリエイトリンクが含まれます。

ABOUT ME
やまちゃん
これまで学生と社会人を合わせて5000人以上にプログラミング学習を指導。 ゼロからイチをわかりやすく解説する専門家として活動しており、本業ではArduinoを用いたIoT開発とロボットプログラミングが専門。 Pythonを用いたアプリ開発、ウェブアプリケーションの開発で業務の効率化をサポートしています。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です