DEV Community

shashank ms
shashank ms

Posted on

Introduction to LLM for Natural Language Generation Tasks

We are going to build a marketing copy generator that turns raw product specs into ready-to-publish descriptions and social posts. This is for solo founders or small teams who need usable draft copy without hiring a writer. The whole thing fits in a single Python script and runs against Oxlo.ai's flat-rate API.

What you'll need

Before starting, grab an Oxlo.ai API key from https://portal.oxlo.ai. You will also need Python 3.10 or newer and the OpenAI SDK.

pip install openai

Step 1: Configure the Oxlo.ai client

First, I set up the client pointing at Oxlo.ai's OpenAI-compatible endpoint. I use llama-3.3-70b here because it handles creative NLG tasks reliably at a flat per-request cost, which keeps the bill predictable even when I send long product briefs.

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 assistant."},
        {"role": "user", "content": "Say hello."},
    ],
)
print(response.choices[0].message.content)

Step 2: Define the system prompt

The system prompt is the only place where I describe tone, format, and constraints. Keeping it in one constant makes the behavior easy to tweak later.

SYSTEM_PROMPT = """You are a direct-response copywriter.
You receive product details and return three pieces of copy:
1. A one-sentence headline under 80 characters.
2. A product description of two short paragraphs.
3. A social media hook under 140 characters.

Rules:
- Use the audience tone specified by the user.
- Do not use em-dashes.
- Output only the copy, labeled with Headline:, Description:, and Hook:."""

Step 3: Build the generator function

Next, I wrap the API call in a function that accepts a product dictionary and returns the generated text. I format the user message as a concise brief so the model gets structured context without extra tokens wasted on fluff.

def generate_copy(product_name, specs, audience, tone):
    user_message = f"""Product: {product_name}
Specs: {specs}
Audience: {audience}
Tone: {tone}"""

    response = client.chat.completions.create(
        model="llama-3.3-70b",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": user_message},
        ],
    )
    return response.choices[0].message.content

Step 4: Add structured output with JSON mode

Parsing free text in production is fragile, so I switch the prompt to request JSON and set response_format={"type": "json_object"}. This lets me validate the output with a tiny schema check. I also switch to qwen-3-32b here because it follows multilingual instruction and structured formatting closely.

import json

SYSTEM_PROMPT_JSON = """You are a direct-response copywriter.
Return JSON with exactly these keys: headline, description, hook.
Rules:
- headline must be under 80 characters.
- description must be two short paragraphs.
- hook must be under 140 characters.
- Use the tone specified in the user message.
- Do not use em-dashes."""

def generate_copy_json(product_name, specs, audience, tone):
    user_message = f"""Product: {product_name}
Specs: {specs}
Audience: {audience}
Tone: {tone}"""

    response = client.chat.completions.create(
        model="qwen-3-32b",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT_JSON},
            {"role": "user", "content": user_message},
        ],
        response_format={"type": "json_object"},
    )
    raw = response.choices[0].message.content
    return json.loads(raw)

Step 5: Batch process a catalog

Finally, I loop over a list of products and collect results. Because Oxlo.ai charges per request, not per token, long spec sheets do not inflate the cost of each item. That makes this loop cheap to run even when the input context grows.

products = [
    {
        "name": "Terra Backpack",
        "specs": "40L capacity, waterproof canvas, laptop sleeve fits 16 inch, weight 1.2kg",
        "audience": "Digital nomads",
        "tone": "Confident and minimal",
    },
    {
        "name": "AeroPress Go",
        "specs": "All-in-one travel coffee maker, 350ml capacity, includes mug and lid",
        "audience": "Campers",
        "tone": "Enthusiastic",
    },
]

results = []
for p in products:
    copy = generate_copy_json(p["name"], p["specs"], p["audience"], p["tone"])
    results.append(copy)
    print(copy)

Run it

Save the script as copygen.py, export your key, and execute it.

export OXLO_API_KEY="your-key-here"
python copygen.py

Expected output for the Terra Backpack looks like this:

{
  "headline": "Built for movement. Designed for work.",
  "description": "The Terra Backpack gives digital nomads 40 liters of organized space without the bulk. Its waterproof canvas shell and padded 16 inch laptop sleeve keep your gear safe from coworking spaces to airport gates.\n\nAt just 1.2kg, it rides light on your shoulders but handles heavy workloads. The clean exterior hides smart pockets for cables, passports, and whatever the road throws at you.",
  "hook": "Your office fits inside. The world fits outside."
}

Wrap-up and next steps

You now have a working NLG pipeline that turns specs into structured marketing copy. If you want to take it further, wire the script into a Google Sheets webhook so stakeholders can submit products through a form, or add a simple Gradio UI so non-technical teammates can tweak tone and regenerate copy without touching code.

Top comments (0)