Ollama API 実践:Python と Node.js クライアント開発ガイド
ターミナルで ollama run gemma3 と打つと、画面に最初の返答が出力されます。ローカルモデルが動き出した瞬間です。
次に気になるのは、これを自分のプロジェクトに組み込めるかどうか。API キーも不要、課金も不要、ローカルで動く——これはかなり魅力的です。
ドキュメントをひと通り見てみると、公式が Python と JavaScript の SDK をそのまま提供していて、しかも OpenAI の SDK を 2 行書き換えるだけでも接続できることが分かりました。思っていたよりずっと簡単です。
ただ、簡単だからといって落とし穴がないわけではありません。ストリーミングレスポンスはどう蓄積するのか。ツール呼び出しの Agent Loop はどう書くのか。thinking モードで推論と回答をどう分けるのか。どれも一度はハマったポイントです。
この記事では、そうした落とし穴を埋めていきます。Python と Node.js の 2 言語を比較し、ネイティブ SDK と OpenAI 互換の 2 つの方式をどちらも分かりやすく解説して、完成度の高いクライアント開発ガイドをお届けします。
ちなみに、まだ Ollama を入れていない方は、まずシリーズ第 1 回の LangChain + Ollama 連携実践 を読んで、ローカルモデルを動かしておくとよいでしょう。
第 1 章:Ollama API の基礎
まずは API がどう動くのかを押さえましょう。
Ollama はデフォルトでローカルに REST API サービスを起動します。アドレスは http://localhost:11434/api です。ブラウザでこのアドレスを開くと、そっけなく「Ollama is running」と表示されます——これでサービスが正常に動いていると分かります。
主なエンドポイント
覚えておくべきコアエンドポイントは 2 つです。
| エンドポイント | 用途 | 特徴 |
|---|---|---|
/api/chat | マルチターン対話 | messages 配列をサポートし、コンテキストを渡せる |
/api/generate | シングルターン生成 | シンプルで、一度きりのタスクに向く |
もう 1 つ /v1/chat/completions があり、これは OpenAI 互換エンドポイントです。手元に既存の OpenAI プロジェクトがあれば、base_url を変えるだけで使えます。あとで詳しく説明します。
curl で試してみる
まずは最も原始的な方法で API を試します。
curl http://localhost:11434/api/chat -d '{
"model": "gemma3",
"messages": [
{ "role": "user", "content": "空はなぜ青いの?" }
]
}'
ターミナルに大量の JSON が出力されます。注目すべきは message.content フィールドで、そこにモデルの回答が入っています。
レスポンス構造はだいたいこんな形です。
{
"model": "gemma3",
"created_at": "2026-04-18T01:23:45.678Z",
"message": {
"role": "assistant",
"content": "空が青く見えるのは主に..."
},
"done": true
}
done フィールドはとても重要です。ストリーミングのときは各 chunk の done が false で、最後の chunk だけ true になります。これはあとでストリーミングを処理するときに使います。
ストリーミングレスポンス
デフォルトでは、API はモデルの生成が終わるまで待ってから一度に返します。しかし「タイプライター効果」をユーザーに見せたいなら、stream: true を付けます。
curl http://localhost:11434/api/chat -d '{
"model": "gemma3",
"messages": [{ "role": "user", "content": "空はなぜ青いの?" }],
"stream": true
}'
今度はターミナルに JSON が 1 行ずつ出てきます。各行が小さな chunk なので、それらを集めて初めて完全な回答になります。
たしかに、こうした chunk を手動で処理するのは面倒です。これこそ公式が SDK を提供している理由で——こうした細かい処理を全部まとめてくれます。
第 2 章:Python SDK 完全実践
Python の SDK は公式がメンテナンスしていて、インストールはとても簡単です。
pip install ollama
入れたらすぐ使えます。Python 3.8+ に対応していて、この点も親切です。
基本呼び出し
最もシンプルな呼び出し方は、1 行で済みます。
from ollama import chat
response = chat(
model='gemma3',
messages=[{'role': 'user', 'content': '空はなぜ青いの?'}]
)
print(response.message.content)
これだけです。chat() 関数は SDK が提供するショートカットで、内部で自動的にデフォルトの Client を作り、ローカルの Ollama サービスに接続します。
接続パラメータをカスタマイズしたい場合——たとえば Ollama を別のマシンで動かしているとき——は、自分で Client を作れます。
from ollama import Client
client = Client(host='http://192.168.1.100:11434')
response = client.chat(model='gemma3', messages=[...])
ストリーミングレスポンス
ストリーミングは重要なポイントです。長く待たされた末に突然全部が出るのではなく、文字が少しずつ出てくる様子をユーザーに見せる必要があります。
from ollama import chat
stream = chat(
model='gemma3',
messages=[{'role': 'user', 'content': '空はなぜ青いの?'}],
stream=True,
)
for chunk in stream:
print(chunk['message']['content'], end='', flush=True)
ここに落とし穴があります。chunk はオブジェクトではなく辞書で返ってきます。なのでアクセス方法は chunk.message.content ではなく chunk['message']['content'] です。私も最初にここでハマり、エラーが出てしばらく原因が分かりませんでした。
非同期クライアント
アプリが非同期アーキテクチャの場合——たとえば FastAPI や aiohttp を使っているとき——は、非同期クライアントを使います。
import asyncio
from ollama import AsyncClient
async def main():
client = AsyncClient()
# 非ストリーミング
response = await client.chat(
model='gemma3',
messages=[{'role': 'user', 'content': 'こんにちは'}]
)
print(response.message.content)
# ストリーミング
stream = await client.chat(
model='gemma3',
messages=[{'role': 'user', 'content': '空はなぜ青いの?'}],
stream=True,
)
async for chunk in stream:
print(chunk['message']['content'], end='', flush=True)
asyncio.run(main())
非同期ストリーミングは async generator を返すので、async for で反復します。同期版とロジックは同じで、await と async を加えるだけです。
Cloud Models
おもしろいことに、Ollama SDK はクラウドモデルもサポートしています。大きいモデルはローカルでは動かしきれないものもあります——たとえば 120B の gpt-oss——が、クラウドなら動きます。
from ollama import chat
response = chat(
model='gpt-oss:120b-cloud',
messages=[{'role': 'user', 'content': 'こんにちは'}]
)
モデル名に -cloud サフィックスを付けると、クラウド API 経由になります。もちろん Ollama のクラウドアカウントと API キーが必要で、設定方法はローカルとは少し違います。興味があれば公式ドキュメントを参照してください。
正直なところ、この機能はかなり実用的です。小さいモデルはローカルで動かしてコストを抑え、大きいモデルはクラウドで動かしてハードウェアを節約する。このハイブリッド方式はなかなか魅力的です。
第 3 章:Node.js SDK 完全実践
Node.js の SDK も同じくシンプルです。
npm i ollama
このパッケージは Node.js とブラウザ環境の両方に対応している点に注意してください。ブラウザ版は個別にインポートします。
// Node.js
import ollama from 'ollama'
// ブラウザ
import ollama from 'ollama/browser'
基本呼び出し
Node.js はデフォルトで非同期なので、書きやすいです。
import ollama from 'ollama'
const response = await ollama.chat({
model: 'gemma3',
messages: [{ role: 'user', content: '空はなぜ青いの?' }],
})
console.log(response.message.content)
Python 版と比べてみましょう。Python は辞書で messages を渡し、Node.js はオブジェクトで渡します。パラメータ名はほぼ同じなので、言語を変えても概念を学び直す必要はありません。
ストリーミングレスポンス
Node.js のストリーミング処理は、もともと非同期 generator です。
import ollama from 'ollama'
const stream = await ollama.chat({
model: 'gemma3',
messages: [{ role: 'user', content: '空はなぜ青いの?' }],
stream: true,
})
for await (const chunk of stream) {
process.stdout.write(chunk.message.content)
}
ここでは console.log ではなく process.stdout.write を使います。console.log は自動で改行してしまうからです。文字が 1 つ出るたびに改行されては困りますよね。
カスタム設定
SDK は host と headers のカスタマイズに対応しています。
import ollama from 'ollama'
// host をカスタマイズ
const client = new ollama.Ollama({ host: 'http://192.168.1.100:11434' })
// またはグローバル設定で
ollama.setDefaultHost('http://192.168.1.100:11434')
// headers を追加(たとえば認証)
const stream = await ollama.chat({
model: 'gemma3',
messages: [{ role: 'user', content: 'こんにちは' }],
headers: { Authorization: 'Bearer xxx' },
})
headers パラメータはなかなか便利です。Ollama サービスの前段に認証プロキシを置いている場合、ここでトークンを渡せます。
ストリーミング生成のキャンセル
進行中のストリーミング生成をキャンセルできる abort() メソッドがあります。
import ollama from 'ollama'
const stream = await ollama.chat({
model: 'gemma3',
messages: [{ role: 'user', content: '長文を書いて...' }],
stream: true,
})
// ユーザーが停止ボタンを押した
ollama.abort()
for await (const chunk of stream) {
// abort 後はループが早めに終了する
process.stdout.write(chunk.message.content)
}
この機能はチャット画面を作るときに欠かせません。モデルが冗長な文章を書き終えるのを待ちたくないユーザーは、ボタン 1 つで止められます。
ブラウザ版
ブラウザでの使い方も似ていますが、いくつか違いがあります。
import ollama from 'ollama/browser'
// ブラウザではストリーミングしか使えない。ネイティブ API が非ストリーミングのクロスオリジンに対応しないため
const stream = await ollama.chat({
model: 'gemma3',
messages: [{ role: 'user', content: 'こんにちは' }],
stream: true,
})
for await (const chunk of stream) {
document.getElementById('output').textContent += chunk.message.content
}
ブラウザ版には制約があります。必ずストリーミングモードを使うことです。Ollama API の非ストリーミングリクエストは大きな JSON を一度に返すため、クロスオリジンではタイムアウトやブロックが起きやすいからです。ストリーミングリクエストは chunk に分かれているので、問題はずっと少なくなります。
この設計は理にかなっています。ブラウザでチャット UI を作るなら、もともとストリーミング表示が必要だからです。
第 4 章:ツール呼び出し実践
ツール呼び出しはエージェントを作る基礎です。Ollama では、自分で定義した関数をモデルに呼び出させ、その戻り値をもとに回答の生成を続けさせられます。
Python SDK にはとても便利な特性があります。Python 関数をそのままツールとして渡すと、SDK が関数の docstring とパラメータの型を自動で解析してくれます。
Python 関数の自動解析
def get_weather(city: str) -> str:
"""指定した都市の天気情報を取得する
Args:
city: 都市名。例:「東京」「大阪」
Returns:
天気を表す文字列
"""
# ダミーデータ
weather_data = {
'東京': '晴れ、気温 18°C',
'大阪': '曇り、気温 22°C',
'福岡': '雨、気温 26°C',
}
return weather_data.get(city, f'{city} の天気データが見つかりません')
from ollama import chat
response = chat(
model='qwen3',
messages=[{'role': 'user', 'content': '東京の今日の天気は?'}],
tools=[get_weather],
)
print(response.message.content)
SDK が関数を自動でツール定義の形式に変換します。名前は関数名から、説明は docstring から、パラメータは型アノテーションから取ります。自分で JSON Schema を手書きする手間が省けます。
Agent Loop 方式
しかし、そう単純ではありません。モデルは複数のツールを呼ぶこともあれば、ツールを呼んだあとにさらに続けて呼びたがることもあります。これを処理するにはループが必要です。
それが Agent Loop です。
from ollama import chat
def add(a: int, b: int) -> int:
"""足し算"""
return a + b
def multiply(a: int, b: int) -> int:
"""掛け算"""
return a * b
tools = [add, multiply]
tool_map = {'add': add, 'multiply': multiply}
messages = [{'role': 'user', 'content': '(3 + 5) * 2 を計算して'}]
while True:
response = chat(model='qwen3', messages=messages, tools=tools)
if response.message.tool_calls:
# モデルがツールを呼びたがっている
for call in response.message.tool_calls:
func_name = call.function.name
func_args = call.function.arguments
result = tool_map[func_name](**func_args)
# ツール呼び出しの結果をメッセージ履歴に追加
messages.append({
'role': 'tool',
'content': str(result),
'tool_name': func_name,
})
else:
# モデルがツールを呼ばなかった=終了
print(response.message.content)
break
ロジックはこうです。
- ツール定義を付けてモデルにメッセージを送る
- モデルが
tool_callsを返したら、対応する関数を実行する - 関数の結果をメッセージ履歴に戻して、再びモデルに送る
- モデルがツールを呼ばなくなるまで繰り返す
この方式はエージェントを作るときに欠かせません。ツール関数をいくつも定義しておけば、いつ・どれを・どの順で呼ぶかはモデルが自分で判断します。
thinking モード
一部のモデル——たとえば qwen3——は thinking モードに対応しています。モデルはまず「考えて」から回答を出します。
from ollama import chat
stream = chat(
model='qwen3',
messages=[{'role': 'user', 'content': '空はなぜ青いの?'}],
stream=True,
think=True,
)
thinking = ''
content = ''
for chunk in stream:
if chunk.message.thinking:
thinking += chunk.message.thinking
elif chunk.message.content:
content += chunk.message.content
print('=== 思考プロセス ===')
print(thinking)
print('=== 最終回答 ===')
print(content)
thinking モードでは、chunk に thinking フィールドが追加されます。思考内容と最終回答を別々に蓄積する必要があります。
この機能はなかなかおもしろいです。モデルがどう一歩ずつ答えを導いたのかが見えます。教育系アプリやプロンプトのデバッグにとても役立ちます。
第 5 章:ネイティブ SDK vs OpenAI 互換 API
ここまでで、選択肢は 2 つあります。
- Ollama ネイティブ SDK を使う(これまで説明したもの)
- OpenAI SDK を使い、アドレスを変えるだけで Ollama に接続する
どちらがよいかは状況次第です。
OpenAI 互換方式
手元に既存の OpenAI プロジェクトがあるなら、最も移行コストが低いのは base_url を変える方法です。
from openai import OpenAI
client = OpenAI(
base_url='http://localhost:11434/v1',
api_key='ollama', # 必須だが無視される
)
response = client.chat.completions.create(
model='gemma3',
messages=[{'role': 'user', 'content': '空はなぜ青いの?'}],
)
print(response.choices[0].message.content)
これだけです。OpenAI SDK は裏で動いているのが Ollama だとはまったく気づきません。あくまで「OpenAI API」と話していると思っています。
Node.js 版も同じです。
import OpenAI from 'openai'
const client = new OpenAI({
baseURL: 'http://localhost:11434/v1',
apiKey: 'ollama',
})
const completion = await client.chat.completions.create({
model: 'gemma3',
messages: [{ role: 'user', content: '空はなぜ青いの?' }],
})
console.log(completion.choices[0].message.content)
2 つの方式の比較
| 観点 | ネイティブ SDK | OpenAI 互換 |
|---|---|---|
| インストール | pip install ollama | OpenAI SDK があればよい |
| ツール呼び出し | 関数の docstring を自動解析 | JSON Schema を手書き |
| ストリーミング | 辞書形式の chunk | 標準の OpenAI 形式 |
| Cloud Models | 対応 | 非対応 |
| 移行コスト | 新規はコストなし | 既存プロジェクトは極めて低い |
選び方の指針
新規プロジェクト:ネイティブ SDK を使いましょう。
理由は次のとおりです。
- ツール呼び出しが手軽。Python 関数をそのままツールとして渡せる
- 対応機能が多い(Cloud Models、thinking モード)
- ドキュメントとサンプルが公式のもので、困ったときに調べやすい
既存 OpenAI プロジェクトの移行:OpenAI 互換方式を使いましょう。
理由は次のとおりです。
- 2 行変えるだけで動く
- ロジックを書き直す必要がない
- あとで OpenAI に戻したいときも簡単
ひとことでまとめると、ネイティブ SDK は機能が充実、OpenAI 互換は移行が速い。あなたのニーズ次第です。
正直、私はどちらも試しました。ネイティブ SDK のツール呼び出しはたしかに楽です——JSON Schema の定義を自分で書かなくても、関数の docstring を丁寧に書くだけで済みます。ただ、すでに OpenAI で動いているプロジェクトなら、Ollama を使うためだけに全面的にリファクタリングする必要はありません。
おわりに
ここまで色々話しましたが、いくつかの要点をまとめます。
基本呼び出し:Python も Node.js も SDK の作りが丁寧で、数行のコードで動きます。ストリーミングは stream=True で有効化するのを忘れずに。
ツール呼び出し:Agent Loop がコアの方式です——モデルがツールを呼ばなくなるまで tool_calls をループ処理します。Python SDK は関数をそのままツールとして渡せるので、JSON Schema を書く手間が省けます。
thinking モード:qwen3 などのモデルが対応し、モデルの思考プロセスを見られます。chunk の中で thinking と content のフィールドを別々に処理しましょう。
方式の選択:新規プロジェクトは機能が充実したネイティブ SDK、既存の OpenAI プロジェクトはアドレスを変えるだけの互換方式を。
次のステップとしては、こんなことをおすすめします。
- まだ Ollama を入れていないなら、シリーズ第 1 回を読んでローカルモデルを動かす
- プロジェクトに合う方式(ネイティブか OpenAI 互換か)を 1 つ選んで、実際に試してみる
- 公式ドキュメントは更新され続け、新機能も次々と追加されるので、時間があるときに目を通す
ローカルで LLM を動かすことのハードルは、どんどん下がっています。Ollama は複雑な部分をシンプルな API の裏に隠してくれます。あなたは呼び出し方さえ知っていればよく、あとは任せられます。
これがこのシリーズの第 2 回でした。次回は Modelfile のカスタマイズについて——モデルを自分の望む形に仕立てる方法を解説します。
Ollama API クライアント開発
Python または Node.js の SDK で Ollama のローカルモデル API を呼び出すための完全ガイド
⏱️ 目安時間: 45 分
- 1
ステップ1: SDK をインストールして基本呼び出しを試す
Python ユーザーは `pip install ollama`、Node.js ユーザーは `npm i ollama` を実行します。
インストールが終わったら、最もシンプルなコードで接続を確認しましょう。
```python
from ollama import chat
response = chat(model='gemma3', messages=[{'role': 'user', 'content': 'こんにちは'}])
print(response.message.content)
```
Ollama サービスが起動していること(デフォルトポートは 11434)と、対応するモデルがダウンロード済みであることを確認してください。 - 2
ステップ2: ストリーミングレスポンスを実装する
ストリーミングモードを有効にして、文字が少しずつ出力される様子をユーザーに見せます。
```python
from ollama import chat
stream = chat(model='gemma3', messages=[...], stream=True)
for chunk in stream:
print(chunk['message']['content'], end='', flush=True)
```
chunk は辞書で返ってくる点に注意。`chunk['message']['content']` でアクセスします。 - 3
ステップ3: ツール呼び出しを設定する(任意)
Python 関数をツールとして定義すると、SDK が docstring と型アノテーションを自動で解析します。
```python
def get_weather(city: str) -> str:
"""都市の天気情報を取得"""
return f'{city}: 晴れ'
response = chat(model='qwen3', messages=[...], tools=[get_weather])
```
Agent Loop を実装すれば、モデルが最終回答を返すまで複数回のツール呼び出しを処理できます。 - 4
ステップ4: ネイティブか OpenAI 互換かを選ぶ
新規プロジェクトには機能が充実したネイティブ SDK(Cloud Models、thinking モード)がおすすめです。
既存の OpenAI プロジェクトなら 2 行変えるだけ。
```python
client = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')
```
移行コストはごくわずかで、いつでも OpenAI に戻せます。
FAQ
Ollama API のデフォルトのポートとアドレスは?
Python SDK のストリーミングレスポンスはどんな型で返る?
Node.js SDK はブラウザ環境でどんな制約がある?
Agent Loop 方式とは?
thinking モードで思考プロセスと最終回答を別々に取得するには?
ネイティブ SDK と OpenAI 互換方式はどう選ぶ?
4分で読めます · 公開日: 2026年4月18日 · 更新日: 2026年6月1日
Ollama ローカル LLM 実践ガイド
検索からこのページに来た場合は、前後の記事もあわせて読むと同じテーマの理解がかなり早く深まります。
前の記事
Ollama GPU アクセラレーション設定:CUDA・ROCm・Metal 全プラットフォーム実践ガイド
Ollama の GPU アクセラレーション完全ガイド。NVIDIA CUDA、AMD ROCm、Apple Metal の 3 プラットフォーム設定、検証手順、マルチ GPU、トラブルシューティングまで。ローカル LLM の推論速度を 10〜20 倍に引き上げます。
第 15 / 18 記事
次の記事
Ollama モデル量子化実践:GGUF フォーマットと精度損失の完全解説
Ollama の GGUF 量子化の仕組みを詳解。Red Hat の 50 万件超の評価データから精度損失の真相を明らかにし、ハードウェア構成ごとの量子化選択指針を提示。コンシューマー向け GPU で大規模モデルを動かす方法を解説します。
第 17 / 18 記事
関連記事
Ollama 入門:ローカルで大規模言語モデルを動かす第一歩
Ollama 入門:ローカルで大規模言語モデルを動かす第一歩
Ollama モデル管理:ダウンロード、切り替え、削除とバージョン管理の完全ガイド
Ollama モデル管理:ダウンロード、切り替え、削除とバージョン管理の完全ガイド
Ollama Modelfile パラメータ徹底解説:専用カスタムモデルを作る完全ガイド
コメント
GitHubアカウントでログインしてコメントできます