ai-blog-gen
v3.3.0
Published
AI-powered SEO blog generator using Pi SDK — any OpenAI/Anthropic compatible provider, competitive research, E-E-A-T, charts, illustrations, validation
Downloads
2,723
Maintainers
Readme
ai-blog-gen
AI-powered SEO blog generator using Pi SDK. Supports any OpenAI or Anthropic compatible provider. A single agent handles competitive research, outline creation, draft writing, E-E-A-T enhancement, and final polish — all in one multi-turn session with web search and file writing tools.
Install
npm install ai-blog-genQuick Start
import { createBlogGenerator } from 'ai-blog-gen'
const blog = createBlogGenerator({
llm: {
provider: 'anthropic',
model: 'claude-sonnet-4-5-20250929',
apiKey: process.env.ANTHROPIC_API_KEY!,
},
})
const result = await blog.generate({
lang: 'en',
topic: 'Complete guide to sustainable energy solutions',
})
console.log(result.title) // SEO-optimized title
console.log(result.slug) // URL-friendly slug
console.log(result.content) // Full markdown article
console.log(result.validation) // { wordCount, hasTLDR, hasFAQ, hasTable, bannedWordsFound }Supported Providers
// Anthropic Claude
const blog = createBlogGenerator({
llm: {
provider: 'anthropic',
model: 'claude-sonnet-4-5-20250929',
apiKey: 'sk-ant-...',
},
})
// OpenAI
const blog = createBlogGenerator({
llm: {
provider: 'openai',
model: 'gpt-4o',
apiKey: 'sk-...',
},
})
// Any OpenAI-compatible endpoint (Ollama, vLLM, LiteLLM, etc.)
const blog = createBlogGenerator({
llm: {
provider: 'my-local',
model: 'llama3',
apiKey: 'not-needed',
baseUrl: 'http://localhost:11434/v1',
},
})
// OpenRouter
const blog = createBlogGenerator({
llm: {
provider: 'openrouter',
model: 'anthropic/claude-sonnet-4',
apiKey: 'sk-or-...',
},
})How It Works
The library creates a multi-turn agent session via Pi SDK in a temporary directory. The agent follows a 5-phase workflow:
- Competitive Research — searches the web, analyzes top results, identifies content gaps
- Outline — creates structured outline with information gain per section
- Draft — writes full article in the target language
- E-E-A-T Enhancement — adds author expertise, trusted sources, internal links
- Final Polish — adds H1 title, TL;DR, FAQ section
After the agent finishes, the library post-processes the output: renders charts, generates illustrations, validates content, and extracts metadata.
Full Configuration
import { createBlogGenerator, createStorageProvider } from 'ai-blog-gen'
const blog = createBlogGenerator({
// Required: LLM provider configuration
llm: {
provider: 'anthropic',
model: 'claude-sonnet-4-5-20250929',
apiKey: process.env.ANTHROPIC_API_KEY!,
},
// Optional: Storage provider for uploading charts/images
storage: createStorageProvider(async (buffer, key, contentType) => {
// Upload to S3, B2, GCS, etc.
return { url: `https://cdn.example.com/${key}` }
}),
// Optional: SEO configuration
bannedWords: ['delve', 'vibrant', 'unlock', 'leverage'],
competitorDomains: ['competitor1.com', 'competitor2.com'],
trustedDomainPatterns: ['\\.gov$', 'reuters\\.com', 'bloomberg\\.com'],
internalLinks: [
{ url: '/listings', anchor: 'Browse Listings', type: 'search' },
{ url: '/about', anchor: 'About Us', type: 'home' },
],
// Optional: Author profiles for E-E-A-T
authors: [
{
id: 'john',
name: 'John Smith',
role: 'Senior Analyst',
bio: '10+ years experience in market analysis...',
credentials: ['PhD Economics', 'Published Author'],
},
],
// Optional: Workspace settings
outputDir: '/tmp/blog-workspace', // custom output dir
keepWorkspace: true, // don't auto-cleanup tmp dir
// Optional: Lifecycle hooks
hooks: {
onLog: (msg) => console.log(msg),
afterResearch: (research) => console.log(`Found ${research.contentGaps.length} gaps`),
afterOutline: (outline) => console.log(`${outline.sections.length} sections planned`),
afterDraft: (content) => console.log(`Draft: ${content.length} chars`),
afterPolish: (content) => console.log('Final polish done'),
},
})Generate Options
const result = await blog.generate({
lang: 'en', // language code
topic: 'Your topic here', // article topic
targetKeyword: 'focus keyword', // optional, defaults to topic
wordCountTarget: 2000, // optional, defaults to 2000
author: myAuthor, // optional, overrides random selection
hooks: { onLog: (msg) => {...} }, // optional, per-call hooks override config hooks
})Result
interface GenerateResult {
filePath: string // path to final markdown file
title: string // SEO-optimized title
slug: string // URL-friendly slug
metaDesc: string // meta description (150-160 chars)
content: string // full markdown article
author: Author // author profile used
charts: string[] // CDN URLs of generated charts
illustration?: string // CDN URL of illustration
seo: SeoMeta // OpenGraph, Twitter, focus keyword
internalLinks: InternalLink[] // links found in content
sources: Source[] // external sources (government/news/research)
validation: ValidationResults // wordCount, hasTLDR, hasFAQ, etc.
research?: CompetitiveResearch // intermediate: competitor analysis
outline?: ArticleOutline // intermediate: structured outline
costUsd?: number // API cost in USD (if available)
}Charts (standalone)
import { generateBarChart, generateLineChart, renderMermaidChart } from 'ai-blog-gen'
// Bar chart
const bar = await generateBarChart(
{ labels: ['A', 'B', 'C'], datasets: [{ label: 'Value %', data: [5.2, 4.8, 5.5], color: '#3b82f6' }] },
'Comparison Chart',
{ storage: myStorage },
)
// Line chart
const line = await generateLineChart(
[2020, 2021, 2022, 2023],
[100, 120, 135, 150],
'Price Trends',
{ storage: myStorage },
)
// Mermaid diagram
const mermaid = await renderMermaidChart('graph TD\n A-->B', { storage: myStorage })Architecture
User config + topic
|
Pi SDK Agent Session (multi-turn, cwd=tmpdir)
+-- Phase 1: web search -> research.json
+-- Phase 2: outline -> outline.json
+-- Phase 3: draft -> blog.md
+-- Phase 4: E-E-A-T + sources -> blog.md
+-- Phase 5: title, TL;DR, FAQ -> blog.md + metadata.json
+-- Optional: Mermaid diagrams -> chart-*.mmd
|
Post-processing (Node.js)
+-- Read files from tmpdir
+-- Render charts (SVG -> WebP via Sharp)
+-- Generate illustration (OpenRouter Flux)
+-- Validate content
+-- Extract links, sources, metadata
+-- Upload via storage provider
|
GenerateResultLicense
MIT
