We're building a Creative Writing Studio agent that drafts poetry, critiques its own work, and rewrites it in the style of any historical art movement. This gives writers and digital artists a concrete way to break through blocks and explore stylistic boundaries without token-cost anxiety on long prompts.
What you'll need
- Python 3.10 or newer
- The OpenAI SDK:
pip install openai - An Oxlo.ai API key from https://portal.oxlo.ai
Step 1: Set up the client and system prompt
First we point the OpenAI SDK at Oxlo.ai and define the agent's creative persona. I use llama-3.3-70b because it follows nuanced stylistic instructions reliably and starts instantly with no cold starts.
from openai import OpenAI
client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")
SYSTEM_PROMPT = """You are a collaborative poetry studio. When asked to draft, write vivid free verse with strong imagery. When asked to critique, evaluate meter, metaphor, and emotional resonance with plain technical language. When asked to rewrite, apply the requested artistic movement faithfully while preserving the core theme."""
Step 2: Generate the first draft
Next we send a theme to the model and capture a raw draft. Because Oxlo.ai uses flat per-request pricing (https://oxlo.ai/pricing), we can pack a detailed brief into the prompt without watching the cost scale with length.
def draft_poem(theme):
user_message = f"Write a raw draft poem about: {theme}. No critique, just the draft."
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
theme = "a subway station at 3 a.m."
first_draft = draft_poem(theme)
print(first_draft)
Step 3: Critique the draft
Now we feed the draft back into the model and ask for a technical breakdown. Appending the full draft to the prompt is still one flat request on Oxlo.ai, so the cost does not budge even as the context grows.
def critique_poem(draft):
user_message = f"Critique this draft poem:\n\n{draft}\n\nList two strengths and two concrete revisions."
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
critique = critique_poem(first_draft)
print(critique)
Step 4: Rewrite in a target style
Finally we pass the draft, the critique, and a target movement to produce a polished revision. You could swap in kimi-k2.6 on Oxlo.ai if you want deeper literary reasoning, but llama-3.3-70b handles the transformation cleanly.
def rewrite_poem(draft, critique, movement):
user_message = (
f"Rewrite the following poem in the style of {movement}.\n\n"
f"Original draft:\n{draft}\n\n"
f"Critique to address:\n{critique}\n\n"
f"Provide only the revised poem."
)
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
final_poem = rewrite_poem(first_draft, critique, "French Surrealism")
print(final_poem)
Run it
Here is the full pipeline wired together, followed by the output I captured on a live run.
if __name__ == "__main__":
theme = "a subway station at 3 a.m."
print("=== DRAFT ===")
draft = draft_poem(theme)
print(draft)
print("\n=== CRITIQUE ===")
crit = critique_poem(draft)
print(crit)
print("\n=== REVISION ===")
final = rewrite_poem(draft, crit, "French Surrealism")
print(final)
Example output:
=== DRAFT === Fluorescent hum, a lone coffee cup rolls toward the tunnel's mouth. No trains. A man folds his newspaper into a bird that will not fly. === CRITIQUE === Strengths: The imagery is concrete and the pacing mimics the emptiness of the setting. The newspaper bird is a strong metaphor. Revisions: The rhythm is uneven in the middle stanza. Expand the sensory details, sound, and smell, to ground the reader more fully. === REVISION === The clock drips mercury onto the platform where a coffee cup dreams of being a turbine. A newspaper unfolds itself into a bird of ash and advertisements. The tunnel yawns, revealing not a train but a clockwork oyster. No one is here. Everyone is here, folded into the tiles like wet photographs.
Next steps
Wrap this in a lightweight Streamlit interface so collaborators can select movements from a dropdown and iterate visually. Or connect the agent to Oxlo.ai's vision models, such as Gemma 3 27B or Kimi VL A3B, by passing a reference image to the chat completions endpoint and asking the agent to match the visual mood before drafting.
Top comments (0)