Skip to content

About

Keep Talking and Nobody Explodes, played by agents

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

7 Commits

Folders and files

Repository files navigation

ktane-agents

Two LLM agents play Keep Talking and Nobody Explodes against each other: a defuser who can see a simulated bomb but not the manual, and an expert who has the manual but can't see the bomb. They talk to each other in plain text — no shared state, no hidden channel — exactly like the real game.


Screenshot 2026-07-31 at 12 51 53 PM Screenshot 2026-07-31 at 12 52 09 PM

This is a deliberately naive baseline, built as a teaching/starting point rather than a polished product:

  • The expert's entire system prompt is the whole manual pasted in, verbatim.
  • Currently using gemini-3.6-flash which is probably much more powerful than we need.
  • Both agents keep full, unsummarized conversation history in an in-memory session.
  • There's no RAG, no context management, no caching, no structured message protocol.

The idea is to give students/experimenters a working end-to-end system they can then improve on (retrieval over the manual, context compression, better protocols, cost/latency optimization, etc.) and measure against.

How it works

  • A Bomb (src/main/kotlin/ktane/engine) is procedurally generated with a random serial number and a set of modules, and implements the actual manual logic for each module type — the same rules a human would follow with the real manual.
  • The defuser agent (ktane.agents.Agents) only has tools: get_bomb_state, inspect_module (returns a rendered photo of a module), and one action tool per module type (cut_wire, press_keypad_button, etc. — see DefuserTools.kt). It has no manual.
  • The expert agent has the full manual text in its system prompt and a reference sheet of keypad symbols, but no tools — it can only talk.
  • GameOrchestrator relays messages back and forth (expert → defuser → expert → ...) via the Google ADK Kotlin runner, driving each turn until the bomb is defused, explodes, or a max exchange count is hit.
  • A Swing window (BombWindow) shows a live, human-readable view of the bomb as the agents play, for spectating.

Supported modules

Wires, Keypad, Who's on First, Memory, Password — implemented per the manual in src/main/resources/manual/manual.md. Battery/port/indicator-dependent rules from the real game are intentionally out of scope.

Requirements

  • JDK 17+
  • A Gemini API key (for the LLM-driven modes)

Setup

export GOOGLE_API_KEY=your-key-here   # https://aistudio.google.com/apikey

Alternatively, configure Vertex AI instead of an API key:

export GOOGLE_GENAI_USE_VERTEXAI=true
export GOOGLE_CLOUD_PROJECT=your-project
export GOOGLE_CLOUD_LOCATION=your-location

Running

Play a full game with the two LLM agents and a live bomb window:

./gradlew run

Watch a scripted perfect solver play instead (no LLMs, no API key needed — good for checking the engine/UI):

./gradlew run -Pargs="--auto"

Options

Bomb customization:
  --modules LIST     Comma-separated module list (repeats allowed) from:
                     wires, keypad, whosonfirst (wof), memory, password
                     (default: one of each of the five)
  --time N           Countdown seconds (default 600)
  --strikes N        Strikes that detonate the bomb (default 3)
  --serial STR       Fixed serial number (default: random, e.g. TR2XL7)
  --batteries N      Batteries on the casing, cosmetic (default 2)
  --seed N           Random seed for reproducible bombs
  --no-speedup       Timer does not speed up after strikes

Run modes:
  --auto             No LLMs: a scripted solver plays (engine/UI demo)
  --model NAME       Gemini model for both agents (default gemini-3.6-flash)
  --defuser-model N  Override model for the defuser only
  --expert-model N   Override model for the expert only
  --max-exchanges N  Stop after N defuser<->expert exchanges (default 200)
  --no-ui            Headless: no live bomb window
  --help             This text

Example: a harder, reproducible bomb with two Wires modules and no UI:

./gradlew run -Pargs="--modules wires,wires,memory --seed 42 --time 300 --no-ui"

Other entry points

  • RenderTest — renders one image of every module type (plus the expert's keypad reference sheet) to renders/, so you can see exactly what the defuser's photos look like without running any agents:

    ./gradlew run -PmainClass=ktane.RenderTestKt
  • StressTest — runs the scripted solver over 300 seeded bombs and checks that all of them are defused with zero strikes, as a regression check on the module rule logic:

    ./gradlew run -PmainClass=ktane.StressTestKt

Project layout

src/main/kotlin/ktane/
  Main.kt              CLI entry point
  RenderTest.kt         module image dump
  StressTest.kt         rule-correctness regression check
  agents/                LLM agents, tools, and the orchestrator
  engine/                bomb/module simulation and rules
  render/                Swing UI and module image rendering
src/main/resources/
  manual/manual.md       the defusal manual given to the expert
  symbols/                keypad symbol images

About

Keep Talking and Nobody Explodes, played by agents

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages