sglang 0.4.7 + deepseek v3-0324 Unsupported tool call ?
code `package com.ruoyi.controller;
import jakarta.annotation.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor; import org.springframework.ai.tool.ToolCallbackProvider; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;
import java.util.Objects;
@RestController @RequestMapping("/client/ai") public class ChatController {
private static final Logger logger = LoggerFactory.getLogger(ChatController.class);
private final ChatClient chatClient;
public ChatController(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder.build();
}
@Resource
private ToolCallbackProvider toolCallbackProvider;
@GetMapping("/chat")
public String chat(String message){
System.out.println("message:"+message);
String answer = chatClient
.prompt()
.user(message)
.tools(toolCallbackProvider)
.call().chatResponse().getResult().getOutput().getText();
System.out.println("answer:"+answer);
return answer;
}
}`
`package com.ruoyi.tool;
import org.springframework.ai.tool.annotation.Tool; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
@Service("weatherServiceTool") public class WeatherServiceTool {
@Tool(description = "获取指定城市的天气")
public WeatherInfo getWeather(String cityName) {
System.out.println("调用工具1:获取指定城市的天气");
if ("北京".equals(cityName)) {
return new WeatherInfo("北京", "晴", 28);
} else if ("上海".equals(cityName)) {
return new WeatherInfo("上海", "多云", 26);
} else {
return new WeatherInfo(cityName, "未知", -999);
}
}
@Tool(description = "获取当前用户所在的时区时间")
String getCurrentDateTime() {
System.out.println("调用工具2:获取当前用户所在的时区时间");
return LocalDateTime.now().atZone(LocaleContextHolder.getTimeZone().toZoneId()).toString();
}
}
`
error sglang
[2025-06-19 02:07:56] INFO: [172.30.213.120:59018](http://172.30.213.120:59018/) - "POST /v1/chat/completions HTTP/1.1" 500 Internal Server Error
[2025-06-19 02:07:56] ERROR: Exception in ASGI application
Traceback (most recent call last):
File "/usr/local/lib/python3.12/dist-packages/uvicorn/protocols/http/h11_impl.py", line 403, in run_asgi
result = await app( # type: ignore[func-returns-value]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/dist-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__
return await self.app(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/dist-packages/fastapi/applications.py", line 1054, in __call__
await super().__call__(scope, receive, send)
File "/usr/local/lib/python3.12/dist-packages/starlette/applications.py", line 112, in __call__
await self.middleware_stack(scope, receive, send)
File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/errors.py", line 187, in __call__
raise exc
File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/errors.py", line 165, in __call__
await self.app(scope, receive, _send)
File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/cors.py", line 85, in __call__
await self.app(scope, receive, send)
File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/exceptions.py", line 62, in __call__
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 53, in wrapped_app
raise exc
File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 714, in __call__
await self.middleware_stack(scope, receive, send)
File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 734, in app
await route.handle(scope, receive, send)
File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 288, in handle
await self.app(scope, receive, send)
File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 76, in app
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 53, in wrapped_app
raise exc
File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 73, in app
response = await f(request)
^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/dist-packages/fastapi/routing.py", line 301, in app
raw_response = await run_endpoint_function(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/dist-packages/fastapi/routing.py", line 212, in run_endpoint_function
return await dependant.call(**values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/sgl-workspace/sglang/python/sglang/srt/entrypoints/http_server.py", line 629, in openai_v1_chat_completions
return await v1_chat_completions(_global_state.tokenizer_manager, raw_request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/sgl-workspace/sglang/python/sglang/srt/openai_api/adapter.py", line 1541, in v1_chat_completions
all_requests = [ChatCompletionRequest(**request_json)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/dist-packages/pydantic/main.py", line 253, in __init__
validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pydantic_core._pydantic_core.ValidationError: 3 validation errors for ChatCompletionRequest
messages.1.ChatCompletionMessageGenericParam.content
Field required [type=missing, input_value={'role': 'assistant', 'to...ityName": "北京"}'}}]}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.11/v/missing
messages.1.ChatCompletionMessageUserParam.role
Input should be 'user' [type=literal_error, input_value='assistant', input_type=str]
For further information visit https://errors.pydantic.dev/2.11/v/literal_error
messages.1.ChatCompletionMessageUserParam.content
Field required [type=missing, input_value={'role': 'assistant', 'to...ityName": "北京"}'}}]}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.11/v/missing
Reproduction
h20 96G 8* 2
model:DeepSeek V3
Environment
docker run -d --gpus all \ --shm-size 500g \ --network=host \ -v /home/nvme01:/model \ --name sglang_deepseek-V3-01 \ -it \ --rm \ --ipc=host \ -e VLLM_HOST_IP=172.17.42.4 \ -e NCCL_IB_HCA=mlx5_ \ -e NCCL_IB_GID_INDEX=3 \ -e GLOO_SOCKET_IFNAME=eth0 \ -e NCCL_SOCKET_IFNAME=eth0 \ -e NCCL_DEBUG=info \ -e NCCL_IB_DISABLE=0 \ lmsysorg/sglang:v0.4.7.post1-cu124 \ python3 -m sglang.launch_server --model-path /model/DeepSeek-V3 --served-model-name=DeepSeek-V3 --tp 16 --dist-init-addr 172.17.42.4:6379 --nnodes 2 --node-rank 0 --trust-remote-code --host 0.0.0.0 --port 8000 --tool-call-parser deepseekv3 --chat-template ./sglang/examples/chat_template/tool_chat_template_deepseekv3.jinja
docker run -d --gpus all \ --shm-size 500g \ --network=host \ -v /home/nvme01:/model \ --name sglang_deepseek-V3-02 \ -it \ --rm \ --ipc=host \ --ipc=host \ -e VLLM_HOST_IP=172.17.42.5 \ -e NCCL_IB_HCA=mlx5_ \ -e NCCL_IB_GID_INDEX=3 \ -e GLOO_SOCKET_IFNAME=eth0 \ -e NCCL_SOCKET_IFNAME=eth0 \ -e NCCL_DEBUG=info \ -e NCCL_IB_DISABLE=0 \ lmsysorg/sglang:v0.4.7.post1-cu124 \ python3 -m sglang.launch_server --model-path /model/DeepSeek-V3 --served-model-name=DeepSeek-V3 --tp 16 --dist-init-addr 172.17.42.4:6379 --nnodes 2 --node-rank 1 --trust-remote-code --host 0.0.0.0 --port 8000 --tool-call-parser deepseekv3 --chat-template ./sglang/examples/chat_template/tool_chat_template_deepseekv3.jinja
Comment From: dev-jonghoonpark
I'm cleaning up log for future reviewers.
3 validation errors for ChatCompletionRequest messages.
ChatCompletionMessageGenericParam.content Field required [type=missing, input_value={'role': 'assistant', 'to...ityName": "北京"}'}}]}, input_type=dict] For further information visit https://errors.pydantic.dev/2.11/v/missing messages.
ChatCompletionMessageUserParam.role Input should be 'user' [type=literal_error, input_value='assistant', input_type=str] For further information visit https://errors.pydantic.dev/2.11/v/literal_error messages.
ChatCompletionMessageUserParam.content Field required [type=missing, input_value={'role': 'assistant', 'to...ityName": "北京"}'}}]}, input_type=dict] For further information visit https://errors.pydantic.dev/2.11/v/missing
Comment From: start-dzl
The same code runs without any issues on vLLM combined with DeepSeek.