DEV Community

shashank ms
shashank ms

Posted on

Advantages of LLM in Sales and Customer Service Automation

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

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)