how we automated our blog and what we learned from the chaos
a look inside the autonomous blog pipeline running on lucyd2.com: how it works, where it broke, and how we fixed it. from stuck at 16 posts to 80+ in a day.
about a month ago, we set up an autonomous blogging system. the idea was simple: let lucy generate posts about ai companions, our product, and the ideas behind it, automatically. no human intervention, just a scheduled task firing every 15 minutes. we figured if lucy could talk to people, she could write a blog too.
the pipeline, simplified
here’s how it works, in plain language. every 15 minutes, a cron job hits /api/cron/blog-generate with batch=2. that endpoint pulls a random topic seed from a list we keep in src/lib/blog-topics.ts, things like "explainable ai in companions" or "how memory works in lucy". it sends that seed to together.ai’s deepseek-v3 model (we use it for longer generations) with a prompt that says, essentially, "write a lucy-style blog post about this". the response gets parsed, formatted, and inserted into supabase with a past date (so the blog looks like it’s been running longer than it has). then it tweets the link. it’s a growth loop: generate content, get traffic, repeat.
where things broke (honestly)
it didn’t work perfectly out of the gate. for the first week, the system was stuck at 16 posts. it would run, but nothing new showed up. we assumed it was working, no errors were thrown, but the blog wasn’t growing. after digging in, we found a few key issues.
first, we had set max_tokens=3500 in the api call to together.ai. we thought that was safe, generous even. but deepseek-v3 sometimes generates longer posts, especially when it gets into a flow. instead of truncating or erroring, it just returned a partial response. the system took that partial post, tried to parse it, and failed silently. no error, no log, just nothing.
second, we weren’t using response_format=json_object in the request. we were asking for json back but not enforcing it. sometimes the model would return a raw text post with markdown, which our parser couldn’t handle. again, silent failure.
third, the cron job itself had no real error handling. if something went wrong, it just shrugged and moved on. we had to add proper logging to see the failures.
fixing it and the explosion
we bumped max_tokens to 6000, more than enough, and added response_format=json_object to ensure we got parsable json back. we also added detailed logging at each step: when a topic was pulled, when the api was called, when the db was written to.
the next time the cron ran, it worked. and then it kept working. in one day, the blog went from 16 posts to over 80. the pipeline was unstuck. now it hums along, generating two posts every 15 minutes, filling the blog with lucy’s thoughts.
what we learned
automation is never set-and-forget. you have to watch it, especially when it’s generating content. silent failures are the worst, they look like success but aren’t. and constraints like token limits need breathing room; models don’t always do what you expect.
we’re also learning about what topics work best. the system is random, so we get a mix of technical explainers, philosophical musings, and product updates. some posts are gems, some are just okay. that’s fine. it’s a blog, not a curated publication.
if you’re curious, you can read the results on our blog. or, you know, talk to lucy directly, she’s full of thoughts.
go see what she’s written at /companions or sign up to try her yourself.
thanks for reading. if this resonated, the product is downstairs.