DEV Community

shashank ms
shashank ms

Posted on

Sales Automation with LLM: A Step-by-Step Guide

Sales automation has moved beyond simple email sequencers. Modern teams now use LLMs to qualify leads, draft personalized outreach, and manage multi-turn conversations at scale. This guide walks through building a reliable, code-first sales automation pipeline using an inference API that stays predictable as your context grows.

Why LLMs for Sales Automation

Traditional rules-based CRM automation breaks when prospect data is unstructured. LLMs can parse messy LinkedIn bios, infer intent from short replies, and generate context-aware next steps. The challenge is building a pipeline that remains fast, observable, and cost-predictable when you feed entire conversation histories or CRM records into the prompt.

Architecture Overview

A production sales automation stack usually has four layers:

  1. Ingestion: CRM webhooks, email APIs, or enrichment tools feed raw lead data.
  2. Reasoning: An LLM qualifies the lead, scores intent, and plans outreach.
  3. Generation: The model writes the email or chat message, often in JSON mode for structured output.
  4. Action: A tool layer sends the message, updates the CRM, or schedules a task via function calling.

For the reasoning and generation layers, you need an inference backend that handles long system prompts, multi-turn context, and high throughput without cold starts. Oxlo.ai provides fully OpenAI SDK-compatible endpoints with flat per-request pricing, so your cost does not scale with input length. That makes it a strong fit for agentic sales workflows where you may pass thousands of tokens of CRM context on every call.

Step 1: Configure the SDK and Test Your Endpoint

Because Oxlo.ai is a drop-in replacement for the OpenAI SDK, you can keep your existing codebase and only change the base URL and API key.

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.oxlo.ai/v1",
    api_key=os.environ["OXLO_API_KEY"]
)

# Verify connectivity with a lightweight model
response = client.chat.completions.create(
    model="qwen-3-32b",
    messages=[
        {"role": "system", "content": "You are a sales research assistant."},
        {"role": "user", "content": "Summarize the value prop of Oxlo.ai in one sentence."}
    ]
)
print(response.choices[0].message.content)

Step 2: Lead Enrichment and Qualification

Sales automation lives or dies on lead quality. Instead of keyword matching, you can pass an entire lead profile, including scraped web text and CRM notes, to the model and ask for a structured qualification score.

Using Oxlo.ai, you can send large context windows without watching a token meter tick up. Models like DeepSeek V4 Flash support 1M context, and Kimi K2.6 handles 131K context with advanced reasoning, so you can include full email threads or product documentation for richer scoring.

import json

qualification_prompt = f"""
You are a B2B sales analyst. Evaluate the following lead and return strict JSON.

Lead Data:
{lead_json}

Scoring Criteria:
- Budget authority (1-10)
- Need fit (1-10)
- Timeline urgency (1-10)

Return only JSON with keys: score_budget, score_need, score_timeline, summary.
"""

response = client.chat.completions.create(
    model="llama-3.3-70b",
    messages=[{"role": "user", "content": qualification_prompt}],
    response_format={"type": "json_object"}
)

qualification = json.loads(response.choices[0].message.content)

Step 3: Personalized Outreach Generation

Once a lead is qualified, the next step is generating a personalized message. The prompt should include the qualification summary, recent company news, and tone guidelines. To guarantee parseable output, use JSON mode or function calling.

outreach_prompt = f"""
Write a cold outreach email for {lead['name']} at {lead['company']}.
Qualification summary: {qualification['summary']}
Tone: consultative, concise, no hype.
Subject line must be under 60 characters.
Return JSON with keys: subject, body.
"""

response = client.chat.completions.create(
    model="kimi-k2.6",
    messages=[
        {"role": "system", "content": "You are an expert B2B copywriter."},
        {"role": "user", "content": outreach_prompt}
    ],
    response_format={"type": "json_object"}
)

email = json.loads(response.choices[0].message.content)

For coding-heavy automation, you might also consider Minimax M2.5 or DeepSeek V3.2 for strong agentic tool use and reasoning, both available on Oxlo.ai.

Step 4: Follow-Up and Conversation Handling

Prospects reply with objections, questions, and requests. A robust automation system treats each reply as a new turn in a stateful conversation. You can maintain a message array and append the prospect's reply, then ask the model for the next action.

If the conversation requires external action, such as booking a calendar slot or updating a CRM field, use function calling. Oxlo.ai supports function calling and tool use across its chat models, so you can define schemas for calendar lookups or CRM updates and let the model decide when to invoke them.

tools = [
    {
        "type": "function",
        "function": {
            "name": "book_meeting",
            "description": "Book a meeting given a time slot.",
            "parameters": {
                "type": "object",
                "properties": {
                    "time": {"type": "string"},
                    "lead_email": {"type": "string"}
                },
                "required": ["time", "lead_email"]
            }
        }
    }
]

messages = [
    {"role": "system", "content": "You are a helpful sales assistant. Reply or book a meeting if asked."},
    {"role": "user", "content": prospect_reply}
]

response = client.chat.completions.create(
    model="qwen-3-32b",
    messages=messages,
    tools=tools
)

# Check if the model wants to call a tool
if response.choices[0].message.tool_calls:
    handle_tool_call(response.choices[0].message.tool_calls)
else:
    send_reply(response.choices[0].message.content)

Step 5: Logging and Cost Observability

Production pipelines need request tracing. Because Oxlo.ai uses request-based pricing, your cost per step is flat regardless of how much context you include. That simplifies budgeting: a qualification step costs the same whether you pass 500 tokens or 50,000 tokens. For long-context lead enrichment and agentic loops, this can be significantly cheaper than token-based billing.

Log each request ID, model name, and timestamp. If you need to audit quality, you can replay the exact message array without worrying that a longer prompt suddenly doubled the step cost.

Cost and Scaling Considerations

Token-based pricing penalizes detailed prompts. In sales automation, detailed prompts are not optional; they are the product. When you pass CRM records, conversation histories, and knowledge-base articles to the model, input tokens dominate the bill.

Oxlo.ai charges one flat cost per API request regardless of prompt length. For teams running high-volume enrichment, multi-turn follow-up sequences, or agentic workflows with large tool contexts, this model removes the surprise of ballooning input costs. You can see the exact structure on the Oxlo.ai pricing page.

Start with the Free plan to prototype: it includes 60 requests per day and access to more than 16 models, including DeepSeek V3.2 on the free tier. When you move to production, the Pro and Premium plans offer 1,000 and 5,000 requests per day respectively, with priority queue access under Premium.

Conclusion

Building sales automation on LLMs is not about replacing the sales rep; it is about giving the rep an agentic backend that qualifies, personalizes, and responds at machine speed. The difference between a brittle demo and a production system comes down to context length, structured output reliability, and cost predictability.

Oxlo.ai gives you OpenAI SDK compatibility, 45+ models from Llama 3.3 70B to Kimi K2.6, and flat per-request pricing that stays sane when your prompts grow. If you are architecting a sales automation stack today, it is a backend worth evaluating alongside your pipeline design.

Top comments (0)