DEV Community

shashank ms
shashank ms

Posted on

Introduction to Deep Reasoning and Its Applications

Most support tools classify tickets by keyword, which fails when customers describe symptoms instead of root causes. In this tutorial we will build a lightweight support agent that reasons through the symptoms, infers the underlying problem, and drafts a precise fix. The agent runs on Oxlo.ai's request-based API, so long transcripts do not inflate the cost.

What you'll need

Step 1: Design the reasoning prompt

We need the model to think before it speaks. I use a system prompt that forces a chain of thought inside JSON so we can parse it later.

SYSTEM_PROMPT = """You are a senior support engineer. Follow these steps for every ticket:
1. Extract the product area and symptoms.
2. Infer the most likely root cause. Do not stop at the symptom.
3. Propose one concrete fix or escalation path.
4. Write a short, polite customer-facing reply.

Respond ONLY as a JSON object with these keys:
- reasoning: a list of your step-by-step thoughts
- root_cause: your inferred cause
- fix: the concrete action
- reply: the customer-facing message
"""

Step 2: Connect to Oxlo.ai

Oxlo.ai exposes an OpenAI-compatible endpoint, so the SDK works with a single line change to the base URL. I use kimi-k2.6 because its reasoning capabilities handle the multi-step analysis well.

from openai import OpenAI
import json

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

ticket = (
    "Hey, since yesterday morning the export to CSV button just spins. "
    "I cleared my cache but it still happens on every project, even the small ones. "
    "My teammate says it works for them. Help?"
)

response = client.chat.completions.create(
    model="kimi-k2.6",
    messages=[
        {"role": "system", "content": SYSTEM_PROMPT},
        {"role": "user", "content": ticket},
    ],
    response_format={"type": "json_object"},
    temperature=0.2,
)

raw = response.choices[0].message.content
result = json.loads(raw)
print(json.dumps(result, indent=2))

Step 3: Guard against shallow answers

Raw JSON from an LLM can drift if the ticket is vague. I add a validation layer that checks the reasoning array has at least two steps and that the fix is specific. If not, we raise a flag instead of sending the reply.

def validate_reasoning(output: dict) -> dict:
    issues = []
    reasoning = output.get("reasoning", [])
    if len(reasoning) < 2:
        issues.append("Reasoning is too shallow.")
    fix = output.get("fix", "")
    if len(fix.split()) < 3:
        issues.append("Fix is too vague.")
    output["validation_issues"] = issues
    return output

validated = validate_reasoning(result)
print("Issues:", validated["validation_issues"])
print("Proposed reply:", validated["reply"])

Step 4: Inject knowledge base context

Deep reasoning needs ground truth. I keep a tiny in-memory knowledge base of known bugs and feed the relevant snippet into the user message so the model grounds its inference in facts rather than hallucination.

KB = {
    "csv-export-spinning": (
        "Known issue: CSV export relies on a background worker. "
        "If the worker queue is stalled, the button spins indefinitely. "
        "Fix: restart the worker pod or clear the queue from the admin panel."
    ),
    "login-loop": (
        "Known issue: SAML token expiry can cause an infinite redirect. "
        "Fix: re-issue the IdP metadata."
    ),
}

def build_context(ticket: str) -> str:
    keywords = ["csv", "export", "spin", "button"]
    if any(k in ticket.lower() for k in keywords):
        return f"Knowledge base hint:\n{KB['csv-export-spinning']}\n\nTicket:\n{ticket}"
    return ticket

contextual_ticket = build_context(ticket)

response2 = client.chat.completions.create(
    model="kimi-k2.6",
    messages=[
        {"role": "system", "content": SYSTEM_PROMPT},
        {"role": "user", "content": contextual_ticket},
    ],
    response_format={"type": "json_object"},
    temperature=0.2,
)

grounded = validate_reasoning(json.loads(response2.choices[0].message.content))
print(json.dumps(grounded, indent=2))

Step 5: Package it into a CLI

I wrap everything in a small script that reads a ticket from the command line, runs the deep reasoning pipeline, and prints the safe reply or a warning.

import sys

def resolve_ticket(ticket_text: str) -> dict:
    context = build_context(ticket_text)
    resp = client.chat.completions.create(
        model="kimi-k2.6",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": context},
        ],
        response_format={"type": "json_object"},
        temperature=0.2,
    )
    output = json.loads(resp.choices[0].message.content)
    return validate_reasoning(output)

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: python agent.py ''")
        sys.exit(1)

    ticket_input = sys.argv[1]
    decision = resolve_ticket(ticket_input)

    if decision["validation_issues"]:
        print("AGENT UNCERTAIN:")
        for i in decision["validation_issues"]:
            print(f" - {i}")
    else:
        print("ROOT CAUSE:", decision["root_cause"])
        print("FIX:", decision["fix"])
        print("\nREPLY:\n", decision["reply"])

Run it

Save the full script as agent.py, export your key, and pass a ticket:

export OXLO_API_KEY="YOUR_OXLO_API_KEY"
python agent.py "The CSV export button spins forever since yesterday. Cache clear did nothing."

Example output:

ROOT CAUSE: Background worker queue is stalled, preventing CSV generation from completing.
FIX: Restart the worker pod or clear the queue from the admin panel.

REPLY:
Hi there, thanks for the detailed report. It sounds like our background worker responsible for CSV generation may have stalled. Could you try restarting the worker pod from your admin panel, or let us know if you'd like us to clear the queue on our end? If the issue persists after that, please share your project ID and we'll investigate immediately.

Wrap-up

Two concrete ways to push this further. First, replace the hardcoded KB dictionary with a vector search step using Oxlo.ai's embeddings endpoint so the agent retrieves hints automatically. Second, wire the output into a webhook that creates the actual support reply instead of printing to stdout.

Top comments (0)