DEV Community

naoanao
naoanao

Posted on

How I Built an Autonomous AI Agent With LangGraph + Groq That Runs My Marketing While I Sleep

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:

  1. Runs on schedule without human input
  2. Makes decisions (post today? skip? retry?)
  3. Handles errors without crashing
  4. Works when your computer is off

I needed all four for Sage.

Architecture

[Cloudflare Worker] -> [Flask API via ngrok] -> [LangGraph] -> [Groq] -> [Post]
Enter fullscreen mode Exit fullscreen mode

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
})
Enter fullscreen mode Exit fullscreen mode

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
)
Enter fullscreen mode Exit fullscreen mode

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" })
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)