LLM for Text Generation Tasks
We are going to build a marketing copy generator that turns a short product brief into three ready-to-use assets: a landing page headline, a two-sentence email pitch, and a social hook. This is useful for growth teams an
We are going to build a marketing copy generator that turns a short product brief into three ready-to-use assets: a landing page headline, a two-sentence email pitch, and a social hook. This is useful for growth teams and indie hackers who ship fast and need consistent messaging without hiring a copywriter.
What you'll need
- Python 3.10 or newer.
- An Oxlo.ai API key from https://portal.oxlo.ai. Oxlo.ai uses request-based pricing, so a long prompt costs the same as a short one. See https://oxlo.ai/pricing for plan details.
- The OpenAI SDK:
pip install openai
Step 1: Connect to Oxlo.ai and test the client
First, I verify that my API key and the Oxlo.ai endpoint are working. I use the OpenAI SDK because Oxlo.ai is fully compatible, so the only difference is the base URL and the model name.
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": "user", "content": "Say 'Connection OK' and nothing else."}
],
)
print(response.choices[0].message.content)
Step 2: Write the system prompt
The system prompt is the only place where I describe the tone, format, and constraints. I keep it strict so the model returns exactly three blocks and does not add fluff.
SYSTEM_PROMPT = """You are a senior product marketing copywriter.
You receive a short product brief and generate exactly three deliverables.
Use the exact headings below.
HEADLINE: A single sentence, max 12 words, suitable for a landing page hero section.
EMAIL: Exactly two sentences, friendly but direct, suitable for a cold outreach email.
SOCIAL: One sentence, under 140 characters, with a clear hook.
Do not add intros, explanations, or markdown code blocks."""
Step 3: Build the generator function
Now I wrap the call in a function named generate_copy. It accepts a brief string, injects the system prompt, and returns the raw text from the model. I use llama-3.3-70b because it handles general-purpose text generation reliably.
def generate_copy(product_brief: str) -> str:
response = client.chat.completions.create(
model="llama-3.3-70b",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": product_brief},
],
temperature=0.7,
max_tokens=512,
)
return response.choices[0].message.content
Step 4: Parse and display the output
The model usually respects the headings, but I add a small printer to split the result into labeled sections so the output is easy to read in the terminal.
def print_copy(raw_text: str) -> None:
lines = raw_text.strip().splitlines()
current_label = "OUTPUT"
for line in lines:
stripped = line.strip()
if stripped.startswith("HEADLINE:"):
current_label = "LANDING PAGE"
stripped = stripped.replace("HEADLINE:", "").strip()
elif stripped.startswith("EMAIL:"):
current_label = "EMAIL"
stripped = stripped.replace("EMAIL:", "").strip()
elif stripped.startswith("SOCIAL:"):
current_label = "SOCIAL"
stripped = stripped.replace("SOCIAL:", "").strip()
if stripped:
print(f"[{current_label}] {stripped}")
brief = (
"Product: Acme Log Collector. "
"It is a serverless log aggregation service that automatically compresses "
"and indexes logs from AWS Lambda, with a one-line SDK integration."
)
raw = generate_copy(brief)
print_copy(raw)
Run it
Save the full script as copygen.py, set your key, and run python copygen.py. Here is what I got on my last run:
$ python copygen.py
[LANDING PAGE] Stop drowning in Lambda logs.
[EMAIL] Acme Log Collector compresses and indexes your AWS Lambda logs automatically. Integrate with one line of code and search everything in seconds.
[SOCIAL] One line of code, zero log chaos. Meet Acme Log Collector.
Your output will vary slightly because temperature is 0.7, but the structure should stay consistent. If you need deterministic results for CI pipelines, drop temperature to 0.0.
Next steps
Add JSON mode to the generate_copy call by setting response_format={"type": "json_object"} and rewrite the system prompt to request a JSON schema. This makes parsing trivial and lets you feed the results directly into a web frontend.
If you are generating copy for long product specs, switch to kimi-k2.6 on Oxlo.ai. Its 131K context window handles full technical white-papers in a single request, and because Oxlo.ai charges per request rather than per token, a 10,000-word brief costs the same as a one-sentence prompt.
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.