AI-powered content generation pipeline built with LangGraph. Generates SEO-optimized Polish articles using a 4-agent workflow.
Live: content-agent-ui.vercel.app
Enter a topic and SEO phrase — the pipeline runs 4 agents in sequence:
- Researcher — searches the web (Tavily or Brave Search) and extracts key facts
- Writer — writes a full Polish article (1000–1500+ words) based on research
- SEO Checker — analyzes the article and generates meta title, meta description, keyword density report
- Image Prompt — generates a detailed image prompt for a thumbnail/social graphic
Progress is streamed in real time via SSE.
Measured on a typical 1,200-word Polish SEO article:
| Agent | Model | Input tokens | Output tokens | Cost (USD) |
|---|---|---|---|---|
| Researcher | claude-haiku-4-5 | ~2,100 | ~800 | ~0ドル.001 |
| Writer | claude-sonnet-4-6 | ~3,400 | ~1,800 | ~0ドル.027 |
| SEO Checker | claude-haiku-4-5 | ~2,200 | ~400 | ~0ドル.001 |
| Image Prompt | claude-haiku-4-5 | ~1,800 | ~200 | ~0ドル.001 |
| Total | ~9,500 | ~3,200 | ~0ドル.030 |
Wall clock time: ~75-90s (sequential). Cache warm: ~45s. Prices based on OpenRouter rates, May 2026.
graph TD
A[User input: topic + SEO phrase] --> B[Researcher<br/>claude-haiku-4-5<br/>Tavily/Brave search]
B --> C{HITL checkpoint<br/>review research}
C --> D[Writer<br/>claude-sonnet-4-6<br/>1000-1500 word article]
D --> E{HITL checkpoint<br/>review draft}
E --> F[SEO Checker<br/>claude-haiku-4-5<br/>meta title, description, density]
E --> G[Image Prompt<br/>claude-haiku-4-5<br/>thumbnail prompt]
F --> H[Final article]
G --> H
Note: HITL checkpoints are available via the stateful API; the default UI runs fully automated.
You need at least one LLM provider and one search provider:
| Key | Where to get | Required |
|---|---|---|
| OpenRouter API Key | openrouter.ai | Recommended |
| Anthropic API Key | console.anthropic.com | Alternative |
| Tavily API Key | tavily.com — 1000 req/mo free | Recommended |
| Brave Search API Key | brave.com/search/api — 2000 req/mo free | Alternative |
Go to ⚙ Settings → paste your keys → Save. Keys are stored in your browser (localStorage) and sent to the server only during generation. The server does not store them.
Enter topic + SEO phrase → click Generate → wait ~60–90s for the full pipeline to complete.
| Agent | Model |
|---|---|
| Researcher | claude-haiku-4.5 |
| Writer | claude-sonnet-4.6 |
| SEO Checker | claude-haiku-4.5 |
| Image Prompt | claude-haiku-4.5 |
- Next.js 15 (App Router, Node.js runtime)
- LangGraph — agent orchestration
- LangChain OpenAI — OpenRouter-compatible LLM client
- Tavily / Brave Search — web research
- Supabase (optional) — article history storage
- Vercel — hosting (max 300s function timeout)
git clone https://github.com/emilpinski/content-agent cd content-agent-ui npm install cp .env.example .env.local # Fill in keys in .env.local (optional — users can provide their own via UI) npm run dev
ANTHROPIC_API_KEY=sk-ant-...
OPENROUTER_API_KEY=sk-or-v1-...
TAVILY_API_KEY=tvly-...
BRAVE_SEARCH_KEY=BSA...
NEXT_PUBLIC_SUPABASE_URL=https://...
SUPABASE_SERVICE_ROLE_KEY=eyJ...
5 requests per minute per IP (in-memory, resets on cold start).
- API keys validated by format before use (
sk-ant-*,sk-or-v1-*) - Input length limited (topic: 300 chars, SEO phrase: 150 chars)
- CSP headers configured
- No key logging on server side
Why not just one big Sonnet prompt? A single prompt cannot search the web, write a full article, audit SEO, and generate an image prompt simultaneously. The multi-agent DAG lets each model specialize: Haiku handles fast, cheap research and metadata; Sonnet does the heavy writing. The result is better quality at lower cost than one monolithic Sonnet call, and each stage is independently testable and replaceable.
Why LangGraph instead of a simple loop? LangGraph gives you a stateful graph with typed edges, conditional routing, and interrupt support for human-in-the-loop steps. A simple loop cannot pause mid-pipeline for user approval, resume from a checkpoint, or branch conditionally (e.g., skip image prompt if the article already has one).
How much does it cost? Roughly 0ドル.03 per article using OpenRouter pricing (May 2026). See the cost table above.