Skip to main content

XiangqiBench

Paper PyPI Python CI License: MIT

Paper | Data card | Changelog | Citation

This repository contains the official implementation of Finding the Move Is Not Winning the Game: XiangqiBench for Closed-Loop Evaluation of LLM Agents.

XiangqiBench asks an LLM agent to convert 119 composed xiangqi (Chinese chess) endgames into checkmate against a Pikafish defender. The agent acts through a small command protocol under per-turn budgets and is scored only on whether it actually delivers mate: finding the right first move is not enough.

Installation

pip install xiangqibench                  # OpenAI-compatible and Azure endpoints
pip install "xiangqibench[anthropic]"     # adds the native Anthropic client

XiangqiBench requires Python 3.10 or later and a Pikafish binary for the defender:

git clone https://github.com/official-pikafish/Pikafish && make -C Pikafish/src -j build
export PIKAFISH_PATH=$PWD/Pikafish/src/pikafish
xiangqibench doctor                       # checks the engine and prints its build and NNUE hash

The paper's defender was Pikafish fd168f68 with the network whose sha256 begins a2f41d4d, searched to depth 18 with one thread and a 256 MB hash. Upstream has since replaced that network, and older builds cannot load the new one, so build the current Pikafish as shown above. Its moves can differ from the paper's defender. Every record stores the engine build and the network hash.

Usage

export OPENAI_API_KEY=...
xiangqibench run --model gpt-5.5 --mode sighted --limit 5
xiangqibench score runs/

Full runs are configured with a single YAML file; xiangqibench init writes a commented example. API keys are read from the environment, never from the file.

mode: restricted                # sighted | restricted
model:
  name: qwen3-235b
  provider: openai              # openai | azure | openai-responses | anthropic
  base_url: http://localhost:8000/v1
  api_key_env: VLLM_API_KEY
run:
  trials: 3
  workers: 8
xiangqibench run -c my_run.yaml           # resumable: re-running fills in missing trials

Command-line flags override the file, and unknown keys are rejected.

Modes

Mode Observation Tools
sighted Board, FEN, and legal moves after every ply view_board, simulate, get_legal_moves
restricted Starting position once, then move diffs only none

xiangqibench prompt --mode <mode> prints the exact system prompt. The paper's observation ablation adds four modes that toggle the per-ply board state and the query tools independently; xiangqibench modes lists them, and the data card describes their case splits.

Scoring

xiangqibench score reports pass@k and pass^k over the earliest three scored trials per (model, mode, case), with 95% case-bootstrap intervals using the paper's seeds. Trials cut short by infrastructure errors are excluded and re-run automatically. Runs that change the standard budgets or defender settings are marked standard: false.

Python API

from xiangqibench import load_config
from xiangqibench.runner import run_suite

report = run_suite(load_config("my_run.yaml"))

Any object with a name attribute and a complete(messages) -> Completion method can be evaluated as an agent; see xiangqibench.runner.play_trial.

Reproducibility

Every trial is stored as one JSON record with the full message history, the move list, the resolved configuration, and the defender's identity, including which backend chose each defender move. The test suite replays archived trials from the paper against this code and checks every environment message and verdict (xiangqibench.replay). Known differences from the code that produced the paper's archive are listed in the changelog.

pip install -e ".[dev]" && pytest

Citation

@misc{chai2026xiangqibench,
  title         = {Finding the Move Is Not Winning the Game: {XiangqiBench} for Closed-Loop
                   Evaluation of {LLM} Agents},
  author        = {Yekun Chai and Qiwei Peng and Haoyi Xiong},
  year          = {2026},
  eprint        = {2610.02425},
  archivePrefix = {arXiv},
  primaryClass  = {cs.CL},
  url           = {https://arxiv.org/abs/2610.02425}
}

License

The code is released under the MIT License. The historical positions are in the public domain. Pikafish is licensed under GPL-3.0; it is not distributed with this package and runs as a separate process.

Metadata

Release files for xiangqibench 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for xiangqibench 0.1.1
File Size Uploaded
xiangqibench-0.1.1.tar.gz 179.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for xiangqibench 0.1.1
File Interpreter ABI Platform
xiangqibench-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 258.8 kB

Release files / xiangqibench-0.1.1.tar.gz

Download URL xiangqibench-0.1.1.tar.gz
Size 179.6 kB
Tags Source
SHA-256 checksum
How to use checksums
09c5b1ca0e9d3df4fc6e0cd60eb29bc60ce7c4a42a27b69d8dbdf2cc00336eb7
BLAKE2b-256 checksum
How to use checksums
8f53683354a4faa58bc1434c1ce9755b50bc537dccab26c11e61d7436bd888ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.

Transparency log

Release files / xiangqibench-0.1.1-py3-none-any.whl

Download URL xiangqibench-0.1.1-py3-none-any.whl
Size 79.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9004c2d09048123edd48d2ded8133e6273a20af83ce5d25bce819c9434b2f282
BLAKE2b-256 checksum
How to use checksums
709e1662061b74cc05de50aa31577d6eee8f5dbf32f8d6b29d88b06ec3a614ee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page