DEV Community

shashank ms
shashank ms

Posted on

Unlocking LLM Potential for Content Creation

Most content teams still write blog posts from scratch. In this tutorial, I will show you how to ship a Python agent that turns a one-line topic into a full draft, outline, and social kit using Oxlo.ai. Because Oxlo.ai uses flat per-request pricing, you can send long briefs and receive full articles without metered costs scaling with word count.

What you'll need

Before we start, grab the following:

Step 1: Configure the Oxlo.ai client

I always start by verifying the connection. Create a file named content_agent.py and initialize the client. Oxlo.ai exposes a fully OpenAI-compatible endpoint, so the SDK works without patches.

from openai import OpenAI
import os

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

# Quick connectivity test
response = client.chat.completions.create(
    model="llama-3.3-70b",
    messages=[{"role": "user", "content": "Say 'Connection OK'"}],
    max_tokens=10
)
print(response.choices[0].message.content)

Step 2: Define the system prompt

The system prompt is the only configuration our agent needs. It encodes voice, structure, and quality rules in one place. I keep it editable so non-coders on my team can tweak tone without touching Python.

SYSTEM_PROMPT = """You are a senior technical content strategist. 
Your job is to turn a topic and audience into publication-ready material.

Rules:
- Write in clear, direct prose. No filler.
- Use Markdown for all output.
- Include concrete examples, not generic advice.
- Match the technical depth to the audience level provided.

When asked for an outline, return a JSON object with keys: title, sections (array of {heading, key_points}).
When asked for a draft, return the full article in Markdown.
When asked for a promotion kit, return a JSON object with keys: meta_description, linkedin_post, twitter_post."""

Step 3: Generate a structured outline

I split generation into two requests. First, I ask for an outline so I can review the narrative arc before burning compute on a full draft. On Oxlo.ai, this costs the same flat rate whether the outline is 200 words or 2,000, so I do not need to truncate the brief.

import json

def generate_outline(topic, audience):
    user_msg = f"Topic: {topic}\nAudience: {audience}\n\nGenerate a detailed outline."
    response = client.chat.completions.create(
        model="llama-3.3-70b",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": user_msg},
        ],
        response_format={"type": "json_object"}
    )
    return json.loads(response.choices[0].message.content)

Step 4: Expand the outline into a draft

Next, I feed the outline back into the model as context. Passing the full outline keeps the draft cohesive. I use the general-purpose Llama 3.3 70B here, but you can swap in Kimi K2.6 if you want heavier reasoning about code samples.

def generate_draft(topic, audience, outline):
    outline_text = json.dumps(outline, indent=2)
    user_msg = (
        f"Topic: {topic}\n"
        f"Audience: {audience}\n\n"
        f"Follow this outline exactly and write the full article:\n{outline_text}"
    )
    response = client.chat.completions.create(
        model="llama-3.3-70b",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": user_msg},
        ],
        temperature=0.7,
    )
    return response.choices[0].message.content

Step 5: Generate metadata and social snippets

Every article needs a meta description and social copy. I run one final request constrained to JSON mode so the output is machine-parseable. This makes it trivial to pipe the results into a CMS or social scheduling tool later.

def generate_promotion_kit(draft, topic):
    user_msg = (
        f"Based on the following article about '{topic}', generate a promotion kit.\n\n"
        f"{draft[:4000]}"
    )
    response = client.chat.completions.create(
        model="llama-3.3-70b",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": user_msg},
        ],
        response_format={"type": "json_object"}
    )
    return json.loads(response.choices[0].message.content)

Step 6: Assemble the pipeline

Now I wire the three stages together. The final script reads a topic and audience from the command line, runs the chain, and writes everything to a timestamped folder. I also added a small helper to save files so the output is reproducible.

import argparse
from datetime import datetime
import os

def save_run(folder, outline, draft, kit):
    os.makedirs(folder, exist_ok=True)
    with open(os.path.join(folder, "outline.json"), "w") as f:
        json.dump(outline, f, indent=2)
    with open(os.path.join(folder, "draft.md"), "w") as f:
        f.write(draft)
    with open(os.path.join(folder, "promotion.json"), "w") as f:
        json.dump(kit, f, indent=2)
    print(f"Saved run to ./{folder}/")

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("topic")
    parser.add_argument("audience")
    args = parser.parse_args()

    print("Generating outline...")
    outline = generate_outline(args.topic, args.audience)

    print("Generating draft...")
    draft = generate_draft(args.topic, args.audience, outline)

    print("Generating promotion kit...")
    kit = generate_promotion_kit(draft, args.topic)

    folder = f"content_run_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
    save_run(folder, outline, draft, kit)

if __name__ == "__main__":
    main()

Run it

Export your key and execute the script:

export OXLO_API_KEY="your-key-here"
python content_agent.py "Optimizing PostgreSQL indexes for high-write workloads" "Senior backend engineers"

You should see three files written to a new folder. The draft will contain a full Markdown article with headers, code examples, and transitions. The promotion kit will look something like this:

{
  "meta_description": "Learn how to tune PostgreSQL indexes when write throughput matters. We cover fillfactor, partial indexes, and BRIN for high-ingest workloads.",
  "linkedin_post": "Write-heavy workloads punish the wrong index strategy. I wrote a step-by-step guide on tuning PostgreSQL indexes for backends that need to ingest, not just query. Covers fillfactor, partial indexes, and when BRIN beats B-Tree.",
  "twitter_post": "Tuning PostgreSQL indexes for high-write workloads: fillfactor, partial indexes, and BRIN basics. New guide for backend engineers."
}

Wrap-up

This agent is already useful, but it is just a starting point. Two concrete next steps: add a Gradio or Streamlit UI so editors can iterate on tone without touching the terminal, or schedule the script in CI to autogenerate weekly drafts from your content calendar.

If your current workflow bills by the token, long outlines and detailed drafts get expensive fast. Oxlo.ai's flat per-request pricing removes that friction, which makes it a natural fit for content pipelines that generate large blocks of text. You can explore plans and model options at https://oxlo.ai/pricing.

Top comments (0)