OllamaのOpenAI互換APIを使う方法|既存OpenAIコードをそのままローカルLLMに切り替える手順

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)ローカルLLM > OllamaのOpenAI互換APIを使う方法|既存OpenAIコードをそのままローカルLLMに切り替える手順
「OllamaのAPIを試したいが、openai Pythonライブラリをそのまま使えるか分からない」
「ChatGPT APIに接続していた既存コードをローカルLLMに切り替えたいが、どこを変えれば動くのか見当がつかない」

そんな悩みを抱えるサーバー管理者やバックエンドエンジニアは多い。OllamaにはOpenAI SDKとほぼ同じ書き方で呼び出せるOpenAI互換APIが標準搭載されている。エンドポイントのベースURLを1行差し替えるだけで、既存コードがそのままローカルLLMに切り替わる。この記事では、/v1/ エンドポイントの仕組みから始まり、Python・curlによる実装例、既存ChatGPTコードの移行パターン、Function Calling(ツール呼び出し)のローカル実装、よくあるエラーの対処法まで、実務で使える手順を順を追って解説する。

この記事のポイント

・OllamaはOpenAI SDK互換の /v1/chat/completions エンドポイントを標準で提供している
・base_url・api_key(ダミー値)・モデル名の3点を変えるだけで既存OpenAIコードが動く
・Function CallingはLlama3.3・mistralで動作確認済み(Gemma 3は制限あり)
・外部公開時はOLLAMA_HOST=0.0.0.0:11434 の設定とNginx認証を組み合わせること


OllamaのOpenAI互換APIを使う方法|既存OpenAIコードをそのままローカルLLMに切り替える手順

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

OllamaのOpenAI互換APIとは何か

Ollamaはバージョン0.1.24(2024年3月)以降、/v1/ プレフィックスでOpenAI互換のエンドポイントを提供している。ネイティブAPIである /api/generate や /api/chat とは別に、OpenAI APIと同じリクエスト・レスポンス構造で推論結果を返す仕組みだ。

主な対応エンドポイントは以下の通り:

・GET /v1/models — 取得済みモデルの一覧(/api/tags 相当)
・POST /v1/chat/completions — チャット形式の推論(最もよく使う)
・POST /v1/completions — テキスト補完形式(旧来型・一部モデルのみ)
・POST /v1/embeddings — テキスト埋め込み取得(nomic-embed-text等の埋め込みモデル用)

この互換APIが整備された背景には、LangChain・LlamaIndex・Continue.devなどOpenAI SDKに依存するエコシステムが広がる中で、それらをそのままローカルで動かしたい需要が急増したことがある。Ollamaの公式ドキュメントでも「OpenAI compatibility」として明記されており、完全互換ではないが主要ユースケースはカバーされている。

なお、Ubuntu ServerへのOllama導入手順はUbuntu ServerでローカルLLMを構築する方法|Ollamaで機密データを外に出さず業務AIを動かす完全ガイドに詳しく記載している。本記事ではOllamaがすでに起動・稼働している状態を前提とする。

事前確認:Ollamaのバージョンと利用可能モデルの確認手順

1. Ollamaのバージョンを確認する

OpenAI互換APIはバージョン0.1.24以降で使用できる。まずバージョンを確認する。

# ollama version check $ ollama --version ollama version is 0.3.14

0.1.24未満の場合は公式ドキュメントの手順に従って更新すること。

2. 取得済みモデルの一覧を確認する

$ ollama list NAME ID SIZE MODIFIED llama3.3:70b-instruct-q4_0 a6eb4748fd29 42 GB 2 weeks ago mistral:7b-instruct-q8_0 f974a74358d6 7.7 GB 3 weeks ago gemma3:27b-instruct-q4_0 a2c9d9d8e37a 17 GB 1 week ago nomic-embed-text:latest 0a109f422b47 274 MB 1 month ago

この一覧に表示されるモデル名(量子化タグを含む完全な名前)が、後のAPIリクエストで指定する model 値になる。`llama3.3` だけでなく `llama3.3:70b-instruct-q4_0` のようにサフィックスまで一致させること。

Function Calling(ツール呼び出し)を使う場合は、Llama3.3 とmistral(v0.3以降)が実績がある。Gemma 3はOpenAI互換ツール定義の解釈に制限があるため、Function Callingが必要な用途では避けた方が安全だ。

3. APIがListenしているか確認する

$ curl -s http://localhost:11434/v1/models | python3 -m json.tool | head -10 { "object": "list", "data": [ { "id": "llama3.3:70b-instruct-q4_0", "object": "model", "created": 1720000000, "owned_by": "library" } ] }

JSONレスポンスが返れば接続可能な状態だ。Connection refusedが出る場合は `systemctl status ollama` でサービス状態を確認する。

OpenAI Python SDK(openai)でOllamaに接続する手順

1. openaiライブラリをインストールする

$ pip install openai $ pip show openai | grep Version Version: 1.40.0

openai 1.x以上が必要。0.x系はAPIの構造が異なるため動作しない。既存プロジェクトで古いバージョンを使っている場合は `pip install --upgrade openai` でアップグレードする。

2. クライアントを初期化してOllamaに向ける

from openai import OpenAI client = OpenAI( base_url="http://localhost:11434/v1", api_key="ollama", # ダミー値でよい(空文字は不可) )

`api_key` にはダミー文字列を渡す必要がある。openaiライブラリがapi_keyの存在を必須としているためで、Ollama側では認証チェックを行わない。`"ollama"` や `"local"` など任意の文字列で動作する。

3. チャット補完リクエストを送る

response = client.chat.completions.create( model="llama3.3:70b-instruct-q4_0", messages=[ {"role": "system", "content": "あなたはLinuxサーバー管理の専門家です。"}, {"role": "user", "content": "Ubuntuでディスク使用量を確認するコマンドを教えてください。"}, ], temperature=0.7, ) print(response.choices[0].message.content)

レスポンスの取り出し方 `response.choices[0].message.content` はOpenAI APIと完全に同じ構文で動く。

temperature・max_tokens・top_p といった主要なパラメータも同様に動作する。presence_penaltyやfrequency_penaltyはOllamaのネイティブパラメータへの変換が行われるため、挙動が微妙に異なる場合がある。

4. ストリーミングで受信する

長文生成やチャットUIではストリーミングが必要になる。

stream = client.chat.completions.create( model="llama3.3:70b-instruct-q4_0", messages=[ {"role": "user", "content": "Nginxの設定ファイルの基本構造を説明してください。"} ], stream=True, ) for chunk in stream: if chunk.choices[0].delta.content is not None: print(chunk.choices[0].delta.content, end="", flush=True) print() # 最後に改行

`stream=True` を指定するとトークンが生成されるたびにchunkが届く。LLMの応答を即時表示するチャットインターフェースや、生成の進捗をリアルタイムで見たいバッチ処理で重宝する。

curlで /v1/chat/completions を叩く実装例

シェルスクリプトや他言語からAPIを呼び出す際は、まずcurlで動作確認するのが確実だ。

1. 基本的なチャットリクエスト

$ curl -s http://localhost:11434/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "llama3.3:70b-instruct-q4_0", "messages": [ {"role": "user", "content": "Linuxでプロセス一覧を表示するコマンドは?"} ] }' | python3 -m json.tool

レスポンス(整形後):

{ "id": "chatcmpl-794", "object": "chat.completion", "created": 1720000123, "model": "llama3.3:70b-instruct-q4_0", "choices": [{ "index": 0, "message": { "role": "assistant", "content": "Linuxでプロセス一覧を表示するには ps コマンドを使います。\n$ ps aux" }, "finish_reason": "stop" }], "usage": { "prompt_tokens": 18, "completion_tokens": 42, "total_tokens": 60 } }

OpenAI API と同じ構造で返ってくることが分かる。`usage` フィールドのトークン数も含まれているため、バッチ処理のコスト管理(ローカルでも処理時間の見積もりに使える)にも役立つ。

2. ストリーミングモードでのcurl

$ curl -N http://localhost:11434/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{"model":"llama3.3:70b-instruct-q4_0","messages":[{"role":"user","content":"Dockerの基本コマンドを3つ教えてください。"}],"stream":true}'

`stream:true` を指定するとServer-Sent Events(SSE)形式で `data: {...}` チャンクが順次届く。最後に `data: [DONE]` が送られて終了する。シェルスクリプトでコンテンツを抽出する場合は `jq -r '.choices[0].delta.content // empty'` でパースするのが便利だ。

既存のChatGPTコードをローカルLLMへ切り替える移行パターン

実際の現場で想定される移行ケースを見てみる。知人のバックエンドエンジニアが社内のChatGPT連携ツールをOllamaに切り替えた際、変更した箇所はわずか3行だったと話していた。

移行前(OpenAI API):

from openai import OpenAI client = OpenAI(api_key="sk-xxxxxxxxxxxxxxxx") response = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": prompt}], temperature=0.5, ) result = response.choices[0].message.content

移行後(Ollama OpenAI互換API):

from openai import OpenAI client = OpenAI( base_url="http://localhost:11434/v1", # ← 追加 api_key="ollama", # ← 差し替え ) response = client.chat.completions.create( model="llama3.3:70b-instruct-q4_0", # ← モデル名を差し替え messages=[{"role": "user", "content": prompt}], temperature=0.5, ) result = response.choices[0].message.content # ← 変更なし

変更点はbase_url・api_key・model nameの3点だけ。レスポンスの取り出し方は完全に同じ構文で動く。環境変数でAPIキーとベースURLを管理しているプロジェクトであれば、.envファイルの書き換えのみで対応できる。

使用するモデルの精度・速度・日本語対応度の比較については、ローカルLLMのモデルを比較する方法|Llama3.3・Mistral・Gemma・Phi-4をUbuntuで使い分けるポイントで詳しく整理しているので参考にしてほしい。

社内でのChatGPT利用に情報セキュリティ上の制約がある場合、この互換APIを活用したローカル切り替えは有効な選択肢になる。導入判断の考え方は社内でChatGPTが使えないときの代替手段|機密データを守るローカルLLMという選択肢も合わせて確認してほしい。

Function Calling(ツール呼び出し)をローカルで実装する手順

Function Calling(OpenAI仕様ではtool_callsとも呼ばれる)はOllamaのOpenAI互換APIでも使用できる。Llama3.3とmistral(v0.3以降)で動作実績がある。問い合わせBotや社内ナレッジ検索など、外部処理と連携する自動化ツールをローカルで構築したい場合に有効だ。

1. ツール定義を含むリクエストを送る

from openai import OpenAI import json client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama") tools = [ { "type": "function", "function": { "name": "get_server_status", "description": "指定したサーバーの稼働状況を返す", "parameters": { "type": "object", "properties": { "hostname": { "type": "string", "description": "確認対象のホスト名またはIPアドレス" }, }, "required": ["hostname"], }, }, } ] response = client.chat.completions.create( model="llama3.3:70b-instruct-q4_0", messages=[ {"role": "user", "content": "webserver01のステータスを確認してください"} ], tools=tools, tool_choice="auto", )

2. ツール呼び出し指示を取り出す

message = response.choices[0].message if message.tool_calls: for tool_call in message.tool_calls: func_name = tool_call.function.name func_args = json.loads(tool_call.function.arguments) print(f"呼び出し関数: {func_name}") print(f"引数: {func_args}") # 出力例: # 呼び出し関数: get_server_status # 引数: {'hostname': 'webserver01'}

3. 実行結果をモデルに返して最終応答を得る

# 実際の処理(サーバーへのping・状態確認など)を実行した結果 tool_result = {"status": "running", "uptime": "15 days", "load": "0.42"} messages_with_result = [ {"role": "user", "content": "webserver01のステータスを確認してください"}, message, { "role": "tool", "tool_call_id": message.tool_calls[0].id, "content": json.dumps(tool_result, ensure_ascii=False), }, ] final_response = client.chat.completions.create( model="llama3.3:70b-instruct-q4_0", messages=messages_with_result, ) print(final_response.choices[0].message.content) # 出力例: webserver01は正常稼働中です。稼働時間は15日、現在の負荷は0.42です。

社内の障害対応ナレッジ検索や問い合わせBotのバックエンドをローカルで動かしたい場合、この構造がそのまま使える。外部にトークンを送らずに済むため、機密情報を含むシステムログや顧客データを扱う処理でも安心して組み込める。

よくあるエラーと対処法

エラー1: httpx.ConnectError: Connection refused

OllamaサービスがListenしていない状態で発生する。

$ systemctl status ollama ○ ollama.service - Ollama Service Loaded: loaded (/etc/systemd/system/ollama.service; enabled) Active: inactive (dead) $ sudo systemctl start ollama $ systemctl status ollama | grep Active Active: active (running)

エラー2: 404 / model not found

OpenAI側のモデル名(gpt-4o等)をそのまま指定した場合や、量子化タグが間違っている場合に発生する。`ollama list` で表示される完全な名前(例: `llama3.3:70b-instruct-q4_0`)を使うこと。タグなしの `llama3.3` だけでも動く場合があるが、明示的に指定した方が安全だ。

エラー3: httpx.ReadTimeout

70Bクラスの大型モデルで最初のトークン生成に時間がかかる場合に発生する。openaiクライアントのtimeoutを延ばして対処する。

client = OpenAI( base_url="http://localhost:11434/v1", api_key="ollama", timeout=300.0, # デフォルト60秒→5分に延長 )

エラー4: 外部サーバーからアクセスできない

OllamaはデフォルトでlocalhostのみでListenする。チームサーバーとして外部からアクセスさせる場合は環境変数でバインドアドレスを変更する。

$ sudo systemctl edit ollama

エディタが開いたら以下を記述して保存する:

[Service] Environment="OLLAMA_HOST=0.0.0.0:11434"

$ sudo systemctl daemon-reload && sudo systemctl restart ollama $ curl http://<サーバーIP>:11434/v1/models # 外部から確認

外部公開する場合は、ポートを直接インターネットに晒さずNginxリバースプロキシとBasic認証を組み合わせることを強く推奨する。認証なし公開は誰でもモデルを実行できる状態になる。

まとめ

OllamaのOpenAI互換APIの要点をまとめる。
操作・設定項目 コマンド・設定値
OpenAI SDKのbase_url設定 base_url="http://localhost:11434/v1"
api_keyのダミー指定 api_key="ollama"(空文字は不可)
モデル名の確認コマンド ollama list で表示される完全名を使う
ストリーミング有効化 Python: stream=True / curl: "stream":true
タイムアウト延長(70Bモデル向け) timeout=300.0 をクライアント初期化時に指定
Function Calling対応モデル Llama3.3、mistral v0.3以降
外部公開時の環境変数 OLLAMA_HOST=0.0.0.0:11434(systemd override.conf)
APIの稼働確認コマンド curl http://localhost:11434/v1/models
OllamaのOpenAI互換APIの最大の強みは、既存コードへの変更量が最小限で済む点にある。base_url・api_key・model nameの3点を差し替えるだけで、現行のOpenAI SDK依存コードがそのままローカルLLMで動く。ChatGPT APIを使っていた社内ツールをローカルに切り替えたい場合、まずこのアプローチを試すのが現実的な第一歩だ。

Function Callingも主要モデルで動作するため、社内ナレッジ検索・障害対応Botといった外部処理連携の自動化にも応用しやすい。ただし注意点として、OllamaのOpenAI互換APIはAssistants API・Files APIなどには対応していない。本番移行前に使用機能の対応可否を確認してから進めること。

OpenAI互換APIでローカルLLM連携を2日間のハンズオンで体験する

本記事で解説したOpenAI互換APIの実装から、Function Calling・RAG連携・既存システムへの組み込みまで、実機GPU環境で手を動かしながら習得したい方向けに、「ローカルAIマスターセミナー」を開催しています。
少人数(最大8名)ZOOMハンズオン形式で実施しています。

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

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

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

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

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

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

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

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

登録10秒/合わなければ解除3秒 / 詳細はこちら

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

この記事を書いた人

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

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

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