ローカルLLMでToolを使おう 【ollama】
対象読者
- OllamaでローカルLLMを動かしたことがあるが、Tool機能を使ったことがない人
本記事のゴール
- Toolとは何かを知ること
- ollama APIを叩いてLLMにToolを提供すること
Toolとは?
LLMの文脈では、ToolはLLMが呼び出すことができる機能を意味します。以下にToolの例を示します:
- ウェブ検索
- 数式の計算
- ファイルシステムアクセス
- コマンドの実行
LLMはテキストの生成しか行うことができませんが、Toolを使うことで外部のデータにアクセスしたり、ファイルシステムの読み書きを行うことができるようになります。強力な機能である反面、セキュリティリスクに注意を払う必要があります。
前提条件
- Python3
- ollama-python を使います
- パッケージ名: ollama
- ollama がローカルで起動していること
- リモートで起動していても良いですが、その場合は
OLLAMA_HOST環境変数を設定するか、カスタムClientを使用する必要があります。
- リモートで起動していても良いですが、その場合は
- 使用モデル: qwen3:30b
- 他のToolをサポートしているモデルでも良いです。どのモデルを使う場合でも、あらかじめ
ollama pullコマンドでモデルをダウンロードしておく必要があります。
- 他のToolをサポートしているモデルでも良いです。どのモデルを使う場合でも、あらかじめ
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は便利な反面、情報の漏洩・破壊リスクもあります。十分なセキュリティ監査を行うこと、およびツールの実行前に人の判断を入れる仕組みの検討をお勧めします。
