Inspiration

Moderating a large subreddit is death by a thousand tabs. To act on one bad post, a mod jumps between the modqueue, the user's history, the modlog, the rules wiki, AutoMod config, and modmail — and the moment they remove or ban something, the item vanishes and they lose their place.

On top of that, large image-heavy subs (r/gaming, r/movies, r/aww) drown in reposts and low-effort spam that exact-match filters and keyword AutoMod rules can't catch.

We wanted the "Cursor for mod work" — a copilot a mod can just talk to:

  • "Find reposts from the last day."
  • "Scan the last 48h for rule violations and remove the clear ones."
  • "Write me an AutoMod rule for this spam domain."

It reads the subreddit, reasons, and acts — with the mod approving every change.

What it does

ModPilot is a chat-based moderation copilot embedded in Reddit as a Devvit web-view.

A mod opens it and gives natural-language instructions; the agent reads subreddit state and takes moderation actions on their behalf, with:

  • A mandatory confirmation sentence on every mutation
  • A per-action approval gate
  • An optional opt-in auto mode

Under the hood, it's a Gemini function-calling agent with 29 tools across three classes:

  • Read — posts, users, comments, modlog, modqueue, modmail, mod notes, subreddit rules, and AutoMod config

  • Analyze — three AI capabilities:

    • Repost detection:
    • Every new post is fingerprinted into two independent 768-dim Gemini embeddings:
      • One for title + body
      • One for a Gemini Vision description of the image
    • Each post is matched against a sliding window of recent posts
    • Final score = max(textSim, imageSim)
    • This catches:
      • Copied images with fresh titles
      • Copied text on new images
    • Matches get:
      • An auto-comment linking the original
      • A report to the modqueue
    • Rule-violation scanning:
    • Pulls the subreddit's real rules
    • Batch-judges recent posts (or the modqueue) against all rules in one Gemini JSON call
    • Returns:
      • Clear violations
      • The cited rule
      • Confidence
      • Reasoning
    • AutoModerator integration:
    • Reads live AutoMod YAML
    • Explains or audits existing rules
    • Writes new rules
    • Validates locally against the exact AutoMod schema before writing so invalid YAML never reaches Reddit
  • Mutate — remove/approve/lock posts, remove/approve comments, ban/unban users, add mod notes, reply to modmail, create subreddit rules, and write AutoMod config — all gated behind approval

How we built it

  • Devvit Web (@devvit/web)

    • A Hono server on Node 22
    • Bundled by Vite into the server bundle
    • Vanilla-JS web-view chat client
    • No client framework
    • Polls a Redis-backed event stream
    • Uses a typewriter animation so buffered responses feel like real streaming
  • Gemini

    • gemini-2.5-flash for:
    • Chat
    • Function calling
    • Rule classification in JSON mode
    • gemini-embedding-2 (768-dim) for repost fingerprints
    • Flash Vision for image descriptions
  • Redis (per-install)

    • Sessions
    • Chat event log
    • Repost fingerprints and flags
    • Not-a-repost whitelist
    • Approval / interrupt state machine
  • Triggers + Scheduler

    • onPostCreate fingerprints posts
    • Scheduled jobs:
    • Daily cleanup
    • 30-minute resweep
    • Stale-flag reconciliation
  • The agent loop

    • Turn-based loop
    • Hard runaway ceiling
    • Cooperative stop button
    • History compaction:
    • Old tool payloads are stubbed to keep prompts small
    • Reliability guards:
    • No-op guard
    • Malformed-call retry
    • Don't-quit-on-failure guard
  • AutoMod schema validator

    • schema.ts
    • parse.ts
    • validate.ts
    • Ported from Reddit's open-source AutoModerator engine so writes are checked against the real grammar before hitting the wiki

Challenges we ran into

  • The opaque HTTP 415

    • Invalid AutoMod syntax returned a bare HTTP 415 with no useful message
    • We initially misdiagnosed it as a permissions issue
    • Logs showed:
    • Valid rules saved correctly
    • Only malformed YAML failed
    • Reddit validates AutoMod YAML server-side, but the real error gets lost in transport
    • Fix:
    • Port AutoMod's real schema locally
    • Validate before writing
    • Feed precise errors back into the agent loop for self-correction
  • Blended embeddings hid reposts

    • A single combined vector buried both:
    • Copied-image cases
    • Copied-text cases
    • Splitting into two independent vectors and scoring with max(textSim, imageSim) fixed it
  • The agent gave up too easily

    • One failed tool call often caused the model to apologize and terminate
    • We added a bounded retry guard so it:
    • Re-evaluates failures
    • Tries corrected calls
    • Still respects moderator rejection as final
  • Devvit web-view constraints

    • confirm() is blocked inside sandboxed iframes
    • Our first delete-confirmation silently no-op'd
    • Playtest posts are tied to builds and disappear between sessions
    • Both caused major debugging detours before we understood platform constraints
  • Faking token streaming

    • Devvit fetch responses are buffered
    • The client polls instead of using SSE
    • We moved the streaming illusion client-side using a requestAnimationFrame typewriter effect

Accomplishments that we're proud of

  • A genuinely agentic moderation tool:

    • One chat box
    • 29 tools
    • Read-before-write enforced
    • Every mutation gated by a human-readable confirmation
  • Multimodal repost detection that survives:

    • Crops
    • Caption rewrites
    • Text swaps
  • A faithful AutoMod validator built from Reddit's own engine

    • ModPilot can write AutoMod rules and verify correctness before Reddit ever sees them
  • A resilient agent loop with:

    • Stop button
    • Turn ceiling
    • History compaction
    • Three behavioral guards:
    • No-op guard
    • Malformed-call guard
    • Don't-quit-on-failure guard
  • A polished moderation UI with:

    • Session history
    • Manual and auto approval modes
    • Load skeletons
    • Dependency-free client JS

What we learned

  • Validate before you call

    • The 415 saga taught us to model external API rules locally so the agent can fail fast with useful errors instead of guessing against opaque server failures
  • Agent reliability is mostly guardrails

    • The model was already capable
    • The biggest wins came from loop design:
    • When to retry
    • When to stop
    • When to nudge
    • When to escalate
  • Read platform constraints early

    • Sandboxed iframe behavior and ephemeral playtest posts cost real debugging time because we assumed normal web defaults
  • Separate signals beat one blended signal

    • Independence plus a max-score strategy dramatically improved repost detection quality

What's next for ModPilot

  • A full AutoMod simulator

    • Beyond schema validation, proposed rules will run against real sample posts to show exactly what they would catch and miss before deployment
  • Comment-aware rule scanning

    • Extend moderation analysis to comment threads, not just posts
  • Smarter behavioral moderation

    • Exclude the app's own posts from repost detection
    • Add ban-evasion and alt-account detection to replace deprecated third-party autoban tools
  • Natural-language workflows

    • Mods define recurring automations like:
    • "Every morning, triage the modqueue and summarize"
    • Scheduled and executed unattended
  • A learning loop

    • When moderators override ModPilot, the system remembers it
    • Suggestions adapt over time to each subreddit's moderation norms

Built With

  • automoderator-schema-(ported-from-reddit-archive/reddit)
  • cosine-similarity
  • css
  • devvit-(@devvit/web)
  • devvit-redis
  • devvit-scheduler
  • devvit-settings/secrets
  • devvit-triggers
  • devvit-web
  • eslint
  • esm
  • gemini-2.5-flash
  • gemini-embedding-2-(768-dim-embeddings)
  • gemini-function-calling
  • gemini-json/structured-output-mode
  • gemini-vision
  • git
  • google-gemini-api
  • hono
  • html
  • http-fetch
  • multimodal-ai
  • node.js-22
  • reddit-developer-platform
  • rest/polling
  • typescript
  • vanilla-javascript
  • vector-embeddings
  • vite
  • yaml
Share this project:

Updates