ローカルLLM×Function Calling実践ガイド【2026年版】——Ollama+Qwen 3・Llama 4でDB検索・ファイル操作・API呼び出しを完全オフラインで実行する

  1. はじめに——ローカルLLMが「テキスト生成マシン」から「仕事をするエージェント」に進化した
  2. 前提知識——Function Callingの仕組みを理解する
    1. Function Callingとは何か
    2. Function Callingの処理フロー(4ステップ)
    3. クラウドAPI vs ローカル実行の違い
  3. 対応モデル選定——2026年のFunction Calling対応ローカルLLM
    1. Qwen 3シリーズ(推奨)
    2. Llama 4シリーズ
    3. その他の注目モデル
  4. 【実践編1】環境構築——Ollamaのセットアップとモデル導入
    1. Ollamaのインストール
    2. Function Calling対応モデルの導入
    3. Pythonライブラリの準備
  5. 【実践編2】はじめてのFunction Calling——単一ツール呼び出し
    1. Pythonコード:単一ツール呼び出し
    2. コードのポイント解説
    3. curl(REST API)での実行
  6. 【実践編3】複数ツールとパラレル呼び出し
    1. 複数ツールの定義
    2. パラレルFunction Calling
  7. 【実践編4】実用シナリオ——社内DBの検索エージェント
    1. シナリオ概要
    2. ツール定義のベストプラクティス
    3. temperatureの設定
  8. 【実践編5】マルチステップエージェント——ReActパターンの実装
    1. ReAct(Reasoning + Acting)パターンとは
    2. 実装のポイント
  9. 【実践編6】OpenAI互換APIとフレームワーク連携
    1. OpenAI互換APIでのFunction Calling
    2. LiteLLMとの連携
    3. MCPサーバーとの統合
  10. RAGとFunction Callingの組み合わせ
  11. トラブルシューティング——よくある問題と対処法
    1. 問題1:LLMがツールを呼ばずに自力で回答する
    2. 問題2:パラメータが不正確
    3. 問題3:マルチツール呼び出しで一部が無視される
    4. 問題4:Thinkingモード中にツール呼び出しが中断する
    5. 問題5:応答が遅い
  12. セキュリティと安全性の考慮事項
    1. 許可リスト方式のツール設計
    2. ファイルパスの制限
    3. Human-in-the-Loop
    4. 入力のバリデーション
  13. よくある質問(Q&A)
    1. Q1. Function CallingとRAGの違いは?
    2. Q2. GPUがないとFunction Callingは使えない?
    3. Q3. 日本語でのツール呼び出しは安定している?
    4. Q4. Ollamaのバージョンはどれが必要?
    5. Q5. MCPサーバーとFunction Callingの関係は?
  14. まとめ——ローカルLLMは「話すだけ」から「働く」へ

はじめに——ローカルLLMが「テキスト生成マシン」から「仕事をするエージェント」に進化した

「ローカルLLMでテキストを生成する」——これはもう当たり前になりました。しかし2026年現在、ローカルLLMにできることは大きく広がっています。

「社内データベースを検索して」「このファイルを読み取って要約して」「Slackに通知を送って」——こうした「実際の操作」を、クラウドAPIを一切使わず、完全にローカル環境でLLMに任せることが可能になっています。

この進化を支えているのがFunction Calling(Tool Use)です。Function Callingとは、LLMが「テキストを生成する」だけでなく、「外部の関数やツールを呼び出す」能力のことです。GPT-4oやClaudeのAPIではすでに広く普及している機能ですが、2025年後半からOllamaがTool Call対応を本格化し、Qwen 3やLlama 4といったオープンモデルが高精度なFunction Callingをサポートするようになりました。

これにより、社内の機密データを外部に送信することなく、ローカルLLMがエージェントとして業務を自動化する世界が現実になっています。

この記事では、Ollama+Qwen 3・Llama 4を使って、Tool定義→呼び出し→結果処理のパイプラインをローカル環境で構築する方法を、コード付きで実践的に解説します。

関連記事:


前提知識——Function Callingの仕組みを理解する

Function Calling(Tool Use)は、LLMに「超能力」を与える仕組みです。まず、全体像を把握しましょう。

Function Callingとは何か

LLMは本質的に「テキスト生成マシン」です。学習データに含まれないリアルタイム情報の取得、正確な数値計算、外部システムの操作——これらはLLM単体ではできません。

Function Callingは、この制限を突破する仕組みです。LLMに「使えるツール(関数)の一覧」を渡しておくと、LLMがユーザーの質問を分析して、適切なツールを選び、必要なパラメータをJSON形式で出力する——これがFunction Callingの基本動作です。

重要なのは、LLM自身が関数を「実行」するわけではないということです。LLMは「この関数をこの引数で呼んでほしい」というリクエストを構造化データとして出力し、実際の実行はアプリケーション側が行います。

Function Callingの処理フロー(4ステップ)

ステップ1:ツール定義
開発者が、LLMに使わせたいツール(関数)の名前・説明・パラメータをJSON Schema形式で定義します。

ステップ2:LLMの判断
ユーザーの入力を受け取ったLLMが、定義されたツールの中から適切なものを選び、パラメータを含むJSON形式の呼び出しリクエストを生成します。ツールが不要と判断した場合は、通常のテキスト応答を返します。

ステップ3:関数の実行
アプリケーション側がLLMの出力をパースし、指定された関数を実際に実行します。

ステップ4:結果の返却と最終応答
関数の実行結果をLLMに返し、LLMがその結果を踏まえてユーザー向けの自然言語応答を生成します。

クラウドAPI vs ローカル実行の違い

観点クラウドAPI(GPT-4o、Claude等)ローカル実行(Ollama+Qwen 3等)
データの送信先外部サーバーに送信されるローカルマシン内で完結
コストトークン従量課金電気代のみ(ハードウェア初期投資は必要)
ネットワーク依存インターネット接続必須完全オフラインで動作可能
レイテンシネットワーク往復ありローカル処理のため低レイテンシ
精度大規模モデルで高精度モデルサイズに依存(14B以上推奨)
カスタマイズ性API仕様に制約されるツールの自由な定義・拡張が可能

対応モデル選定——2026年のFunction Calling対応ローカルLLM

すべてのローカルLLMがFunction Callingに対応しているわけではありません。Ollamaのモデルページで「Tools」タグが付いているモデルが対応モデルです。2026年3月時点での主要な選択肢を整理します。

Qwen 3シリーズ(推奨)

Alibaba(阿里巴巴)が開発したQwen 3は、2026年現在、ローカルFunction Callingで最も安定した選択肢です。

特徴:

  • Thinkingモード(複雑な推論)とNon-thinkingモード(高速な日常対話)をシームレスに切り替え可能
  • Parallel Function Calls(複数ツールの同時呼び出し)にネイティブ対応
  • Hermes形式のTool Useテンプレートを採用し、Ollamaとの互換性が高い
  • 日本語性能が高く、日本語でのツール呼び出し指示も安定

モデルサイズ別の推奨:

モデルパラメータ必要VRAMFunction Calling精度用途
qwen3:8b8B6〜8GB単純なツール呼び出しは可能、複雑なケースでは不安定学習・プロトタイプ
qwen3:32b32B24〜32GB(Q4量子化時)高精度、安定したパラレル呼び出し本番運用の推奨最低ライン
qwen3:72b72B48GB以上最高精度、複雑なマルチステップツール呼び出しも安定高精度が必要な業務用途
qwen3-coder:32b32B24〜32GBコーディング+ツール呼び出しに最適化開発支援エージェント

Qwen 3シリーズでは、推論中のThinkingモードをFunction Callingと組み合わせることも可能です。Ollamaではthink=Trueオプションで有効化できます。ただし、Thinkingモード中に出力されるストップワードがツール呼び出しパーサーに干渉する場合があるため、安定性を重視する場合はenable_thinking: Falseの設定も検討してください。

Llama 4シリーズ

Metaが開発したLlama 4は、MoE(Mixture of Experts)アーキテクチャを採用し、大規模パラメータを効率的に活用するモデルです。

主要モデル:

  • Llama 4 Scout:109Bパラメータ(17Bアクティブ)、テキスト+画像入力に対応
  • Llama 4 Maverick:400Bパラメータ(17Bアクティブ)、最高性能

Function Calling対応状況:Llama 4はPythonic形式のツール呼び出しをサポートしています。JSON形式とPythonic形式の両方に対応しますが、Pythonic形式が推奨されています。Parallel Function Calls(並列ツール呼び出し)にも対応しており、Llama 3.xシリーズからの大きな進化です。

注意点:Llama 4 Scoutでも最低48GB以上のVRAMが推奨されるため、個人・中小企業ではGPUリソースの確保が課題になります。Q4量子化を使えば32GBでも動作可能な場合がありますが、Function Callingの精度が低下する可能性があります。

その他の注目モデル

モデル特徴Tool Calling評価
GLM-430Bクラスで精密なツール呼び出しコーディング+システム操作タスクに強い
Mistral Nemo12Bでツール対応、軽量リソース制約のある環境で有用
DeepSeek-R1強力な推論能力論理判断を要するツール使用に適する
Phi-4Microsoft製、コンパクトVS Code Copilot連携でのツール使用に実績

モデル選定の基本原則:Function Callingの安定性はモデルサイズに大きく依存します。8Bクラスのモデルでは単純なツール呼び出しは可能ですが、複雑なプロンプトやマルチツール呼び出しでは不安定になりがちです。本番運用では14B〜32B以上が推奨されています。

関連記事:ローカルLLMモデル選定ガイド


【実践編1】環境構築——Ollamaのセットアップとモデル導入

ここからは実際にFunction Callingを動かすための環境構築手順を解説します。

Ollamaのインストール

macOS / Linux:

curl -fsSL https://ollama.com/install.sh | sh

Windows:公式サイト(ollama.com)からインストーラーをダウンロードして実行します。

インストール後、以下のコマンドでOllamaが動作していることを確認します。

ollama --version

Function Calling対応モデルの導入

# Qwen 3 8B(学習・プロトタイプ向け)
ollama pull qwen3:8b

# Qwen 3 32B(本番推奨)
ollama pull qwen3:32b

# Llama 4 Scout(高リソース環境向け)
ollama pull llama4:scout

モデルのダウンロード後、ツール対応を確認します。

ollama show qwen3:8b

出力の中に「Tools」や「tools」のCapabilityが表示されていれば、Function Callingに対応しています。

Pythonライブラリの準備

pip install ollama

Ollamaの公式Pythonライブラリを使用します。OpenAI互換APIも利用可能ですが、Ollama固有の機能(Thinkingモード、ツール結果の返却形式)を活用するため、公式ライブラリの使用を推奨します。

関連記事:ローカルLLM入門ガイド


【実践編2】はじめてのFunction Calling——単一ツール呼び出し

最もシンプルなFunction Callingの実装から始めましょう。「都市名を渡すと気温を返す関数」をLLMに使わせます。

Pythonコード:単一ツール呼び出し

from ollama import chat

# ステップ1:ツールとして使う関数を定義
def get_temperature(city: str) -> str:
    """都市の現在の気温を取得する

    Args:
        city: 都市名
    Returns:
        現在の気温
    """
    # 実際にはAPIやデータベースから取得する
    temperatures = {
        "東京": "18°C",
        "大阪": "20°C",
        "札幌": "5°C",
    }
    return temperatures.get(city, "データなし")

# ステップ2:ユーザーの質問を送信(ツール定義付き)
messages = [{"role": "user", "content": "東京の気温を教えて"}]

response = chat(
    model="qwen3",
    messages=messages,
    tools=[get_temperature],  # Python関数を直接渡せる
)

# ステップ3:LLMがツール呼び出しを要求したか確認
messages.append(response.message)

if response.message.tool_calls:
    call = response.message.tool_calls[0]

    # ステップ4:関数を実際に実行
    result = get_temperature(**call.function.arguments)

    # ステップ5:結果をLLMに返して最終応答を得る
    messages.append({
        "role": "tool",
        "tool_name": call.function.name,
        "content": str(result)
    })

    final_response = chat(
        model="qwen3",
        messages=messages,
        tools=[get_temperature],
    )
    print(final_response.message.content)

コードのポイント解説

Python関数の直接渡し:Ollamaの公式Pythonライブラリでは、toolsパラメータにPython関数を直接渡すことができます。関数のdocstringと型ヒントから、ツールのJSON Schemaが自動的に生成されます。これにより、手動でJSON Schemaを書く手間が省けます。

toolロールの活用:ツールの実行結果をLLMに返す際は、"role": "tool"を使用し、"tool_name"で呼び出された関数名を明示します。これにより、LLMは「自分が要求したツールの結果」として正しく解釈できます。

判断の自律性:LLMはツールが必要ないと判断した場合、tool_callsを含まない通常のテキスト応答を返します。例えば「こんにちは」と入力すれば、気温取得関数を呼ばずに挨拶を返します。

curl(REST API)での実行

Pythonを使わず、Ollamaの/api/chatエンドポイントに直接リクエストすることも可能です。

curl -s http://localhost:11434/api/chat \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3",
    "messages": [{"role": "user", "content": "東京の気温は?"}],
    "stream": false,
    "tools": [{
      "type": "function",
      "function": {
        "name": "get_temperature",
        "description": "都市の現在の気温を取得する",
        "parameters": {
          "type": "object",
          "required": ["city"],
          "properties": {
            "city": {
              "type": "string",
              "description": "都市名"
            }
          }
        }
      }
    }]
  }'

【実践編3】複数ツールとパラレル呼び出し

実際の業務では、複数のツールを定義し、LLMに状況に応じて適切なツールを選ばせる必要があります。

複数ツールの定義

from ollama import chat
import json
import sqlite3

def search_database(query: str) -> str:
    """社内データベースからキーワードで検索する

    Args:
        query: 検索キーワード
    Returns:
        検索結果(JSON形式)
    """
    conn = sqlite3.connect("company.db")
    cursor = conn.cursor()
    cursor.execute(
        "SELECT * FROM products WHERE name LIKE ?",
        (f"%{query}%",)
    )
    results = cursor.fetchall()
    conn.close()
    return json.dumps(results, ensure_ascii=False)

def read_file(filepath: str) -> str:
    """指定されたファイルの内容を読み取る

    Args:
        filepath: 読み取るファイルのパス
    Returns:
        ファイルの内容
    """
    try:
        with open(filepath, "r", encoding="utf-8") as f:
            return f.read()[:2000]  # 最初の2000文字
    except FileNotFoundError:
        return "ファイルが見つかりません"

def send_notification(channel: str, message: str) -> str:
    """指定チャンネルに通知を送信する

    Args:
        channel: 通知先チャンネル名
        message: 送信するメッセージ
    Returns:
        送信結果
    """
    # 実際にはSlack API等を呼び出す
    print(f"[通知送信] #{channel}: {message}")
    return f"#{channel} に通知を送信しました"

# 3つのツールを渡してLLMに判断させる
messages = [{"role": "user", "content": "商品データベースから'ノートPC'を検索して"}]

response = chat(
    model="qwen3:32b",
    messages=messages,
    tools=[search_database, read_file, send_notification],
)

パラレルFunction Calling

Qwen 3とLlama 4は、一度のリクエストで複数のツールを同時に呼び出す(Parallel Function Calls)機能をサポートしています。

例えば「東京と大阪の気温を教えて」と質問すると、LLMは2つのget_temperature呼び出しを同時に返します。

# パラレル呼び出しの処理
if response.message.tool_calls:
    # 複数のツール呼び出しを処理
    for call in response.message.tool_calls:
        func = available_functions[call.function.name]
        result = func(**call.function.arguments)
        messages.append({
            "role": "tool",
            "tool_name": call.function.name,
            "content": str(result)
        })

    # すべてのツール結果を返して最終応答を得る
    final_response = chat(
        model="qwen3:32b",
        messages=messages,
        tools=tools_list,
    )

注意点:8Bクラスのモデルでは、パラレル呼び出しを要求されても一部のツールを無視したり、ツールの出力を無視して自力で回答しようとするケースがあります。パラレル呼び出しの安定性を重視するなら、32B以上のモデルを推奨します。


【実践編4】実用シナリオ——社内DBの検索エージェント

ここでは、実務で役立つ具体的なシナリオとして、「社内データベースに自然言語で質問できるエージェント」を構築します。

シナリオ概要

  • 目的:営業チームが「先月の売上トップ5の商品は?」のような自然言語で社内DBに問い合わせできる
  • 構成:Ollama(Qwen 3:32b)+SQLiteデータベース+Pythonスクリプト
  • データの送信先:なし(完全オフラインで動作)

ツール定義のベストプラクティス

Function Callingの成功率を左右するのは、ツール定義(descriptionとparameters)の品質です。

良い定義の例:

{
  "type": "function",
  "function": {
    "name": "query_sales_data",
    "description": "売上データベースから指定された条件で売上情報を検索する。期間、商品カテゴリ、並び順を指定可能。",
    "parameters": {
      "type": "object",
      "properties": {
        "start_date": {
          "type": "string",
          "description": "検索開始日(YYYY-MM-DD形式)。例: 2026-01-01"
        },
        "end_date": {
          "type": "string",
          "description": "検索終了日(YYYY-MM-DD形式)。例: 2026-01-31"
        },
        "category": {
          "type": "string",
          "description": "商品カテゴリ。例: 'ノートPC', '周辺機器', 'ソフトウェア'"
        },
        "sort_by": {
          "type": "string",
          "enum": ["sales_amount", "quantity", "profit"],
          "description": "並び替えの基準。sales_amount=売上金額, quantity=販売数量, profit=利益"
        },
        "limit": {
          "type": "integer",
          "description": "取得する件数の上限。デフォルトは10"
        }
      },
      "required": ["start_date", "end_date"]
    }
  }
}

ツール定義のコツ:

  • descriptionは具体的に:「データを検索する」ではなく「売上データベースから指定された条件で売上情報を検索する」と書く
  • パラメータの説明に例を含める:「日付(YYYY-MM-DD形式)。例: 2026-01-01」のように具体例を提供する
  • enumで選択肢を制限する:自由入力よりenum(選択肢リスト)を使うことで、LLMの出力精度が向上する
  • requiredを適切に設定する:必須パラメータと任意パラメータを明確に分ける

temperatureの設定

Function Callingの安定性を高めるために、temperatureは0〜0.2に設定することを強く推奨します。高いtemperatureではLLMが不正確なパラメータを生成したり、不要なツール呼び出しを行ったりする確率が上がります。

response = chat(
    model="qwen3:32b",
    messages=messages,
    tools=tools,
    options={"temperature": 0.1}
)

【実践編5】マルチステップエージェント——ReActパターンの実装

ここまでは「1回の質問→1回(または複数並列)のツール呼び出し→最終応答」というシングルショットのパターンを紹介しました。しかし実際の業務では、複数のステップを連鎖的に実行する必要があります。

ReAct(Reasoning + Acting)パターンとは

ReActは、LLMが「考える(Reasoning)→行動する(Acting)→観察する(Observation)→再び考える」というサイクルを繰り返すパターンです。

例えば「先月の売上トップ商品について、その商品の在庫状況を確認し、在庫が少なければSlackに通知して」という指示の場合、以下のステップが自動的に連鎖します。

ステップ1:売上データベースを検索(query_sales_data)
ステップ2:結果を受け取り、トップ商品のIDを抽出(LLMの推論)
ステップ3:在庫データベースで在庫数を確認(check_inventory)
ステップ4:在庫が閾値以下ならSlack通知を送信(send_notification)

実装のポイント

MAX_STEPS = 10  # 無限ループ防止

messages = [{"role": "user", "content": user_input}]

for step in range(MAX_STEPS):
    response = chat(
        model="qwen3:32b",
        messages=messages,
        tools=all_tools,
        options={"temperature": 0.1}
    )

    messages.append(response.message)

    # ツール呼び出しがなければ最終応答として終了
    if not response.message.tool_calls:
        print(f"最終応答: {response.message.content}")
        break

    # ツール呼び出しを実行
    for call in response.message.tool_calls:
        func = available_functions[call.function.name]
        result = func(**call.function.arguments)
        messages.append({
            "role": "tool",
            "tool_name": call.function.name,
            "content": str(result)
        })
else:
    print("最大ステップ数に達しました")

重要:MAX_STEPSの設定——マルチステップエージェントでは、LLMがツール呼び出しのループに入る可能性があります。必ず最大ステップ数を設定し、無限ループを防止してください。

重要:書き込み操作の承認——ファイルの書き込みやメッセージの送信など、副作用のある操作は、実行前にユーザーの承認を挟むことを強く推奨します。LLMの判断ミスによる意図しない操作を防ぐためです。


【実践編6】OpenAI互換APIとフレームワーク連携

OllamaはOpenAI互換のAPIエンドポイントを提供しているため、既存のフレームワークやツールとシームレスに連携できます。

OpenAI互換APIでのFunction Calling

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:11434/v1",
    api_key="ollama"  # Ollamaでは任意の文字列でOK
)

response = client.chat.completions.create(
    model="qwen3:32b",
    messages=[{"role": "user", "content": "東京の気温は?"}],
    tools=[{
        "type": "function",
        "function": {
            "name": "get_temperature",
            "description": "都市の現在の気温を取得する",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "都市名"}
                },
                "required": ["city"]
            }
        }
    }],
    tool_choice="auto"
)

この互換性により、OpenAI APIで動作する既存のコードを、ほぼそのままローカルLLMに切り替えることが可能です。

LiteLLMとの連携

LiteLLMを使えば、複数のLLMプロバイダーを統一的なインターフェースで切り替えられます。開発時はローカルのOllama、本番ではクラウドAPI——といったハイブリッド運用が容易になります。

MCPサーバーとの統合

OllamaのFunction Callingは、MCPサーバーのツール呼び出しと組み合わせることで、ローカルLLMをMCPエコシステムに接続できます。OllamaのSTDIOトランスポートを使えば、ローカルMCPサーバーとの連携も完全オフラインで動作します。

関連記事:MCPサーバー自作ガイド


RAGとFunction Callingの組み合わせ

Function CallingとRAG(Retrieval-Augmented Generation)は補完的な関係にあります。

RAG:関連文書を検索してコンテキストとしてLLMに渡す。「知識の拡張」。

Function Calling:外部ツールを呼び出して操作を実行する。「能力の拡張」。

この2つを組み合わせることで、「社内文書から情報を検索し、その結果に基づいてデータベースを更新する」といった高度なワークフローが実現できます。

例えば、ツールの一つとして「ベクトルデータベース検索関数」を定義し、LLMがユーザーの質問に応じてRAG検索を自律的に実行する——というパターンです。これにより、RAGのトリガーをLLM自身が判断する「エージェント型RAG」が構築できます。

関連記事:ローカルLLM×RAG統合ガイド


トラブルシューティング——よくある問題と対処法

問題1:LLMがツールを呼ばずに自力で回答する

原因:ツールのdescriptionが不明確、またはモデルが「ツールなしで回答できる」と判断している。

対処法:descriptionをより具体的かつ詳細にする。「この関数は〇〇のデータソースから取得するため、推測ではなく正確な情報が得られる」といった説明を追加する。systemメッセージで「利用可能なツールを積極的に使用してください」と指示する方法も有効です。

問題2:パラメータが不正確

原因:パラメータの型やフォーマットの説明が不足している。

対処法:descriptionに具体的なフォーマット例を含める(「YYYY-MM-DD形式。例: 2026-03-17」)。enumで選択肢を制限できる場合は積極的に使用する。

問題3:マルチツール呼び出しで一部が無視される

原因:モデルサイズが小さい(8B以下)場合に頻発する。

対処法:32B以上のモデルにアップグレードする。それが難しい場合は、パラレル呼び出しを避け、1回のリクエストで1つのツールのみ呼ばせるシングルショット方式を採用する。

問題4:Thinkingモード中にツール呼び出しが中断する

原因:Qwen 3のThinkingモードで、思考過程の中にツール呼び出しのストップワードが含まれる場合がある。

対処法:Function Calling時はenable_thinking: Falseに設定するか、ReAct形式ではなくHermes形式のテンプレートを使用する。Qwen-Agentフレームワークを使用すると、この問題が自動的にハンドリングされます。

問題5:応答が遅い

対処法:Q4やQ5の量子化モデルを使用する。コンテキスト長を必要最小限に設定する(デフォルトの128Kから32Kに削減するだけで大幅に高速化する場合がある)。GPUが利用可能であればGPU推論を優先する。


セキュリティと安全性の考慮事項

ローカルLLMのFunction Callingは「完全オフライン」で動作するため、クラウドAPIと比較してデータの外部送信リスクはありません。しかし、ローカル実行ならではのリスクも存在します。

許可リスト方式のツール設計

LLMに渡すツールは、ブロックリスト(禁止リスト)ではなく、許可リスト方式で設計してください。「このツールだけ使っていい」を明示する方が、「このツール以外なら何でも使っていい」よりも遥かに安全です。

ファイルパスの制限

ファイル操作ツールを定義する場合は、アクセス可能なディレクトリをホワイトリスト方式で制限してください。LLMの誤判断やプロンプトインジェクションにより、意図しないファイルの読み取り・書き込みが発生するリスクがあります。

Human-in-the-Loop

書き込み操作、ネットワーク通信、データの削除など、副作用のある操作は実行前にユーザーの確認を必須にしてください。特に初期段階では、すべてのツール呼び出しをログに記録し、想定外の動作がないか監視することを推奨します。

入力のバリデーション

ツール関数の引数は、LLMが生成したものであるため、必ずバリデーションを行ってください。SQLインジェクション、パストラバーサル、コマンドインジェクションなど、従来のWebアプリケーションセキュリティと同じ対策が必要です。


よくある質問(Q&A)

Q1. Function CallingとRAGの違いは?

RAGは「LLMの知識を外部文書で拡張する」仕組みで、主に情報検索と回答生成に使います。Function Callingは「LLMに外部ツールを操作させる」仕組みで、データベース操作、API呼び出し、ファイル操作など「アクション」の実行に使います。両者は排他的ではなく、組み合わせて使うことで最大の効果を発揮します。

Q2. GPUがないとFunction Callingは使えない?

CPU推論でもFunction Callingは動作します。ただし推論速度が大幅に遅くなります。8Bモデル+CPU推論で1回のツール呼び出しサイクルに数十秒かかるケースもあります。16GB以上のRAMと、可能であれば8GB以上のVRAMを持つGPUの使用を推奨します。

Q3. 日本語でのツール呼び出しは安定している?

Qwen 3は日本語性能が高く、日本語でのツール呼び出し指示も安定しています。ただし、ツールのdescriptionやパラメータ説明は英語で記述する方が精度が高い傾向があります。ユーザーからの入力は日本語、ツール定義は英語——というハイブリッド構成が実用的です。

Q4. Ollamaのバージョンはどれが必要?

Function Calling対応にはOllama v0.8以降が必要です。ストリーミングツール呼び出しやParallel Function CallsなどのサポートはV0.8で本格化しました。ollama --versionでバージョンを確認し、古い場合はアップデートしてください。

Q5. MCPサーバーとFunction Callingの関係は?

MCPサーバーは、LLMが外部ツールにアクセスするための標準プロトコルです。OllamaのFunction Callingで定義するツールの「裏側」としてMCPサーバーを配置することで、ツールの再利用性と相互運用性が高まります。例えば、あるMCPサーバーで定義したGitHub操作ツールを、Claude DesktopでもOllamaでも同じように使えるようになります。

関連記事:MCPサーバー自作ガイド


まとめ——ローカルLLMは「話すだけ」から「働く」へ

2026年のローカルLLMは、テキスト生成の域を超えて、業務を自動化するエージェントへと進化しています。この記事の要点を3つにまとめます。

1. Function CallingでローカルLLMが「実際に仕事をする」存在になった。DB検索、ファイル操作、API呼び出し——これらをクラウドAPIなし・完全オフラインで実行できます。Qwen 3やLlama 4のTool Call対応により、精度も実用レベルに達しています。

2. モデル選定が成功の鍵。Function Callingの安定性はモデルサイズに直結します。プロトタイプは8B、本番運用は32B以上を基準に選定してください。ツール定義のdescription品質とtemperature設定も精度に大きく影響します。

3. セキュリティは「ローカルだから安全」ではない。データの外部送信リスクはなくても、ファイルアクセスの制限、入力バリデーション、書き込み操作の承認フローなど、ローカル実行特有のセキュリティ対策は必須です。

ローカルLLMのFunction Callingは、「クラウドAPIの廉価版」ではありません。機密データを外に出さず、コストをかけず、ネットワークに依存しない——この3つの優位性は、中小企業にとって特に大きな価値を持ちます。

関連記事:

免責事項:本記事は2026年3月時点の公開情報に基づく情報提供であり、特定の製品・サービスを推奨するものではありません。各モデル・ツールの仕様は頻繁に更新されるため、最新情報は各公式ドキュメントで確認してください。コード例は概念説明のためのものであり、本番環境での使用前に十分なテストと検証を行ってください。

コメント

タイトルとURLをコピーしました