OllamaでJSON Schema出力を作る入門
CHATGPT / AIChatGPTなどの生成AIを活用して運営・記事制作・更新を行っています。制作方針
OllamaのローカルAPIへ小さなJSON Schemaを渡し、非ストリーミング応答をJSONとして取り出して必須項目と型を確認するまでを、失敗時の戻し方とともに解説します。

先に結論
OllamaのローカルAPIでは、/api/chatのformatへJSON Schemaを渡すと、自由文ではなく指定した形のJSONを生成させられます。ただし、生成時の制約とアプリ側の検証は別工程です。応答をそのまま保存や画面表示へ渡さず、外側のAPI応答を読み、message.contentをJSONとしてparseし、必須fieldと型をもう一度確認します。
この記事ではsummaryとkeywordsだけの小さなschemaを使い、最初の成功、成功確認、失敗時の戻し方まで進めます。Ollama Cloudは2026年8月3日時点で構造化出力に対応していないため、対象は手元のOllamaが提供するlocalhost:11434のAPIだけです。
確認日時: 2026年8月3日 19:15(Asia/Tokyo)
固定した版: Ollama v0.32.0(commitf1a0ffd、2026年7月11日公開)を基準に、2026年8月3日の公式API docsを再確認
検証区分: 公式documentationとreleaseを照合した机上調査です。Ollamaの起動、model取得、生成結果、schema追従率は実機検証していません。掲載するjq式は構文を確認しますが、特定modelでの成功を保証しません。
対象外: Ollama Cloud、OpenAI互換endpoint、画像入力、tool calling、production向け外部公開
構造化出力で分ける2つの仕事
JSON Schemaは、JSON documentに必要なpropertyや型を記述する仕様です。Ollama公式の構造化出力docsは、formatへ”json”またはJSON Schemaを渡せると説明しています。単に”json”を指定する場合と違い、schemaを渡せば「objectである」「summaryは文字列」「keywordsは文字列の配列」といった形を要求できます。
ただし、安全にアプリへ組み込むには次の2段階を分けます。
- 生成制約: Ollamaへschemaを渡し、modelが期待する形を作りやすくする
- 受信後の検証: HTTP応答と
message.contentをparseし、必須fieldと型をアプリ側で確認する
公式docsも、PythonではPydantic、JavaScriptではZodからschemaを作り、返されたcontentを同じ型定義で検証する例を示しています。構造化出力は「検証不要になる機能」ではなく、生成と検証の契約を同じschemaへ揃える機能と理解すると実装を分けやすくなります。
始める前の確認
この記事はOllamaをinstall済みで、少なくとも1つのlocal modelを取得済みの人を対象にします。まず既存状態を壊さないread-onlyのcommandで確認します。
ollama --version
ollama list
ollama ps
以下の例は公式docsと同じgpt-ossというmodel名を使います。手元にない場合は勝手に別modelをdownloadせず、ollama listに表示されたmodel名へ置き換えてください。modelによってschemaへの追従は変わり得るため、model名とtagは検証記録に残します。
Ollama APIの既定はstreamingです。今回は完成した1つの応答を確認しやすくするため、stream: falseを必ず指定します。streamingを使う場合は、断片を連結してから検証する別実装が必要です。
最短手順:Schemaを渡して1回呼ぶ
1. request JSONを作る
shellのquote崩れを避けるため、jqで正しいJSONを組み立てます。入力文も固定し、最初はpropertyを2つだけにします。
jq -n --arg model "gpt-oss" '{
model: $model,
messages: [{
role: "user",
content: "次の文章を1文で要約し、重要語を最大3件挙げてください。文章: ローカルAPIでは入力を端末内で処理できる構成を選べます。"
}],
stream: false,
format: {
type: "object",
properties: {
summary: {type: "string"},
keywords: {type: "array", items: {type: "string"}}
},
required: ["summary", "keywords"]
},
options: {temperature: 0}
}' > ollama-request.json
jq empty ollama-request.json
最後のcommandが何も表示せず終了code 0なら、request file自体はJSONとして読めます。temperature: 0は結果の揺れを抑えるための出発点で、同じ回答を保証する値ではありません。公式docsも構造化出力の再現性を高める方法として低いtemperatureを案内しています。
2. local APIへ送る
curl --fail-with-body --silent --show-error \
-H 'Content-Type: application/json' \
--data-binary @ollama-request.json \
http://localhost:11434/api/chat \
> ollama-response.json
ここで失敗した場合、空の成功結果として扱って次へ進んではいけません。curlがnon-zeroならollama-response.jsonをアプリ入力へ渡さず、「つまずきやすい点」でservice、model名、requestの順に戻します。
3. 外側と内側を順番に確認する
OllamaのAPI応答そのものがJSONで、その内側のmessage.contentにもmodelが生成したJSON文字列が入ります。2層を混同せず検査します。
# API応答全体がJSONか
jq empty ollama-response.json
# contentがJSONで、必須fieldの型が合うか
jq -e '
(.message.content | fromjson) as $doc
| (($doc | type) == "object")
and (($doc.summary | type) == "string")
and (($doc.keywords | type) == "array")
and all($doc.keywords[]; type == "string")
' ollama-response.json
# 検証後のdocumentだけを表示する
jq '.message.content | fromjson' ollama-response.json
3つのcommandが成功して初めて、この例の「最初の成功」です。画面に波括弧が見えただけ、HTTP 200だっただけ、fromjsonに通っただけでは、必須fieldと型の確認は完了していません。
成功確認のチェックリスト
curlが終了code 0で、API応答全体をjqが読めるmessage.contentをfromjsonでparseできるsummaryが存在し、文字列であるkeywordsが存在し、すべての要素が文字列である- 検証前のcontentをDB更新、command実行、HTML生成などへ使っていない
このjq式は今回の小さなschemaだけを確認する最短例です。文字数、列挙値、入れ子、日付形式、余分なpropertyの禁止まで必要なら、PydanticやZodなどのJSON Schema対応validatorで同じschemaを再利用してください。
つまずきやすい点と戻し方
localhostへ接続できない
curlが接続を拒否されたら、schemaを変更する前にollama —versionとollama psへ戻ります。serviceをどう起動するかはOSとinstall方法で異なるため、推測でsystem設定を変更せず、公式Troubleshootingの該当platform手順を確認してください。
modelが見つからない
HTTP errorにmodel未取得が示されたら、ollama listの正確な名前とtagをrequestへ反映します。記事の例に合わせるためだけに大型modelを取得する必要はありません。元のrequest fileを残し、—arg modelの値だけを変更すれば戻せます。
contentがJSONとして読めない
fromjsonが失敗した結果は利用せず、raw responseを別名で保全します。最初はschemaを小さく保ち、temperatureを0、streamをfalseに固定します。それでも失敗する場合は、model名、Ollama version、schema、promptを記録して別modelとの比較対象にします。成功するまで無制限にretryすると負荷と待ち時間が読めなくなるため、アプリ側では上限を決めます。
JSONにはなったが内容が用途に合わない
Schemaが保証するのは主に形です。要約が事実に合うか、keywordが適切か、危険な文字列でないかは別の意味検証です。schemaへ制約を足す前に、アプリ側の許容条件を決め、失敗時は保存や後続処理を止めます。
Cloud endpointで同じrequestを送っている
2026年8月3日の公式docsはOllama Cloudが構造化出力に未対応と明記しています。local APIで成功したrequestをCloudへそのまま移植できるとは限りません。本記事の手順はlocalhost:11434に限定し、外部公開やCloud移行は適用外です。
さらに深く理解する
schemaを複雑にする前に、成功/失敗を記録する測定単位を決めます。Ollama構造化出力の玄人向け検証記事では、生成制約と型検証を二重化し、schema複雑度、temperature、streaming、model差を混ぜずに評価する方法を整理します。
Ollama自体とllama.cppの役割を先に比較したい場合は、Ollamaとllama.cppの用途別比較を参照してください。
参考資料
- Ollama公式:Structured Outputs(2026年8月3日確認)
- Ollama公式:POST /api/chat(2026年8月3日確認)
- Ollama公式:Streaming(2026年8月3日確認)
- Ollama公式GitHub:v0.32.0(2026年7月11日公開、2026年8月3日確認)


