Docs Menu & Search

Documentation

Tool Calling & Structured Output

Let a model call your functions, or make it answer in JSON that matches a schema.

Both work exactly as in OpenAI’s API: nabh.cloud passes tools, tool_choice and response_format through to the model unchanged. Whether a model honours them depends on the model — each model page shows Function Calling and Structured / JSON Output as Supported, Not Supported or Unverified.

Tool (Function) Calling

Describe your functions in tools. When the model wants one, the reply has finish_reason: "tool_calls" and message.tool_calls with the function name and JSON arguments. You run the function and send the result back as a tool message; the model then answers. nabh.cloud never runs your functions — it only relays the conversation.

import json
from openai import OpenAI

client = OpenAI(api_key="nbh_your_key_here", base_url="https://api.nabh.cloud/v1")

tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Current weather for a city",
        "parameters": {
            "type": "object",
            "properties": {"city": {"type": "string"}},
            "required": ["city"],
        },
    },
}]
messages = [{"role": "user", "content": "Do I need an umbrella in Mumbai today?"}]

# 1. The model decides to call your function
first = client.chat.completions.create(model="gpt-oss-20b", messages=messages, tools=tools)
call = first.choices[0].message.tool_calls[0]
args = json.loads(call.function.arguments)          # {"city": "Mumbai"}

# 2. You run it and send the result back
messages.append(first.choices[0].message)
messages.append({"role": "tool", "tool_call_id": call.id,
                 "content": json.dumps({"city": args["city"], "rain_chance": 0.8})})

# 3. The model answers using your result
final = client.chat.completions.create(model="gpt-oss-20b", messages=messages, tools=tools)
print(final.choices[0].message.content)

Models with function calling verified: gpt-oss-20b, qwen3-6-27b, llama-3-70b-instruct, gpt-oss-120b, qwen3-5-397b, gemma-4-26b-a4b, glm-5-2, deepseek-v4-1-flash, deepseek-v4-pro, kimi-k2-7-code, kimi-k3, minimax-m3 — live list. Use tool_choice to force a specific function ({"type": "function", "function": {"name": "get_weather"}}) or to stop tool use ("none").

Structured / JSON Output

response_format asks the model to reply in JSON — either any valid JSON object (json_object) or JSON matching your schema (json_schema). Verified on gemma-4-26b-a4b; other models may follow it but haven’t been verified (live list).

curl https://api.nabh.cloud/v1/chat/completions \
  -H "Authorization: Bearer nbh_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemma-4-26b-a4b",
    "messages": [{"role": "user", "content": "Extract the name and city: Priya moved to Pune last year."}],
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "person",
        "schema": {
          "type": "object",
          "properties": {"name": {"type": "string"}, "city": {"type": "string"}},
          "required": ["name", "city"]
        }
      }
    }
  }'
  • Always say in the prompt that you want JSON too — some models only follow response_format reliably when the instructions agree.
  • Parse defensively: a reply cut off by max_tokens (finish_reason: "length") is incomplete JSON. Raise max_tokens rather than retrying blindly.
  • Tool calling is often the more reliable way to get structured data from models without verified JSON output: describe the shape as a function’s parameters and read tool_calls[0].function.arguments.

Billing

Tool definitions, tool results and schemas are part of the input, so they count as input tokens; each round trip in a tool-calling loop is a separate, separately billed request.