Cited llama.cpp --jinja · tool-call success not measured on the local desktop
Tool calling and structured JSON with llama.cpp on a Radeon GPU
Hermes, Cline, Continue, and Roo need OpenAI-style tool calls and JSON that parses. llama.cpp documents that path in docs/function-calling.md and the server README (checked 2026-10-14): start llama-server with --jinja, send tools on /v1/chat/completions, and optionally constrain the body with response_format, a JSON Schema, or GBNF. AMDai has not measured tool-call success or grammar decode on the local desktop, so those cells stay not measured yet — run Stack Lab grammar-ab/1. Stack Lab pack grammar-ab/1 is the free-form versus grammar / JSON-schema A/B. It is not an allowlisted Open-in-Stack-Lab deep link — open the planner, then record an amdai-bench card. House daily driver is Qwen3.6-35B-A3B UD-Q5_K_XL on llama.cpp Vulkan, one R9700, 262144 context, f16 KV. UD-Q3_K_XL is a labeled estimate (Hugging Face listing for Qwen3.6-35B-A3B-UD-Q3_K_XL.gguf (16.8 GB)). Q1/Q2 stay off.
- Coding assistant
- Harnesses
- Hermes
- Open WebUI
- Backends
- llama.cpp
- Speed up llama.cpp
- Long context
- Speculative decoding
- Stack Lab
- amdai-bench
- Sampling
- Chat templates
How we test — Measured cells cite official amdai-bench/run@1 cards. Estimates stay labeled. Q3 is estimate-only. Q1/Q2 stay off.
Daily driver · 35B llama.cpp · 262K
Minimum system RAM needed
42.9 GB
Measured · 42.9 GiB raw · 256K context
local-desktop-20261012-2314-35b-udq5kxl-1gpu-256k-llamacpp-f16
RAM needed at full context
42.9 GB
Measured · 42.9 GiB raw · 256K full context
local-desktop-20261012-2314-35b-udq5kxl-1gpu-256k-llamacpp-f16
Measured peak system RAM on the local desktop: 42.9 GB (Linux GiB labeled GB). Measured, pending re-verify after RAM fix.
Breakdown
- Offloaded weights ·
- 0 GiB
- Separable embed in RAM ·
- 0 GiB
- KV in RAM at selected ·
- 0 GiB
- KV in RAM at full context ·
- 0 GiB
- Runtime / backend ·
- 0.85 GiB
- OS / desktop baseline ·
- 8.00 GiB
- Headroom ·
- 16.0 GiB
If the app is not installed, packages are not published yet. There is no public download URL. Read the Stack Lab install notes . If Stack Lab is already running on this machine, open the local app .
If the app is not installed, packages are not published yet. There is no public download URL. Read the Stack Lab install notes . If Stack Lab is already running on this machine, open the local app .
What a tool call is
A tool call is an OpenAI-shaped /v1/chat/completions request that includes a tools array. The model returns tool_calls instead of (or before) a normal message. llama.cpp parses that when --jinja is on and the chat template understands tools. Function-calling.md: native handlers exist for several families (Llama 3.1 / 3.3, GPT-OSS Harmony, Hermes 2/3, Functionary, Mistral Nemo, Command R7B, DeepSeek R1). Unrecognized templates fall back to Generic — logs say Chat format: Generic. Generic may use more tokens. Parallel / multiple tool calls stay off unless the payload sets "parallel_tool_calls": true, and only some templates support them.
Official path: llama.cpp function-calling.md · coding assistant · harnesses.
--jinja and templates
function-calling.md: start llama-server with --jinja. The server README (checked 2026-10-14) lists --jinja / --no-jinja and says the default is enabled. The house pin still passes --jinja so a rebuilt binary cannot silently drop it. The template comes from the GGUF metadata unless you override it. --chat-template-file loads a Jinja file. --chat-template names a built-in (chatml is the documented “many models, YMMV” fallback when there is no official tool_use template). Inspect GET /props for chat_template and chat_template_tool_use. --skip-chat-parsing dumps reasoning and tool markup into content instead of parsing them.
Official Qwen3.6-35B-A3B card documents tool use (vLLM / sglang parsers on that card). llama.cpp function-calling.md does not name this 3.6 file in the native-handler table. After launch, read the server log for Chat format and GET http://127.0.0.1:8080/props. Do not invent a handler name or a --chat-template-file path for the house GGUF. Llama 3.3 70B is listed as Llama 3.x native. GPT-OSS is listed as Harmony. Gemma 3 27B and GLM 5.3 Flash are not named on that table — treat them as not documented there.
-
--jinja / --no-jinja
Use the Jinja chat-template engine. function-calling.md requires --jinja for OpenAI-style tools. Server README default is enabled (checked 2026-10-14). House pin still passes --jinja.
llama.cpp function-calling.md; server README — --jinja (checked 2026-10-14)
-
--chat-template / --chat-template-file
Override the GGUF metadata template. Built-in names include chatml (documented YMMV fallback). A file path loads a custom Jinja. Inspect /props for chat_template and chat_template_tool_use before you invent a filename.
llama.cpp server README — --chat-template, --chat-template-file; function-calling.md
-
--skip-chat-parsing
Force a pure content parser. Reasoning and tool markup stay in message.content instead of being split out. Useful when think-tags leak into a harness that expects tool_calls.
llama.cpp server README — --skip-chat-parsing
-
parallel_tool_calls (request body)
Multiple / parallel tool calls. Official default is off. Enable with "parallel_tool_calls": true. Only some templates support it; verification is based on the Jinja template.
llama.cpp function-calling.md; server README — parallel_tool_calls
-
response_format / json_schema / grammar
Constrain the whole reply to JSON or a GBNF grammar. Server README: {"type":"json_object"} or a schema object. -j / --json-schema and --grammar-file on the CLI. Not a substitute for a tools array.
llama.cpp server README — response_format, json_schema, grammar; grammars/README.md
Structured JSON
Tool calling injects the tool schema into the prompt. Constrained decoding is a different knob: it forces the next tokens to match a grammar. Official grammars/README.md: JSON Schema converts to GBNF via json-schema-to-grammar; the schema is not injected except during tool calling, so describe a free-form JSON shape in the prompt. Use response_format {"type":"json_object"} or a schema-constrained object when the whole reply must be JSON (calculator output, recipe export) and you are not in a tool loop. Use --grammar / --grammar-file when the output is not JSON. Use tools + --jinja when the harness expects tool_calls. A grammar can stall — llama.cpp issue #4218. Do not invent an overhead tok/s; measure ${TC_PACK}.
Official: server README · grammars/README.md · GBNF · JSON schema. Measure pack grammar-ab/1 on Stack Lab — do not invent an overhead tok/s.
House launch
the house default is Qwen3.6-35B-A3B Unsloth UD-Q5_K_XL, llama.cpp Vulkan, one R9700, 262144 context, f16 KV. Add --jinja for tools. House /v1 is http://127.0.0.1:8080/v1 with model id qwen — same pin as /setup/coding-assistant. function-calling.md cautions that extreme KV quants (example: q4_0 KV) can degrade tool calling. House KV stays f16. A tools payload and multi-turn history eat context — size -c on /long-context.
House Hermes on the local desktop also talks to Strata on :8083 for the Flash fast-agent path. llama.cpp function-calling.md does not document Strata. Treat Strata tool calls as not verified here. Attach notes stay on /harnesses/hermes and /backends/strata.
Daily-driver recipe: qwen36-35b.llamacpp-vulkan.262k · Coding clients: /setup/coding-assistant · Hermes: /harnesses/hermes · Strata (not verified for tools): /backends/strata.
# House daily-driver shape with --jinja. Not a measured tool-call pin. ./build-vk/bin/llama-server \ -m ~/models/Qwen3.6-35B-A3B-UD-Q5_K_XL.gguf \ --jinja \ -ngl 99 \ -c 262144 \ --cache-type-k f16 \ --cache-type-v f16 \ --host 127.0.0.1 --port 8080
# Shape only. Official tools payload from docs/function-calling.md,
# pointed at the house /v1 (model id qwen). Not a measured success rate.
curl http://127.0.0.1:8080/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{
"model": "qwen",
"messages": [{"role":"user","content":"What is the weather in Istanbul?"}],
"tools": [{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "Get the current weather in a given location",
"parameters": {
"type": "object",
"properties": {
"location": {"type":"string","description":"City and country/state"}
},
"required": ["location"]
}
}
}]
}'
# Shape only. response_format from the llama.cpp server README.
# Describe the fields in the prompt — the schema is not injected.
curl http://127.0.0.1:8080/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{
"model": "qwen",
"messages": [{"role":"user","content":"Return one JSON object with a name string."}],
"response_format": {"type":"json_object"}
}'
Shape only. Official tools payload from
function-calling.md,
pointed at house qwen on
127.0.0.1:8080. Not a measured success rate.
Troubleshooting
-
Tools ignored
Confirm --jinja, then GET /props for a tools-aware chat_template / chat_template_tool_use. Read the log for Chat format: Generic versus a native handler. A missing or default-only template often means the model writes prose. Do not invent a --chat-template-file for the house 35B — start from the GGUF metadata.
-
Malformed JSON
Tool arguments are model text unless you also constrain them. For a whole-reply JSON object, use response_format or --json-schema. For a custom shape, use GBNF. Measure parse success on Stack Lab grammar-ab/1. Do not copy a free-form 35B tok/s as a grammar figure.
-
Think-tags leaking into tool calls
Reasoning tokens can land in content when the parser and the template disagree. Official server README: --skip-chat-parsing keeps everything in content; reasoning_effort none disables thinking when the template honors it. The official Qwen3.6 card documents enable_thinking on other engines — that is their cite, not a llama.cpp flag we invent.
-
Template mismatch
function-calling.md: override with --chat-template-file, or try --chat-template chatml when there is no official tool_use template (YMMV). Wrong template is the usual “tools ignored” or “markup in content” cause. Check /props after every override.
-
Long-context drift
Tool schemas and multi-turn tool results sit in the KV cache. Official UD-Q5 1-GPU llama.cpp decode already drops from 102.39 tok/s at 4K to 44.4 at 256K — same file, no tools. Size -c on /long-context. Extreme KV quants can degrade tool calling (function-calling.md). House KV stays f16.
Measured 35B — no tools
Official Qwen3.6-35B-A3B llama.cpp Vulkan cells from existing run cards. These launches have no tools array. Tool-call and grammar cells stay unmeasured. UD-Q3_K_XL is a labeled estimate. Full matrix: /benchmarks.
| Quant | Kind | 4K decode | 32K decode | Note |
|---|---|---|---|---|
| Q6_K | Measured | 103.23 tok/s | 71.19 tok/s |
Official local desktop llama.cpp Vulkan, one R9700. Free-form — no tools array.
local-desktop-20261012-2355-35b-q6k-1gpu-4k-llamacpp-f16local-desktop-20261012-2356-35b-q6k-1gpu-32k-llamacpp-f16 |
| UD-Q5_K_XL | Measured | 102.39 tok/s | 90.52 tok/s |
Official local desktop llama.cpp Vulkan, one R9700. Free-form — no tools array.
local-desktop-20261012-2311-35b-udq5kxl-1gpu-4k-llamacpp-f16local-desktop-20261012-2312-35b-udq5kxl-1gpu-32k-llamacpp-f16 |
| Q5_K_M | Measured | 109.73 tok/s | 96.21 tok/s |
Official local desktop llama.cpp Vulkan, one R9700. Free-form — no tools array.
local-desktop-20261012-2327-35b-q5km-1gpu-4k-llamacpp-f16local-desktop-20261012-2327-35b-q5km-1gpu-32k-llamacpp-f16 |
| Q4_K_M | Measured | 117.69 tok/s | 101.88 tok/s |
Official local desktop llama.cpp Vulkan, one R9700. Free-form — no tools array.
local-desktop-20261012-2341-35b-q4km-1gpu-4k-llamacpp-f16local-desktop-20261012-2342-35b-q4km-1gpu-32k-llamacpp-f16 |
| UD-Q3_K_XL | Q3 estimate | not measured yet — run Stack Lab grammar-ab/1 | not measured yet — run Stack Lab grammar-ab/1 | Hugging Face listing for Qwen3.6-35B-A3B-UD-Q3_K_XL.gguf (16.8 GB). Q3 is a labeled estimate — not a local desktop run, not a tool-call card. |
VRAM fit
Calculator estimate for Qwen3.6-35B-A3B on llama.cpp, f16 KV. A tools payload does not change weights. UD-Q3_K_XL is a labeled estimate. Do not read leftover as a tool-call speed cell.
One R9700 · 32K
| Quant | Weights | Total | Usable | Leftover |
|---|---|---|---|---|
| Q6_K Estimate | 26.7 GB | 28.2 GB | 32.0 GB | 3.77 GB leftover (estimate) |
| Q5_K_M / UD-Q5_K_XL Estimate | 24.8 GB | 26.2 GB | 32.0 GB | 5.76 GB leftover (estimate) |
| Q4_K_M Estimate | 19.8 GB | 21.2 GB | 32.0 GB | 10.8 GB leftover (estimate) |
| UD-Q3_K_XL Q3 estimate | 15.6 GB | 17.0 GB | 32.0 GB | 15.0 GB leftover (estimate) |
One R9700 · 262K
KV grows. Tool schemas sit in that window. Size -c on
/long-context.
| Quant | Total | Leftover |
|---|---|---|
| Q6_K | 32.7 GB of 32.0 GB | no leftover — offload (estimate) |
| Q5_K_M / UD-Q5_K_XL | 30.7 GB of 32.0 GB | 1.32 GB leftover (estimate) |
| Q4_K_M | 25.6 GB of 32.0 GB | 6.40 GB leftover (estimate) |
| UD-Q3_K_XL | 21.4 GB of 32.0 GB | 10.6 GB leftover (estimate) |
System RAM
A tools array does not add GGUF weight; it does add prompt tokens. When -ngl leaves layers on the host, shopper lines stay Minimum system RAM needed (full-system estimate rounded to a real kit, with a breakdown — labeled estimate until a card overlays it) and RAM needed at full context (cache included when measured llama.cpp peaks exist). House 35B UD-Q5_K_XL on one 32 GB R9700 does not offload. The 16 GB example is house 35B Q4_K_M on an RX 7800 XT at 32K selected — estimate unless a measured card overlays the kit.
House 35B · in-VRAM on one R9700
Daily driver · 35B llama.cpp · 262K
Minimum system RAM needed
42.9 GB
Measured · 42.9 GiB raw · 256K context
local-desktop-20261012-2314-35b-udq5kxl-1gpu-256k-llamacpp-f16
RAM needed at full context
42.9 GB
Measured · 42.9 GiB raw · 256K full context
local-desktop-20261012-2314-35b-udq5kxl-1gpu-256k-llamacpp-f16
Measured peak system RAM on the local desktop: 42.9 GB (Linux GiB labeled GB). Measured, pending re-verify after RAM fix.
Breakdown
- Offloaded weights ·
- 0 GiB
- Separable embed in RAM ·
- 0 GiB
- KV in RAM at selected ·
- 0 GiB
- KV in RAM at full context ·
- 0 GiB
- Runtime / backend ·
- 0.85 GiB
- OS / desktop baseline ·
- 8.00 GiB
- Headroom ·
- 16.0 GiB
Offload example · 16 GB + 35B Q4
Minimum system RAM needed and RAM needed at full context. Estimate. A tools payload does not add GGUF weight.
Minimum system RAM needed
32 GB kit
Estimate · 29.2 GiB raw · 32K context
RAM needed at full context
48 GB kit
Estimate · 33.6 GiB raw · 256K full context
Estimate. Offloaded weights + KV in RAM + runtime + OS/desktop + headroom, rounded up to a 32 GB DIMM kit.
Breakdown
- Offloaded weights ·
- 3.76 GiB
- Separable embed in RAM ·
- 0 GiB
- KV in RAM at selected ·
- 0.69 GiB
- KV in RAM at full context ·
- 5.06 GiB
- Runtime / backend ·
- 0.71 GiB
- OS / desktop baseline ·
- 8.00 GiB
- Headroom ·
- 16.0 GiB
FAQ
-
Do I need --jinja for tool calls?
Yes for the documented OpenAI-style path. function-calling.md starts llama-server with --jinja. The server README default is enabled (checked 2026-10-14); the house pin still passes the flag. Then send a tools array on /v1/chat/completions.
-
Tools array or JSON Schema — which one?
Use tools + --jinja when the harness expects tool_calls (Hermes, Cline, Continue). Use response_format / --json-schema / GBNF when the whole reply must be one JSON object and you are not in a tool loop. The schema is not injected except during tool calling. Grammar cost stays not measured yet — run Stack Lab grammar-ab/1.
GBNF · Stack Lab · amdai-bench
-
Can a Q3 file call tools?
UD-Q3_K_XL may appear as a labeled estimate (Hugging Face listing for Qwen3.6-35B-A3B-UD-Q3_K_XL.gguf (16.8 GB)). House files stay Q6 / Q5 / Q4. A template flag does not change that. Q1/Q2 stay off.
Sources
- llama.cpp function-calling.md
- llama.cpp server README
- llama.cpp GBNF guide
- llama.cpp json-schema-to-grammar.cpp
- Qwen3.6-35B-A3B model card
- Llama 3.3 70B model card
- gpt-oss-20b model card
- llama.cpp repository
- AMDai — coding assistant
- AMDai — harnesses
- AMDai — Open WebUI
- AMDai — backends
- AMDai — llama.cpp
- AMDai — Strata
- AMDai — Hermes
- AMDai — speed up llama.cpp
- AMDai — long context
- AMDai — Stack Lab
- AMDai — amdai-bench
Also: Coding assistant · Harnesses · Speculative decoding · Glossary · FAQ.