The Short Answer
Check two separate operations. First, confirm that the model returns a structured tool_calls array. Then send a tool message with the same call ID.
- 1
Use one small function with one required string argument.
- 2
Check the function name and parse the arguments as JSON.
- 3
Return a tool message with the exact
tool_call_id. - 4
Confirm that the final assistant response uses the tool result.
Send a Minimal Tool Definition
Keep the first test small. A complex schema can hide whether the endpoint rejects tools or only rejects one schema feature.
{
"model": "your-model-id",
"messages": [{"role": "user", "content": "What is the weather in Dubai?"}],
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
}
}],
"tool_choice": "auto"
}Check the Complete Response Shape
The arguments field is a JSON string. Parse it before use. Also keep the call ID because the next request must reference it.
{
"choices": [{
"message": {
"role": "assistant",
"tool_calls": [{
"id": "call_123",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{"city":"Dubai"}"
}
}]
},
"finish_reason": "tool_calls"
}]
}The interaction follows the official OpenAI function-calling guide.
Map Each Symptom to the Failed Contract
| Symptom | Likely failure | Check next |
|---|---|---|
400 for tools | Capability unsupported | Provider and model support |
| Plain text instead of a call | Model behavior | Tool choice and model capability |
| Missing function name | Response shape | Compatibility server mapping |
| Arguments do not parse | Model or server output | Raw argument string and truncation |
| Tool message is rejected | Round-trip contract | Role, call ID, and message order |
| Final answer ignores result | Model behavior | Tool output and conversation state |
Verify the Full Round Trip
LLMCompat runs one probe for call emission and another for the result round trip. This split shows which contract failed.