GoodPut AI

Tool calls

Define tools, handle calls, and return results in both protocols.

Platform models support function calling: the model decides when to call your tools and provides structured JSON arguments. You execute the tool and return the result so the model can continue. See each model’s capabilities in the catalog.

OpenAI protocol

Define a tool and send a request

resp = client.chat.completions.create(
    model="deepseek/deepseek-v4-pro",
    messages=[{"role": "user", "content": "What is the weather in Beijing today?"}],
    tools=[{
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get the current weather for the specified city",
            "parameters": {
                "type": "object",
                "properties": {"city": {"type": "string"}},
                "required": ["city"],
            },
        },
    }],
)

Execute the call and return its result

When the model calls a tool, finish_reason is tool_calls:

msg = resp.choices[0].message
if msg.tool_calls:
    call = msg.tool_calls[0]
    result = get_weather(**json.loads(call.function.arguments))
    followup = client.chat.completions.create(
        model="deepseek/deepseek-v4-pro",
        messages=[
            {"role": "user", "content": "What is the weather in Beijing today?"},
            msg,  # Return the assistant message containing tool_calls unchanged
            {"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)},
        ],
        tools=tools,
    )

tool_choice supports auto (default), required, none, or a specific function.

Anthropic protocol

Define tools with input_schema. A tool call has stop_reason: tool_use; return its result in a tool_result block in a user message:

{
  "model": "z-ai/glm-5.2",
  "max_tokens": 1024,
  "tools": [{
    "name": "get_weather",
    "description": "Get the current weather for the specified city",
    "input_schema": {
      "type": "object",
      "properties": {"city": {"type": "string"}},
      "required": ["city"]
    }
  }],
  "messages": [
    {"role": "user", "content": "What is the weather in Beijing today?"},
    {"role": "assistant", "content": [{"type": "tool_use", "id": "toolu_xx", "name": "get_weather", "input": {"city": "Beijing"}}]},
    {"role": "user", "content": [{"type": "tool_result", "tool_use_id": "toolu_xx", "content": "{\"temp\": 31}"}]}
  ]
}

Notes

  • Multi-turn tool calls with reasoning models: return the previous assistant message, including reasoning, unchanged. Do not trim or rewrite it; the gateway handles protocol-field compatibility.
  • Tool definitions count as input tokens. Consider prompt caching when you have many tools.
  • Streaming tool arguments arrive as incremental JSON (delta.tool_calls[].function.arguments for OpenAI; input_json_delta for Anthropic). Assemble them in the client.

On this page