Inspiration
There are millions of mid-career office professionals — dispatchers, accountants, logistics managers, clerks. People in their 30s and 40s who are good at their jobs and spend a stupid amount of that job doing the same file chore every morning: take two spreadsheets, merge them by hand into one summary, their columns, their order, their rules. Forty minutes a day, for years.
They know a script could do this. But they're not programmers, and hiring one means explaining, negotiating, waiting — so it stays on the "later" pile forever. AI coding tools don't help either: they're not going to install a CLI, manage API keys, or learn what a repo is. They don't want to become technical. They want the chore gone.
We built Intern for them: vibe-coding for people who will never call it that.
What it does
You train an intern the way you'd train a real one:
- The brief. Explain the job in plain words, the way you'd explain it to someone starting on Monday. Rambling is fine.
- Questions. The intern asks a few clarifying questions.
- Read-back. It repeats the job back in plain language. You correct it or say "yes, that's the job." Nothing starts until you approve.
- Show me one you did. You upload two input files and the output you made from them by hand. That's the entire specification — your own work is the spec.
- Training. The loop runs: an LLM writes a script, executes it in a sandbox, and a deterministic scorer compares the output against yours cell by cell. Every mismatch becomes a concrete finding ("kilos where you wanted tonnes", "sort order wrong"), and the model patches the code. You watch each attempt land as a paper slip on the Ledger: 41% → 68% → 96% → 100%.
- First day. The trained intern gets its own page. Drop today's files — files it has never seen — and the correct summary comes back in under two seconds.
$20 once per intern. No subscription, no setup, no keys. We host it, we secure it, it just works — that's what the twenty dollars buys.
The core idea: the AI is the trainer, not the worker
Almost every agent product ships the LLM inside the loop forever, so every run costs tokens, adds latency, and can hallucinate on row 14. We do the opposite.
The LLM only exists at training time, as a search operator over programs. The reward signal is one the model cannot fake: cell-level F1 against the user's own hand-made example. When training converges, the model is removed. What ships is a plain deterministic Python script — instant, auditable, and it runs for cents.
A static guard enforces this: the generated artifact is scanned for any network or LLM imports and the build fails if one appears. Our trained demo intern reproduces the unseen next-day reference byte-for-byte, in either file-upload order, with 0 network calls and 0 model calls at runtime. First attempt from a strong model scored 41% — that number is why the loop has to exist, and why "just ask GPT" was never the product.
How we built it
- Loop engine (Python): codegen → sandboxed runner → cell-level scorer → repairer, with plateau/budget stops. The scorer distinguishes a totals-row bug from a column bug so the repairer patches precisely instead of rewriting working code. Live training converged 68 → 96 → 100 in 3 attempts, 53 seconds, on gpt-5.6-terra; recorded cassettes replay the exact run offline in 0.6s.
- API (FastAPI + SSE): jobs, uploads, live training events with replay — refresh mid-training and the Ledger rebuilds.
- Web (Next.js): monochrome "Carbon Copy" design system — paper, ink, hairlines, one rubber stamp. Built for a 40-year-old office worker, not for us: 15px minimum text, plain language, state in the URL so the back button never destroys work.
- 29 tests, 18+ commits, tagged milestones.
Sponsor tools (all live, with proof in SPONSORS-STATUS.md)
- Zero.xyz — the intern's hands. Our whole product is Zero's thesis pointed at a person: Zero unblocks the agent, we unblock the human, and nobody asks anyone for an API key. During training the agent hit the email-transport gap and used a real
zero searchto discover a send-mail service (logged searchId as proof). Capabilities are discovered at training time and baked into the artifact — same principle as the LLM itself. - Nexla — the intern's inbox. Files should arrive from where they already live. We created a real Nexla flow (
intern-andrei-dispatch-inbound, source 125755 / flow 634481, ACTIVE) for inbound file delivery. - Pomerium — the intern's badge. Model-written code doesn't get to roam, and users' files are their own. Pomerium fronts each intern's page; unauthenticated requests get a 302 to sign-in. We led with the threat model, not the config file.
- Akash — the intern's desk. A trained intern is a container with no GPU, no model, and no state: 0.1 CPU, pennies a day. Everyone uses Akash for inference; we use it for the absence of inference — that's why "$20 once" works as a business. The demo you're reading about is deployed on Akash right now.
Challenges we hit
The scorer had to be smarter than "diff the files" — totals-row bugs and column bugs need different findings or the repairer rewrites working code. Cassette keys leaked the job slug early on, breaking replay determinism until we hashed the frozen spec. The Akash validator rejected our compose-style depends_on, so we made the API container self-seeding. And a Linux-only sandbox rlimit would have crashed pandas on providers — caught during pre-deploy validation.
What's next
More intern types (email-in/email-out via Nexla, scheduled runs), PDF/scan inputs via Zero-discovered extraction, and one Akash deployment per intern — the SDL is already written per-intern, so scaling is "the same thing, more containers."
Built With
- akash
- claude
- nexla
- openai
- pomerium
- zero.xyz
Log in or sign up for Devpost to join the conversation.