Skip to main content

AI blog generator with 6-pass pipeline and built-in humanizer that removes AI writing tells.

Project description

blog-pipeline

AI blog generator that doesn't sound like AI.

6-pass Claude API pipeline with a built-in humanizer, topic deduplication, internal linking, and Supabase sync. The humanizer is the key differentiator — it enforces a strict writing ruleset that removes every common AI tell.


Quick start

# Clone and install
git clone https://github.com/ownmy-app/blog-pipeline
cd blog-pipeline
pip install -e .

# Set your API key
export ANTHROPIC_API_KEY=sk-ant-...

# Generate 5 blog posts
blog-generate --count 5 --niche "developer tooling and SaaS"

# Re-humanize existing drafts only
blog-generate --passes 4

# Run tests
pytest tests/ -v

Required environment variables:

ANTHROPIC_API_KEY=sk-ant-...          # required

# Optional (for Supabase sync in pass 0 and 6)
SUPABASE_URL=https://xxx.supabase.co
SUPABASE_KEY=eyJ...
BLOG_SITE_URL=https://yourblog.com

Passes

Pass What it does
0 Fetches existing titles from Supabase (prevents duplicates)
1 Identifies new topics (skips anything already written)
2 Plans structure per topic (comparison / deep-dive / case-study / how-to / opinion)
3 Generates full markdown content
4 Humanizer — strips AI tells (see below)
5 Adds internal links across all posts
6 Pushes to Supabase + updates local registry

The Humanizer

Pass 4 enforces these rules on every post:

  • Banned words: leverage, seamless, robust, cutting-edge, game-changer, revolutionize, synergy, paradigm, transformative, unlock, delve, streamline, elevate, empower, holistic, utilize, facilitate, innovative
  • No em-dashes (—) — replaced with commas or full stops
  • No semicolons connecting sentences
  • No emojis
  • Contractions required: it's, we're, you'll, don't
  • Active voice only
  • Max 1 exclamation mark per post
  • No "In conclusion / In summary" section openers

Use the humanizer standalone:

from blog_pipeline.humanizer import humanize_post
clean = humanize_post(my_ai_draft)

Setup

git clone https://github.com/ownmy-app/blog-pipeline
cd blog-pipeline
pip install -e .
cp .env.example .env
# Edit .env with your ANTHROPIC_API_KEY

Run

# Full pipeline: generate 5 blogs
blog-generate --passes 1-6 --count 5 --niche "developer tooling and SaaS"

# Re-humanize existing drafts only
blog-generate --passes 4

# Push already-written files to Supabase
blog-generate --passes 6

# Generate content without pushing
blog-generate --passes 1-5 --count 3

Output

  • blogs/<slug>.md — humanized markdown files
  • blogs/_topics.json — topic cache
  • blogs/_plans.json — structure plans
  • blogs/_registry.json — pushed blog tracking

Immediate next steps

  1. Make the humanizer prompt configurable via HUMANIZER_RULES env / YAML
  2. Add --audit flag: re-score all pushed blogs and unpublish weak ones
  3. Add SEO scoring pass (keyword density check, meta description generation)
  4. Package as a GitHub Action: auto-generate blogs on schedule

Commercial viability

  • Package the humanizer as a standalone API: POST /humanize → clean post
  • Charge per post ($0.10–0.50) or monthly flat ($49–149)
  • Differentiator: "the only AI blog writer that bans its own clichés by design"
  • Add AI-detector score before/after to prove improvement

Example output

Running pytest tests/ -v:

============================= test session starts ==============================
platform darwin -- Python 3.13.9, pytest-9.0.2, pluggy-1.5.0
cachedir: .pytest_cache
rootdir: /tmp/ownmy-releases/blog-pipeline
configfile: pyproject.toml
plugins: anyio-4.12.1, cov-7.1.0
collecting ... collected 4 items

tests/test_pipeline.py::test_check_banned_words_flags_corporate_speak PASSED [ 25%]
tests/test_pipeline.py::test_check_banned_words_passes_clean_text PASSED [ 50%]
tests/test_pipeline.py::test_check_banned_words_flags_em_dash_clusters FAILED [ 75%]
tests/test_pipeline.py::test_humanize_post_returns_string PASSED         [100%]

============================= short test summary info ==========================
FAILED tests/test_pipeline.py::test_check_banned_words_flags_em_dash_clusters
========================= 1 failed, 3 passed in 0.43s ==========================

See examples/sample-post.md for a realistic humanized blog post produced by the pipeline.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

blog_pipeline-0.1.0.tar.gz (23.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

blog_pipeline-0.1.0-py3-none-any.whl (14.8 kB view details)

Uploaded Python 3

File details

Details for the file blog_pipeline-0.1.0.tar.gz.

File metadata

  • Download URL: blog_pipeline-0.1.0.tar.gz
  • Upload date:
  • Size: 23.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for blog_pipeline-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f1607ab10b814c1a41945f7ea47bbb65e4a0e7cfc51ee1ce57cb915289aa5882
MD5 34625a536675fe2a2b422c65dba13b6f
BLAKE2b-256 c4880a999184ea88c46179efedcffc6155a385b388214316b40aecdf50ae8e4f

See more details on using hashes here.

File details

Details for the file blog_pipeline-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: blog_pipeline-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 14.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for blog_pipeline-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 851f831891ac4341b6937c2f1acc8b551d5a655ef1302f93cc9d35b981816ceb
MD5 19b039d7c7c48e06bc27f1ff90f8049c
BLAKE2b-256 7d11abcfea882dafe4c75a2e1ddd2b0bfa2d0345fe5aa2daf48523e5fa385389

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page