API リファレンス

LLM AI Server with llama.cpp が端末内で公開する HTTP API の仕様と使用例です。Ollama 互換エンドポイント(/api/*)と OpenAI 互換エンドポイント(/v1/*)、および llama.cpp WebUI 互換エンドポイント(/props, /slots ほか)を、現行の OllamaApiServer 実装をもとに整理しています。

関連文書: 操作マニュアル | 技術仕様 | プライバシーポリシー

Ollama 互換 OpenAI 互換 SSE / NDJSON streaming Multimodal Tools / Function Calling

目次

1. 基本情報

2. 互換性サマリ

主要なチャット / 生成クライアントが利用する範囲では Ollama・OpenAI の両仕様と互換です。一方で、本アプリは「端末内 1 モデル・1 推論」を前提とした実装のため、一部の管理系エンドポイントや統計フィールドは提供しません。

区分内容
Ollama 互換(実装済み)POST /api/generatePOST /api/chatGET/POST /api/tags。応答形は {model, created_at, response|message, done} 系で互換。ツール利用時は done_reasontool_callsreasoning_content を追加。
OpenAI 互換(実装済み)POST /v1/chat/completions(streaming は SSE、終端 data: [DONE])、GET /v1/modelsobjectchoices[].message/deltafinish_reason を返却。
llama.cpp WebUI 互換GET /propsGET /slotsGET /health/v1/health)、GET /models、Bundled WebUI 配信。
拡張(独自)マルチモーダル入力(image_url / input_audio)、共有 MCP / Function Definitions 設定、reasoning_content、パフォーマンス指標を本文末尾に付記するオプション。
未実装(注意点)OpenAI 応答に id / created / usage含まれません。Ollama 応答に total_duration / eval_count / prompt_eval_count / context などの統計は含まれません。埋め込み(/api/embed, /v1/embeddings)、モデル管理(/api/show, /api/pull, /api/ps, /api/version)、/v1/completions(旧 completions)は提供しません。

トークン使用量などの統計が必要な場合は、出力設定の「パフォーマンス指標を表示」を有効にすると、生成完了後にトークン数・処理時間・速度が本文末尾(OpenAI は最終 delta、Ollama は追加 chunk)に付記されます。

3. 共通仕様

3-1. 同時実行と待機キュー

3-2. エラー応答

/api/* 系はプレーンな JSON / テキストでエラーを返し、/v1/* 系は OpenAI 形式のエラーオブジェクトを返します。

// /v1/* のエラー形式
{
  "error": {
    "message": "No messages provided",
    "type": "invalid_request_error",
    "code": 400
  }
}
ステータス意味
400JSON 不正、必須項目欠落、非対応の content[].type、未対応モダリティ など
404未定義の経路
405非対応の HTTP メソッド
500設定ロード失敗、生成失敗 など
503ビジー(キュー満杯 / 待機タイムアウト / リセット進行中)

4. POST/api/generate

単一プロンプトからの生成(Ollama generate 互換)。既定で streaming(NDJSON)。

リクエスト

フィールド説明
modelstringプロファイル名。未指定時は "default"
promptstringユーザープロンプト。
systemstring?任意。システムプロンプト(設定側より優先)。
streambool既定 truefalse で一括応答。
toolsarray?任意。指定すると内部ツール実行ループに切り替わります(12 章)。

非ストリーミング応答

curl http://localhost:11434/api/generate -d '{
  "model": "my-profile",
  "prompt": "日本の首都は?",
  "stream": false
}'
{
  "model": "my-profile",
  "created_at": "2026-06-14T03:10:00Z",
  "response": "日本の首都は東京です。",
  "done": true
}

ストリーミング応答(NDJSON)

1 行 1 JSON。各 chunk は "done": falseresponse に部分文字列。最後に "done": true の chunk を送出します。

{"model":"my-profile","created_at":"...","response":"日本","done":false}
{"model":"my-profile","created_at":"...","response":"の首都は","done":false}
{"model":"my-profile","created_at":"...","response":"","done":true}

5. POST/api/chat

messages 配列による会話生成(Ollama chat 互換)。既定で streaming(NDJSON)。

リクエスト

フィールド説明
modelstringプロファイル名。未指定時は "default"
messagesarray必須。{role, content} の配列。rolesystem / user / assistant / toolcontent は文字列、またはマルチモーダル用の配列(11 章)。
streambool既定 true
toolsarray?任意(12 章)。

非ストリーミング応答

curl http://localhost:11434/api/chat -d '{
  "model": "my-profile",
  "stream": false,
  "messages": [
    {"role": "system", "content": "あなたは簡潔に答えるアシスタントです。"},
    {"role": "user", "content": "富士山の標高は?"}
  ]
}'
{
  "model": "my-profile",
  "created_at": "2026-06-14T03:10:00Z",
  "message": { "role": "assistant", "content": "3,776 m です。" },
  "done": true
}

ストリーミング応答(NDJSON)

{"model":"my-profile","created_at":"...","message":{"role":"assistant","content":"3,776"},"done":false}
{"model":"my-profile","created_at":"...","message":{"role":"assistant","content":" m です。"},"done":false}
{"model":"my-profile","created_at":"...","message":{"role":"assistant","content":""},"done":true}

6. GETPOST/api/tags

利用可能なモデル(プロファイル)一覧。Ollama tags 互換。

curl http://localhost:11434/api/tags
{
  "models": [
    {
      "name": "my-profile",
      "model": "my-profile",
      "modified_at": "2026-06-14T03:10:00Z",
      "size": 0,
      "details": {
        "format": "gguf",
        "family": "llama",
        "parameter_size": "unknown",
        "quantization_level": "unknown"
      }
    }
  ]
}

sizeparameter_size 等は端末側で確定できないため固定値(0 / "unknown")です。より詳しい状態・モダリティが必要な場合は /v1/models を使ってください。

7. POST/v1/chat/completions

OpenAI Chat Completions 互換。既定で streaming(SSE)。OpenAI 公式 SDK の base_url をこのサーバーに向けるだけで利用できます。

リクエスト

フィールド説明
modelstringプロファイル名。空 / 未指定時は現在ロード中のモデル、なければ既定プロファイルに解決されます。
messagesarray必須。OpenAI 形式。content は文字列または {type, ...} パーツ配列(11 章)。
streambool既定 true
tools / tool_choice / parallel_tool_callsarray / any / bool任意(12 章)。
サンプリング各種number 等temperature, top_p, top_k, min_p, presence_penalty, frequency_penalty ほか(10 章)。リクエスト単位で設定を上書きします。

非ストリーミング応答

curl http://localhost:11434/v1/chat/completions -d '{
  "model": "my-profile",
  "stream": false,
  "messages": [
    {"role": "user", "content": "Say hello in Japanese."}
  ]
}'
{
  "object": "chat.completion",
  "model": "my-profile",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "こんにちは!" },
      "finish_reason": "stop"
    }
  ]
}

注意: 本アプリの応答には id / created / usage は含まれません。これらを必須とする一部クライアントでは欠落として扱われます。

ストリーミング応答(SSE)

先頭に delta.role="assistant" の chunk、続いて delta.content を持つ chunk 群、最後に finish_reason:"stop" の chunk と data: [DONE] を送出します。

data: {"object":"chat.completion.chunk","model":"my-profile","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}

data: {"object":"chat.completion.chunk","model":"my-profile","choices":[{"index":0,"delta":{"content":"こん"},"finish_reason":null}]}

data: {"object":"chat.completion.chunk","model":"my-profile","choices":[{"index":0,"delta":{"content":"にちは!"},"finish_reason":null}]}

data: {"object":"chat.completion.chunk","model":"my-profile","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: [DONE]

8. GET/v1/models・/models

OpenAI 互換のモデル一覧に加え、llama.cpp WebUI 向けの models 配列(状態・モダリティ)も同時に返します。

curl http://localhost:11434/v1/models
{
  "object": "list",
  "data": [
    {
      "id": "my-profile",
      "name": "my-profile",
      "object": "model",
      "owned_by": "llamacpp",
      "created": 1781000000,
      "in_cache": true,
      "path": "/data/.../my-model.gguf",
      "status": { "value": "loaded" },
      "tags": []
    }
  ],
  "models": [
    {
      "name": "my-profile",
      "model": "my-profile",
      "modified_at": "2026-06-14T03:10:00Z",
      "size": 4100000000,
      "capabilities": ["multimodal"],
      "modalities": { "vision": true, "audio": false },
      "details": { "format": "gguf", "family": "llama", "parameter_size": "unknown", "quantization_level": "unknown" }
    }
  ]
}

data[] が OpenAI 互換、models[] が llama.cpp WebUI 互換です。modalities はロード済みモデルなら実際の対応状況、未ロードならファイルからの推定値を返します。

9. GET/props・/slots・/health

主に同梱 WebUI(llama.cpp 風)の初期化に使われるエンドポイントです。?model=<プロファイル名> で対象を指定できます。

curl "http://localhost:11434/props?model=my-profile"

10. サンプリングパラメータ

/v1/chat/completions ではリクエスト本文に次のキーを含めると、そのリクエストのあいだ設定値を上書きします(指定しなかった項目はプロファイルの値を使用)。

キー対応する設定
temperaturenumber温度
top_kintTop-k
top_pnumberTop-p
min_pnumberMin-p
typ_pnumberTypical-p
dynatemp_range / dynatemp_exponentnumberDynamic temperature
xtc_probability / xtc_thresholdnumberXTC サンプラー
repeat_last_nintPenalty 対象トークン数
repeat_penaltynumberRepeat penalty
presence_penalty / frequency_penaltynumberPresence / Frequency penalty
dry_multiplier / dry_base / dry_allowed_length / dry_penalty_last_nnumber / intDRY サンプラー
mirostat / mirostat_tau / mirostat_etaint / numberMirostat

n_predict: 0 を指定すると pre-encode のみを行い、空応答で早期復帰します(プロンプト評価のウォームアップ用)。

11. マルチモーダル入力

/api/chat/v1/chat/completions では、content をパーツ配列にすることで画像・音声を渡せます。ロード中のモデルが vision / audio に対応している必要があり、非対応の場合は 400 を返します。

type説明
text / input_textテキスト(text フィールド)。
image_urlimage_url.url に HTTP/HTTPS の画像 URL、または data:image/...;base64, 形式の data URL。リモート取得は 10MB 上限。
input_audioinput_audio.data(base64)と input_audio.format"wav" または "mp3")。
curl http://localhost:11434/v1/chat/completions -d '{
  "model": "my-vision-profile",
  "stream": false,
  "messages": [
    {
      "role": "user",
      "content": [
        {"type": "text", "text": "この画像を説明して"},
        {"type": "image_url", "image_url": {"url": "data:image/jpeg;base64,/9j/4AAQ..."}}
      ]
    }
  ]
}'
// 音声入力(wav / mp3)
{
  "role": "user",
  "content": [
    {"type": "text", "text": "この音声を文字起こしして"},
    {"type": "input_audio", "input_audio": {"data": "UklGR...", "format": "wav"}}
  ]
}

12. ツール / Function Calling

リクエストに tools を渡すか、アプリの「MCP 設定」で共有 MCP / Function Definitions を有効にすると、内部ツール実行ループに切り替わります。/api/generate/api/chat/v1/chat/completions のいずれでも利用できます。

// OpenAI 互換のツール定義例(非ストリーミング応答の一部)
{
  "object": "chat.completion",
  "model": "my-profile",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "",
        "tool_calls": [
          {
            "id": "call_1",
            "type": "function",
            "function": { "name": "get_weather", "arguments": "{\"city\":\"Tokyo\"}" }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ]
}

13. クライアント例

OpenAI Python SDK

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:11434/v1",
    api_key="not-needed",  # 認証は不要(任意の文字列で可)
)

resp = client.chat.completions.create(
    model="my-profile",
    messages=[{"role": "user", "content": "こんにちは"}],
    stream=False,
)
print(resp.choices[0].message.content)

OpenAI 互換ストリーミング(Python)

stream = client.chat.completions.create(
    model="my-profile",
    messages=[{"role": "user", "content": "俳句を1つ"}],
    stream=True,
)
for chunk in stream:
    delta = chunk.choices[0].delta
    if delta.content:
        print(delta.content, end="", flush=True)

Ollama 互換(curl / NDJSON)

curl -N http://localhost:11434/api/chat -d '{
  "model": "my-profile",
  "messages": [{"role": "user", "content": "自己紹介して"}]
}'

JavaScript(fetch / SSE)

const res = await fetch("http://localhost:11434/v1/chat/completions", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    model: "my-profile",
    messages: [{ role: "user", content: "Hello" }],
    stream: true,
  }),
});

const reader = res.body.getReader();
const decoder = new TextDecoder();
while (true) {
  const { value, done } = await reader.read();
  if (done) break;
  for (const line of decoder.decode(value).split("\n")) {
    if (!line.startsWith("data: ")) continue;
    const data = line.slice(6);
    if (data === "[DONE]") break;
    const json = JSON.parse(data);
    process.stdout.write(json.choices[0].delta.content ?? "");
  }
}

本ページは現行の Android 実装(OllamaApiServer)に基づきます。応答例は説明のため整形しています。実際のフィールド構成・既定値はアプリのバージョンにより変わることがあります。