DEV Community

shashank ms
shashank ms

Posted on

LLM Inference for Dialogue Systems: A Comprehensive Guide

We are building a customer support dialogue agent that handles order lookups across multiple turns without losing context. It helps teams automate repetitive support workflows without maintaining brittle state machines. Because conversation histories grow quickly, Oxlo.ai's flat per-request pricing keeps costs predictable even when transcripts get long.

What you'll need

Step 1: Verify the connection

Before adding state, make sure the Oxlo.ai endpoint responds. A single call confirms your key works and that latency is acceptable for real-time dialogue.

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 customer support agent."},
        {"role": "user", "content": "Hi, I need help with my order."},
    ],
)

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

Step 2: Define the system prompt

The system prompt is the agent's script. It sets the persona, boundaries, and escalation rules. Keep it in its own variable so non-engineers can edit it later.

SYSTEM_PROMPT = """You are a support agent for TechFlow, an electronics store.
Your job is to help users with order status, returns, and basic troubleshooting.
Rules:
- Always ask for the order ID if the user mentions an order but does not provide one.
- If the user asks for a refund, verify the order ID and confirm eligibility before proceeding.
- If the user is frustrated or explicitly asks for a human, offer to escalate to a human agent.
- Keep responses under 100 words unless explaining technical steps.
- Do not invent order details. Use the lookup_order tool when you need data.
"""

Step 3: Add conversation memory

Dialogue systems need to remember prior turns. A lightweight class stores the message history and appends new exchanges so the model sees the full context on every call.

class SupportAgent:
    def __init__(self, client):
        self.client = client
        self.history = [{"role": "system", "content": SYSTEM_PROMPT}]

    def chat(self, user_message):
        self.history.append({"role": "user", "content": user_message})

        response = self.client.chat.completions.create(
            model="llama-3.3-70b",
            messages=self.history,
        )

        assistant_message = response.choices[0].message.content
        self.history.append({"role": "assistant", "content": assistant_message})
        return assistant_message

Step 4: Add order lookup with function calling

Agents hallucinate facts less when they can call a tool. We give the model a lookup_order function and feed the JSON result back into the conversation before generating the final reply.

import json

def lookup_order(order_id):
    db = {
        "ORD-1234": {"status": "shipped", "item": "USB-C Cable", "eligible_for_return": True},
        "ORD-5678": {"status": "processing", "item": "Mechanical Keyboard", "eligible_for_return": False},
    }
    return db.get(order_id, {"error": "Order not found"})

class SupportAgent:
    def __init__(self, client):
        self.client = client
        self.history = [{"role": "system", "content": SYSTEM_PROMPT}]

    def chat(self, user_message):
        self.history.append({"role": "user", "content": user_message})

        response = self.client.chat.completions.create(
            model="llama-3.3-70b",
            messages=self.history,
            tools=[{
                "type": "function",
                "function": {
                    "name": "lookup_order",
                    "description": "Retrieve order status and return eligibility",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "order_id": {"type": "string", "description": "The order ID"}
                        },
                        "required": ["order_id"]
                    }
                }
            }],
            tool_choice="auto",
        )

        message = response.choices[0].message

        if message.tool_calls:
            tool_call = message.tool_calls[0]
            if tool_call.function.name == "lookup_order":
                args = json.loads(tool_call.function.arguments)
                result = lookup_order(args["order_id"])

                self.history.append({
                    "role": "assistant",
                    "content": None,
                    "tool_calls": [{
                        "id": tool_call.id,
                        "type": tool_call.type,
                        "function": {
                            "name": tool_call.function.name,
                            "arguments": tool_call.function.arguments
                        }
                    }]
                })
                self.history.append({
                    "role": "tool",
                    "tool_call_id": tool_call.id,
                    "content": json.dumps(result)
                })

                second = self.client.chat.completions.create(
                    model="llama-3.3-70b",
                    messages=self.history,
                )
                reply = second.choices[0].message.content
                self.history.append({"role": "assistant", "content": reply})
                return reply

        self.history.append({"role": "assistant", "content": message.content})
        return message.content

Step 5: Trim history to control context length

Real conversations can exceed dozens of turns. To avoid slowing down responses, we cap the history to the most recent exchanges while always preserving the system prompt at index zero.

import json

def lookup_order(order_id):
    db = {
        "ORD-1234": {"status": "shipped", "item": "USB-C Cable", "eligible_for_return": True},
        "ORD-5678": {"status": "processing", "item": "Mechanical Keyboard", "eligible_for_return": False},
    }
    return db.get(order_id, {"error": "Order not found"})

class SupportAgent:
    def __init__(self, client, max_turns=10):
        self.client = client
        self.max_turns = max_turns
        self.history = [{"role": "system", "content": SYSTEM_PROMPT}]

    def _trim(self):
        if len(self.history) > (self.max_turns * 2) + 1:
            self.history = [self.history[0]] + self.history[-(self.max_turns * 2):]

    def chat(self, user_message):
        self._trim()
        self.history.append({"role": "user", "content": user_message})

        response = self.client.chat.completions.create(
            model="llama-3.3-70b",
            messages=self.history,
            tools=[{
                "type": "function",
                "function": {
                    "name": "lookup_order",
                    "description": "Retrieve order status and return eligibility",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "order_id": {"type": "string", "description": "The order ID"}
                        },
                        "required": ["order_id"]
                    }
                }
            }],
            tool_choice="auto",
        )

        message = response.choices[0].message

        if message.tool_calls:
            tool_call = message.tool_calls[0]
            if tool_call.function.name == "lookup_order":
                args = json.loads(tool_call.function.arguments)
                result = lookup_order(args["order_id"])

                self.history.append({
                    "role": "assistant",
                    "content": None,
                    "tool_calls": [{
                        "id": tool_call.id,
                        "type": tool_call.type,
                        "function": {
                            "name": tool_call.function.name,
                            "arguments": tool_call.function.arguments
                        }
                    }]
                })
                self.history.append({
                    "role": "tool",
                    "tool_call_id": tool_call.id,
                    "content": json.dumps(result)
                })

                second = self.client.chat.completions.create(
                    model="llama-3.3-70b",
                    messages=self.history,
                )
                reply = second.choices[0].message.content
                self.history.append({"role": "assistant", "content": reply})
                return reply

        self.history.append({"role": "assistant", "content": message.content})
        return message.content

Run it

The script below simulates a short session. The first query triggers a tool call, and the second builds on that context to answer a follow-up.

agent = SupportAgent(client)

session = [
    "Hi, where is my order ORD-1234?",
    "Can I return it?",
    "Thanks, that is all for now.",
]

for query in session:
    print(f"User: {query}")
    print(f"Agent: {agent.chat(query)}")
    print()

Example output:

User: Hi, where is my order ORD-1234?
Agent: Your order ORD-1234 for the USB-C Cable has already shipped. Is there anything else I can help you with?

User: Can I return it?
Agent: Yes, that order is eligible for a return. Would you like me to start the return process for you?

User: Thanks, that is all for now.
Agent: You are welcome. Feel free to reach out if you need anything else.

Next steps

Swap in qwen-3-32b or kimi-k2.6 if you need stronger multilingual or reasoning skills for complex troubleshooting flows. For pricing that stays flat regardless of how long your transcripts grow, see https://oxlo.ai/pricing.

Top comments (0)