Kryyt / Developers

Function Calling

The model requests a function. Your application decides whether and how to execute it.

Declare a read-only tool

Tool declaration
{
  "model": "deepseek-v4.1-flash",
  "messages": [
    {
      "role": "user",
      "content": "When is the Chandigarh office open?"
    }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_office_hours",
        "description": "Look up the public opening hours for a supported office.",
        "parameters": {
          "type": "object",
          "properties": {
            "city": {
              "type": "string",
              "enum": [
                "Chandigarh",
                "London"
              ]
            }
          },
          "required": [
            "city"
          ],
          "additionalProperties": false
        }
      }
    }
  ],
  "tool_choice": "auto",
  "max_tokens": 512
}

Handle a tool call

The following fragment assumes client, messages, and tools are already defined. Keep the complete assistant message before appending tool results. Bound the loop and reject unknown tools or invalid arguments.

Bounded tool loop
import json

hours = {"Chandigarh": "09:00-18:00", "London": "09:00-17:00"}
for _ in range(4):
    response = client.chat.completions.create(
        model="deepseek-v4.1-flash", messages=messages, tools=tools,
        tool_choice="auto", max_tokens=512,
    )
    message = response.choices[0].message
    messages.append(message.model_dump(exclude_none=True))
    if not message.tool_calls:
        print(message.content or "")
        break
    for call in message.tool_calls:
        args = json.loads(call.function.arguments)
        if (call.function.name != "get_office_hours"
                or not isinstance(args, dict)
                or not isinstance(args.get("city"), str)
                or args.get("city") not in hours):
            raise ValueError("Tool request is not allowed")
        messages.append({
            "role": "tool", "tool_call_id": call.id,
            "content": json.dumps({"hours": hours[args["city"]]}),
        })
else:
    raise RuntimeError("Tool-call budget exhausted")

Permissions belong in your application

Function arguments and tool results are untrusted data. Enforce user authorization, tenant boundaries, input validation, timeouts, and an execution budget. Require confirmation for consequential actions. Never use a model-generated function name or argument as executable code.

Web tools and connectors