本文へ移動
cccskills
無料GitHub で公開

ollama-api

The Ollama REST API as it is on this machine - /api/generate and /api/chat with streaming NDJSON, /api/embed vs the older /api/embeddings, /api/tags, /api/ps, /api/show, pull progress, create/copy/delete, the OpenAI-compatible /v1 endpoints, the options map, keep_alive, the error shapes, and the environment variables that change what the daemon does.

日本語の概要は準備中です。原文の説明を表示しています。

連携ツールOpenAI
インストール方法を見る

含まれるファイル(1)

  • SKILL.md15.6 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

The Ollama REST API

The daemon is a plain HTTP server on the loopback interface. Everything below is the shape this install answers with - not a client library's wrapper.

The address

Ollama binds 127.0.0.1:11434 unless OLLAMA_HOST says otherwise. The value is host:port (a scheme is accepted). Two different readers use it:

  • the daemon reads OLLAMA_HOST as the address to BIND (0.0.0.0:11434 to serve the whole network);
  • a client reads it as the address to CONNECT to.

That asymmetry is the classic mistake: setting OLLAMA_HOST=0.0.0.0:11434 for the server and then pointing a client at http://0.0.0.0:11434 works on Linux and fails on Windows. Clients should default to http://127.0.0.1:11434.

The first request of any session should be the version, because every other behaviour is version-dependent:

curl -s http://127.0.0.1:11434/api/version
{"version":"0.40.3"}

dsh-ollama's ollama_status answers this and the model inventory in one call; when you are writing a program, this is the endpoint to probe.

The three request shapes

One prompt: /api/generate

curl -s http://127.0.0.1:11434/api/generate -d '{"model":"qwen2.5:7b","prompt":"Why is the sky blue?","stream":false}'

stream: false answers ONE JSON object carrying the whole completion and every timing field. stream: true (the daemon's default) answers NDJSON - see below.

A conversation: /api/chat

curl -s http://127.0.0.1:11434/api/chat -d '{"model":"qwen2.5:7b","messages":[{"role":"system","content":"Be brief."},{"role":"user","content":"Why is the sky blue?"}],"stream":false}'

Roles are system, user, assistant and tool. The same model, template and options apply; the difference is that the daemon applies the chat template to the whole array instead of wrapping one prompt.

Vectors: /api/embed

curl -s http://127.0.0.1:11434/api/embed -d '{"model":"nomic-embed-text","input":["the cat sat","a cat was sitting"]}'

input is a string or an array. The answer is {"embeddings": [[...], [...]], "model": "...", ...} - one vector per input, in order. Older daemons only have the single-prompt form:

curl -s http://127.0.0.1:11434/api/embeddings -d '{"model":"nomic-embed-text","prompt":"the cat sat"}'

That answers {"embedding": [...]}. Prefer /api/embed: one request, many inputs, and a dimension you can rely on. If /api/embed returns 404, fall back.

Streaming is NDJSON

A streaming answer is one JSON object per line, each line terminated by \n, with done: false on every partial object and done: true on the last one. The partial objects carry response (generate) or message.content (chat); the FINAL object carries the token counts and the durations. Nothing before the last line has a measurement in it.

curl -s http://127.0.0.1:11434/api/generate -d '{"model":"qwen2.5:7b","prompt":"Say hello"}'

Three properties follow from that shape, and each one is a bug waiting to happen:

  1. A line is not a document. Parse per line; do not buffer the whole body and JSON.parse it.
  2. The last line is the measurement. If your reader stops at the first done: true it has the numbers; if it stops at end-of-stream it may have them too, but the done object is the contract.
  3. A stream can be cut. A cancelled request, a killed daemon or a timeout ends the stream with no done object at all. Treat "no done object" as a failed measurement, not as an empty answer.

A reader that keeps the text and the final object:

const response = await fetch('http://127.0.0.1:11434/api/generate', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({ model: 'qwen2.5:7b', prompt: 'Say hello', stream: true }),
})
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`)
const reader = response.body.getReader()
const decoder = new TextDecoder()
let buffer = ''
let text = ''
let final = null
for (;;) {
  const { value, done } = await reader.read()
  if (done) break
  buffer += decoder.decode(value, { stream: true })
  let newline = buffer.indexOf('\n')
  while (newline >= 0) {
    const line = buffer.slice(0, newline).trim()
    buffer = buffer.slice(newline + 1)
    newline = buffer.indexOf('\n')
    if (line === '') continue
    const item = JSON.parse(line)
    if (item.response) text += item.response
    if (item.done === true) final = item
  }
}
if (final === null) throw new Error('the stream ended without a done object')
console.log(text, final.eval_count, final.eval_duration)

(The arithmetic that turns those two numbers into tok/s is the ollama-inference-metrics skill's subject.)

The final object

/api/generate with stream: false and the last line of a streaming call have the same fields:

fieldunitwhat it covers
responsestringthe generated text (chat: message.content)
donebooltrue on the final object
done_reasonstringstop (the model stopped) or length (it hit num_predict/context)
contextint[]the token ids of prompt+answer - pass it back as context to continue
total_durationnsthe whole daemon-side request
load_durationnsloading the weights (0 when they were resident)
prompt_eval_countintprompt tokens evaluated
prompt_eval_durationnsevaluating the prompt
eval_countinttokens generated
eval_durationnsgenerating them

done_reason: "length" is the one field a reader must not ignore: the answer was CUT by your num_predict or the context window, not finished by the model.

Options and keep_alive

options is the sampling/runtime map. The ones that change the measurement:

optionrangeeffect
num_predict-1..Nmax tokens to generate; -1 (the default) means "until the model stops or the context fills"
temperature0..20 = greedy; the only defensible setting for a reproducible benchmark
seedintfixes sampling when temperature > 0; set it anyway so a rerun is comparable
num_ctx128..context window in tokens; the single biggest memory/speed knob
top_k, top_p, min_psampling cutoffs
repeat_penalty, repeat_last_nrepetition control
stopstring[]stop sequences
num_gpuintlayers offloaded to the GPU (0 = CPU only)
num_threadintCPU threads
use_mmap, use_mlockboolweight paging

Anything the daemon does not recognise in options is silently ignored - which is why a typo is worse than an error: the run reports numbers taken at a setting nobody chose. dsh-ollama closes the map for exactly that reason.

keep_alive is a TOP-LEVEL sibling of options, not an option:

  • "5m", "30s", "1h" - keep the weights loaded that long after the request;
  • 0 - unload as soon as this request finishes;
  • -1 - never unload.
curl -s http://127.0.0.1:11434/api/generate -d '{"model":"qwen2.5:7b","prompt":"hi","keep_alive":"10m"}'

Unloading is the documented use of an empty request:

curl -s http://127.0.0.1:11434/api/generate -d '{"model":"qwen2.5:7b","keep_alive":0}'

That is the call that makes a "cold" benchmark honest: without it, run 1 is as warm as run 2 and the load time you meant to measure never appears.

Models: list, inspect, pull, delete

curl -s http://127.0.0.1:11434/api/tags

/api/tags is the inventory: name, size (bytes), digest (sha256:...), modified_at, and details (family, families, parameter_size, quantization_level, format).

curl -s http://127.0.0.1:11434/api/ps

/api/ps is what is LOADED right now: size, size_vram, context_length, expires_at, and the same details. size_vram is 0 for a CPU-resident model; size_vram / size is the offload share.

curl -s http://127.0.0.1:11434/api/show -d '{"model":"qwen2.5:7b"}'

/api/show is the model's own metadata: details, parameters (the Modelfile defaults - read them before assuming temperature), template, license, model_info (general.architecture, *.context_length, *.embedding_length, *.block_count) and capabilities (completion, tools, embedding, vision, thinking depending on the model). capabilities is what tells you whether a tag can embed at all.

curl -s http://127.0.0.1:11434/api/pull -d '{"model":"qwen2.5:7b","stream":true}'

A pull is NDJSON progress, not a completion: {"status":"pulling manifest"}, then one line per layer with digest, total and completed, then {"status":"verifying sha256 digest"}, then {"status":"success"}. It is measured in gigabytes and minutes; there is no partial-success state - a cut pull leaves layers cached and the next pull resumes them.

curl -s -X DELETE http://127.0.0.1:11434/api/delete -d '{"model":"llama3.2:1b"}'

Delete answers 200 with an empty body. It frees the bytes immediately; the model comes back only by pulling it again. dsh-ollama requires the tag repeated as confirm for this reason.

The other model verbs, for completeness:

curl -s http://127.0.0.1:11434/api/copy -d '{"source":"qwen2.5:7b","destination":"qwen2.5:7b-mine"}'
curl -s http://127.0.0.1:11434/api/create -d '{"model":"my-model","from":"qwen2.5:7b","system":"You answer in one sentence."}'

copy and create are not tools in this pack - they mutate the model store in ways an agent should not do implicitly - but they are part of the surface and worth knowing when a user asks why a tag exists.

Errors, and what they mean

Ollama reports a problem as a non-2xx status with a JSON body {"error": "..."}.

statusbodymeaningthe fix
404model "x" not found, try pulling it firstthe tag is not on diskollama pull x
404404 page not foundthe route does not exist on this daemon (an older build, or a typo)check /api/version, use the older shape
400invalid options / json: cannot unmarshal ...the body's shape is wrongcompare with this page
500...the model failed while loading or runningread the message; often memory (num_ctx too large)
(none)fetch failed / ECONNREFUSEDthe DAEMON is not runningollama serve, or the desktop app

A 500 whose message mentions memory is not a bug in your code: num_ctx sizes the KV cache, and a context the machine cannot hold fails at load. Try a smaller num_ctx or a smaller quantization.

Structured output

format is a top-level field. "json" asks for any valid JSON; a JSON Schema asks for that shape and is the reliable form:

curl -s http://127.0.0.1:11434/api/generate -d '{"model":"qwen2.5:7b","prompt":"Give me one user: name and age.","format":{"type":"object","properties":{"name":{"type":"string"},"age":{"type":"integer"}},"required":["name","age"]},"stream":false}'

The answer's text is a JSON document (not a Markdown fence). Parse it and fail loudly when it does not parse - a schema is a strong request, not a guarantee.

Tool calling

/api/chat accepts tools (a JSON-Schema function list) in the same shape as the OpenAI tools array. The model answers with message.tool_calls: [{ function: { name, arguments } }] and no content; you run the function, append a {role: "tool", content: "...", tool_name: "..."} message, and call again.

curl -s http://127.0.0.1:11434/api/chat -d '{"model":"qwen2.5:7b","messages":[{"role":"user","content":"What is the weather in Lisbon?"}],"tools":[{"type":"function","function":{"name":"weather","description":"Current weather","parameters":{"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}}}],"stream":false}'

Not every model supports tools: check capabilities from /api/show first, or you will get a plain-text answer that looks like a refusal.

The OpenAI-compatible endpoints

Ollama also serves /v1: the same daemon, the OpenAI wire format. Use it when a client library or SDK already speaks OpenAI and you cannot change it.

curl -s http://127.0.0.1:11434/v1/chat/completions -d '{"model":"qwen2.5:7b","messages":[{"role":"user","content":"hi"}]}'
curl -s http://127.0.0.1:11434/v1/completions -d '{"model":"qwen2.5:7b","prompt":"hi"}'
curl -s http://127.0.0.1:11434/v1/embeddings -d '{"model":"nomic-embed-text","input":"hi"}'
curl -s http://127.0.0.1:11434/v1/models

Two cost-saving facts about this surface:

  • the timings are not in the OpenAI body; the usage object carries token counts only. If you need the durations, use the native /api route;
  • stream: true here is Server-Sent Events (data: {...} lines ending data: [DONE]), not NDJSON. A reader written for /api will not parse it.

The CLI, for the same operations

taskAPICLI
list modelsGET /api/tagsollama list
loaded modelsGET /api/psollama ps
inspectPOST /api/showollama show qwen2.5:7b
pullPOST /api/pullollama pull qwen2.5:7b
deleteDELETE /api/deleteollama rm qwen2.5:7b
one promptPOST /api/generateollama run qwen2.5:7b "hi"
daemon-ollama serve

ollama run starts an interactive session when given no prompt; it is not a drop-in for a scripted call, and it prints the finished text without the timing fields.

Environment variables that change the daemon

These are read by the SERVER at start, not per request:

variabledefaultwhat it does
OLLAMA_HOST127.0.0.1:11434the bind address
OLLAMA_MODELS~/.ollama/modelswhere the weights live
OLLAMA_KEEP_ALIVE5mdefault residency for a loaded model
OLLAMA_NUM_PARALLEL1 (auto)concurrent requests one model serves; each gets its own KV cache slot
OLLAMA_MAX_LOADED_MODELS3 x GPUs (auto)how many models may be resident at once
OLLAMA_MAX_QUEUE512queued requests before the daemon answers 503
OLLAMA_FLASH_ATTENTIONoffa speed/memory trade at long context
OLLAMA_KV_CACHE_TYPEf16q8_0 / q4_0 shrink the KV cache
OLLAMA_ORIGINSlocalhost onlyCORS origins the daemon accepts from a browser
OLLAMA_DEBUGoffverbose server logging

Two settings interact in a way that ruins benchmarks: with OLLAMA_NUM_PARALLEL=2, one model serves two requests at once, so two "sequential" runs can overlap and both report a lower tok/s. Measure with parallelism at its default, or state it in the result.

What not to do

  • Do not assume the daemon is running. Probe /api/version and say the address you tried.
  • Do not buffer a streaming response and parse it as one JSON document.
  • Do not invent an options key: an unknown one is ignored, and the numbers become a claim about a setting the daemon never applied.
  • Do not quote total_duration as latency: it is the daemon's own span, and it excludes the transport.
  • Do not treat a 404 for a model as "the daemon is broken": the fix is ollama pull, and the error body says so.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

Author an editorial HTML+SVG diagram with the Diagram Design kit - choose the visual type, read its reference, start from an example, and satisfy the safety and accessibility contract that diagram_write({kind:"html"}) enforces.

日本語の概要は準備中です。原文の説明を表示しています。

vecnode/vn-code102026年10月20日 更新

Control this machine's Docker or Podman engine through the docker_* tools - read the engine's state first, list containers and images, inspect one, tail its logs, pull an image and start it, then stop, restart or remove what you started. Covers the engine that is asleep behind Docker Desktop and the exact call for each verb, the confirm rule removals obey, and the flags the tools deliberately do not have.

日本語の概要は準備中です。原文の説明を表示しています。

vecnode/vn-code102026年10月20日 更新

Drive ffmpeg through the media_run tool as an argv array - remux instead of re-encode, map streams explicitly, trim at keyframes, scale and crop, extract audio and frames, and build GIFs, contact sheets and concatenations. Covers the flags this pack injects, reading a failure from its exit code and last log lines, and the version-dependent spellings to hedge.

日本語の概要は準備中です。原文の説明を表示しています。

vecnode/vn-code102026年10月20日 更新

Read a media file's real structure with ffprobe through media_run - the JSON invocation and how to read it, what every family of field means, how to count frames, sample without decoding everything, detect HDR and interlacing, and diagnose a missing duration, a stream with no frames or a container that lies. Covers when media_probe's own report is already enough.

日本語の概要は準備中です。原文の説明を表示しています。

vecnode/vn-code102026年10月20日 更新

Use when the user wants to design, redesign, shape, critique, audit, polish, simplify, harden, animate, or otherwise improve a frontend interface: websites, landing pages, dashboards, product UI, components, forms, settings, onboarding, empty states, and native iOS or Android screens. Handles UX review, hierarchy, layout, typography, color, motion, UX copy, accessibility, responsive behavior, edge cases, and capturing or documenting design systems (DESIGN.md, tokens). Also for making bland UI bolder, loud UI quieter, or ambitious visual effects. Not for backend-only or non-UI tasks.

日本語の概要は準備中です。原文の説明を表示しています。

vecnode/vn-code102026年10月20日 更新

Author Mermaid diagrams that parse the first time: choose the right diagram type for the question, write syntax the parser accepts, and keep the picture readable in a narrow panel. A bundled reference covers complex, large diagrams.

日本語の概要は準備中です。原文の説明を表示しています。

vecnode/vn-code102026年10月20日 更新

vecnode のスキルをすべて見る

このスキルの問題を報告する