We are going to build a customer support chatbot that handles order status questions and basic troubleshooting. This tutorial is for developers who need to ship a working agent without managing infrastructure or unpredictable token costs. By the end, you will have a CLI tool that maintains conversation history, calls a mock order API, and runs entirely on Oxlo.ai.
What you'll need
- Python 3.10 or newer
- The OpenAI SDK:
pip install openai - An Oxlo.ai API key from https://portal.oxlo.ai
- A virtual environment (optional but recommended)
Step 1: Configure the Oxlo.ai client
Create a file named support_bot.py and initialize the client. I use llama-3.3-70b here because it is a strong general-purpose model, but you can swap in kimi-k2.6 or deepseek-v3.2 later if you need deeper reasoning or coding capabilities.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.oxlo.ai/v1",
api_key=os.environ.get("OXLO_API_KEY")
)
Step 2: Write the system prompt
The system prompt is the only fine-tuning we need for now. It sets boundaries, tone, and instructs the model to use our tool for order lookups.
SYSTEM_PROMPT = """You are a customer support agent for an electronics store.
You help users with order status, returns, and basic troubleshooting.
Be concise and friendly. If a user asks about an order, you must use the lookup_order tool.
If you do not know something, say so. Do not make up order details."""
Step 3: Manage conversation history
A chatbot without memory is useless. We will keep a simple list of turns and format them into the message array that the Oxlo.ai API expects. Because Oxlo.ai uses request-based pricing, sending the full conversation history every turn does not inflate your cost per call.
history = []
def build_messages(user_input):
messages = [{"role": "system", "content": SYSTEM_PROMPT}]
for turn in history:
messages.append({"role": "user", "content": turn["user"]})
messages.append({"role": "assistant", "content": turn["assistant"]})
messages.append({"role": "user", "content": user_input})
return messages
Step 4: Define a tool for order lookups
We give the model access to a lookup_order function. The function definition is passed in the tools parameter so the LLM knows when to call it. For this tutorial we use a hardcoded dictionary, but in production this would query your ERP or database.
import json
TOOLS = [
{
"type": "function",
"function": {
"name": "lookup_order",
"description": "Get order status by order ID",
"parameters": {
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "The order ID, e.g. ORD-12345"
}
},
"required": ["order_id"]
}
}
}
]
def lookup_order(order_id):
db = {
"ORD-12345": {"status": "shipped", "item": "USB-C Cable", "eta": "2 days"},
"ORD-67890": {"status": "processing", "item": "Webcam Pro", "eta": "5 days"}
}
return db.get(order_id, {"status": "not_found", "message": "Order not found."})
Step 5: Handle tool calls and generate the final response
When the model requests a tool call, we execute the function, append the result, and send everything back to Oxlo.ai for a final answer.
def chat(user_input):
messages = build_messages(user_input)
response = client.chat.completions.create(
model="llama-3.3-70b",
messages=messages,
tools=TOOLS,
tool_choice="auto"
)
assistant_message = response.choices[0].message
# Check if the model wants to call a tool
if assistant_message.tool_calls:
tool_calls_payload = []
for tc in assistant_message.tool_calls:
tool_calls_payload.append({
"id": tc.id,
"type": "function",
"function": {
"name": tc.function.name,
"arguments": tc.function.arguments
}
})
messages.append({
"role": "assistant",
"content": assistant_message.content or "",
"tool_calls": tool_calls_payload
})
for tc in assistant_message.tool_calls:
if tc.function.name == "lookup_order":
args = json.loads(tc.function.arguments)
result = lookup_order(args["order_id"])
messages.append({
"role": "tool",
"tool_call_id": tc.id,
"content": json.dumps(result)
})
# Send the tool results back to get the final response
final = client.chat.completions.create(
model="llama-3.3-70b",
messages=messages
)
reply = final.choices[0].message.content
else:
reply = assistant_message.content
# Save to history
history.append({"user": user_input, "assistant": reply})
return reply
Step 6: Build the CLI loop
Wire everything into a simple loop that accepts user input, prints the assistant reply, and tracks history.
if __name__ == "__main__":
print("Support Bot: Hi! How can I help you today? (type 'exit' to quit)")
while True:
user_input = input("You: ").strip()
if user_input.lower() in ("exit", "quit"):
break
if not user_input:
continue
reply = chat(user_input)
print(f"Support Bot: {reply}")
Run it
Export your key and run the script. Here is a sample session showing the bot retrieving an order and then answering a follow-up.
$ export OXLO_API_KEY="sk-oxlo.ai-..."
$ python support_bot.py
Support Bot: Hi! How can I help you today? (type 'exit' to quit)
You: Where is my order ORD-12345?
Support Bot: Your order ORD-12345 for USB-C Cable has shipped and should arrive in 2 days.
You: Can I return it?
Support Bot: Yes, you can return items within 30 days of delivery. I can help you start a return request if you would like.
You: exit
Next steps
Replace the mock lookup_order dictionary with a real database query or REST call to your order management system. If you want the bot to answer questions from your help center, add a retrieval step using Oxlo.ai embedding models such as bge-large to pull relevant articles into the system prompt before each turn.
Top comments (0)