「Pythonから呼び出して業務システムに組み込みたいが、何から始めればいいか」
そんな悩みを抱える業務システムにLLMを組み込みたいプログラマー・開発者は多いはずです。この記事では、OllamaのREST APIを使ってcurl・Pythonから推論リクエストを送る具体的な実装手順を解説します。/api/generateと/api/chatの使い分けから、Pythonクライアントの実装例、社内ツールへ組み込む際の設計・セキュリティ注意点まで、「API連携の基本から実務投入まで」をゴールにします。
この記事のポイント
・Ollama APIは curl -s http://localhost:11434/api/generate でリクエストを送れる
・/api/generateは単発補完、/api/chatは会話履歴を保持するチャット形式で使い分ける
・Pythonからはrequestsライブラリまたはollama公式SDKで簡単に呼び出せる
・APIに認証機構はないため、社内ツールへ組み込む際はufwでアクセス制限が必須
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
OllamaのREST APIでできること|/api/generateと/api/chat
OllamaはインストールするとデフォルトでHTTPサーバーを起動し、`http://localhost:11434` にREST APIを公開します。CLIの `ollama run` コマンドもこのAPIを内部で叩いているだけで、プログラムから直接エンドポイントにリクエストを送れます。主要なエンドポイントは以下の2つです。
・/api/generate:単発のテキスト補完。プロンプトを渡すとテキストが返る。チャット履歴は管理しない
・/api/chat:会話形式。messagesにrole(user/assistant/system)付きの配列を渡す。履歴を引き継いだ応答が返る
どちらを使うべきかの判断基準は単純です。一問一答でよい処理(テキスト要約・翻訳・コード生成)は `/api/generate`、対話的なサポート窓口や多ターンの指示が必要な処理は `/api/chat` を選びます。
もう一つ押さえておきたいのが `stream` パラメータです。デフォルトでは `stream: true` になっており、トークンが逐次JSONで流れてきます。`stream: false` を指定すると全文が揃ってから1つのJSONレスポンスとして返るため、スクリプト処理や業務システムへの組み込みでは `stream: false` のほうが扱いやすい場面が多いです。
Ollamaの構築やUbuntu Serverへのセットアップが済んでいない場合は、Ubuntu ServerでローカルLLMを構築する方法|Ollamaで機密データを外に出さず業務AIを動かす完全ガイドを先に確認してください。
curlでAPIを叩く基本|リクエスト・レスポンスの読み方
まず動作確認として、curlで最もシンプルなリクエストを送ってみます。Ollamaが `http://localhost:11434` で起動していれば以下がそのまま通ります。1. /api/generate の基本リクエスト
# 基本的なgenerate APIリクエスト(stream: falseで全文受信) $ curl -s http://localhost:11434/api/generate \ -d '{ "model": "gemma3:4b", "prompt": "Pythonでリスト内包表記の基本を100字で説明してください", "stream": false }' | python3 -m json.tool { "model": "gemma3:4b", "created_at": "2026-06-24T03:00:00.000000000Z", "response": "リスト内包表記は `[式 for 変数 in イテラブル]` の形式で...", "done": true, "done_reason": "stop", "total_duration": 2341500000, "load_duration": 102400000, "prompt_eval_count": 32, "eval_count": 87 }
・response:モデルが生成したテキスト本体
・done:trueなら生成完了
・total_duration:推論にかかった合計時間(ナノ秒)
・eval_count:生成したトークン数
2. /api/chat の基本リクエスト
# チャット形式でシステムプロンプト付きリクエスト $ curl -s http://localhost:11434/api/chat \ -d '{ "model": "gemma3:4b", "messages": [ { "role": "system", "content": "あなたはLinuxサーバー管理の専門家です。簡潔に答えてください。" }, { "role": "user", "content": "cronで毎日0時にスクリプトを実行するcrontab設定を教えてください" } ], "stream": false }' | python3 -c "import sys,json; r=json.load(sys.stdin); print(r['message']['content'])" cronで毎日0時に実行する場合は以下の設定をcrontabに追加します: 0 0 * * * /path/to/your/script.sh ...
なお、stream無しで返ってくるまでの時間はモデルサイズとGPU/CPU性能に依存します。gemma3:4bならGPU環境で1~3秒が目安です。モデルごとの性能差についてはローカルLLMのモデルを比較する方法|Llama3.3・Mistral・Gemma・Phi-4をUbuntuで使い分けるポイントを参照してください。
3. よく使うその他のエンドポイント
# ローカルにあるモデル一覧を取得 $ curl -s http://localhost:11434/api/tags | python3 -m json.tool { "models": [ { "name": "gemma3:4b", "size": 3340000000, "digest": "a72c7f4d3796..." } ] } # APIサーバーの生存確認 $ curl -s http://localhost:11434 Ollama is running # 現在ロードされているモデルの確認 $ curl -s http://localhost:11434/api/ps | python3 -m json.tool
Ollama APIのリクエストオプション|temperatureとseedで生成品質を制御する
/api/generate と /api/chat のどちらでも、リクエストボディに `options` オブジェクトを追加すると生成パラメータを細かく制御できます。デフォルト値のままでも動作しますが、業務ツールへ組み込む際は用途に合わせた調整が必要です。よく使うオプションパラメータは以下です。
・temperature:出力のランダム性(デフォルト0.8)。0に近いほど確定的な出力になり、2に近いほど多様な出力になる。コード生成・翻訳など正確性が求められる用途は0.1~0.3が目安
・top_p:確率分布の上位p%のトークンから選択するパラメータ(デフォルト0.9)。temperatureと組み合わせて出力の多様性を制御する
・seed:同じseedと同じプロンプトで再現性のある出力を得るために使用。テスト・デバッグ時に便利
・num_predict:生成するトークンの最大数(デフォルト-1でモデル依存)。出力を特定の長さに制限したい場合に指定する
# temperatureを低く設定して確定的なコード生成リクエスト $ curl -s http://localhost:11434/api/generate \ -d '{ "model": "gemma3:4b", "prompt": "Pythonで文字列を逆順にするコードを1行で書いてください", "stream": false, "options": { "temperature": 0.1, "seed": 42, "num_predict": 200 } }' | python3 -c "import sys,json; print(json.load(sys.stdin)['response'])" s = "hello" print(s[::-1]) # または "hello"[::-1]
一方、「アイデア出し」「複数の言い回しを提案させる」用途では `temperature: 1.0~1.5` のほうが多様な候補が返ってきます。業務ツールに組み込む際は用途ごとにoptionsを切り替えられる設計にしておくと、後から調整が容易です。
PythonからOllama APIを呼び出す実装例
curlで動作が確認できたら、Pythonから呼び出す実装に移ります。方法は2つあります。標準ライブラリに近い `requests` を使う方法と、Ollama公式のPython SDKを使う方法です。1. requestsライブラリを使ったシンプルな実装
requestsはほとんどのPython環境で使えるため、依存関係を増やしたくない場合に適しています。# requests利用(pip install requests が必要) import requests import json def ask_ollama(prompt: str, model: str = "gemma3:4b") -> str: """Ollama /api/generate を呼び出して回答テキストを返す""" url = "http://localhost:11434/api/generate" payload = { "model": model, "prompt": prompt, "stream": False } response = requests.post(url, json=payload, timeout=120) response.raise_for_status() return response.json()["response"] # 使用例 answer = ask_ollama("Linuxのsystemctlでサービスを再起動するコマンドは?") print(answer)
2. Ollama公式Python SDKを使った実装
# pip install ollama でインストール import ollama # /api/generate に相当 response = ollama.generate(model="gemma3:4b", prompt="Pythonのwith文の使い方を説明して") print(response["response"]) # /api/chat に相当(会話履歴付き) chat_response = ollama.chat( model="gemma3:4b", messages=[ {"role": "system", "content": "Linuxの専門家として答えてください"}, {"role": "user", "content": "viでファイルを保存して終了するショートカットは?"} ] ) print(chat_response["message"]["content"]) # ストリーミング処理(トークンを逐次受信) stream = ollama.generate(model="gemma3:4b", prompt="cronの書き方を説明して", stream=True) for chunk in stream: print(chunk["response"], end="", flush=True) print()
3. 会話履歴を管理するチャットクライアントの実装
import requests class OllamaChat: """会話履歴を保持するOllamaチャットクライアント""" def __init__(self, model: str = "gemma3:4b", system_prompt: str = ""): self.model = model self.messages = [] if system_prompt: self.messages.append({"role": "system", "content": system_prompt}) def chat(self, user_input: str) -> str: self.messages.append({"role": "user", "content": user_input}) payload = { "model": self.model, "messages": self.messages, "stream": False } r = requests.post("http://localhost:11434/api/chat", json=payload, timeout=120) r.raise_for_status() reply = r.json()["message"]["content"] self.messages.append({"role": "assistant", "content": reply}) return reply def reset(self): """履歴をリセット(system promptは保持)""" self.messages = [m for m in self.messages if m["role"] == "system"] # 使用例 bot = OllamaChat(model="gemma3:4b", system_prompt="Linux管理の専門家として答えてください") print(bot.chat("SSHのポートを変更するには?")) print(bot.chat("その設定をsystemctlで反映させるコマンドも教えて"))
社内ツール・業務システムへ組み込む際の設計と注意点
OllamaのREST APIを使って業務システムへ組み込む際の設計上のポイントと、見落としがちな注意点をまとめます。1. APIに認証機構がない問題とufwによるアクセス制限
OllamaのAPIはデフォルトで認証を要求しません。`http://サーバーIP:11434/api/generate` に対してネットワーク上のどこからでもリクエストを送れてしまいます。社内サーバーで運用する場合は必ずufwでアクセス元を制限してください。# ufw でOllama APIポート(11434)を社内NWのみに制限する $ sudo ufw allow from 192.168.1.0/24 to any port 11434 $ sudo ufw deny 11434 # 設定確認 $ sudo ufw status Status: active To Action From -- ------ ---- 11434 ALLOW 192.168.1.0/24 11434 DENY Anywhere
ファイアウォール設計の詳細やsystemd設定と合わせたセキュアな構築手順は、Ubuntu ServerでローカルLLMを構築する完全ガイドで解説しています。
2. 複数ユーザーが同時利用する場合のモデル競合
Ollamaは1プロセスで1モデルをGPUメモリにロードして推論します。複数リクエストが同時に来た場合、後続のリクエストは前のリクエストが完了するまでキューで待機します。同一モデルへの並列推論は直列処理です。複数モデルに跨るリクエスト(A部署はgemma3:4b、B部署はllama3.3:70b-instruct-q4_0を使う)の場合は、モデル切替のたびにGPUメモリのアンロード・ロードが発生します。この切替コストが数秒~10秒以上になることがあります。用途別にモデルを固定するか、Ollamaインスタンスを複数立ち上げてロードバランスする設計が必要になります。
社内導入時の情シス向けの考え方(機密データをローカルに閉じる判断軸)については、社内でChatGPTが使えないときの代替手段|機密データを守るローカルLLMという選択肢も参考にしてください。
3. Flaskを使った社内APIラッパーの最小実装
社内ツールからOllamaを使えるようにする最もシンプルな方法は、Ollamaの前にFlaskの薄いラッパーAPIを置くことです。# pip install flask requests from flask import Flask, request, jsonify import requests app = Flask(__name__) OLLAMA_URL = "http://localhost:11434/api/generate" DEFAULT_MODEL = "gemma3:4b" @app.route("/ask", methods=["POST"]) def ask(): data = request.get_json() prompt = data.get("prompt", "") model = data.get("model", DEFAULT_MODEL) if not prompt: return jsonify({"error": "promptが必要です"}), 400 r = requests.post(OLLAMA_URL, json={ "model": model, "prompt": prompt, "stream": False }, timeout=120) r.raise_for_status() return jsonify({"response": r.json()["response"]}) if __name__ == "__main__": app.run(host="0.0.0.0", port=8080)
OllamaのREST APIでハマりやすいエラーと対処法
API連携の実装で実際にハマりやすいエラーとその対処法を整理します。1. ConnectionRefusedError / Connection refused(接続できない)
# まずOllamaが動いているか確認 $ curl http://localhost:11434 Ollama is running ← 表示されなければOllamaが停止している # systemdで起動していない場合は手動起動 $ systemctl status ollama $ sudo systemctl start ollama # または手動でサーバーを起動 $ ollama serve &
2. model 'xxx' not found(モデルが見つからない)
# ダウンロード済みモデル一覧を確認 $ ollama list NAME ID SIZE MODIFIED gemma3:4b a72c7f4d3796 3.3 GB 2 hours ago # モデルがない場合はpullで取得 $ ollama pull gemma3:4b pulling manifest ...
3. timeoutエラー(タイムアウト)
初回リクエストではモデルのGPUメモリへのロードが走るため、requestsのデフォルトタイムアウト(なし or 短い値)だとタイムアウトすることがあります。`timeout=120` など余裕を持った値を設定してください。70Bクラスのモデルでは初回ロードに30秒以上かかることもあります。4. JSONDecodeError(レスポンス解析失敗)
stream: true(デフォルト)のままにしていると、1トークンごとの改行区切りJSONが連続して流れてきます。これをそのまま `json.loads()` するとJSONDecodeErrorになります。`"stream": false` を指定するか、ストリーミングを処理する場合は行ごとにパースしてください。# ストリーミングレスポンスを行ごとにパースする例 import requests, json r = requests.post("http://localhost:11434/api/generate", json={"model": "gemma3:4b", "prompt": "こんにちは"}, stream=True, timeout=120) full_text = "" for line in r.iter_lines(): if line: chunk = json.loads(line) full_text += chunk.get("response", "") if chunk.get("done"): break print(full_text)
5. メモリ不足でモデルがロードされない
知人のインフラエンジニアがRAM 16GBのサーバーで llama3.3:70b-instruct-q4_0(約43GB)を使おうとしてOllamaがクラッシュしたケースがあります。量子化タグ(`-q4_0` `-q8_0`)はGPUメモリでの消費を抑えますが、サーバーのRAMも合算で確認が必要です。VRAM不足でGPUからCPUにフォールバックすると推論速度が大幅に低下します。`ollama ps` でメモリ使用状況を確認してください。本記事のまとめ|Ollama API連携早見表
OllamaのREST APIはシンプルなHTTP POSTで利用できます。`stream: false` を指定してcurlやPythonのrequestsで叩くのが最も手軽な出発点です。社内ツールに組み込む際は認証がないことを必ず認識し、ufwでアクセス元を絞ることが最低限のセキュリティ対策になります。20年以上Linuxサーバーを運用してきた経験から言うと、ローカルLLMの業務投入で最初に躓くのは「APIの叩き方」よりも「ネットワーク設計とアクセス制御の抜け」です。curlで動けば終わりではなく、「どこからどこへのアクセスを許可するか」を設計してから公開してください。
| やりたいこと | エンドポイント / コマンド | 備考 |
|---|---|---|
| 単発テキスト生成 | curl -s http://localhost:11434/api/generate -d '{"model":"gemma3:4b","prompt":"...","stream":false}' |
stream:falseで全文一括受信 |
| チャット形式で会話 | curl -s http://localhost:11434/api/chat -d '{"model":"gemma3:4b","messages":[...],"stream":false}' |
messagesにrole付き配列を渡す |
| APIサーバー生存確認 | curl http://localhost:11434 |
"Ollama is running"が返ればOK |
| モデル一覧取得 | curl -s http://localhost:11434/api/tags |
ローカルのモデル一覧がJSON返却 |
| PythonSDKで生成 | ollama.generate(model="gemma3:4b", prompt="...") |
pip install ollama が必要 |
| PythonSDKでチャット | ollama.chat(model="gemma3:4b", messages=[...]) |
会話履歴はmessagesリストで管理 |
| APIポートを社内限定に | sudo ufw allow from 192.168.1.0/24 to any port 11434 |
認証がないため必須のセキュリティ対策 |
| 別サーバーのOllamaに接続 | OLLAMA_HOST=http://192.168.1.100:11434 ollama list |
環境変数でURL変更可能 |
Ollama API連携から業務活用まで2日間のハンズオンで体験する
curlで叩ける状態から、Pythonで業務ツールに組み込むところまで手を動かして習得したい方向けに、「ローカルAIマスターセミナー」を開催しています。
少人数(最大8名)ZOOMハンズオン形式で実施しています。
・Ubuntu ServerでローカルLLMを構築する方法|Ollamaで機密データを外に出さず業務AIを動かす完全ガイド
・社内でChatGPTが使えないときの代替手段|機密データを守るローカルLLMという選択肢
・ローカルLLMのモデルを比較する方法|Llama3.3・Mistral・Gemma・Phi-4をUbuntuで使い分けるポイント
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます