Okay this is genuinely cool. Keyword to live WordPress post, fully hands off, that’s the dream setup a lot of people talk about but never actually finish building. Respect for pushing it all the way through publish + Telegram ping.
On internal linking, here’s what’s worked for me: keep a simple list of your published posts (title, URL, short summary) somewhere your workflow can query, then have an agent pull 2-3 relevant ones and slot in anchor links after the draft is done, not while it’s writing. Trying to do both at once tends to make the linking feel forced.
For keyword density, I’d stop trying to force it during generation and just check it after. Write naturally, then run a quick script to count how often the keyword and its variants show up, and if it’s off, kick it back through GPT-4o for a light pass. Way less awkward than trying to hit a number while writing.
One more thing since you’re doing this at scale: worth checking new keywords against what you’ve already published so you’re not accidentally writing five articles that all fight for the same ranking.
Are you doing any manual review before it goes live, or is it truly zero-touch right now? Kind of want to see this thing run end to end.
The internal linking approach makes total sense — I was trying to do it during generation which is exactly why it felt forced. Keeping a published posts index in Supabase and having an agent pull relevant ones after the draft is done is clean. Implementing that next.
On keyword density you’re right, checking after and kicking it back through GPT-4o for a light pass is way simpler than trying to hit a number mid-generation. Less prompt complexity too.
The cannibalization check is something I hadn’t thought about at all. At scale that’s a real problem. Going to add a step that queries existing published posts before the brief is even generated.
To answer your question it’s currently zero-touch. Keyword goes in, article comes out live. No manual review. The fact-checker agent handles most of the quality control but it’s not perfect. I’m thinking of adding a Human Rewriter node as an optional step for sensitive topics.
If you want to see it run end to end I can record a live demo
Nice build. The end-to-end part is the strongest signal here, especially because you pushed it all the way through WordPress publishing instead of stopping at content generation.
The main thing I would look at next is failure handling around the publish step. For example, if the article is published but the image upload or Telegram notification fails, a retry could create a duplicate post unless the workflow keeps a stable content ID or checks WordPress before publishing again.
For sensitive topics, I would also keep the fact-checker but publish as a draft first and add an optional human approval step. That gives you zero-touch operation for low-risk content without treating every topic the same.
I’d also be interested in how you are handling source traceability. Are the final claims linked back to the Firecrawl or SerpAPI results anywhere in the workflow?
Really good catch on the duplicate post risk I hadn’t thought through that failure scenario carefully. Currently the workflow doesn’t store a content ID before publishing, so a retry after a failed image upload could absolutely create a duplicate. Going to add a step that saves the WordPress post ID to Supabase immediately after publish, then checks for it before any retry logic runs.
The draft-first approach for sensitive topics is the right call. Low-risk content goes live automatically, anything flagged by the fact-checker as sensitive publishes as draft and waits for approval. Clean separation.
On source traceability honestly, not yet. The SerpAPI and Firecrawl results feed into the research agent but the final article doesn’t link claims back to sources in any structured way. It’s something I’ve been thinking about. The cleanest approach I’ve seen is storing the source URLs alongside the content brief in a structured field, then having the writer agent reference them. Haven’t implemented it yet though.
That’s probably the biggest gap in the current build.