TECHNOLOGY

Align vLLM tool parsers, chat templates and tool-result messages

In this article
THE QUICK TAKE

Reliable vLLM tool calling requires a compatible parser, chat template, and conversation history containing tool results.

Reliable vLLM tool calling requires a compatible parser, chat template, and conversation history containing tool results. Enabling automatic tool choice does not replace that agreement. Test a complete invocation followed by the model’s next answer. One successfully extracted tool_calls object does not establish that the server will interpret the tool response correctly or preserve its relationship to the earlier assistant message.

Assign the parser and template their roles

The parser extracts calls from the format a particular model generates. The template prepares tool descriptions and conversation history for that model. vLLM connects automatic choice with enable-auto-tool-choice, a tool-call-parser, and a compatible template. Capabilities depend on the parser and model. Support for one mode does not prove support for strict schemas, parallel calls, or every tool-choice value. List these capabilities independently in the acceptance contract instead of treating tool calling as one indivisible feature.

Validate the result message

After the assistant requests a tool, the client returns its result with the necessary identification. The Hugging Face guide demonstrates histories containing tools and their corresponding messages. Pay attention to argument representation: an internal template and an external OpenAI-compatible API can expect different structures. Save the actual serialized second-turn request. Testing only the first answer misses failures that appear when the chat template processes a longer history containing assistant calls and tool results.

Use a harmless worked round trip

Define a fictional lookup_status tool accepting a string item_id and returning a predetermined local object. Ask the model to obtain the status, capture its call, return the fixture result, and request an explanation. This checks the contract without performing external actions. Compare the function name, argument structure, call identifier, and result association. An unknown name or broken association should produce an intelligible client error rather than accidentally dispatching a different function. Keep the fixture deterministic so that investigation concerns the message path rather than a changing tool service.

Exercise difficult branches separately

Add an answer requiring no tool, a repeated call, two permitted calls, and an invalid argument. If the selected parser lacks parallel-call support, document that limitation instead of expecting an artificial successful test. For streaming, verify argument assembly and the point at which a call becomes complete. Do not execute a function after the first suggestive text fragment; its arguments may still be incomplete. Retain raw events alongside the client’s assembled representation so that conversion mistakes can be located precisely.

Define the accepted contract

The artifact includes the model revision, parser, template, tool schema, and two consecutive request-response pairs. It shows when ordinary text is permitted and when a call is expected. Document unknown-tool handling and local function failures separately. A parser extracts structure; the application still determines which functions may run. Repeat the entire round trip whenever any of these components changes. An unchanged public model name does not guarantee an unchanged second-turn input or correct correlation with the result of an earlier invocation.

Tool calling through OpenRouter: the model proposes, your app executes; Testing streaming responses from the vLLM API.

← All articles