DEV Community

shashank ms
shashank ms

Posted on

OpenAI SDK Compatibility Explained

We are going to build a customer support agent that looks up order details and checks refund eligibility using the standard OpenAI Python SDK pointed at Oxlo.ai. If you already use the OpenAI client in production, this is exactly how you migrate or multi-home without touching your inference layer.

What you'll need

Python 3.10 or newer installed locally. An Oxlo.ai API key from https://portal.oxlo.ai. The free tier gives you 60 requests per day, enough to test every step here. Install the SDK with pip.

pip install openai

Step 1: Verify connectivity

Oxlo.ai exposes a fully OpenAI-compatible chat completions endpoint. Instantiate the official client with Oxlo.ai's base URL and your API key, then send a single-turn message to confirm the path works.

from openai import OpenAI

client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")

response = client.chat.completions.create(
    model="llama-3.3-70b",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Say hello and confirm you are running on Oxlo.ai"},
    ],
)

print(response.choices[0].message.content)

Step 2: Define the system prompt

The system prompt locks the agent into our support domain and instructs it to ask for missing order IDs rather than hallucinating answers.

SYSTEM_PROMPT = """You are a customer support agent for a direct-to-consumer electronics store.
Your job is to help users with order status and refund eligibility.
You have access to tools that look up real data.
If the user does not provide an order_id, ask for it.
Be concise. Do not make up information not returned by a tool."""

Step 3: Declare the tools

We describe two functions using OpenAI's JSON schema format. Oxlo.ai parses these definitions and emits structured tool calls that match the standard API shape exactly.

TOOLS = [
    {
        "type": "function",
        "function": {
            "name": "get_order_status",
            "description": "Retrieve the current status of an order by its order ID.",
            "parameters": {
                "type": "object",
                "properties": {
                    "order_id": {
                        "type": "string",
                        "description": "The unique order identifier, e.g. ORD-12345"
                    }
                },
                "required": ["order_id"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "check_refund_eligibility",
            "description": "Check whether an order is eligible for a refund.",
            "parameters": {
                "type": "object",
                "properties": {
                    "order_id": {
                        "type": "string",
                        "description": "The unique order identifier, e.g. ORD-12345"
                    }
                },
                "required": ["order_id"]
            }
        }
    }
]

Step 4: Implement the tool handlers

In production these would query a database or ERP. For this tutorial we return hardcoded dictionaries so the agent can exercise the full loop without external dependencies.

import json

def get_order_status(order_id: str):
    return {
        "order_id": order_id,
        "status": "shipped",
        "carrier": "FastPost",
        "estimated_delivery": "2026-01-15"
    }

def check_refund_eligibility(order_id: str):
    return {
        "order_id": order_id,
        "eligible": True,
        "policy_window_days": 30,
        "reason_required": True
    }

TOOL_MAP = {
    "get_order_status": get_order_status,
    "check_refund_eligibility": check_refund_eligibility,
}

Step 5: Build the tool loop

The agent calls the model, detects any tool calls, executes the local functions, and feeds the results back as tool messages. This loop is identical to the pattern you would use with any OpenAI-compatible provider.

def run_agent(user_message: str):
    messages = [
        {"role": "system", "content": SYSTEM_PROMPT},
        {"role": "user", "content": user_message},
    ]

    while True:
        response = client.chat.completions.create(
            model="llama-3.3-70b",
            messages=messages,
            tools=TOOLS,
            tool_choice="auto",
        )

        choice = response.choices[0]

        if choice.finish_reason == "tool_calls":
            messages.append({
                "role": "assistant",
                "content": choice.message.content or "",
                "tool_calls": [tc.model_dump() for tc in choice.message.tool_calls]
            })

            for tc in choice.message.tool_calls:
                fn_name = tc.function.name
                fn_args = json.loads(tc.function.arguments)
                result = TOOL_MAP[fn_name](**fn_args)

                messages.append({
                    "role": "tool",
                    "tool_call_id": tc.id,
                    "content": json.dumps(result),
                })
        else:
            return choice.message.content

Run it

Call the agent with a request that requires tool use and reasoning. The model will ask for an order ID if you omit one, or invoke the tools if you provide it.

if __name__ == "__main__":
    query = "I want a refund for order ORD-98210. Is that possible?"
    answer = run_agent(query)
    print(answer)

Expected output:

Order ORD-98210 is eligible for a refund under our 30-day policy. You will need to provide a reason when submitting the request. Would you like me to start that process for you?

Wrap-up

You now have a working support agent running entirely on Oxlo.ai through the standard OpenAI SDK. A concrete next step is to replace the simulated tool handlers with real HTTP requests to your internal APIs. If you need deeper reasoning for complex multi-step tickets, swap the model string to deepseek-r1-671b or kimi-k2.6 without changing any client code. See https://oxlo.ai/pricing to pick a plan that fits your volume.

Top comments (0)