Skip to main content

SportAgent: Multi-Agent LLM framework for Kalshi sports markets

Project description

SportAgent: Multi-Agent LLM Sports Prediction Framework


News

  • [2026-06] SportAgent v0.2.0 — Distribution + LLM auth: new sportagent update command + automatic update notices; run without an API key via the new Claude Code CLI proxy (claude) or Codex CLI proxy (codex) — sportagent setup auto-detects installed CLIs and asks provider × auth method; GitHub Actions CI (test matrix, PyPI publish on tag, macOS/Windows binaries).
  • [2026-06] SportAgent v0.1.3 — Real quantitative Stats Analyst tools: get_four_factors (eFG%, turnover rate, OREB rate, FT-rate) and get_elo_winprob (deterministic Elo prior with home-court/MoV/playoff K) ground the debate in real box-score signals; fixed the Trader probability-parse bug and a Four-Factors small-sample bug.
  • [2026-06] SportAgent v0.1.2 — Stability + UX fixes: fixed a live-run crash that aborted runs mid-pipeline, final reports now render Markdown properly, added per-run logging to ~/.sportagent/logs/ (with per-agent timings + tracebacks), and the live UI now shows "deep reasoning…" / "still working…" hints so long deep-model steps read as working, not stuck.
  • [2026-06] SportAgent v0.1.1 — Kalshi data-correctness fixes: market prices now read the live *_dollars fields, and game-winner markets resolve to the exact game date you select (no more stale/expired tickers). Default Kalshi environment switched to prod (read-only) for real market prices.
  • [2026-06] SportAgent v0.1.0 — First public release. Winner-first NBA predictions, a schedule-driven game-picker wizard, a live streaming UI, and saved Markdown reports.

⚠️ SportAgent is designed for research and educational purposes. Predictions are probabilistic and depend on the chosen models, model temperature, data quality, and other non-deterministic factors. v1 is read-only — it never places orders. This is not financial, investment, or betting advice.

SportAgent Framework

SportAgent is a multi-agent prediction framework that mirrors the dynamics of a real sports analysis desk. By deploying specialized LLM-powered agents — from an odds analyst, a stats analyst, a news/injury analyst, and a sentiment expert, to a bull/bear research debate, a trader, and a risk-management committee — the platform collaboratively evaluates a game and produces an explainable, winner-first prediction:

🏀 PREDICTION: New York Knicks win — 64% (San Antonio Spurs 36%)

The system cross-checks the Kalshi sports-market contract price (the market-implied probability) against a de-vigged sportsbook consensus, treats that verified snapshot as the source of truth for exact prices, and then reasons about the edge between the market and its own estimate. All quantitative math (implied probability, vig removal, edge, Kelly sizing, Brier calibration) is deterministic — never left to the language model.

The framework is sport-agnostic at its core (core/), with each sport added as a self-contained adapter under sports/<sport>/. NBA ships first.

Our framework decomposes the prediction task into specialized roles.

Analyst Team

  • Odds Analyst — Reads the verified-odds snapshot (Kalshi contract price vs. de-vigged sportsbook consensus), flags any mispricing, and establishes the market-implied probability.
  • Stats Analyst — Evaluates team strength: season record, recent form, head-to-head history, and rest / back-to-back status, weighing the factors a desk would price in.
  • News / Injury Analyst — Monitors injury reports, lineup changes, and late-breaking availability news that can swing a game's win probability.
  • Sentiment Analyst — Aggregates public and community chatter (Reddit / sportsbook discussion) into a single sentiment read, watching for contrarian signals where heavy public money on one side flags value on the other.

Research Team

  • Comprises a Bull and a Bear researcher who critically assess the analysts' findings. Through a structured debate, they weigh the case for and against the favored team, and a Research Manager (deep-think model) synthesizes the debate into a committed probability estimate.

Trader

  • Converts the research thesis into a concrete position, using the deterministic probability/Kelly helpers to size a (hypothetical) stake against the verified market price.

Risk Management and Decision Manager

  • A risk committee of Aggressive, Neutral, and Conservative voices debates the position from every angle.
  • The Decision Manager (deep-think model) renders the final, winner-first call: which team wins, the win probability, a confidence level, and plain-language reasoning — with the betting view (BUY YES / BUY NO / HOLD, edge, suggested stake) retained as an optional secondary section.

Installation and CLI

Installation

Clone SportAgent:

git clone https://github.com/Paul-le-cimanova/SportAgent.git
cd SportAgent

Create a virtual environment in any environment manager you like:

conda create -n sportagent python=3.13
conda activate sportagent

Install the package and its dependencies (this also installs the sportagent command):

pip install -e .

Configure your keys

sportagent setup          # interactive wizard → writes .env
sportagent doctor --live  # verify keys + live API pings

You'll need:

Key Required What it's for Get it
ANTHROPIC_API_KEY LLM (default: Claude) https://console.anthropic.com
KALSHI_ACCESS_KEY_ID + KALSHI_PRIVATE_KEY_PATH Kalshi market prices (read-only) https://kalshi.com/account/profile
THE_ODDS_API_KEY Sportsbook consensus odds (free tier) https://the-odds-api.com
BALLDONTLIE_API_KEY NBA team stats / schedule https://app.balldontlie.io
OPENWEB_NINJA_API_KEY optional Injury / lineup news https://www.openwebninja.com
OPENAI_API_KEY optional If you prefer GPT models https://platform.openai.com

Keys live in a gitignored .env. Never commit your .env or your Kalshi .pem. Kalshi defaults to prod (KALSHI_ENV=prod) because v1 is read-only and prod gives real market prices; set KALSHI_ENV=demo for the sandbox.

Alternatively, copy .env.example to .env and fill in your keys:

cp .env.example .env

CLI Usage

Launch the interactive wizard:

sportagent               # bare command → game-picker wizard
python -m sportagent.cli # alternative: run directly from source

The wizard is schedule-driven — you never type team names. You'll pick a sport, then a date (Today / Tomorrow / Upcoming 7 days / a specific future date), then a real game from that day's schedule, then research depth and models. SportAgent then streams the multi-agent run live and saves a full report.

For power users, the one-liner skips the wizard:

sportagent analyze "Knicks @ Spurs" --game-date 2026-06-05

Flags: --game-date YYYY-MM-DD, --sport, --kalshi-env demo|prod, --deep-llm, --quick-llm, --live/--no-live, --save/--no-save.

Reports

Each run is saved to ~/.sportagent/results/<matchup>/<date>/:

  • complete_report.md — the winner headline plus every section
  • per-section Markdown (odds / stats / news / sentiment / research / trader / decision)
  • full_state.json — the raw final pipeline state

SportAgent Package

Implementation Details

SportAgent is built on LangGraph for flexibility and modularity. A StateGraph runs the analyst → research → trader → risk → decision pipeline over a shared game state. Two LLM tiers are used: a deep model for the Research and Decision Managers, and a quick model for everyone else. It currently supports Anthropic (Claude) and OpenAI (GPT) providers.

Every data fetcher fails open — a dead or rate-limited source returns a clear placeholder string rather than crashing the run.

Python Usage

To use SportAgent inside your code, import the package and initialize a SportAgentGraph(). The .analyze() method returns (final_state, recommendation):

from sportagent.core.graph.sport_graph import SportAgentGraph
from sportagent.default_config import DEFAULT_CONFIG

graph = SportAgentGraph(config=DEFAULT_CONFIG.copy(), debug=True)

state, recommendation = graph.analyze("Knicks @ Spurs", game_date="2026-06-05")
print(recommendation)

You can adjust the default configuration to set your own models, debate depth, and more:

from sportagent.core.graph.sport_graph import SportAgentGraph
from sportagent.default_config import DEFAULT_CONFIG

config = DEFAULT_CONFIG.copy()
config["llm_provider"] = "anthropic"                       # "anthropic" or "openai"
config["deep_think_llm"] = "claude-opus-4-8"               # managers
config["quick_think_llm"] = "claude-haiku-4-5-20251001"    # analysts / researchers / trader / risk
config["max_debate_rounds"] = 2
config["max_risk_rounds"] = 2

graph = SportAgentGraph(config=config)
state, recommendation = graph.analyze("Knicks @ Spurs", game_date="2026-06-05")
print(recommendation)

See sportagent/default_config.py for all configuration options.

Persistence and Memory

SportAgent keeps an append-only decision log at ~/.sportagent/memory/sport_memory.md. Each completed run records its prediction. Before a later run, SportAgent resolves any prior settled games (fetching the final Kalshi result), scores its earlier call with a Brier calibration, writes a short reflection, and injects the most recent same-matchup lessons plus a few cross-game lessons into the Decision Manager's prompt — so each analysis carries forward what worked and what didn't.

Override the path with SPORTAGENT_MEMORY_LOG_PATH.

Reproducibility

SportAgent is LLM-driven, so two runs of the same game can differ. This is expected for a tool built on language models, not a defect, and the variation comes from a few distinct sources.

Language-model sampling is non-deterministic: even at a fixed temperature, providers do not guarantee byte-identical output, and reasoning models vary the most. Live data also moves — injury news, sentiment, and odds shift as a game approaches, so a run today sees different inputs than a run yesterday.

What does not vary: the game identity is resolved deterministically before any agent runs, and a verified-odds snapshot grounds every exact price claim, so the analysts cannot fabricate a different matchup or invent prices. All quantitative math is deterministic.

To reduce variation, lower the sampling temperature (set temperature in your config or SPORTAGENT_TEMPERATURE in .env) and pair it with a non-reasoning model.

Multi-sport

The core is sport-agnostic; sports are added as adapters under sportagent/sports/<sport>/. NBA ships first. NFL / MLB / soccer are scaffolded — soccer needs 3-way win/draw/loss handling, already modeled in MarketRef.outcome_structure.

Development

pip install -e ".[dev]"
pytest

Contributing

Contributions are welcome — bug fixes, documentation, new sport adapters, and feature ideas.

License

MIT

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

sportagent-0.3.0.tar.gz (126.3 kB view details)

Uploaded Source

Built Distribution

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

sportagent-0.3.0-py3-none-any.whl (144.8 kB view details)

Uploaded Python 3

File details

Details for the file sportagent-0.3.0.tar.gz.

File metadata

  • Download URL: sportagent-0.3.0.tar.gz
  • Upload date:
  • Size: 126.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sportagent-0.3.0.tar.gz
Algorithm Hash digest
SHA256 39504c4a9f0af3b6d92d71c363d5efde0c28fcb546e47f9cf951fa16874ecbce
MD5 e519754ebfd181d5854bb671b8eacf77
BLAKE2b-256 7664cb68ed6b876242d5784da84b4722f56d4e70e0d468c07e3e2698a76fda3d

See more details on using hashes here.

Provenance

The following attestation bundles were made for sportagent-0.3.0.tar.gz:

Publisher: publish.yml on Paul-le-cimanova/SportAgent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sportagent-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: sportagent-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 144.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sportagent-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d318bcdb6acf14458de6dfc4966ca91caac75af6711f385631701e4ac8d012af
MD5 f91a1a71d3f4c5143dd67baccca1b7ad
BLAKE2b-256 ea8f6daa65d3d648919728ad0b490cae430a43dbd886313fc247bf80c7861b8d

See more details on using hashes here.

Provenance

The following attestation bundles were made for sportagent-0.3.0-py3-none-any.whl:

Publisher: publish.yml on Paul-le-cimanova/SportAgent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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