Skip to main content

BlindPath: An LLM-Navigation Benchmark for Partial-Observation Grid Worlds

Project description

BlindPath ๐Ÿ—บ๏ธ

An LLM-Navigation Benchmark for Partial-Observation Grid Worlds

BlindPath tests whether LLM agents can navigate a 2D grid world under partial observability โ€” a key challenge in real game AI that most existing benchmarks ignore.


Key Distinctions

Property BlindPath Typical Benchmarks
Targets Game AI agents General reasoning
Observability Partial (vision window) Full global state
Input format Non-rigid (hybrid prompting) Fixed natural language
Task complexity Long-horizon planning Short single-step

Benchmark Metrics

Metric Formula Measures
Success Rate Successes / Episodes ร— 100% Task completion
Optimal Rate OptimalPathLen / LegalActions ร— 100% Navigation efficiency
Feasible Rate LegalActions / TotalActions ร— 100% Spatial rule adherence
Compliance Ratio TotalActions / Iterations ร— 100% Output format compliance
Exploration Ratio SeenTiles / AccessibleVisionTiles ร— 100% Coverage

Installation

pip install -e .

Or install dependencies directly:

pip install anthropic numpy

Quick Start

from blindpath import BlindPathEnv, EnvConfig, RandomAgent, Session

config = EnvConfig(
    seed=42,
    env_size=(20, 20),
    num_goals=1,
    obstacle_count=20,
    vision_size=7,       # agent sees a 7ร—7 window around itself
)

agent = RandomAgent(seed=42)
session = Session(agent, config, verbose=True)

# Single episode
metrics = session.run()
print(metrics.summary())

# Multi-episode benchmark
results = session.run_benchmark(num_episodes=20, base_seed=42)
print(results.summary())

Hybrid Prompting Architecture

Developers supply a custom_prompt that is combined with BlindPath's pre-defined static rules before being fed to the LLM. This gives full flexibility over how state information is presented:

from blindpath import LLMAgent, Session, BlindPathEnv, StepResult

class MyAgent(LLMAgent):
    def _prompt(self, prompt: str) -> str:
        # Example: call your LLM's API here
        # return my_llm_client.generate(prompt)
        return '{"action": "Up"}'

def my_prompt(env: BlindPathEnv, result: StepResult) -> str:
    pos = result.agent_position
    return (
        f"You are at column {pos.x}, row {pos.y}. "
        f"Goals remaining: {result.goals_remaining}. "
        "Move towards any visible 'G' tile."
    )

agent = MyAgent(prompt_builder=my_prompt)
session = Session(agent, config)

Action Space

{"action": "Up"}
Action Effect
"Up" Move agent by (0, -1)
"Down" Move agent by (0, +1)
"Left" Move agent by (-1, 0)
"Right" Move agent by (+1, 0)

Grid Labels

Symbol Meaning
A Agent
E Empty
O Obstacle (impassable)
G Goal
B Boundary (edge of map)

Hyperparameters

Parameter Type Default Notes
seed int | None None Falls back to system time; ensures reproducibility when set
env_size (int, int) (40, 40) Minimum 5ร—5
num_goals int 1 โ‰ฅ1
obstacle_count int 0 Number of obstacles
vision_size int 11 Must be odd; โ‰ฅ3

Each episode uses a unique, procedurally generated map. When running a benchmark with run_benchmark(num_episodes=N, base_seed=S), each episode receives seed = base_seed + i, producing a different grid layout every time while keeping the full run reproducible.


Running the Baselines

# Random agent (10 episodes)
python experiments/run_random.py --episodes 10 --seed 42

# POMCP agent (5 episodes)
python experiments/run_pomcp.py --episodes 5 --sims 300

# LLM agent (1 episode)
export ANTHROPIC_API_KEY="sk-ant-..."
python experiments/run_llm.py --model claude-haiku-4-5 --verbose

Project Structure

blindpath/
โ”œโ”€โ”€ Constants/
โ”‚   โ”œโ”€โ”€ env.py        # Default/minimum config values
โ”‚   โ””โ”€โ”€ tiles.py      # Tile label constants (A, E, O, G, B)
โ”œโ”€โ”€ DataClasses/
โ”‚   โ”œโ”€โ”€ env_config.py  # EnvConfig dataclass
โ”‚   โ”œโ”€โ”€ generated_map.py # GeneratedMap dataclass
โ”‚   โ”œโ”€โ”€ step_result.py # StepResult dataclass
โ”‚   โ””โ”€โ”€ vector2.py     # Vector2 dataclass
โ”œโ”€โ”€ Util/
โ”‚   โ”œโ”€โ”€ astar.py       # A* pathfinding
โ”‚   โ””โ”€โ”€ grid_formatting.py # grid_to_ascii()
โ”œโ”€โ”€ core/
โ”‚   โ”œโ”€โ”€ grid.py           # Grid class
โ”‚   โ”œโ”€โ”€ map_generation.py # Procedural map generation
โ”‚   โ””โ”€โ”€ env.py            # BlindPathEnv
โ”œโ”€โ”€ agents/
โ”‚   โ”œโ”€โ”€ base.py           # BaseAgent abstract class
โ”‚   โ”œโ”€โ”€ random_agent.py
โ”‚   โ”œโ”€โ”€ pomcp_agent.py
โ”‚   โ””โ”€โ”€ llm_agent.py
โ”œโ”€โ”€ eval/
โ”‚   โ”œโ”€โ”€ episode_metrics.py # EpisodeMetrics dataclass
โ”‚   โ””โ”€โ”€ benchmark_results.py # BenchmarkResults dataclass
โ””โ”€โ”€ session.py            # Session lifecycle + run_benchmark()
experiments/
โ”œโ”€โ”€ arguments.py  # Shared CLI argument parsing
โ”œโ”€โ”€ run_random.py
โ”œโ”€โ”€ run_pomcp.py
โ””โ”€โ”€ run_llm.py

Baselines

  • Random Agent โ€” Uniform random action selection. Lower bound.
  • POMCP Agent โ€” Partially Observable Monte-Carlo Planning with particle filters. Traditional method baseline for partial-info navigation.
  • LLM Agent โ€” Claude via the Anthropic API. The primary evaluation target.

Iteration Limit

max_iterations = OptimalPathLength ร— (full_area / vision_area) ร— 3

Scales to allow for back-tracking proportional to how blind the agent is.


Related Work

  • PPLN โ€” Similar task, no partial observability
  • GWSOT โ€” Spatial awareness probing, full state
  • GameTraversalBenchmark โ€” 2D navigation, global state
  • GridRoute โ€” Prompt engineering for pathfinding

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

blindpath-0.1.0.tar.gz (27.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

blindpath-0.1.0-py3-none-any.whl (32.9 kB view details)

Uploaded Python 3

File details

Details for the file blindpath-0.1.0.tar.gz.

File metadata

  • Download URL: blindpath-0.1.0.tar.gz
  • Upload date:
  • Size: 27.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.5

File hashes

Hashes for blindpath-0.1.0.tar.gz
Algorithm Hash digest
SHA256 21f36dbcd4510c60091d56eb10bed8f4b9f6da342edc8d57094072ebfe7d79f2
MD5 d8f8df26ee39a3a5888696ec90118d83
BLAKE2b-256 de3f8279ac67b1381792656ac2aa76903b986dc99fa11b3f29fd443d13f08e5e

See more details on using hashes here.

File details

Details for the file blindpath-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: blindpath-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 32.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.5

File hashes

Hashes for blindpath-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 54cd898fe6428fd590ce0d945837399f39971010ffcb8c4ce7014fe78b02b81f
MD5 c5398b144c2cb47bca5389485a70d868
BLAKE2b-256 c7003ab4d1a94f877b6f70c872f088196389c1d079daf8b8f6d6d6d2ba3e1e32

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page