# DeepSeek-V3 tool\_choice="auto", not working but tool\_choice="required" is working

**URL:** https://discuss.vllm.ai/t/deepseek-v3-tool-choice-auto-not-working-but-tool-choice-required-is-working/1006
**Category:** Tool Calling
**Created:** [July 4, 2025, 7:49am UTC](https://discuss.vllm.ai/t/deepseek-v3-tool-choice-auto-not-working-but-tool-choice-required-is-working/1006 "2025-07-04T07:49:07Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Vipin](https://avatars.discourse-cdn.com/v4/letter/v/edb3f5/32.png) [@Vipin](https://discuss.vllm.ai/u/Vipin)
#### Post date: [July 4, 2025, 7:49am UTC](https://discuss.vllm.ai/t/deepseek-v3-tool-choice-auto-not-working-but-tool-choice-required-is-working/1006/1 "2025-07-04T07:49:07Z")

</div>

DeepSeek-V3 tool\_choice=“auto”, not working but tool\_choice=“required” is working

- args:  
- --model  
- deepseek-ai/DeepSeek-V3  
- --port  
- “8080”  
- --tensor-parallel-size  
- “8”  
- --served-model-name  
- deepseek\_v3  
- --trust-remote-code  
- --enable-auto-tool-choice  
- --tool-call-parser  
- deepseek\_v3  
- --chat-template  
- /vllm-workspace/examples/tool\_chat\_template\_deepseekv3.jinja  
command:  
- python3  
- -m  
- vllm.entrypoints.openai.api\_server

tools = [  
{  
“type”: “function”,  
“function”: {  
“name”: “get\_weather”,  
“description”: “Retrieve the weather for a specific location. The user must provide a location first.”,  
“parameters”: {  
“type”: “object”,  
“properties”: {  
“location”: {  
“type”: “string”,  
“description”: “The city and state, e.g. San Francisco, CA”,  
},  
},  
“required”: [“location”]  
},  
}  
},  
]  
response = openai.chat.completions.create(  
model=‘deepseek\_v3’,  
messages=[  
{  
“role”: “user”,  
“content”: “get weather in San Francisco”  
}  
],  
tools=tools,  
tool\_choice=“auto”,  
temperature=0.5,  
max\_tokens=5000,  
top\_p=1,  
frequency\_penalty=0,  
presence\_penalty=1,  
stream=False,

)

ouput in case auto  
ChatCompletion(id=‘chatcmpl-5d61e3e0-47b5-4a0d-9819-bbddfb7b0e12’, choices=[Choice(finish\_reason=‘stop’, index=0, logprobs=None, message=ChatCompletionMessage(content=’

json\n{“location”: “San Francisco, CA”}\n

\<｜tool▁call▁end｜\>', refusal=None, role=‘assistant’, annotations=None, audio=None, function\_call=None, tool\_calls=, reasoning\_content=None), stop\_reason=None)], created=1751608114, model=‘deepseek\_v3’, object=‘chat.completion’, service\_tier=None, system\_fingerprint=None, usage=CompletionUsage(completion\_tokens=15, prompt\_tokens=209, total\_tokens=224, completion\_tokens\_details=None, prompt\_tokens\_details=None), prompt\_logprobs=None, kv\_transfer\_params=None)

---

<div class="post-metadata">

### Author: ![RunLLM](https://yyz2.discourse-cdn.com/flex036/user_avatar/discuss.vllm.ai/runllm/32/233_2.png) [@RunLLM](https://discuss.vllm.ai/u/RunLLM)
#### Post date: [July 4, 2025, 7:50am UTC](https://discuss.vllm.ai/t/deepseek-v3-tool-choice-auto-not-working-but-tool-choice-required-is-working/1006/2 "2025-07-04T07:50:03Z")

</div>

For DeepSeek-V3 with vLLM, `tool_choice="required"` works, but `tool_choice="auto"` may not trigger tool calls as expected. This is a known issue: the model often fails to generate tool calls in “auto” mode, while “required” forces the model to use the provided tools and works reliably. This behavior is confirmed in user reports and discussions, and is not unique to your setup—others have observed that DeepSeek-V3 and DeepSeek-R1 models only reliably call tools when `tool_choice="required"` is set, not `"auto"` ([source](https://github.com/vllm-project/vllm/issues/19001), [source](https://github.com/vllm-project/vllm/pull/18874)).

The root cause is that, in “auto” mode, the model itself decides whether to use a tool, and DeepSeek-V3’s tool-calling logic is not always triggered unless forced. There is no official fix or workaround in the vLLM documentation as of now; using `"required"` is the recommended approach for consistent tool calling ([source](https://docs.vllm.ai/en/stable/features/tool_calling.html#required-function-calling)). Would you like a step-by-step breakdown or example code?

Sources:

- [GitHub Issue: How to use DeepSeek-R1-0528-Qwen3-8B with function call](https://github.com/vllm-project/vllm/issues/19001)
- [GitHub PR: Add DeepSeek-R1-0528 function call chat template](https://github.com/vllm-project/vllm/pull/18874)

---

<div class="post-metadata">

### Author: ![NilsHellwig](https://yyz2.discourse-cdn.com/flex036/user_avatar/discuss.vllm.ai/nilshellwig/32/410_2.png) [@NilsHellwig](https://discuss.vllm.ai/u/NilsHellwig)
#### Post date: [August 25, 2025, 11:29am UTC](https://discuss.vllm.ai/t/deepseek-v3-tool-choice-auto-not-working-but-tool-choice-required-is-working/1006/3 "2025-08-25T11:29:07Z")

</div>

```auto
def get_weather(location: str, unit: str):

```

```auto
**return**  **f**"Getting the weather for {location} in {unit}..."

```

```auto
tool_functions = {“get_weather”: get_weather}

```

```auto
tools = [{

```

```auto
“type”: “function”,

```

```auto
“function”: {

```

```auto
“name”: “get_weather”,

```

```auto
“description”: “Get the current weather in a given location”,

```

```auto
“parameters”: {

```

```auto
“type”: “object”,

```

```auto
“properties”: {

```

```auto
“location”: {“type”: “string”, “description”: “City and state, e.g., ‘San Francisco, CA’”},

```

```auto
“unit”: {“type”: “string”, “enum”: [“celsius”, “fahrenheit”]}

```

```auto
},

```

```auto
“required”: [“location”, “unit”]

```

```auto
}

```

```auto
}

```

```auto
}]

```

```auto
response = client.chat.completions.create(

```

```auto
model=client.models.list().data[0].id,

```

```auto
messages=[{“role”: “user”, “content”: “Please tell me what is 1+1”}],

```

```auto
tools=tools,

```

```auto
tool_choice=“auto”

```

```auto
)

```

```auto
tool_call = response.choices[0].message.tool_calls[0].function

```

```auto
print(f"Function called: {tool_call.name}")

```

```auto
print(f"Arguments: {tool_call.arguments}")

```

```auto
print(f"Result: {tool_functions[tool_call.name](**json.loads(tool_call.arguments))}")

```

Similarly, I’m getting a function although tool\_coice is set to `auto`. the prompt doesn’t expect a function in response

---

<div class="post-metadata">

### Author: ![RunLLM](https://yyz2.discourse-cdn.com/flex036/user_avatar/discuss.vllm.ai/runllm/32/233_2.png) [@RunLLM](https://discuss.vllm.ai/u/RunLLM)
#### Post date: [August 25, 2025, 11:29am UTC](https://discuss.vllm.ai/t/deepseek-v3-tool-choice-auto-not-working-but-tool-choice-required-is-working/1006/4 "2025-08-25T11:29:35Z")

</div>

This is expected: with `tool_choice="auto"`, vLLM passes the decision to the model, but some models (including Llama-3.1 and others) may over-trigger tool calls even when the prompt doesn’t require them. This is a model behavior, not a vLLM bug—if the model “thinks” a tool is relevant, it will call it, regardless of prompt intent ([source](https://docs.vllm.ai/en/stable/features/tool_calling.html#automatic-function-calling)).

To avoid this, use `tool_choice="none"` to disable tool calls, or improve your prompt to discourage tool use. For strict control, use `tool_choice={"type": "function", "function": {"name": "get_weather"}}` to force or block tool calls as needed ([source](https://docs.vllm.ai/en/stable/features/tool_calling.html#named-function-calling)). Would you like more detail or example code?

Sources:

- [https://github.com/vllm-project/vllm/issues/22578](https://github.com/vllm-project/vllm/issues/22578)
- [https://github.com/vllm-project/vllm/issues/7912](https://github.com/vllm-project/vllm/issues/7912)

---

<div class="post-metadata">

### Author: ![ausarhuy](https://yyz2.discourse-cdn.com/flex036/user_avatar/discuss.vllm.ai/ausarhuy/32/786_2.png) [@ausarhuy](https://discuss.vllm.ai/u/ausarhuy)
#### Post date: [October 13, 2025, 4:11am UTC](https://discuss.vllm.ai/t/deepseek-v3-tool-choice-auto-not-working-but-tool-choice-required-is-working/1006/5 "2025-10-13T04:11:57Z")

</div>

Anyone found a fix for this yet? Since vLLM v1, it seems like tool choice must be set to `required`, otherwise, LLM will respond in Content not from ToolCall. Tested on Deepseek R1 Qwen 8B and granite 4.0 tiny.
