Inspiration
I wanted to get better at debating and realised there's basically nowhere to practise. You need another person who's willing to argue with you properly, and then you need someone to tell you who won and why. If you weren't in a debate club at school, you never get that.
There are AI debate apps already. I tried them. They're text chatbots, and the reviews all say the same thing: the AI doesn't listen. It either agrees with you the second you push back or it just repeats itself forever. I don't think that's a prompting problem. If one model is arguing a side and also deciding whether you beat it, it's marking its own homework. Of course it's dishonest.
How do you make an AI opponent that argues honestly?
What it does
You pick a motion, pick a side, and argue it out loud against an AI character. Actual speech, timed rounds, like a real debate. The opponents have their own styles. Socrates just asks questions until you contradict yourself. Cleopatra reframes everything. Santa Claus argues from pure emotion and it's genuinely hard to rebut him without sounding like a monster.
Three separate GPT-5.6 agents:
- The debater argues in character. Its difficulty adjusts to how well you're doing.
- The referee is invisible. It scores every turn you take: did you answer their last point, was it new or a repeat, did you use a fallacy, did you actually damage one of their claims. The opponent is only allowed to concede a point when the referee says you won it. Every concession gets written to a ledger with the ruling that caused it.
- The judge reads everything at the end and decides the match as argued, clash by clash. It quotes your actual words back at you. Best moment, worst moment, what you should have said instead, one thing to practise.
When you finish there's a rematch button that flips you onto the other side of the same motion. Arguing the side you just beat is the best exercise in debating, so I made it the biggest button on the screen. You can also download the whole transcript as markdown.
How we built it
The build ran on Codex prompts. I worked in phases: write a spec, have Codex propose its design before touching code, push back on the design, then build. The architecture decisions below came out of that back-and-forth, and they're the interesting part.
Three agents, strict separation. The debater, referee, and judge are separate GPT-5.6 calls with separate prompts, and the debater never sees the referee's instructions, scores, or reasoning. It only receives the current claim state and a difficulty number. That wall is the whole honesty mechanism. The moment one model can see how it's being judged, or judges itself, you're back to an opponent that folds to be agreeable.
Different model tiers for different jobs. The debater runs on gpt-5.6-terra with reasoning effort off, because a 100-word spoken turn needs speed, not deliberation, and its cleverness comes from the persona prompt and match state anyway. The referee also runs on terra since it outputs structured JSON, not prose. The judge runs on gpt-5.6-terra with reasoning on, because it runs once, at the end, when nobody is waiting and depth actually matters. All of it is per-agent env config, so each one stays independently tunable.
The referee runs concurrently, one turn behind. Scoring every user turn with a second model call would normally double the response latency. Instead the referee fires at the same time as the debater, and its ruling shapes the next opponent turn. Nobody notices a one-turn calibration lag. The single exception is the opponent's closing, where the engine deliberately waits for the final ruling, because if you won a point in your last rebuttal and the closing ignored it, that's the exact "not listening" failure this app exists to kill, at the worst possible moment.
Trust details. Speech to text is gpt-4o-transcribe, voices are gpt-4o-mini-tts with per-persona delivery directions. Every state-driving output is schema validated with a retry. The judge's quotes are checked as exact substrings of what you actually said, because models paraphrase when they quote, and coaching built on a quote that isn't quite yours ruins the entire effect.
Challenges we ran into
The audio started making loud scratching noises halfway through the build. Codex traced it to a single byte. Network reads were being forwarded as-is, and when a read had an odd byte count, the client dropped the extra byte, which shifted every 16-bit sample after it. Fix was to carry the stray byte on the server and only emit aligned chunks. There's now a test that corrupts the audio on purpose and proves the stream recovers. Favourite bug of the project.
The referee also drifted too harsh after I tightened its fallacy detection. Strong arguments stopped registering, which silently made the game unwinnable. Fixed it with anchored score rubrics and two fixture debates that live in the test suite: one argued well, one argued terribly on purpose. The good one has to damage claims. The bad one has to get nothing.
Then I gave it to two friends. One of them got caught reading the opponent's transcript while their prep timer quietly ran out, and had five seconds left when they looked up. So I changed the rule: the clock doesn't start until you claim the floor. Prep ends with a "take the floor" prompt that waits for you, and there's a live mic meter so you can see it's hearing you. No test suite would have found that.
Accomplishments that we're proud of
A spoken debate that actually feels live. First benchmark said 6.4 seconds before the opponent even started thinking. Shipped version: real audio in about 2.1, and the gap that's left plays as the opponent deliberating. Getting from "dead on arrival" to "feels like a person taking a breath" is the thing I'd show first.
What's next for Riposte
The three-agent engine is all server-side, so new formats are mostly new prompts. Moot court, where the persona sits on the bench and interrupts you mid-argument. Language practice, where holding your own in a spoken argument is the actual fluency test. Teacher tools on top of the transcripts and scores that already exist. Different formats, same referee underneath.
Log in or sign up for Devpost to join the conversation.