OpenAI-Compatible Tool Calling: Test and Fix tool_calls

A compatible endpoint must do more than accept the tools field. It must return a valid tool call and accept the matching tool result.

Published
Updated
Reading time
8 minutes
1Send toolsSchema and prompt
2Receive callName and arguments
3Send resultMatching call ID
4Receive answerUses tool output

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. 1

    Use one small function with one required string argument.

  2. 2

    Check the function name and parse the arguments as JSON.

  3. 3

    Return a tool message with the exact tool_call_id.

  4. 4

    Confirm that the final assistant response uses the tool result.

Run both tool probes

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.

POST /chat/completions request body
{
  "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.

Expected assistant message
{
  "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

SymptomLikely failureCheck next
400 for toolsCapability unsupportedProvider and model support
Plain text instead of a callModel behaviorTool choice and model capability
Missing function nameResponse shapeCompatibility server mapping
Arguments do not parseModel or server outputRaw argument string and truncation
Tool message is rejectedRound-trip contractRole, call ID, and message order
Final answer ignores resultModel behaviorTool 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.