API guides
Tool calling
A model proposes a tool call; your application decides whether and how to execute it. Send the result back to the model so it can finish its answer. Choose a model that supports tools.
The tool loop
- 01
- DescribeProvide a named tool and a JSON schema for its arguments.
- 02
- Validate & runInspect the requested name and arguments. Only execute allowed operations.
- 03
- ReturnAttach the tool result to the matching tool_call_id and ask the model to continue.
Complete example
Install the OpenAI Python SDK and set STRAITLY_API_KEY. This example uses a harmless local lookup with mock data. It never executes model-generated shell commands or reaches an external service.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.straitly.ai/v1",
api_key=os.environ["STRAITLY_API_KEY"],
)
tools = [{
"type": "function",
"function": {
"name": "get_office_hours",
"description": "Get office hours for a city.",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string", "enum": ["San Francisco"]}},
"required": ["city"],
"additionalProperties": False,
},
},
}]
messages = [{"role": "user", "content": "When is the San Francisco office open?"}]
import json
for _ in range(4):
reply = client.chat.completions.create(
model="claude-sonnet-5", messages=messages, tools=tools,
).choices[0].message
if not reply.tool_calls:
print(reply.content)
break
messages.append(reply.model_dump(exclude_none=True))
for call in reply.tool_calls:
args = json.loads(call.function.arguments)
if call.function.name != "get_office_hours":
raise ValueError("Unknown tool")
if not isinstance(args, dict) or args != {"city": "San Francisco"}:
raise ValueError("Invalid arguments")
result = {"hours": "09:00-17:00", "timezone": "America/Los_Angeles", "mock": True}
messages.append({
"role": "tool", "tool_call_id": call.id,
"content": json.dumps(result),
})
else:
raise RuntimeError("Tool-call limit reached")Execute safely
- Allowlist tool names and validate argument types, allowed values, and permissions. Never eval the arguments.
- Require confirmation for destructive or sensitive operations. A model request is not user authorization.
- Set a maximum number of tool rounds and handle malformed arguments without retrying forever.
- Deduplicate side effects when retrying requests. Do not run a payment, email, or write operation twice because a response timed out.
Streaming tools
Tool-call arguments may arrive in fragments. Accumulate them by index or call ID and wait for a complete call before parsing and executing. Do not treat each delta as a separate invocation.