PARSER selects Ollama’s streaming output decoder. It separates raw generated tokens into:
message.contentmessage.thinkingmessage.tool_calls
It does not generally instruct the model; the matching RENDERER supplies the prompt instructions. Renderer and parser therefore need compatible conventions.
The current parser registry is defined in model/parsers/parsers.go.
PARSER value |
Expected model tool-call convention |
|---|---|
qwen3 |
JSON inside <tool_call>...</tool_call> |
qwen3-thinking |
Same JSON tool format, plus <think>...</think> |
qwen3-coder |
Qwen pseudo-XML: <function=name><parameter=key>value</parameter></function> inside <tool_call> |
qwen3.5, ornith |
Qwen3-Coder pseudo-XML, plus <think>...</think> |
qwen3-vl-instruct |
JSON inside <tool_call>...</tool_call> |
qwen3-vl-thinking |
Same JSON format, plus thinking |
nemotron-3-nano, nemotron-3.5-nano |
Qwen-style pseudo-XML tool calls, plus thinking |
ministral |
[TOOL_CALLS]name[ARGS]{JSON} |
functiongemma |
<start_function_call>call:name{args}<end_function_call> |
gemma4, gemma4-no-thinking |
<|tool_call>call:name{arguments}<tool_call|> |
deepseek3 |
DeepSeek special-token envelope with function name, separator, and JSON arguments |
cogito |
DeepSeek-like envelope, with a fenced JSON argument block |
glm-4.7, glm-ocr |
GLM XML-like <tool_call>name<arg_key>…</arg_key><arg_value>…</arg_value></tool_call> |
laguna, poolside-v1 |
<tool_call> with GLM-style argument tags or JSON; includes several fallback forms |
lfm2, lfm2-thinking |
Python-style calls between <|tool_call_start|> and <|tool_call_end|> |
olmo3 |
Python-style calls inside <function_calls>...</function_calls> |
cohere |
JSON action array between <|START_ACTION|> and <|END_ACTION|> |
harmony |
Harmony channel/recipient protocol with JSON arguments |
glimmer |
Harmony-like message headers combined with ATEM XML-like function calls |
<tool_call>
{"name":"get_weather","arguments":{"location":"Tokyo"}}
</tool_call>
The body must be JSON with name and arguments (model/parsers/qwen3.go).
<tool_call>
<function=get_weather>
<parameter=location>
Tokyo
</parameter>
<parameter=units>
celsius
</parameter>
</function>
</tool_call>
This is not standard XML. Ollama converts <function=name> into an XML element with a name attribute before parsing it (model/parsers/qwen3coder.go).
Qwen3.5 additionally separates:
<think>
reasoning
</think>
and delegates the subsequent tool call to the Qwen3-Coder parser (model/parsers/qwen35.go).
<tool_call>
{"name":"get_weather","arguments":{"location":"Tokyo"}}
</tool_call>
Although its wrapper resembles Qwen3.5, the contents are JSON rather than Qwen3.5 pseudo-XML (model/parsers/qwen3vl.go).
[TOOL_CALLS]get_weather[ARGS]{"location":"Tokyo"}
Thinking-capable variants use:
[THINK]
reasoning
[/THINK]
See model/parsers/ministral.go.
Conceptually:
<|tool▁calls▁begin|>
<|tool▁call▁begin|>
get_weather<|tool▁sep|>{"location":"Tokyo"}
<|tool▁call▁end|>
<|tool▁calls▁end|>
The unusual vertical bars and low-line characters are literal Unicode characters, not ordinary | and _. The arguments must be JSON (model/parsers/deepseek3.go).
<|tool▁calls▁begin|>
<|tool▁call▁begin|>
function<|tool▁sep|>get_weather
```json
{"location":"Tokyo"}
<|tool▁call▁end|> <|tool▁calls▁end|>
Cogito specifically expects the JSON code fence as part of its format ([model/parsers/cogito.go](/C:/cygwin64/home/atarashi/work-git/ollama/model/parsers/cogito.go:309)).
#### FunctionGemma
```text
<start_function_call>
call:get_weather{location:"Tokyo"}
<end_function_call>
This uses a custom key:value argument syntax rather than strict JSON (model/parsers/functiongemma.go).
<|tool_call>
call:get_weather{location:"Tokyo"}
<tool_call|>
Gemma 4 uses special asymmetric delimiters and a custom argument representation. Ollama also includes limited repair logic for malformed arguments (model/parsers/gemma4.go).
<tool_call>
get_weather
<arg_key>location</arg_key>
<arg_value>Tokyo</arg_value>
<arg_key>units</arg_key>
<arg_value>celsius</arg_value>
</tool_call>
Argument keys and values are paired by order. Their counts must match (model/parsers/glm46.go).
<|tool_call_start|>
get_weather(location='Tokyo', units='celsius')
<|tool_call_end|>
It accepts Python-style calls and supports multiple calls:
<|tool_call_start|>
[get_weather(location='Tokyo'), get_time(zone='Asia/Tokyo')]
<|tool_call_end|>
It also has a fallback for unwrapped Python-style calls (model/parsers/lfm2.go).
<function_calls>
get_weather(location="Tokyo")
get_time(zone="Asia/Tokyo")
</function_calls>
Each line is parsed as a Python-like function call (model/parsers/olmo3.go).
<|START_ACTION|>
[
{
"tool_call_id":"0",
"tool_name":"get_weather",
"parameters":{"location":"Tokyo"}
}
]
<|END_ACTION|>
<|END_OF_TURN_TOKEN|>
Normal content instead uses <|START_TEXT|>...<|END_TEXT|> (model/parsers/cohere.go).
<|start|>assistant<|channel|>commentary to=functions.get_weather <|constrain|>json<|message|>
{"location":"Tokyo"}
<|call|>
The recipient identifies the function, and the message body contains its JSON arguments. Harmony also maps analysis to thinking and final to visible content.
Conceptually:
<|start|>assistant to=get_weather<|message|>
<atem:function_calls>
<atem:invoke name="get_weather">
<atem:parameter name="location">Tokyo</atem:parameter>
</atem:invoke>
</atem:function_calls>
<|eot|>
The parser validates the recipient, invocation name, and declared tool before producing a call (model/parsers/glimmer.go).
olmo3-think: extracts thinking terminated by</think>but does not parse tools.passthrough: returns all generated text unchanged; no thinking or tool extraction.
A parser is not a generic “find any JSON that resembles a function call” mechanism. Each parser recognizes a particular model protocol:
matching RENDERER
→ teaches and frames the expected protocol
model output
→ must follow that protocol
matching PARSER
→ converts it into content, thinking, and API tool_calls
A mismatch can cause tool-call syntax to appear as ordinary text, be buffered indefinitely while streaming, or produce a parsing error. JSON alone is sufficient only for parser conventions that explicitly expect JSON at that position.