текстовая игра на основе llm + interrupt: README.md
This commit is contained in:
+70
-60
@@ -1,9 +1,7 @@
|
|||||||
# Interactive Text Adventure – LLM + Interrupt
|
# Text Adventure with LLM and Interrupt
|
||||||
|
|
||||||
A lightweight Python project that turns a large language model (LLM) into an interactive “choose‑your‑own‑adventure” game.
|
A lightweight “choose‑your‑own‑story” game that lets a large language model (LLM) generate the plot while the user makes decisions in real time via the console.
|
||||||
The story is generated by the LLM, then paused for user input via a console prompt (`questionary`). After the player selects an option, the graph resumes and the LLM writes a short ending based on that choice.
|
The project demonstrates how to combine **LangGraph** state management, **LangChain** for LLM calls, and **questionary** for interactive prompts.
|
||||||
|
|
||||||
> **TL;DR** – Run `python game.py`, answer the prompts, and watch the AI craft your story in real time.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -13,6 +11,8 @@ The story is generated by the LLM, then paused for user input via a console prom
|
|||||||
- [Prerequisites](#prerequisites)
|
- [Prerequisites](#prerequisites)
|
||||||
- [Installation](#installation)
|
- [Installation](#installation)
|
||||||
- [Running the Game](#running-the-game)
|
- [Running the Game](#running-the-game)
|
||||||
|
- `client.py` – Interactive CLI
|
||||||
|
- `agent.py` – Stand‑alone demo (no user input)
|
||||||
- [Example Session](#example-session)
|
- [Example Session](#example-session)
|
||||||
- [Project Structure](#project-structure)
|
- [Project Structure](#project-structure)
|
||||||
|
|
||||||
@@ -20,11 +20,16 @@ The story is generated by the LLM, then paused for user input via a console prom
|
|||||||
|
|
||||||
## What It Does
|
## What It Does
|
||||||
|
|
||||||
1. **Generate a story hook** – The LLM creates an opening paragraph and three possible actions.
|
1. **LLM generates a hook** – the opening line of an adventure.
|
||||||
2. **Pause for user input** – Using `questionary`, the script presents the options and waits for the player to choose one.
|
2. The graph pauses (`interrupt`) and presents **three options** to the player via `questionary`.
|
||||||
3. **Resume & finish** – The graph resumes, feeding the chosen option back into the LLM, which writes a short ending that reflects the decision.
|
3. Player selects an option; the choice is fed back into the LLM.
|
||||||
|
4. LLM writes a short continuation based on that choice.
|
||||||
|
5. The cycle repeats until the story ends or the user quits.
|
||||||
|
|
||||||
The whole flow is orchestrated by **LangGraph**, which manages state (`GameState`) and handles the custom `interrupt` node that triggers the human‑in‑the‑loop pause.
|
The game showcases:
|
||||||
|
- LangGraph state nodes and checkpoints
|
||||||
|
- Human‑in‑the‑loop via custom interrupt handling
|
||||||
|
- Simple CLI integration with `questionary`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -32,102 +37,107 @@ The whole flow is orchestrated by **LangGraph**, which manages state (`GameState
|
|||||||
|
|
||||||
| Component | Minimum Version | Notes |
|
| Component | Minimum Version | Notes |
|
||||||
|-----------|-----------------|-------|
|
|-----------|-----------------|-------|
|
||||||
| Python | 3.10+ | Tested on 3.12 |
|
| Python | 3.10+ | Tested on 3.11 |
|
||||||
| OpenAI API key | – | Set as `OPENAI_API_KEY` environment variable or in a `.env` file. |
|
| Ollama | – | Optional if you use a local LLM; otherwise set `OPENAI_API_KEY` for OpenAI. |
|
||||||
| LangGraph | Latest (pip install) | Handles the graph logic and checkpointing. |
|
| Qdrant | – | Not required for this demo (only used in advanced setups). |
|
||||||
| LangChain‑OpenAI | Latest | Provides the LLM wrapper (`ChatOpenAI`). |
|
|
||||||
| Questionary | Latest | For interactive console prompts. |
|
|
||||||
|
|
||||||
> **Optional** – If you want to run locally without an OpenAI key, you can replace `ChatOpenAI` with a local model (e.g., Ollama) and adjust the import accordingly.
|
**Environment variables**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# If using OpenAI
|
||||||
|
export OPENAI_API_KEY="sk-..."
|
||||||
|
|
||||||
|
# If using Ollama locally
|
||||||
|
export OLLAMA_HOST="http://localhost:11434"
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Clone the repo (or copy the files)
|
git clone https://github.com/yourname/text-adventure.git
|
||||||
git clone https://github.com/your-username/interactive-adventure.git
|
cd text-adventure
|
||||||
cd interactive-adventure
|
python -m venv .venv # optional but recommended
|
||||||
|
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
||||||
# Create a virtual environment (recommended)
|
|
||||||
python -m venv .venv
|
|
||||||
source .venv/bin/activate # On Windows: .venv\Scripts\activate
|
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
`requirements.txt` contains:
|
`requirements.txt` contains:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
langgraph>=0.1.0
|
|
||||||
langchain-openai>=0.2.0
|
langchain-openai>=0.2.0
|
||||||
|
langgraph>=0.1.0
|
||||||
questionary>=1.10.0
|
questionary>=1.10.0
|
||||||
python-dotenv>=1.0.0 # optional, for .env support
|
python-dotenv>=1.0.0
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Running the Game
|
## Running the Game
|
||||||
|
|
||||||
The entire game is contained in a single script: `game.py`.
|
### 1. Interactive CLI (`client.py`)
|
||||||
|
|
||||||
|
Launch the game and follow on‑screen prompts.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Make sure your OpenAI key is available:
|
python client.py
|
||||||
export OPENAI_API_KEY="sk-..."
|
|
||||||
|
|
||||||
# Run the game
|
|
||||||
python game.py
|
|
||||||
```
|
```
|
||||||
|
|
||||||
If you prefer to use a `.env` file, create a file named `.env` in the project root with:
|
**What happens**
|
||||||
|
|
||||||
```dotenv
|
- The program asks for a theme (e.g., “fantasy”, “sci‑fi”).
|
||||||
OPENAI_API_KEY=sk-...
|
- LLM creates an opening hook.
|
||||||
|
- Three choices appear; pick one.
|
||||||
|
- LLM writes a short continuation.
|
||||||
|
- Repeat until you type `quit` or the story ends.
|
||||||
|
|
||||||
|
### 2. Stand‑alone Demo (`agent.py`)
|
||||||
|
|
||||||
|
Runs the same logic but without user interaction – useful for quick tests or automated runs.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python agent.py
|
||||||
```
|
```
|
||||||
|
|
||||||
The script will automatically load it via `python-dotenv`.
|
It will automatically generate a theme, hook, and options, then print the final story to stdout.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Example Session
|
## Example Session
|
||||||
|
|
||||||
Below is a typical console interaction. The AI generates an opening and three actions; you pick one; the AI finishes.
|
```text
|
||||||
|
$ python client.py
|
||||||
|
Enter a theme (or press Enter for random): mystery
|
||||||
|
|
||||||
```
|
LLM Hook:
|
||||||
$ python game.py
|
"In the dim glow of the lantern, Detective Marlowe stared at the cryptic note left on the desk..."
|
||||||
Welcome to the Interactive Adventure!
|
|
||||||
|
|
||||||
[Story Hook]
|
Choose an action:
|
||||||
You find yourself in a dimly lit cavern, the air thick with damp stone. A faint glow emanates from a crystal embedded in the wall.
|
1. Inspect the note closely.
|
||||||
|
2. Call the forensic team.
|
||||||
|
3. Leave the office and investigate the alley.
|
||||||
|
|
||||||
Choose your action:
|
> 1
|
||||||
1) Inspect the crystal closely.
|
|
||||||
2) Search for an exit.
|
|
||||||
3) Call out to see if anyone is nearby.
|
|
||||||
|
|
||||||
Your choice: 1
|
LLM Continuation:
|
||||||
|
"She unfolded the brittle paper, revealing a series of numbers that seemed to map out the city’s underground tunnels..."
|
||||||
[Ending]
|
|
||||||
You reach out and touch the crystal. It hums, releasing a burst of light that reveals a hidden passage behind the stone wall. The adventure continues...
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Feel free to experiment with different choices – each run will produce a unique narrative!
|
The game continues until you decide to quit or the story naturally concludes.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
```text
|
```text
|
||||||
interactive-adventure/
|
.
|
||||||
├── game.py # Main script containing LangGraph logic
|
├── agent.py # Non‑interactive demo
|
||||||
├── requirements.txt
|
├── client.py # Interactive CLI with questionary
|
||||||
└── README.md
|
├── requirements.txt # Dependencies
|
||||||
|
└── README.md # This file
|
||||||
```
|
```
|
||||||
|
|
||||||
- **`game.py`** – Defines `GameState`, the graph nodes (`generate_story`, `interrupt_node`, `finish_ending`), and runs the loop.
|
Feel free to tweak `agent.py` or `client.py` to experiment with different LLM prompts, themes, or interrupt handling strategies.
|
||||||
- **`requirements.txt`** – Lists all Python dependencies.
|
|
||||||
|
|
||||||
---
|
Happy adventuring!
|
||||||
|
|
||||||
Happy adventuring! 🚀
|
|
||||||
Reference in New Issue
Block a user