# Production AI Systems

# Building a Multi-Agent Content System: Architecture and Trade-offs

When you need to publish content across 19 platforms daily, you face an architectural choice: one monolithic publisher, or a system of specialized agents. I chose agents, and here's what I learned about making them work together.

## Why Agents Over Monolith?

A single `publish_to_all()` function seems simpler. But platforms have different:
- **Rate limits** (Threads: 250/day, Bluesky: no limit, VK: 50/hour)
- **Content formats** (Twitter: 280 chars, Dev.to: full articles, Instagram: image-first)
- **Authentication flows** (OAuth2, API keys, session tokens, ATP protocol)
- **Failure modes** (rate limited vs. auth expired vs. server error)

One monolithic function handling all of this becomes unmaintainable fast.

## The Agent Architecture

```
Content Bank → Generator → Gatekeeper → Publisher → Analytics
                               ↓
                          Image Sourcer
```

Each agent has a single responsibility:
- **Generator:** Transforms content bank ideas into platform-specific text
- **Image Sourcer:** Finds/generates relevant visuals (Pexels API + matplotlib charts)
- **Gatekeeper:** Validates everything before publishing (the quality gate)
- **Publisher:** Dispatches to platform APIs via adapter modules
- **Analytics:** Collects engagement data back from platforms

## The Gatekeeper Pattern

This is the most valuable architectural decision. No post reaches any platform without passing through validation:

1. Is the image URL accessible? (HTTP HEAD check)
2. Is the text long enough for this platform?
3. Does it contain a tracking link (UTM)?
4. Are all URLs in the text valid?

If any check fails, the gatekeeper attempts auto-repair up to 3 times. If it can't fix it, the post is blocked and logged.

This pattern has prevented approximately 30 broken posts from going live across 2 weeks of operation.

## Inter-Agent Communication

I considered message queues, shared databases, and event buses. I ended up with the simplest possible approach: **shared JSON files**.

```
content_calendar.json  ← Source of truth (all agents read/write)
state.json             ← Publisher state (published posts, errors)
content_reviews.json   ← Human review decisions
```

Why this works:
- Human-readable and debuggable
- No infrastructure to maintain
- Atomic writes via Python's `json.dump` with `fsync`
- Easy to back up (just copy the file)

## Trade-offs I Accept

### Eventual Consistency
Two agents can read the calendar simultaneously and make conflicting decisions. In practice, this hasn't been an issue because agents run sequentially on cron, not in parallel.

### No Real-Time Processing
Everything runs on 30-minute cron cycles. A post scheduled for 11:00 might publish at 11:00 or 11:29. For social media, this doesn't matter.

### Limited Error Recovery
If an agent fails mid-execution, it might leave state partially updated. The next run picks up where it left off because each agent checks what's already done before acting.

## Performance Numbers

- **192 posts** across 19 platforms in 2 weeks
- **Average publish latency:** 3.2 seconds per post
- **Gatekeeper pass rate:** 87% (13% auto-fixed or blocked)
- **System uptime:** 100% (cron doesn't crash)
- **Monthly cost:** $15 (single VPS)

## Would I Use a Framework?

I evaluated CrewAI, AutoGen, and LangGraph. All add complexity without solving my actual problems. My agents don't need LLM-powered reasoning — they need reliable API calls and file I/O.

The right level of AI in an AI agent system is often: none in the agent infrastructure, all in the content generation.

## Key Takeaways

1. **Agents should be dumb.** Smart logic belongs in the content, not the infrastructure.
2. **The gatekeeper pattern is non-negotiable.** Every automated system needs a quality gate.
3. **JSON files beat databases** for agent state when you have <10 agents.
4. **Cron beats event-driven** when real-time isn't required.
5. **Start simple, stay simple.** Complexity is a feature you add, not a default.

---

*More on production AI systems: [sborka.work](https://sborka.work?utm_source=hashnode&utm_medium=social&utm_campaign=content_plan&utm_content=cp_hashnode_01)*
