TT Lab
Blog

한국어 English 日本語 中文

Get started
Blog

Blog

Tool Calling: The parser turns text into function calls, and strict binds the arguments

Status: Draft (2026-10-27), Empirical. Measurements were taken using a single 8GB-class laptop GPU (Ada generation), vLLM 0.31.0, and Qwen3-Reranker-0.6B (a Qwen3 0.6B causal language model fine-tuned for reranking). Official documentation was checked on 2026-10-27 based on version 0.32.0 (released 2026-10-18), and differences from the 0.31.0 documentation are noted separately. Added 2026-10-27. Results re-measured with conversational Qwen3-0.6B, Qwen3-0.6B-GPTQ-Int8, Qwen3-4B-AWQ, and vLLM 0.32.0 have been added to Section 3-1. The previous figures measured with 0.31.0 remain unchanged. Writing rules: Empirical data is the default. Unmeasured items are marked as [Unmeasured] and unverified items as [Unverified].

Table of Contents

1. Tool calling is text in a predefined format

Imagine a scenario where an agent calls a weather API. There is no special output device called a "function call" inside the model. The model still generates tokens one by one, and it simply learned during training that "when calling a tool, write it in this shape." The Qwen series uses the Hermes format.

<tool_call>
{"name": "get_weather", "arguments": {"city": "Seoul", "unit": "c"}}
</tool_call>

The server performs three tasks:

  1. It inserts the list of tools into the prompt. The model's chat template writes the request's tools into the system prompt as text.
  2. It selects the text written by the model. The message.tool_calls tool parser is responsible for finding the above shape in the generated text and translating it into an OpenAI-format. Since shapes vary by model, there are multiple parsers such as hermes, llama3_json, mistral, qwen3_xml .
  3. It enforces the shape if necessary. tool_choice If required is

or a specific function name, the structured output from Part 4 enforces the shape of the call at the token level. --enable-auto-tool-choice The options to enable this are as follows. If tool_choice="auto" is absent,

vllm serve <모델> --enable-auto-tool-choice --tool-call-parser hermes

requests are not accepted.

tool_choice Call Obligation What Guarantees the Shape
auto None, model decides Parser only. If the model gets the shape wrong, it remains as text or is omitted
required At least one required Structured output enforces the shape
Named ({"type":"function","function":{"name":...}}) That specific function Structured output enforces the shape
none Do not call Tool definitions remain in the prompt by default (removed with--exclude-tools-when-tool-choice-none )

The official documentation states regarding named calls: "Guarantees a parsable call, but does not guarantee a high-quality call." This sentence neatly summarizes the empirical results of this article.

Shape and arguments are bound separately

Starting from version 0.21.0, xgrammar introduced structural tags to enforce tool calls, and current documentation divides enforcement into two layers.

The server-side baseline --tool-strict-level has three options: auto(default, follows request), function(enforces envelope on all requests), and parameter(treats all tools like strict). Since most agent frameworks do not attach strict , this allows operators to raise the baseline. The environment variable VLLM_ENFORCE_STRICT_TOOL_CALLING=false completely disables structural tags.

3. Direct Measurement

Environment and Method

Results

tool_choice strict Number of tool_calls generated Arguments following schema Response time (median)
auto None 0/5 0/5 24.5ms
auto Yes 0/5 0/5 24.6ms
required None 4/5 0/5 216.6ms
Named None 4/5 0/5 216.2ms
required Yes 5/5 5/5 263.1ms
Named Yes 5/5 5/5 261.7ms

Transfers several raw responses as-is.

With the same seed, required and the named output were identical down to the character. This is because having only one tool causes both approaches to generate the same grammar.

The server counts this as well. After the test, /metrics of vllm:tool_call_parser_invocations_total was outcome="tool_call" 18, outcome="no_tool_call" 12 in non-streaming chat requests. This matches the values counted by the client (18 responses with tool_calls, 12 without).

How to Read

  1. required without strict only guaranteed that "a call exists." While the function name was correct, the arguments were either an empty object or missing required fields. Both the 0.31.0 and 0.32.0 documentation state that "tools without strict accept only a loose argument grammar even with required and naming," and actual measurements matched this statement.
  2. Enabling strict followed the schema, but the semantics were incorrect. All arguments were parsed as JSON and adhered to the required fields and enum values, but Seoul never appeared in the questions, and values like "none" also appeared. Grammar only restricts the remaining tokens to "allowed tokens"; the model still decides which token to pick among them.
  3. The time differences are mostly due to token counts. The strict side took about 50ms longer, but {} also included the increased token count from using both fields, so it should not be interpreted purely as the cost of grammar validation. The values isolating just the grammar cost are in Part 4.

3-1. Re-measurement on 2026-10-27: Tool-aware models and 0.32.0

The previous test examined the "scope enforced by the server" using a model unaware of tools. This time, we look at the content using a model trained for tool calling.

Model tool_choice strict Call count Correct city/unit Response time median
Qwen3-0.6B auto None 6/6 6/6 162.1ms
Qwen3-0.6B required None 6/6 6/6 178.0ms
Qwen3-0.6B Named None 6/6 6/6 178.1ms
Qwen3-0.6B auto, required, named Yes 18/18 18/18 184.1~185.4ms
Qwen3-0.6B GPTQ 8-bit All 6 cases None/Yes 36/36 36/36 115.7~140.6ms
Qwen3-4B AWQ 4-bit All 6 cases None/Yes 36/36 36/36 338.7~362.4ms

This test is relatively simple with a single tool and a short prompt. Accuracy with multiple tools or complex arguments remains unmeasured.

4. Takeaways for Production

5. Unverified Items

References

Sign in to like

Comments

No comments yet.

Sign in to leave a comment