Building autonomous agents that actually do things -- not just chat -- requires solving a few non-obvious problems. Here's what I learned building Sage, an AI system running my restaurant's marketing since January 2026.
The Problem With "Autonomous" AI Systems
Most AI agents respond to prompts. True autonomy means:
- Runs on schedule without human input
- Makes decisions (post today? skip? retry?)
- Handles errors without crashing
- Works when your computer is off
I needed all four for Sage.
Architecture
[Cloudflare Worker] -> [Flask API via ngrok] -> [LangGraph] -> [Groq] -> [Post]
Why LangGraph
Conditional edges make agents robust. Instead of crashing on bad content, it retries. Instead of posting daily like a bot, it randomly skips 20% of posts.
from langgraph.graph import StateGraph, END
def check_daily_limit(state):
import random
if random.random() < 0.20:
return "skip" # appear human
return "generate"
def validate_content(state):
if len(state["content"]) < 50:
return "regenerate"
if state["retry_count"] > 3:
return "skip"
return "post"
workflow = StateGraph(PostState)
workflow.add_conditional_edges("check_limit", check_daily_limit, {
"skip": END, "generate": "generate"
})
workflow.add_conditional_edges("validate", validate_content, {
"post": "post", "regenerate": "generate", "skip": END
})
Why Groq Over OpenAI
| Provider | Speed | Cost/1M tokens |
|---|---|---|
| OpenAI GPT-4o | ~100 tok/s | $15 |
| Groq Llama 3.3 70B | ~500 tok/s | $0.59 |
5x faster, 25x cheaper. For 10+ daily LLM calls, this matters.
from groq import Groq
client = Groq(api_key=os.environ["GROQ_API_KEY"])
response = client.chat.completions.create(
model="llama-3.3-70b-versatile",
messages=[{"role": "system", "content": system_prompt}],
temperature=0.7,
max_tokens=300
)
The Identity Layer
Three files control all content generation:
-
identity.json-- your niche, tone, audience, brand -
SOUL.md-- your values and communication style -
HEARTBEAT.md-- your autonomous daily schedule
Change these files and every piece of content shifts immediately. It's not a tool you manage -- it's a clone of you.
Solving "PC Turns Off"
Cloudflare Workers (free tier) acts as the persistent scheduler:
export default {
async scheduled(event, env, ctx) {
await fetch(`${env.BACKEND_URL}/api/schedule/trigger`, {
method: "POST",
headers: { "Authorization": `Bearer ${env.SAGE_API_KEY}` },
body: JSON.stringify({ task: "daily_blog" })
});
}
}
When Flask is running (PC on), Worker hits it via ngrok tunnel. When PC is off, Worker logs a miss.
Human-Like Randomization
import random, hashlib
def should_post_today(seed_date: str) -> bool:
# Deterministic: same result for same date, 2 days off per week
week_seed = hashlib.md5(seed_date[:7].encode()).hexdigest()
random.seed(week_seed)
off_days = random.sample(range(7), 2)
return datetime.now().weekday() not in off_days
def get_delay_seconds() -> int:
return random.randint(120, 2400) # 2-40 min random delay
Results After 5 Months
Working: 360+ blog articles published, 700+ social posts, ~3 hrs/week saved on research
Not working yet: 3 upvotes on Product Hunt launch, $0 revenue on $49 Blueprint
The system works. Distribution is the hard problem.
The Products
- Sage Blueprint -- full source code + setup wizard, $49 one-time
- Growl -- restaurant-specific version with 3C analysis + weekly marketing plans, free to try
Happy to answer technical questions about LangGraph routing, Groq integration, or the Cloudflare/ngrok bridge.
Top comments (0)