Project 4: AI-Powered Content Platform¶
Project Overview¶
Build a content platform that uses AI to help users create, edit, and optimize written content: - Generate blog posts, marketing copy, and documentation from outlines - Adjust tone and style (professional, casual, technical) - Optimize for SEO with keyword suggestions and meta descriptions - Manage content with a simple dashboard
Time estimate: 12-18 hours Skills used: Prompt Engineering, Structured Output, Full-Stack Development, RAG
Architecture¶
[Dashboard UI]
|
v
[FastAPI Backend]
|-- POST /generate (outline -> draft)
|-- POST /rewrite (text + instructions -> improved text)
|-- POST /seo (text -> SEO analysis + suggestions)
|-- CRUD /articles (manage saved content)
v
[AI Pipeline]
|-- Content Generator (GPT-4.1-mini)
|-- Tone Adjuster (system prompt variants)
|-- SEO Analyzer (structured output)
|-- Style Reference RAG (optional: learn from examples)
v
[Database] (SQLite for simplicity)
Step 1: Content Generation Pipeline¶
from openai import OpenAI
import json
client = OpenAI()
TONE_PROMPTS = {
"professional": "Write in a professional, authoritative tone. Use industry terminology. Be concise and data-driven.",
"casual": "Write in a friendly, conversational tone. Use simple language. Include analogies and relatable examples.",
"technical": "Write for a technical audience. Include code examples, specifications, and detailed explanations.",
"marketing": "Write persuasive copy. Focus on benefits over features. Use power words and clear calls to action.",
}
def generate_content(
topic: str,
outline: list[str],
tone: str = "professional",
target_length: int = 800,
) -> dict:
"""Generate a content piece from a topic and outline."""
tone_instruction = TONE_PROMPTS.get(tone, TONE_PROMPTS["professional"])
outline_text = "
".join(f"- {item}" for item in outline)
response = client.chat.completions.create(
model="gpt-4.1-mini",
messages=[
{
"role": "system",
"content": f"""You are an expert content writer.
{tone_instruction}
Write well-structured content with:
- An engaging introduction that hooks the reader
- Clear section headings (use ## for sections)
- Substantive paragraphs with specific details
- A conclusion with key takeaways
- Target approximately {target_length} words"""
},
{
"role": "user",
"content": f"Topic: {topic}
Outline:
{outline_text}
Write the full article."
}
],
temperature=0.7
)
content = response.choices[0].message.content
word_count = len(content.split())
return {
"content": content,
"word_count": word_count,
"tone": tone,
"topic": topic,
}
Step 2: SEO Analyzer¶
def analyze_seo(content: str, target_keyword: str) -> dict:
"""Analyze content for SEO and provide improvement suggestions."""
response = client.chat.completions.create(
model="gpt-4.1-mini",
messages=[
{
"role": "system",
"content": """You are an SEO expert. Analyze the given content and provide actionable recommendations.
Respond as JSON with these fields:
- title_suggestions: array of 3 SEO-optimized title options
- meta_description: a 155-character meta description
- keyword_density: approximate percentage of target keyword
- missing_keywords: related keywords that should be added
- readability_score: "easy" / "moderate" / "difficult"
- improvements: array of specific improvement suggestions
- overall_score: integer 1-100"""
},
{
"role": "user",
"content": f"Target keyword: {target_keyword}
Content:
{content}"
}
],
response_format={"type": "json_object"},
temperature=0.2
)
return json.loads(response.choices[0].message.content)
Step 3: Content Rewriter¶
def rewrite_content(
content: str,
instructions: str,
preserve_structure: bool = True
) -> str:
"""Rewrite content based on specific instructions."""
structure_note = (
"Preserve the existing heading structure and section organization."
if preserve_structure else
"Feel free to restructure if it improves the content."
)
response = client.chat.completions.create(
model="gpt-4.1-mini",
messages=[
{
"role": "system",
"content": f"""You are an expert editor. Rewrite the given content
following the user's instructions. {structure_note}
Return only the rewritten content, no commentary."""
},
{
"role": "user",
"content": f"Instructions: {instructions}
Content to rewrite:
{content}"
}
],
temperature=0.5
)
return response.choices[0].message.content
Step 4: FastAPI Backend¶
from fastapi import FastAPI
from pydantic import BaseModel
import sqlite3
import uuid
from datetime import datetime
app = FastAPI(title="AI Content Platform")
# Simple SQLite storage
def get_db():
conn = sqlite3.connect("content.db")
conn.execute("""CREATE TABLE IF NOT EXISTS articles (
id TEXT PRIMARY KEY,
title TEXT,
content TEXT,
tone TEXT,
seo_score INTEGER,
created_at TEXT,
updated_at TEXT
)""")
return conn
class GenerateRequest(BaseModel):
topic: str
outline: list[str]
tone: str = "professional"
target_length: int = 800
class RewriteRequest(BaseModel):
content: str
instructions: str
class SEORequest(BaseModel):
content: str
target_keyword: str
@app.post("/generate")
async def generate(req: GenerateRequest):
result = generate_content(req.topic, req.outline, req.tone, req.target_length)
return result
@app.post("/rewrite")
async def rewrite(req: RewriteRequest):
result = rewrite_content(req.content, req.instructions)
return {"content": result}
@app.post("/seo")
async def seo_analysis(req: SEORequest):
result = analyze_seo(req.content, req.target_keyword)
return result
@app.post("/articles")
async def save_article(title: str, content: str, tone: str = "professional"):
db = get_db()
article_id = str(uuid.uuid4())[:8]
now = datetime.utcnow().isoformat()
db.execute(
"INSERT INTO articles VALUES (?, ?, ?, ?, ?, ?, ?)",
(article_id, title, content, tone, 0, now, now)
)
db.commit()
return {"id": article_id, "message": "Article saved"}
@app.get("/articles")
async def list_articles():
db = get_db()
rows = db.execute("SELECT id, title, tone, seo_score, created_at FROM articles ORDER BY created_at DESC").fetchall()
return [{"id": r[0], "title": r[1], "tone": r[2], "seo_score": r[3], "created_at": r[4]} for r in rows]
Evaluation¶
| Metric | Target | How to Measure |
|---|---|---|
| Content quality | 4+ / 5 rating | Human evaluation of 10 generated articles |
| SEO score | 70+ / 100 | Run SEO analyzer on generated content |
| Tone accuracy | 90%+ | Judge rates tone match for 20 samples |
| Rewrite quality | Improved readability | Compare before/after readability scores |
| API latency | < 10s for generation | Time each endpoint |
Extension Ideas¶
- Add RAG over a style guide to ensure brand consistency
- Implement A/B title testing with click prediction
- Add image suggestion capabilities
- Build a Markdown preview in the dashboard
- Add content scheduling and publishing integration
Resources¶
- OpenAI Structured Outputs: JSON mode for reliable parsing
- Yoast SEO: Reference for SEO scoring criteria
- Hemingway Editor: Reference for readability analysis
- Next.js: For building the dashboard frontend
Next Project¶
Project 5: Conversational AI with Memory — Build a personal AI assistant with persistent memory that learns user preferences over time.