Chapter 9. Tool calling through Distributed Inference with llm-d
Tool calling enables a large language model to request the execution of external functions during an inference conversation. Agent frameworks such as LangChain, CrewAI, and AutoGen rely on tool calling to build multi-step workflows where the model selects tools, generates structured arguments, and processes tool results across multiple turns.
The Distributed Inference with llm-d serving stack preserves tool calling parameters transparently. When a request includes tool definitions, the stack passes them through every layer, from the Gateway to the Endpoint Picker (EPP) to vLLM, without requiring any llm-d-specific configuration. The following Chat Completions API parameters pass through the stack unaltered:
-
tools: Function definitions including name, description, and JSON Schema parameters -
tool_choice: Tool selection mode, such asauto,required,none, or a named function -
parallel_tool_calls: Boolean that controls whether the model can generate multiple tool calls in a single response -
response_format: Structured output schema for JSON mode or JSON Schema constrained decoding
Tool call response objects, including tool_calls arrays with function.name and function.arguments, return to the client with the same fidelity. Streaming tool call deltas also pass through every stack layer without modification. This passthrough behavior works in both non-disaggregated and disaggregated prefill-decode deployments. Non-tool-calling requests are not affected in latency or throughput.
To use tool calling through Distributed Inference with llm-d, set the appropriate vLLM tool calling arguments on the LLMInferenceService custom resource.
The tool_choice request parameter controls how the model handles tool definitions. When a request includes tools but omits tool_choice, vLLM defaults to auto. The auto mode and the required and named function modes use different enforcement mechanisms. In auto mode, the model generates free-form output and the configured tool-call parser extracts tool calls from the result. In required and named function modes, vLLM uses guided decoding to constrain generation to the tool schemas, which produces structurally valid tool call arguments without relying on the parser. Use auto for agent workflows where the model needs to decide whether to call a tool. Use required or a named function when you need guaranteed tool call output with schema-valid arguments. For the full list of tool_choice values and their runtime requirements, see Supported tool calling parameters for Distributed Inference with llm-d.
Tool calling has not been validated with speculative decoding or Multi-Token Prediction (MTP). These features can interfere with the token generation process that vLLM uses to construct tool call objects. Known failure modes include corrupted function.arguments JSON in streaming responses and incomplete tool call parsing when multiple tool calls span a single streaming chunk. Non-streaming requests might succeed while streaming responses exhibit corruption. If you experience issues with tool calling while using speculative decoding or MTP, disable them for workloads that require tool calling.
9.1. Tool calling component responsibilities Copy linkLink copied to clipboard!
The Distributed Inference with llm-d serving stack is responsible for preserving tool calling parameters in transit. The vLLM runtime, not llm-d, handles the following concerns:
- Model-specific tool calling support and generation quality
- Chat template processing of tool definitions and tool-call history
- Tool call parser selection and model-specific output parsing
-
tool_choicebehavior - Parallel tool call response handling
- Structured output enforcement for required, named, and strict automatic tool calls
For model-specific tool calling configuration, see the vLLM tool calling documentation and the Red Hat AI Inference tool calling guide.
9.2. Configure tool calling for Distributed Inference with llm-d deployments Copy linkLink copied to clipboard!
You can enable tool calling for models served through Distributed Inference with llm-d by adding vLLM tool calling arguments to the LLMInferenceService custom resource. The Distributed Inference with llm-d serving stack forwards tool calling parameters to vLLM without modification, so no Distributed Inference with llm-d-specific configuration is required.
Prerequisites
- You have deployed a model using Distributed Inference with llm-d.
- The model you deployed supports tool calling. For supported models and parser values, see vLLM tool calling documentation.
-
You have access to the OpenShift CLI (
oc).
Procedure
Identify the correct
--tool-call-parservalue for your model.The parser must match the chat template format used by the model. For the list of supported parsers by model, see vLLM tool calling documentation. Most supported models provide a compatible chat template, but some models also require an explicit
--chat-template.Create or edit the
LLMInferenceServicecustom resource to include the tool calling arguments.Add
--enable-auto-tool-choiceand--tool-call-parserto theVLLM_ADDITIONAL_ARGSenvironment variable underspec.template.containersfor the container namedmain. Save the following YAML to a file namedllminferenceservice.yaml:apiVersion: serving.kserve.io/v1alpha2 kind: LLMInferenceService metadata: name: my-tool-calling-service namespace: <my_namespace> spec: replicas: 1 model: uri: hf://RedHatAI/Qwen3.5-9B-FP8-dynamic name: RedHatAI/Qwen3.5-9B-FP8-dynamic router: route: {} gateway: {} scheduler: {} template: containers: - name: main env: - name: VLLM_ADDITIONAL_ARGS value: >- --enable-auto-tool-choice --tool-call-parser=qwen3_coder --reasoning-parser=qwen3 resources: limits: cpu: '4' memory: 32Gi nvidia.com/gpu: "1" requests: cpu: '2' memory: 16Gi nvidia.com/gpu: "1"where:
--enable-auto-tool-choice-
Enables automatic tool choice for supported models. When a request uses
tool_choice="auto", the model can decide whether to return a text response or generate one or more tool calls. Automatic tool choice requires a compatible--tool-call-parserfor the model. This flag defaults tofalsein vLLM, so it must be set explicitly. --tool-call-parser- Specifies the parser that vLLM uses to extract tool calls from the model’s output. This value must match the chat template format of the model.
--reasoning-parser- Specifies the parser that vLLM uses to separate the model’s internal reasoning from its generated content. This flag does not enable reasoning in the model but tells the engine to treat reasoning and output separately. The reasoning parser is unrelated to tool calling but is recommended for this model.
Apply the custom resource:
$ oc apply -f llminferenceservice.yaml -n <my_namespace>Wait for the deployment to become ready:
$ oc get llminferenceservice my-tool-calling-service -n <my_namespace> -wExample output
NAME READY AGE my-tool-calling-service True 3mThe READY column shows
Truewhen the deployment is ready to serve requests.
Verification
Get the route URL for your model endpoint:
$ ROUTE_URL=$(oc get llmisvc -n <my_namespace> my-tool-calling-service -o jsonpath='{.status.url}')Send a tool calling request to verify the configuration:
$ curl -s -X POST "${ROUTE_URL}/v1/chat/completions" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $(oc whoami -t)" \ -d { "model": "RedHatAI/Qwen3.5-9B-FP8-dynamic", "temperature": 0, "messages": [ { "role": "system", "content": "You are a helpful assistant with access to tools. Use the get_weather tool when asked about weather." }, { "role": "user", "content": "What is the weather in San Francisco?" } ], "tools": [ { "type": "function", "function": { "name": "get_weather", "description": "Get the current weather in a given location.", "parameters": { "type": "object", "properties": { "location": { "type": "string", "description": "City and state." }, "unit": { "type": "string", "enum": ["celsius", "fahrenheit"] } }, "required": ["location"] } } } ], "tool_choice": "auto" } | python3 -m json.toolThe
| python3 -m json.toolpart of the command is optional and formats the JSON output for readability.Setting
"tool_choice": "auto"in the request lets the model automatically decide whether to call a tool based on the request content. For the full list oftool_choicevalues, see Supported tool calling parameters for Distributed Inference with llm-d.Verify the response contains a
tool_callsarray withfunction.nameset toget_weatherandfunction.argumentscontaining alocationvalue.Example output
{ "id": "chatcmpl-abc123", "object": "chat.completion", "model": "RedHatAI/Qwen3.5-9B-FP8-dynamic", "choices": [ { "index": 0, "message": { "role": "assistant", "content": null, "tool_calls": [ { "id": "call_abc123", "type": "function", "function": { "name": "get_weather", "arguments": "{\"location\": \"San Francisco, CA\"}" } } ] }, "finish_reason": "tool_calls" } ] }If the response contains plain text in the
contentfield instead of atool_callsarray, see Tool calling troubleshooting for Distributed Inference with llm-d.To complete a multi-turn tool calling loop, send the tool execution result back to the model in a follow-up message with
roleset totool. The Distributed Inference with llm-d stack preserves tool result messages in the same way as tool call requests. For the complete multi-turn pattern, see Extending Red Hat AI Inference with Tool Calling Capabilities.
9.3. Supported tool calling parameters for Distributed Inference with llm-d Copy linkLink copied to clipboard!
You can use the following Chat Completions API tool calling parameters with models served through Distributed Inference with llm-d. The Distributed Inference with llm-d serving stack preserves these parameters in both request and response paths, passing them through the Gateway, Endpoint Picker (EPP), and vLLM layers without modification.
9.3.1. Tool calling request parameters Copy linkLink copied to clipboard!
The following request parameters pass through the Distributed Inference with llm-d stack to the vLLM runtime. The response_format parameter is a general Chat Completions parameter, not specific to tool calling, but is included here because it is commonly used alongside tool definitions in agentic workflows.
| Parameter | Type | Description |
|---|---|---|
|
| Array of objects |
Function definitions that the model can call. Each tool object contains a |
|
| Boolean |
Controls whether vLLM enforces the function’s argument schema when generating a tool call. For |
|
| String or object |
Controls whether the model can generate tool calls and, when applicable, which tools it can select. Supported values are |
|
| Boolean |
Controls whether a response can contain multiple tool calls. The default is |
|
| Object |
Specifies the output format for the model response. You can use |
9.3.2. Tool choice behavior in vLLM Copy linkLink copied to clipboard!
The tool_choice request parameter controls how the model handles tool definitions in a request. The behavior varies by mode, and some modes require specific vLLM runtime flags. When a request includes tools but omits tool_choice, vLLM defaults to auto. This means that any deployment serving tool calling requests requires --enable-auto-tool-choice and a compatible --tool-call-parser unless every request explicitly sets tool_choice to required, a named function, or none. For an overview of how these modes differ, see Tool calling through Distributed Inference with llm-d.
tool_choice | Tool selection | Schema enforcement | Runtime requirements |
|---|---|---|---|
|
| The model decides whether to return normal content or generate one or more calls to the available tools. |
By default, generation is unconstrained and the configured tool-call parser extracts tool calls from the generated output. If a tool specifies |
Requires the vLLM runtime to be started with |
|
| The model must generate one or more tool calls and selects from the tools supplied in the request. | vLLM uses structured output constraints derived from the supplied tool schemas. |
Supported by default. |
| Named function |
The request specifies the function that the model must call by using | vLLM uses structured output constraints derived from the selected function’s parameter schema. |
Supported by default. |
|
| The model does not generate tool calls and returns normal response content. | Not applicable. |
Supported by default. By default, vLLM still provides the tool definitions to the chat template. You can start vLLM with |
9.3.3. Tool calling response objects Copy linkLink copied to clipboard!
The following response objects pass through the Distributed Inference with llm-d stack from the vLLM runtime to the client.
| Object | Type | Description |
|---|---|---|
|
| Array of objects |
An array of tool call objects in the response |
|
| Array of objects |
In streaming responses, tool call data arrives incrementally in |
When a request includes multiple tools, the tool_calls array in the response might not contain all of them. The number of tool calls returned depends on the model, the tool-call parser, and the prompt. Some models generate tool calls one at a time across multiple conversation turns rather than returning all calls in a single response. If you expect multiple tool calls but receive fewer, verify that the model and --tool-call-parser support parallel tool calling for your use case.
These parameters are specific to what the Distributed Inference with llm-d serving stack preserves in transit. The vLLM runtime handles the following aspects of tool calling:
- Model-specific tool calling support and generation quality
- Chat template processing of tool definitions and tool-call history
- Tool call parser selection and model-specific output parsing
-
tool_choicebehavior - Parallel tool call response handling
- Structured output enforcement for required, named, and strict automatic tool calls
For information about which models support tool calling and which --tool-call-parser values to use, see vLLM tool calling documentation.
9.4. Tool calling troubleshooting for Distributed Inference with llm-d Copy linkLink copied to clipboard!
Diagnose and resolve issues with tool calling through the Distributed Inference with llm-d serving stack. The Distributed Inference with llm-d stack passes tool calling parameters through transparently, so tool calling failures are almost always caused by the vLLM runtime configuration, not the stack itself.
- Model returns text instead of tool calls
Symptoms:
-
Agent frameworks receive plain text where
tool_callsobjects are expected -
The response
contentfield contains text andtool_callsis absent or empty - Application workflows stall because the agent framework cannot determine a next action
-
The HTTP response status is
200 OKwith no error
Diagnosis:
Verify the
LLMInferenceServicehas vLLM tool calling arguments configured:$ oc get llmisvc <service_name> -n <my_namespace> -o yaml | grep -A 2 "VLLM_ADDITIONAL_ARGS"The
VLLM_ADDITIONAL_ARGSvalue must include both--enable-auto-tool-choiceand--tool-call-parser=<parser>. Missing flags are the most common cause: the model does not process tool definitions without them.Verify the
--tool-call-parservalue matches the model.The parser must match the chat template format of the deployed model. An incorrect parser causes the model to generate tool calls that vLLM cannot extract, resulting in plain text responses. For the correct parser value, see vLLM tool calling documentation.
Verify the request includes a
toolsarray with valid function definitions.Inspect the request body sent by the agent framework or test client. The request must include a
toolsarray with at least one tool definition containingname,description, andparameters.
Resolution:
-
If vLLM tool calling arguments are missing or incorrect, update the
LLMInferenceServicecustom resource. See Configure tool calling for Distributed Inference with llm-d deployments. -
If the request is missing the
toolsarray, update the client or agent framework configuration. - If the vLLM configuration is correct and the request includes tools, the issue is likely model-specific. For model-level troubleshooting, see Extending Red Hat AI Inference with Tool Calling Capabilities.
-
Agent frameworks receive plain text where
- Tool calls are corrupted or incomplete in streaming responses
Symptoms:
-
The
function.argumentsfield intool_callscontains malformed or truncated JSON -
Multi-tool streaming responses are missing one or more expected
tool_callsentries - The issue occurs only in streaming mode; non-streaming requests return correct tool calls
- Agent frameworks fail to parse tool call arguments or receive fewer tool calls than expected
Diagnosis:
Verify whether speculative decoding or Multi-Token Prediction (MTP) is enabled on the deployment.
Check the
LLMInferenceServicefor arguments such as--speculative-model,--num-speculative-tokens, or MTP-related flags:$ oc get llmisvc <service_name> -n <my_namespace> -o yaml | grep -A 2 "VLLM_ADDITIONAL_ARGS"Test the same request with speculative decoding or MTP disabled.
Remove the speculative decoding or MTP arguments from the
VLLM_ADDITIONAL_ARGSenvironment variable in theLLMInferenceServicecustom resource and reapply it. If tool calling works correctly after removing these arguments, the issue is caused by the interaction between speculative decoding or MTP and tool call token generation.Test with non-streaming mode to confirm the issue is specific to streaming.
Set
"stream": falsein the request body and verify that the response contains correcttool_callsobjects.
Resolution:
Disable speculative decoding or MTP for workloads that require tool calling. These features have not been validated with tool calling and can interfere with the token generation process that vLLM uses to construct streaming tool call deltas.
For more information, see Tool calling through Distributed Inference with llm-d.
-
The