DEVUP Docs
Back to Dashboard
OpenAI-compatible

Tool Calling

DEVUP AI supports OpenAI-compatible tool calling for models that expose this capability. By defining external tools (like APIs or database queries), you can allow the model to intelligently choose when and how to call them. Tool-call quality, feature support, and parameter compliance may vary by model.

Tool-calling flow

1

User request

Send messages and available tool definitions.

2

Model requests tool

Receive the requested tool name and generated arguments.

3

Validate & execute

Validate the tool name and arguments, then run the application-owned function.

4

Return tool result

Append a role: "tool" message using the matching tool_call_id.

5

Final answer

Send the updated conversation and receive the model’s final response.

Setup

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["DEVUP_API_KEY"],
    base_url="https://api.devupai.com/v1",
)
1

Define a local function

First, define the function in your application that the model can call. This is a local demonstration function that returns static data. The application fully owns this logic.

import json

def get_current_weather(location):
    """Get the current weather in a given location"""
    if "san francisco" in location.lower():
        return json.dumps({"location": "San Francisco", "temperature": "60"})
    return json.dumps({"location": location, "temperature": "unknown"})
2

Send tools to the model

Provide the tool definition in the request using JSON Schema. The model will determine if it needs to call the tool based on the user's message.

tools = [{
    "type": "function",
    "function": {
        "name": "get_current_weather",
        "description": "Get the current weather in a given location",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "The city and state, e.g. San Francisco, CA"
                }
            },
            "required": ["location"]
        },
    }
}]

messages = [{"role": "user", "content": "What is the weather in San Francisco?"}]

response = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-V4-Pro",
    messages=messages,
    tools=tools,
    tool_choice="auto",
)

assistant_message = response.choices[0].message
tool_calls = assistant_message.tool_calls

if tool_calls:
    for tool_call in tool_calls:
        print(tool_call.model_dump())
Illustrative response
json
{
  "id": "call_abc123",
  "type": "function",
  "function": {
    "name": "get_current_weather",
    "arguments": "{\"location\": \"San Francisco, CA\"}"
  }
}
3

Execute and return results

After validating the tool name and parsing the JSON arguments, execute your local function. Append the assistant's message, followed by the tool result containing the matching tool_call_id.

# Safely append the assistant message using model_dump()
messages.append(assistant_message.model_dump(exclude_unset=True))

for tool_call in tool_calls:
    function_name = tool_call.function.name
    if function_name == "get_current_weather":
        function_args = json.loads(tool_call.function.arguments)
        function_response = get_current_weather(location=function_args.get("location"))

    # Append the tool result back to the conversation
    messages.append({
        "tool_call_id": tool_call.id,
        "role": "tool",
        "content": function_response,
    })

# Get the final answer from the model
second_response = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-V4-Pro",
    messages=messages,
    tools=tools,
    tool_choice="auto",
)

print(second_response.choices[0].message.content)
Illustrative final response

The current temperature in San Francisco, CA is 60 degrees Fahrenheit.

Tool execution safety

Security Best Practices

  • Treat model-generated arguments as untrusted user input.
  • Strictly allowlist executable tool names.
  • Validate arguments rigorously against the JSON schema.
  • Never execute arbitrary code or shell commands.
  • Apply strict timeouts to prevent hanging executions.
  • Handle tool failures gracefully and safely.
  • Never expose secrets or credentials in the tool results.
  • Limit result size to prevent context overflow.

Best Practices

Descriptions

Write clear and specific tool names and descriptions. The model's decision to invoke a tool depends heavily on them.

Validation

Use strict, minimal JSON schemas. Always validate all arguments on your application side before running any logic.

Focus

Keep the list of provided tools focused. Providing too many unrelated tools can degrade model reasoning.

Predictability

Check the selected model's robust capabilities. Use deterministic settings like a lower temperature when appropriate.

Supported capabilities

Single tool calls
Model can request a single tool execution.Model-dependent
Parallel tool calls
Model can request multiple independent tools at once.Model-dependent
tool_choice: "auto"
Model decides whether to use a tool or reply directly.Supported
tool_choice: "none"
Forces the model to skip tools and reply directly.Supported
Explicit selection
Force the model to call a specific tool.Model-dependent
Streaming
Receive tool call arguments incrementally via SSE.Model-dependent

What's Next