Ollamaの公式PythonライブラリでLLMを呼び出す方法|pip install ollamaでストリーミング・非同期・ツール使用を実装する手順

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)ローカルLLM > Ollamaの公式PythonライブラリでLLMを呼び出す方法|pip install ollamaでストリーミング・非同期・ツール使用を実装する手順
「PythonからOllamaを呼び出したいが、HTTPリクエストを自前で書くと煩雑になる」
「LangChainは覚えることが多すぎる。もっとシンプルにローカルLLMをPythonで使いたい」

そんな悩みを抱えるLinuxエンジニアは多いはずです。Ollamaには公式のPythonライブラリ(`ollama`パッケージ)が用意されており、`pip install ollama` 一行でインストールできます。この記事では、基本的なチャット呼び出しからストリーミング応答・非同期クライアント・ツール使用(Function Calling)・マルチターン対話まで、公式ライブラリを使った実装手順を解説します。

curlやrequestsを使った低レベルなHTTP操作や、LangChainなどのフレームワーク不要で、数行のコードからローカルLLMを呼び出せるようになることが目標です。

この記事のポイント

・pip install ollama でフレームワーク不要のPythonクライアントを導入できる
・ollama.chat(stream=True) でストリーミング応答をジェネレータとして逐次処理できる
・AsyncClient と asyncio.gather() を組み合わせて複数リクエストを並列処理できる
・tools パラメータで Function Calling を OpenAI 互換フォーマットで実装できる


Ollamaの公式PythonライブラリでLLMを呼び出す方法|pip install ollamaでストリーミング・非同期・ツール使用を実装する手順

「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

なぜOllama公式Pythonライブラリを選ぶのか

OllamaにはREST APIが備わっているため、curlやPythonの `requests` ライブラリで直接叩くことも可能です。しかし、ストリーミング応答の逐次処理・エラーハンドリング・レスポンスのJSON解析を自前で実装すると、コード量が増えてメンテナンスコストが上がります。

公式Pythonライブラリ(`ollama`パッケージ)は、これらの煩雑な処理をすべて内部で吸収します。同期・非同期・ストリーミングの切り替えもAPIパラメータ一つで対応できます。LangChainのような大規模フレームワークと比べてインストールが軽量で、依存パッケージが `httpx` のみのため、スクリプトや社内マイクロサービスへの組み込みに向いています。

Ollamaサーバー自体の構築方法については「Ubuntu ServerでローカルLLMを構築する方法|Ollamaで機密データを外に出さず業務AIを動かす完全ガイド」を参照してください。本記事はOllamaサービスが `http://localhost:11434` で稼働している前提で進めます。

前提環境とインストール手順

1. 前提条件を確認する

本記事の動作確認環境は Ubuntu 24.04 LTS・Python 3.11・Ollama 0.3系です。Ollamaサービスが起動していることを `ollama list` と `curl` で確認してください。

$ ollama list NAME ID SIZE MODIFIED llama3.3:70b-instruct-q4_0 abc1234def56 43 GB 2 hours ago $ curl -s http://localhost:11434/api/tags | python3 -m json.tool | grep '"name"' "name": "llama3.3:70b-instruct-q4_0",

`ollama list` でモデルが表示されること、curlでAPIが応答することを確認してから次へ進んでください。

2. 仮想環境を作成してインストールする

システムのPython環境を汚染しないよう、プロジェクト専用のvenvを作成してからインストールします。

$ python3 -m venv ~/ollama-py-env $ source ~/ollama-py-env/bin/activate (ollama-py-env) $ pip install ollama Collecting ollama Downloading ollama-0.3.0-py3-none-any.whl (11 kB) Installing collected packages: ollama Successfully installed ollama-0.3.0 (ollama-py-env) $ python3 -c "import ollama; print(ollama.__version__)" 0.3.0

インストールが完了したら、バージョンが表示されることを確認してください。依存パッケージは `httpx` のみで非常に軽量です。

基本的なチャット呼び出しを実装する

1. 同期チャットの最小構成

`ollama.chat()` にモデル名とメッセージリストを渡すだけで応答が返ります。最小構成は以下のとおりです。

import ollama # basic synchronous chat call response = ollama.chat( model='llama3.3:70b-instruct-q4_0', messages=[ {'role': 'user', 'content': 'Linuxのinodeとは何ですか?50字以内で答えてください'} ] ) print(response['message']['content'])

2. レスポンスオブジェクトの構造を確認する

`response` は辞書型で、主なキーは `message`・`model`・`created_at`・`done`・`total_duration` です。トークン消費量は `prompt_eval_count`・`eval_count` で取得できます。

import ollama response = ollama.chat( model='llama3.3:70b-instruct-q4_0', messages=[{'role': 'user', 'content': 'Hello'}] ) print(f"回答: {response['message']['content']}") print(f"入力トークン: {response['prompt_eval_count']}") print(f"出力トークン: {response['eval_count']}") print(f"処理時間: {response['total_duration'] / 1_000_000:.0f}ms")

3. システムプロンプトを設定する

ロールに `system` を指定することで、モデルの振る舞いを制御できます。業務用途では専門領域に特化した指示を与えると回答精度が向上します。

response = ollama.chat( model='llama3.3:70b-instruct-q4_0', messages=[ { 'role': 'system', 'content': 'あなたはLinuxサーバー管理の専門家です。技術的な質問に簡潔に答えてください。' }, { 'role': 'user', 'content': 'systemctlとserviceコマンドの違いを教えてください' } ] ) print(response['message']['content'])

モデルの選択基準については「ローカルLLMのモデルを比較する方法|Llama3.3・Mistral・Gemma・Phi-4をUbuntuで使い分けるポイント」も参考にしてください。

ストリーミング応答で出力をリアルタイムに受け取る

1. stream=Trueでジェネレータを取得する

長文を生成する場合、全文が生成されるまで待つのではなく逐次的に受け取る方が体験が良くなります。`stream=True` を指定するとジェネレータが返り、各チャンクをforループで処理できます。

import ollama stream = ollama.chat( model='llama3.3:70b-instruct-q4_0', messages=[ {'role': 'user', 'content': 'Linuxのファイルパーミッションについて詳しく説明してください'} ], stream=True ) for chunk in stream: print(chunk['message']['content'], end='', flush=True) print() # 最後に改行

2. ストリーミングの完了と処理時間を計測する

各チャンクに含まれる `done` フラグが `True` になったとき、生成が完了しています。完了時のトークン数と処理時間を出力する例を示します。

import ollama import time start = time.time() stream = ollama.chat( model='llama3.3:70b-instruct-q4_0', messages=[{'role': 'user', 'content': 'bashのfor文の書き方をコード例付きで説明してください'}], stream=True ) for chunk in stream: print(chunk['message']['content'], end='', flush=True) if chunk['done']: elapsed = time.time() - start print(f"\n\n--- 処理時間: {elapsed:.1f}秒 / 出力トークン: {chunk.get('eval_count', 'N/A')} ---")

ストリーミングを使う場合、最終チャンクの `done` が `True` になるまでループを抜けないように注意してください。途中でコネクションが切れた場合は `httpx.RemoteProtocolError` が発生します。

非同期クライアントで並列リクエストを処理する

1. AsyncClientの基本構成

複数のリクエストを同時に処理したい場合は `AsyncClient` を使います。`asyncio.gather()` と組み合わせることで、複数の質問を並列実行できます。

import asyncio from ollama import AsyncClient async def ask(client: AsyncClient, question: str) -> str: response = await client.chat( model='llama3.3:70b-instruct-q4_0', messages=[{'role': 'user', 'content': question}] ) return response['message']['content'] async def main(): client = AsyncClient() questions = [ 'cronの書き方を教えてください', 'rsyncの主なオプションを教えてください', 'iptablesでポートを開ける方法を教えてください', ] results = await asyncio.gather(*[ask(client, q) for q in questions]) for q, a in zip(questions, results): print(f"Q: {q}\nA: {a[:100]}...\n") asyncio.run(main())

2. 非同期ストリーミングを実装する

非同期クライアントでもストリーミングが使えます。`async for` でチャンクを受け取ります。

import asyncio from ollama import AsyncClient async def stream_response(prompt: str): client = AsyncClient() async_stream = await client.chat( model='llama3.3:70b-instruct-q4_0', messages=[{'role': 'user', 'content': prompt}], stream=True ) async for chunk in async_stream: print(chunk['message']['content'], end='', flush=True) print() asyncio.run(stream_response('DockerとPodmanの違いを教えてください'))

非同期クライアントは、FastAPIやAioHTTPを使ったWebアプリケーションに組み込む場合に特に有用です。社内向けのAPIサービス構築については「社内でChatGPTが使えないときの代替手段|機密データを守るローカルLLMという選択肢」も参考にしてください。

ツール使用(Function Calling)を実装する

1. ツール定義を用意する

Function Callingを使うと、モデルがPython関数を呼び出すタイミングを自律的に判断できます。ツール定義はOpenAI互換フォーマットで記述します。以下はLinuxコマンドを実行するツールの例です。

import ollama import subprocess tools = [ { 'type': 'function', 'function': { 'name': 'run_readonly_command', 'description': '読み取り専用のLinuxコマンドを実行して結果を返す', 'parameters': { 'type': 'object', 'properties': { 'command': { 'type': 'string', 'description': '実行するコマンド(例: df -h, free -m, uptime)' } }, 'required': ['command'] } } } ] SAFE_COMMANDS = ('df ', 'free ', 'uptime', 'uname ', 'date', 'hostname') def run_readonly_command(command: str) -> str: if not any(command.startswith(p) for p in SAFE_COMMANDS): return "エラー: 許可されていないコマンドです" result = subprocess.run( command.split(), capture_output=True, text=True, timeout=5 ) return result.stdout or result.stderr

2. ツール呼び出しループを実装する

モデルがツール使用を要求した場合、実際に関数を実行して結果をメッセージリストに追記し、再度チャットを呼び出します。

messages = [ {'role': 'user', 'content': 'このサーバーのディスク使用状況とメモリ使用状況を教えてください'} ] response = ollama.chat( model='llama3.3:70b-instruct-q4_0', messages=messages, tools=tools ) while response['message'].get('tool_calls'): messages.append(response['message']) for tool_call in response['message']['tool_calls']: func_name = tool_call['function']['name'] func_args = tool_call['function']['arguments'] if func_name == 'run_readonly_command': result = run_readonly_command(func_args['command']) messages.append({'role': 'tool', 'content': result}) response = ollama.chat( model='llama3.3:70b-instruct-q4_0', messages=messages, tools=tools ) print(response['message']['content'])

ツール使用に対応するモデルはLlama3.3など一部に限られます。Mistral・Gemma 3・Phi-4でも対応しているモデルがありますが、`ollama show <モデル名>` でCapabilityを確認してから使用してください。

会話履歴を保持するマルチターン対話を実装する

1. メッセージリストを蓄積する

マルチターン対話は、メッセージリストにアシスタントの応答を追記しながら `ollama.chat()` を繰り返し呼び出すことで実現できます。

import ollama conversation = [ {'role': 'system', 'content': 'あなたはLinuxの技術サポートAIです。'} ] def chat(user_input: str) -> str: conversation.append({'role': 'user', 'content': user_input}) response = ollama.chat( model='llama3.3:70b-instruct-q4_0', messages=conversation ) answer = response['message']['content'] conversation.append({'role': 'assistant', 'content': answer}) return answer print(chat('sshdの設定ファイルはどこにありますか?')) print(chat('そのファイルでポート番号を変えるにはどうすればいいですか?')) print(chat('変更後にどんなコマンドで反映させますか?'))

2. 会話履歴のトークン数を管理する

長い会話はコンテキストウィンドウ(`num_ctx`)の上限に達する可能性があります。古いメッセージを切り捨てる簡易的なトリミング処理を用意しておくと安全です。

def trim_history(messages: list, max_pairs: int = 10) -> list: """systemプロンプトを保持しつつ最新N往復のみ残す""" system = [m for m in messages if m['role'] == 'system'] non_system = [m for m in messages if m['role'] != 'system'] return system + non_system[-(max_pairs * 2):] # 50往復を超えたらトリミング if len(conversation) > 105: conversation[:] = trim_history(conversation, max_pairs=10) print("会話履歴を最新10往復に圧縮しました")

コンテキストウィンドウを明示的に指定したい場合は `options={'num_ctx': 8192}` をチャット呼び出しに追加してください。

よくあるエラーと対処法

公式ライブラリを使ってもいくつかのエラーに遭遇することがあります。代表的なケースと対処法をまとめます。

ConnectionError: Ollamaサーバーに接続できない
`httpx.ConnectError` が発生する場合、Ollamaサービスが停止しているか、ポートが異なる可能性があります。`systemctl status ollama` でサービス状態を確認してください。リモートサーバーに接続する場合は `Client(host='http://192.168.1.10:11434')` のように `host` を指定します。

ResponseError: model not found
モデル名のタイポや量子化タグの誤りが原因です。`ollama list` で正確なモデル名を確認し、`llama3.3:70b-instruct-q4_0` のようにサフィックス形式で指定してください。`:q4_0` 単独表記(`llama3.3:q4_0` 形式)は実在しません。

TimeoutError: レスポンスが返らない
大規模モデルのロード時間が原因のことがあります。`Client(timeout=300)` のようにタイムアウトを延ばしてください。デフォルトは `httpx` のデフォルト値(約5秒)です。

ストリーミングが途中で止まる
コンテキストウィンドウが満杯になると生成が停止します。`options` パラメータで `num_ctx` を明示的に指定して対処します。

from ollama import Client # タイムアウトとコンテキストウィンドウを明示指定する例 client = Client(host='http://localhost:11434', timeout=300) response = client.chat( model='llama3.3:70b-instruct-q4_0', messages=[{'role': 'user', 'content': '長い文書の要約をお願いします...'}], options={'num_ctx': 8192, 'temperature': 0.1} ) print(response['message']['content'])

まとめ

Ollama公式Pythonライブラリを使えば、フレームワーク不要でローカルLLMをPythonから簡潔に呼び出せます。同期・非同期・ストリーミング・Function Callingのすべてが `import ollama` 一行でアクセスできる状態になり、スクリプト・社内ツール・APIサーバーへの統合がシンプルに実現できます。
機能主なメソッド・クラスポイント
同期チャットollama.chat(model=..., messages=[...])最小構成・辞書型レスポンス
ストリーミングollama.chat(..., stream=True)forループでチャンク逐次処理
非同期チャットAsyncClient().chat(...)asyncio.gather()で並列化
非同期ストリーミングawait client.chat(..., stream=True)async forで逐次処理
ツール使用ollama.chat(..., tools=[...])OpenAI互換フォーマット
マルチターン対話messagesリスト蓄積trim_history()でトークン管理
接続カスタマイズClient(host=..., timeout=...)リモート接続・タイムアウト設定
LangChainやLlamaIndexとの連携が必要な高度なRAGパイプラインを構築する場合は、それぞれの専用記事を参照してください。シンプルなスクリプトや社内ツールへの統合であれば、公式ライブラリだけで十分に対応できます。現場で長年Linuxサーバーを扱ってきたエンジニアに共通する経験則として、依存が少なく薄いラッパーから始めて、必要になったときに重厚なフレームワークへ移行するアプローチが結局は保守コストを下げる、という話をよく聞きます。

ローカルLLMのPython連携を2日間体験する

公式ライブラリの使い方を手を動かして習得したい方、ストリーミングや非同期処理をチームのプロジェクトに組み込みたい方向けに、「ローカルAIマスターセミナー」を開催しています。
少人数(最大8名)ZOOMハンズオン形式で実施しています。

>> ローカルAIマスターセミナーの詳細を確認する
ローカルLLMの構築・運用に関する関連記事もあわせて参考にしてください。

Ubuntu ServerでローカルLLMを構築する方法|Ollamaで機密データを外に出さず業務AIを動かす完全ガイド
社内でChatGPTが使えないときの代替手段|機密データを守るローカルLLMという選択肢
ローカルLLMのモデルを比較する方法|Llama3.3・Mistral・Gemma・Phi-4をUbuntuで使い分けるポイント

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。