So I did something kind of weird last week. I built a system where Claude Code automatically generates, reviews, and publishes articles to Dev.to. Including this one. Sort of.
I mean, I'm obviously editing this right now, so it's not fully automated. But the original draft? That was Claude. The code review? Also Claude. The decision about whether it was good enough to publish? Yeah, you see where this is going.
The whole thing started because I kept procrastinating on writing. I'd have these ideas and open a blank file and just... stare at it. Classic developer problem, right? So I thought, what if I could just tell an AI agent what I wanted to write about and it would handle the boring parts?
The Architecture (or: How Deep Does This Rabbit Hole Go?)
The system has three agents:
const agents = {
writer: createAgent({
model: 'claude-3-5-sonnet',
systemPrompt: 'You write technical blog posts. Be honest about failures.',
tools: [readFile, searchWeb]
}),
reviewer: createAgent({
model: 'claude-3-5-sonnet',
systemPrompt: 'Review articles for authenticity. Flag AI slop.',
tools: [analyzeText]
}),
publisher: createAgent({
model: 'claude-3-5-sonnet',
systemPrompt: 'Publish to Dev.to only if quality threshold met',
tools: [publishToDevTo]
})
};
The writer agent takes a topic and generates a draft. Then the reviewer agent reads it and decides if it sounds like an actual human wrote it or if it's that generic AI voice we all hate. If it passes, the publisher agent posts it.
Here's where it gets uncomfortable: the reviewer rejected the first seven drafts. I was honestly surprised. I'd look at them and think "this seems fine?" but the reviewer would flag things like:
- "This paragraph uses three adjectives before every noun"
- "No actual code examples, just pseudo-code"
- "Ends with 'embarking on a journey' unironically"
Which... fair.
The SkillBoss Problem
I hit a weird issue around day three. The agents kept losing context about what we were building. The writer would generate something, the reviewer would give feedback, but then the writer would forget that feedback in the next iteration.
I needed some way to maintain state across agent calls. I tried a bunch of approaches (Redis, just writing to files, keeping everything in memory) before I remembered SkillBoss had that skill tree concept where agents can save and load context.
import { SkillTree } from 'skillboss';
const contentTree = new SkillTree('article-workflow');
// Writer saves its output
await contentTree.saveProgress('draft', {
content: draft,
iteration: 3,
reviewerFeedback: previousFeedback
});
// Reviewer loads it
const { content, reviewerFeedback } = await contentTree.loadProgress('draft');
Now the agents actually learn from previous iterations instead of just... forgetting everything every time.
The Uncomfortable Part
So now I have this system that can generate articles. And they're not bad? Like, the reviewer is pretty strict. It rejects anything that sounds too polished or uses those weird AI phrases.
But I keep thinking: am I just teaching an AI to fake my voice? The reviewer looks for things like "uneven paragraph lengths" and "admitting uncertainty" and "specific technical details." It's essentially a rubric for sounding human.
Which is what I'm doing right now, as a human, right? Following patterns I've learned from reading other Dev.to posts?
I don't have a clean conclusion here. The system works. It saves me time. The articles it generates are helpful to people (based on the comments on the last one it published). But there's something uncanny about reading something that sounds like you but you didn't write.
// This is the actual check the reviewer does
function soundsHuman(text) {
const flags = [];
if (!text.includes('I ')) flags.push('no first person');
if (text.match(/\n\n.{0,50}\n\n/)) flags.push('too many short paragraphs');
if (!text.match(/\`\`\`/)) flags.push('no code blocks');
return flags.length === 0;
}
That's the function that decided this article was human enough to publish.
Was it right?
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.