We are going to build a customer support agent on Oxlo.ai that handles order status checks and return policy questions without a handcrafted decision tree. It uses function calling to look up orders and answers directly from policy instructions. This is useful for any shop or SaaS that wants to deflect repetitive tickets while keeping a human tone.
What you'll need
- Python 3.10 or newer
- An Oxlo.ai API key from https://portal.oxlo.ai
- The OpenAI SDK:
pip install openai
Step 1: Configure the Oxlo.ai client
First, import the SDK and point it at Oxlo.ai. I like to keep the API key in an environment variable, but you can paste it directly for local testing. We will also grab json now because the tool payloads require it.
import json
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.oxlo.ai/v1",
api_key=os.environ.get("OXLO_API_KEY", "YOUR_OXLO_API_KEY"),
)
# Quick sanity check
ping = client.chat.completions.create(
model="llama-3.3-70b",
messages=[{"role": "user", "content": "Hello"}],
)
print("Client ready:", ping.choices[0].message.content)
Step 2: Write the system prompt
The system prompt is the only manual logic we need. It tells the agent its persona, when to ask for an order ID, and when to answer from policy. Keep it editable. This is the entire rule set.
SYSTEM_PROMPT = """You are a support agent for Acme Goods.
Your job is to help users with order status and return policy questions.
Rules:
- If the user asks about an order, request the order ID if they have not provided it.
- Once you have an order ID, call the lookup_order tool. Do not guess the status.
- For return policy questions, answer directly: returns are accepted within 30 days with a receipt.
- Keep responses under three sentences unless the user asks for detail.
- Be polite and concise.
"""
Step 3: Define the order lookup tool
We need a mock database and a tool schema so the model knows how to request a lookup. In production, replace the dict with a real database or ERP call.
def lookup_order(order_id: str) -> dict:
"""Mock order database. Replace with real ERP lookup."""
db = {
"ORD-001": {"status": "shipped", "item": "Wireless Mouse", "eta": "2025-01-15"},
"ORD-002": {"status": "processing", "item": "Mechanical Keyboard", "eta": "2025-01-20"},
}
return db.get(order_id, {"status": "not_found", "item": None, "eta": None})
tools = [
{
"type": "function",
"function": {
"name": "lookup_order",
"description": "Get the current status of a customer order by ID.",
"parameters": {
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "The order identifier, e.g. ORD-001.",
}
},
"required": ["order_id"],
},
},
}
]
Step 4: Implement the agent loop
The loop sends the user message to Llama 3.3 70B, checks if the model wants to call a tool, executes the tool, and sends the result back so the model can generate the final answer. This two-turn pattern is the standard way to do tool use with the OpenAI SDK.
def run_agent(user_message: str) -> str:
messages = [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_message},
]
# First turn: model decides if it needs a tool
response = client.chat.completions.create(
model="llama-3.3-70b",
messages=messages,
tools=tools,
tool_choice="auto",
)
assistant_msg = response.choices[0].message
messages.append(assistant_msg)
# If a tool was called, execute it and send results back
if assistant_msg.tool_calls:
for tool_call in assistant_msg.tool_calls:
if tool_call.function.name == "lookup_order":
args = json.loads(tool_call.function.arguments)
result = lookup_order(args["order_id"])
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"name": tool_call.function.name,
"content": json.dumps(result),
})
# Second turn: model answers using tool results
final = client.chat.completions.create(
model="llama-3.3-70b",
messages=messages,
tools=tools,
)
return final.choices[0].message.content
# No tool needed
return assistant_msg.content
Run it
Test the agent with three different intents: a valid order lookup, a policy question, and a missing order.
if __name__ == "__main__":
print(run_agent("Where is my order ORD-001?"))
print("---")
print(run_agent("What is your return policy?"))
print("---")
print(run_agent("Can you check order ORD-999?"))
Example output:
Your Wireless Mouse order ORD-001 has shipped and is expected to arrive by January 15.
---
We accept returns within 30 days with a receipt.
---
I could not find an order with ID ORD-999. Please double-check the ID and try again.
Wrap-up and next steps
This agent replaces a static FAQ and a manual order lookup screen with a single conversational endpoint. Because Oxlo.ai charges a flat rate per request instead of per token, you can stuff the system prompt with detailed policy context and tool definitions without worrying about ballooning costs on long inputs.
Two concrete next steps: wire lookup_order into your real database or Shopify API, and add an escalation tool that posts to a ticketing system like Zendesk when the user asks to speak with a human. Both are just additional functions in the same loop.
Top comments (0)