AWS Builder Center
Teaching a Rubber Duck to Debug by Only Asking Questions

Teaching a Rubber Duck to Debug by Only Asking Questions

A debugging companion that uses only Socratic questions-never gives answers first-with a reveal button after 5 questions.

Last Thursday at midnight, I was stuck on a bug in my React code. The component kept re-rendering infinitely. I'd been staring at it for an hour, trying console.log statements, checking dependencies, rewriting the useEffect. Nothing worked.
Then I started talking to my actual rubber duck-the yellow one on my desk. "Why is this re-rendering?" Out loud. To a plastic duck. And somehow, by the third question I asked myself, I realized the bug: I was setting state inside the render function. Obvious in hindsight. Invisible when you're stuck.
That's the power of rubber duck debugging. But real ducks don't talk back. They don't ask you the right questions. They just sit there judging you silently.
What if the duck could ask questions back?

What and Who

Bug Duck is a debugging assistant that never gives you the answer. It only asks Socratic questions to guide you to the solution yourself.
You describe your bug. The duck asks: "What did you expect to happen?" You answer. It asks: "What actually happened?" You answer. It asks: "What changed right before it broke?"
After 5 questions, a "Reveal Answer" button appears. If you still haven't figured it out, the duck will finally tell you. But most of the time, you solve it before hitting that button-because the right questions force you to think differently.
I built this for developers who get stuck and immediately ask ChatGPT for the answer. That gives them the fix, but they don't learn how to debug. They don't build the muscle of working through problems systematically.
The duck teaches you to ask the right questions. Next time you're stuck, you won't need the duck. You'll ask yourself.

How I Built It

The stack:
  • Frontend: Static HTML/CSS/JavaScript on S3, served through CloudFront
  • Backend: Python Lambda with Function URL
  • AI: Amazon Bedrock Converse API with Claude Haiku 4.5 (us.anthropic.claude-haiku-4-5-20251001-v1:0)
  • Infrastructure: AWS CDK (TypeScript)
The flow:
  1. User describes their bug in the chat interface
  2. Frontend sends message + conversation history to Lambda
  3. Lambda tracks question count and sends a strict "questions-only" system prompt to Bedrock
  4. Claude responds with a Socratic question (never a direct answer)
  5. After 5 questions, frontend shows the "Reveal Answer" button
  6. If clicked, a special override message tells Claude it can now give solutions

The System Prompt

The entire behavior hinges on this system prompt:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
system_prompt = """You are a debugging rubber duck. NEVER give direct answers or solutions. Only ask clarifying Socratic questions to help the developer think through the problem.

Examples of good questions:
- "What did you expect to happen?"
- "What actually happened?"
- "What have you tried so far?"
- "What does that error message tell you?"
- "What happens if you comment out that line?"
- "Where does that variable get its value?"
- "What changed right before it broke?"

Keep questions short and targeted. Use duck personality: warm, patient, slightly silly. Add "🦆" occasionally.

IMPORTANT: Never suggest solutions, never give code, never explain what's wrong. Only ask questions that guide them to discover the answer themselves."""
The hardest part was tuning this to be strict. Claude is helpful by nature-it wants to solve your problems. Getting it to withhold answers and only ask questions took multiple iterations.

The Hard Part: Counting Questions Without Breaking Context

This was harder than I expected. I needed to:
  1. Track how many questions the duck has asked
  2. Maintain conversation history so the duck remembers what was already discussed
  3. Show the reveal button at exactly 5 questions
  4. Allow the duck to give answers only after reveal is clicked
The solution: every message includes the full conversation history, and the Lambda counts questions by looking for ? characters in assistant messages. When the frontend sees question_count >= 5, it shows the reveal button.
When clicked, the reveal button sends a special override message:
1
"The user is asking for a direct answer. You can now provide a helpful suggestion or solution instead of asking more questions."
This tells Claude to break character and actually help. It's a clean separation: 5 questions of Socratic guidance, then optional direct help if you're still stuck.

The Delightful Detail: The Five-Question Limit

The 5-question limit is not arbitrary-it's based on how real debugging works.
When I tested Bug Duck with 4 deliberately introduced bugs in my own code:
  1. React infinite re-render - Solved after question 3 ("Where does that state change happen?")
  2. Python KeyError - Solved after question 4 ("What does the error message tell you?")
  3. JavaScript undefined variable - Solved after question 2 ("Where does that variable get its value?")
  4. SQL query returning empty - Needed reveal button (I'd misunderstood the schema)
3 out of 4 bugs solved before hitting the reveal button. That's the sweet spot. If the limit were 10 questions, you'd give up. If it were 2, you wouldn't have time to think. Five is enough to guide you without feeling endless.
There's also a small "quack celebration" 🦆 that appears each time the duck asks a new question. It's silly, but it makes the interaction feel playful instead of frustrating. Debugging is stressful. A cartoon duck quacking at you helps.

Proof It Works

Test It Yourself

Try this: "My Python script throws a KeyError when I try to access user data from a dictionary."
The duck will ask:
  • "What did you expect to happen when you accessed that key?"
  • "What does the KeyError message tell you?"
  • "How are you building that dictionary?"
  • "What happens if you print the dictionary right before accessing it?"
By question 3 or 4, you'll probably realize: you're using the wrong key name, or the data isn't in the dictionary at all.

What I Measured

  • Latency: 1.5-2.5 seconds per question (Haiku is fast)
  • Token usage: 200-350 tokens per response (questions are shorter than explanations)
  • Cost per conversation: ~$0.0003 for a full 5-question + reveal session
  • Solved without reveal button: 3 out of 4 bugs in my own testing

What I'd Do Next

Right now, it's a single-conversation chatbot. Next steps:
  1. Save conversation history - Let users bookmark debugging sessions so they can come back later or share with teammates
  2. Code snippet highlighting - If you paste code, the duck could ask "What happens if you change line 5?" and highlight that line
  3. Domain-specific ducks - A "SQL Duck" that asks database-specific questions, a "React Duck" that knows about hooks and state
  4. Voice input - Talking out loud to a duck is part of the ritual. Add speech-to-text so you can literally talk to it
  5. Analytics dashboard - Track which types of questions lead to solutions fastest, refine the Socratic prompts

What I Learned

This was my first time:
  • Writing a system prompt that withholds information (harder than writing one that provides information)
  • Tracking conversation state across multiple API calls without a database (everything lives in the frontend)
  • Making an AI agent that teaches instead of solves
The biggest lesson: Constraints make better teachers. By forcing the duck to only ask questions, it forces the user to think. If I'd let the duck give hints or partial answers, users would just wait for the full solution. The strict "questions only" rule is what makes this work.

Try It

If you're stuck on a bug and about to Google the answer, try Bug Duck first: https://d2io1147h8dx3t.cloudfront.net 
Talk to the duck. Answer its questions. You might solve the bug yourself before the duck tells you. And next time, you won't need the duck at all.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article