Inspiration

In VEX, every match is 2v2, so who you pick as an alliance partner can matter as much as your own robot. But at most competitions, scouting means clipboards, messy group chats, and guessing during alliance selection with only a few seconds to decide. At a VEX competition, a lot changes in one day. A team that dominated the morning might break an intake at lunch, or a struggling team might fix its intake and suddenly start winning. Rankings and score sheets can't keep up with that, and the info usually lives in one scout's head or gets lost in a group chat. By the time alliance selection comes around, teams are picking based on how things looked hours ago.

We wanted a tool that knows every team at an event before it even starts, updates in real time as things happen, and gives us honest, data-backed advice instead of gut feelings.

What it does

VEX Scout AI is a scouting app that does four jobs at a tournament:

  • Rates every team (0–100) using verified results from RobotEvents, weighted toward teams with a long track record. One great event counts less than ten good ones.
  • Predicts any match by blending three opinions with equal votes: a statistics model, a machine-learning model, and an AI analysis. For example, the stats model says 53%, ML says 58%, and AI says 56%, so the combined prediction is 56%.
  • Plans with AI. It writes scouting reports for each team, and a Strategy Copilot answers questions like "How should we play 80001C?" using real match data.
  • Scouts in seconds. Scouts tap chips or just talk into the mic. Saying "Fast robot and driver, auton works 9 of 10 on the left side" automatically becomes tags and auton stats. Live updates like "robot down" instantly lower a team's rating, and every pick and prediction updates with it.

How we built it

Front end: Built with Streamlit, plus custom CSS cards, rating rings, a phone-friendly layout, and a mic button for voice scouting.

Back end: Python, with all data stored in a single SQLite file. Results come from the RobotEvents API, and every response is cached for 6 hours. That cut reloading an event from 39 API calls to 0, keeps us under the rate limit, and lets the app keep working even when the API is down.

The stats (no AI): We fit three classic ratings on every scored match of the season (239 matches across 8 events):

  • Elo: winners gain rating and losers lose it, more for bigger margins: $$\Delta = K \cdot \text{margin} \cdot (\text{result} - \text{expected})$$
  • OPR: every alliance score is treated as an equation, and solving them all gives each team's points per match: $$\text{score} \approx \text{OPR}(A) + \text{OPR}(B)$$
  • CCWM: the same solve on points allowed (DPR) gives each team's effect on the margin: $$\text{CCWM} = \text{OPR} - \text{DPR}$$

Machine learning: A logistic regression, trained with gradient descent on 227 matches, looks at four gaps between red and blue alliances (OPR, experience, Elo, and win rate), using only stats known before each match: $$P(\text{red wins}) = \frac{1}{1 + e^{-(w \cdot x + b)}}$$ It learned that OPR matters most (weights: OPR +0.93, experience +0.29, Elo +0.14, win rate +0.03).

AI: We use Claude and ChatGPT in three ways:

  • Single calls read scouting notes, voice text, and live updates, filling in a fixed form.
  • A two-model pipeline writes team reports: Claude drafts, ChatGPT reviews and pushes back, then Claude accepts or rejects each point with a reason and writes the final version.
  • An agent powers the Strategy Copilot. Claude picks from 7 tools (team profile, recent matches, scouting notes, predict_match, record a note, game rules, event teams) in a loop of up to 12 rounds.

Challenges we ran into

  • Keeping the AI honest. AI likes to sound confident even when the data is thin. We made every answer fill a strict format, banned claims like "a bad match is due," blocked trends drawn from fewer than 4 matches, and required that any number the copilot quotes come from our predict_match tool.
  • API rate limits. Reloading an event used to take 39 RobotEvents calls. We built a caching layer in the database so reloading takes 0.
  • Voice input on phones. Browsers block the microphone on plain http, so we had to run a second copy of the app over https just so voice scouting would work on phones.
  • Thin early-season data. Some teams have only played one event. We pull those teams' scores toward 50 so one lucky event doesn't make a team look like a powerhouse.
  • Keeping it fast. Streamlit reruns the whole script on every tap, so we used session state, caching, and dialogs that rerun only the team panel to keep scouting quick.

Accomplishments that we're proud of

  • Our ML model picked the winner in 68% of 69 matches it had never seen, with a Brier score of 0.193. That beats Elo alone (0.205) and a coin flip (0.25). Lower is better.
  • 13 out of 13 matches cited by the AI checked out as real. Zero made-up matches.
  • Getting two AI models to actually check each other's work. In testing, ChatGPT caught that Claude's draft overstated a team's consistency (its scores swung ±34 points), and Claude accepted the correction and fixed it.
  • A full "robot down" flow: preview the change first (overall 75 → 41), apply it with a full edit history, and watch every rating, pick, and prediction update automatically.
  • The app still works if the AI goes down. Notes fall back to keyword rules, and all the stats keep running.

What we learned

  • How classic sports stats like Elo and OPR actually work, and how to solve systems of equations to get them.
  • How to train and test a machine-learning model properly, including only using data from before each match and measuring accuracy on matches the model never saw.
  • The difference between an AI agent (the model decides what to do next) and a pipeline (our code controls the order), and when to use each.
  • That AI is most useful when it's backed by real data and strict rules, not when it's just asked for an opinion.
  • How front end, back end, databases, and outside APIs all connect in a real app.

What's next for VEX Scout AI

  • Hosting it online so it doesn't stop when our laptop sleeps.
  • Adding logins so only our team can edit data and use our API credits.
  • Learning adjustments from data. Right now, "robot down" multiplies a score by 0.55, which is an informed guess. We want the model to learn that number from real matches.
  • Better early-season predictions as more teams compete and more data comes in.
  • Sharing it with other teams so the whole VEX community can scout smarter.

Built With

  • chatgpt
  • claude
Share this project:

Updates

Submission history