ローカルLLMでToolを使おう 【ollama】

対象読者

  • OllamaでローカルLLMを動かしたことがあるが、Tool機能を使ったことがない人

本記事のゴール

  • Toolとは何かを知ること
  • ollama APIを叩いてLLMにToolを提供すること

Toolとは?

LLMの文脈では、ToolはLLMが呼び出すことができる機能を意味します。以下にToolの例を示します:

  • ウェブ検索
  • 数式の計算
  • ファイルシステムアクセス
  • コマンドの実行

LLMはテキストの生成しか行うことができませんが、Toolを使うことで外部のデータにアクセスしたり、ファイルシステムの読み書きを行うことができるようになります。強力な機能である反面、セキュリティリスクに注意を払う必要があります。

前提条件

  • Python3
  • ollama-python を使います
  • ollama がローカルで起動していること
    • リモートで起動していても良いですが、その場合は OLLAMA_HOST 環境変数を設定するか、カスタムClientを使用する必要があります。
  • 使用モデル: qwen3:30b
    • 他のToolをサポートしているモデルでも良いです。どのモデルを使う場合でも、あらかじめ ollama pull コマンドでモデルをダウンロードしておく必要があります。

Toolを使う

Ollama公式ブログの記事に天気予報を提供するToolを使う例がありますので参考にしてください。本記事では数式を計算させるToolを提供する例を示します。Ollama CLI (ollamaコマンド) は2025年11月11日時点でToolをサポートしていないようです。Toolを使うにはAPIを叩く必要があります。

main.py:

import ollama

MODEL = 'qwen3:30b'

messages=[
  {'role': 'user', 'content': '10 + 20 は?'}
]

response = ollama.chat(
  model=MODEL,
  messages=messages,
  tools=[{
    'type': 'function',
    'function': {
      'name': 'evaluate_expression',
      'description': 'Evaluate the given expression',
      'parameters': {
        'type': 'object',
        'properties': {
          'expression': {
            'type': 'string',
            'description': 'The expression',
          },
        },
        'required': ['expression'],
      },
    },
  }],
)

result = None
if 'tool_calls' in response['message']:
  print('ツールが呼び出されました')
  messages.append(response['message'].model_dump())
  tool_calls = response['message']['tool_calls']
  expression = tool_calls[0].function.arguments['expression']
  messages.append({
      'role': 'tool',
      # セキュリティリスクがあるため、eval() をproductionで使用しないこと
      'content': str(eval(expression, {}, {}))
  })
  response = ollama.chat(
    model=MODEL,
    messages=messages,
  )
  result = response['message']['content']
else:
  result = response['message']['content']

print(result)
  • MODEL = 'qwen3:30b'
    • モデル qwen3:30b を使用します。お好みによりモデルを変更してください。
  • {'role': 'user', 'content': '10 + 20 は?'}
    • 10 + 20 を計算させるプロンプトです。
  • 最初の response = ollama.chat(...
    • 前述のプロンプトと共にツールの情報をollamaに投げます。
  • if 'tool_calls' in response['message']:
    • ツールを提供しても、LLMが必ずしもツールを使用するとは限りません。LLMがツールを使用するという判断をした場合はこのブロックに入ります。
  • eval(expression, {}, {})
    • 数式を eval 関数で評価します。セキュリティリスクがあるため、productionでは使用しないでください!また、開発でも出所の怪しいモデルは使用しないでください!
  • 最後の response = ollama.chat(...
    • ツールの実行結果を、今までの会話履歴を含めてollamaに投げます。

実行結果

実行結果を示します。フレンドリーに 10 + 20 の解を答えてくれています。私が使用したモデルでは thinking が有効になっているため、thinkingブロックも出力されています。

$ uv run main.py 
ツールが呼び出されました
<think>
Okay, the user asked "10 + 20 は?" which is Japanese for "What is 10 + 20?" I need to provide the answer. The previous response used the evaluate_expression tool and got 30. So the correct answer is 30. I should just state that clearly. Maybe add a friendly note to confirm if they need more help. Keep it simple and straightforward.
</think>

10 + 20 の答えは **30** です!  
何か他に質問があればお気軽にどうぞ 😊

最後に

本記事ではToolをローカルLLM (ollama) で使う例を示しました。Toolは便利な反面、情報の漏洩・破壊リスクもあります。十分なセキュリティ監査を行うこと、およびツールの実行前に人の判断を入れる仕組みの検討をお勧めします。

新規CTA