agents/openai.yaml
interface:
display_name: "World Cup Predict"
short_description: "Predict World Cup winners & scorelines with verifiable pre-match intel via AnyCap"
default_prompt: "Predict this World Cup matchup: who wins and the likely scoreline"
README.md
# AnyCap World Cup Predict
> Predict who will win and the likely scoreline for any World Cup match -- backed by
> structured, verifiable pre-match intel. An [AnyCap](https://anycap.ai) agent skill
> for football (soccer) fans.
**World Cup match prediction + pre-match intel.** This skill turns a matchup (or a
player name, or a whole squad) into clean, sourced data -- profiles, current form,
head-to-head records, squad dossiers, and past-tournament history -- and then,
optionally, makes a **for-fun call**: likely winner, a playful scoreline, and a
confidence level, always shipped with a disclaimer.
Keywords: World Cup prediction, predicted score, who will win, match prediction,
football/soccer prediction, head-to-head, squad lineup, player stats, AI agent skill.
## What it does
- **Match prediction (for fun)** -- weighs FIFA ranking, recent form, head-to-head,
and key players to call a winner + scoreline with a confidence label.
- **User-defined dimensions** -- add, drop, or re-weight what matters: home
advantage, injuries, rest/fatigue, weather, head coach, "vibes", and more.
- **Verifiable pre-match intel** -- structured player profiles, squad/roster tables,
current form, and career/World Cup stats.
- **Historical context** -- tournament track record, group + knockout results, and
head-to-head between two teams.
- **Honest sourcing** -- grounded search first, cross-checked against authoritative
sources (e.g. Wikipedia) when accuracy matters.
> **Predictions are for entertainment only** -- data-informed guesses, not statements
> of fact, odds, or betting advice. See [`references/predict.md`](references/predict.md).
## Requirements
- The [`anycap`](https://anycap.ai) CLI, installed and authenticated (`anycap status`).
- `jq` for parsing JSON output.
- Any agent that can run shell commands.
## Quick start
Ask your agent things like:
- "Predict France vs Brazil at the World Cup -- who wins and the score?"
- "Predict Mexico vs Korea, and weight home advantage and heat heavily."
- "Give me Jude Bellingham's profile as structured data."
- "Build the England 2026 World Cup squad as a table."
Or call the underlying CLI directly:
```bash
anycap search --prompt 'Give the basic profile of footballer Jude Bellingham as JSON with fields: full_name, date_of_birth, nationality, height, position, current_club, shirt_number, national_team. Only the JSON.' \
| jq -r '.data.content'
```
## How it works
The full workflow lives in [`SKILL.md`](SKILL.md). References:
- [`references/lookup.md`](references/lookup.md) -- single player lookup & disambiguation
- [`references/batch.md`](references/batch.md) -- whole squad / matchup tables
- [`references/stats.md`](references/stats.md) -- career & World Cup stats
- [`references/history.md`](references/history.md) -- past-tournament context & head-to-head
- [`references/verify.md`](references/verify.md) -- cross-checking against authoritative sources
- [`references/predict.md`](references/predict.md) -- the for-fun prediction method + disclaimer
## License
MIT -- see [LICENSE](../LICENSE).
references/batch.md
# Batch / Squad Mode
Turn a list of player names (or a whole World Cup squad) into a structured table or JSON array.
## Principle
One structured grounding call per player. Do **not** crawl every search result -- that wastes credits and floods context. Prune first, retrieve only the profile.
## Step 1 -- Get the squad list
If you already have the names, skip to Step 2. To fetch a national-team squad:
```bash
anycap search --prompt 'List the full <COUNTRY> 2026 World Cup squad as a JSON array of player names. Only the JSON.' \
| jq -r '.data.content'
```
Verify roster completeness against Wikipedia if the squad must be exact (see [verify.md](verify.md)) -- squads change due to injuries.
## Step 2 -- Loop one profile per player
Save names to a file (one per line), then loop:
```bash
# players.txt: one player name per line
while IFS= read -r name; do
[ -z "$name" ] && continue
profile=$(anycap search --prompt "Basic profile of footballer $name as JSON with fields: full_name, date_of_birth, nationality, height, position, current_club, shirt_number, national_team. Only the JSON." \
| jq -r '.data.content' \
| sed -e 's/^```json//' -e 's/^```//' -e '/^$/d')
echo "$profile" | jq -c --arg q "$name" '. + {query_name:$q}'
done < players.txt | jq -s '.' > squad.json
```
Notes:
- The `sed` strips ``` ```json ``` fences so the inner object is valid for `jq`.
- `jq -s '.'` at the end slurps all per-player objects into a single array.
- Add `--arg q "$name"` to keep the original query name for traceability.
- Each player costs 5 credits (grounding). A 26-player squad ~= 130 credits. Check `anycap status` for balance before a full run.
## Step 3 -- Render a table
From `squad.json`, produce a Markdown table:
```bash
jq -r '["Name","DOB","Nat","Pos","Club","No."], (.[] | [.full_name, .date_of_birth, .nationality, .position, .current_club, (.shirt_number|tostring)]) | @tsv' squad.json \
| column -t -s $'\t'
```
## Performance
- If your runtime supports concurrency, run several grounding calls in parallel (background jobs) and collect outputs, rather than strictly sequential. Respect rate limits -- back off on `RATE_LIMITED`.
- For large lists, consider `--query --no-crawl` first to confirm each name resolves to a real player before spending grounding credits.
## Robustness
- Skip and log any player whose profile fails to parse as JSON; do not abort the whole batch.
- Record `_retrieved_at` once per run; club/number are point-in-time.
references/history.md
# Historical World Cup Context
Use past-tournament history to add context to a matchup: format, group-stage and knockout results, and the key players who decided each edition. Curated high-confidence facts are baked in; full brackets and standings are pulled live to stay accurate.
> History informs context, not outcomes. Past performance does not determine future results. Surface the data; let the user judge.
## Tournament format
- **Group stage**: teams are drawn into groups and play a round-robin; the top finishers advance. Points: win 3, draw 1, loss 0. Tiebreakers: goal difference, goals scored, then head-to-head / fair-play / draw depending on the edition's rules.
- **Knockout stage**: single-elimination from the round of 16 (or round of 32 in the 48-team era) through quarter-finals, semi-finals, third-place play-off, and final. Draws go to extra time, then penalties.
- **Format changes by edition** -- the 1998-2022 editions used 32 teams in 8 groups of 4 (top 2 advance to a round of 16). The **2026 edition expands to 48 teams** with a new group/knockout structure (round of 32). Confirm the exact format for the edition in question via live retrieval below rather than assuming.
## Baked-in: finals & podium (high confidence)
| Year | Host | Champion | Runner-up | Third | Final |
|------|------|----------|-----------|-------|-------|
| 2022 | Qatar | Argentina | France | Croatia | 3-3 (4-2 pens) |
| 2018 | Russia | France | Croatia | Belgium | 4-2 |
| 2014 | Brazil | Germany | Argentina | Netherlands | 1-0 (a.e.t.) |
| 2010 | South Africa | Spain | Netherlands | Germany | 1-0 (a.e.t.) |
| 2006 | Germany | Italy | France | Germany | 1-1 (5-3 pens) |
All-time titles: Brazil 5; Germany 4; Italy 4; Argentina 3; France 2; Uruguay 2; England, Spain 1 each.
## Baked-in: key players per edition (high confidence)
| Year | Golden Ball (best player) | Golden Boot (top scorer) | Best Young Player |
|------|---------------------------|--------------------------|-------------------|
| 2022 | Lionel Messi (Argentina) | Kylian Mbappé (France, 8) | Enzo Fernández (Argentina) |
| 2018 | Luka Modrić (Croatia) | Harry Kane (England, 6) | Kylian Mbappé (France) |
| 2014 | Lionel Messi (Argentina) | James Rodríguez (Colombia, 6) | Paul Pogba (France) |
| 2010 | Diego Forlán (Uruguay) | Thomas Müller (Germany, 5) | Thomas Müller (Germany) |
| 2006 | Zinedine Zidane (France) | Miroslav Klose (Germany, 5) | Lukas Podolski (Germany) |
For editions before 2006, or any detail not in these tables, verify via live retrieval rather than relying on memory.
## Live: full group-stage standings
Baking every group's table for every edition is large and error-prone -- pull it on demand and verify:
```bash
anycap search --prompt 'Final group-stage standings for the <YEAR> World Cup, group <X>, as JSON array of {team, played, won, drawn, lost, goals_for, goals_against, points, advanced(boolean)}. JSON only.' \
| jq -r '.data.content'
```
Verify the advancing teams against Wikipedia's tournament page (see [verify.md](verify.md)).
## Live: knockout bracket & results
```bash
anycap search --prompt 'Knockout-stage results for the <YEAR> World Cup as JSON: round_of_16, quarter_finals, semi_finals, third_place, final -- each an array of {team_a, team_b, score, winner, decided_by(regulation|extra_time|penalties)}. JSON only.' \
| jq -r '.data.content'
```
Caveats:
- Scores for matches decided on penalties should record the regulation score plus the shootout result.
- For a single team's run, ask for "the <COUNTRY> knockout path in the <YEAR> World Cup" instead of the full bracket.
## Live: key players for a tournament or team
Go beyond the baked-in awards (full top-scorer lists, standout performers, a team's decisive players):
```bash
anycap search --prompt 'Key players of the <YEAR> World Cup as JSON: golden_ball, golden_boot{player,goals}, top_scorers[{player,team,goals}], standout_performers[{player,team,note}]. JSON only.' \
| jq -r '.data.content'
```
```bash
anycap search --prompt 'The <COUNTRY> key players at the <YEAR> World Cup as JSON array of {player, position, goals, assists, note}. JSON only.' \
| jq -r '.data.content'
```
Verify any player figure you will present as fact against Wikipedia (see [verify.md](verify.md)).
## Live: team tournament history
```bash
anycap search --prompt 'World Cup history for the <COUNTRY> national football team as JSON: titles, last_title_year, best_finish, total_appearances, current_world_ranking. Numbers only, JSON only.' \
| jq -r '.data.content'
```
## Live: head-to-head between two teams
```bash
anycap search --prompt 'Head-to-head record between <TEAM A> and <TEAM B> national football teams as JSON: total_meetings, team_a_wins, team_b_wins, draws, last_meeting_date, last_meeting_result, world_cup_meetings. JSON only.' \
| jq -r '.data.content'
```
Caveats:
- H2H aggregates vary by source (friendlies vs competitive matches counted differently). Note the ambiguity rather than presenting one number as definitive.
- For a World Cup-only record, say so explicitly in the prompt.
## Folding history into matchup intel
When sizing up Team A vs Team B (see [batch.md](references/batch.md)):
1. Build both squads (profiles + form/stats).
2. Add each team's tournament history and recent World Cup runs (group + knockout above).
3. Add the head-to-head record and any shared knockout history.
4. Note key players on each side (baked-in awards + live per-team key players).
5. Present the layers side by side -- **squad quality**, **current form**, **historical context (group + knockout + key players)**. Then optionally finish with a for-fun winner + scoreline call per [predict.md](predict.md), kept separate from the factual layers and always followed by its disclaimer.
references/lookup.md
# Single Player Lookup & Disambiguation
The default path for one player's basic info. Optimize for a clean structured answer in as few calls as possible.
## Step 1 -- Grounding structured profile
Ask for JSON explicitly and parse with `jq`:
```bash
anycap search --prompt 'Give the basic profile of footballer <PLAYER NAME> as JSON with fields: full_name, date_of_birth, nationality, height, position, current_club, shirt_number, national_team. Only the JSON.' \
| jq -r '.data.content'
```
Notes:
- Put **"Only the JSON."** at the end so the model does not wrap the answer in prose.
- The answer may arrive inside a ```json fenced block. Strip the fences before re-parsing if you need to `jq` the inner object.
- Costs 5 credits.
## Step 2 -- Disambiguation
Many footballers share names (e.g. multiple "Luis García", "Danilo", "Rodrigo"). Lock onto the right person:
**Option A -- add context to the prompt** (cheapest):
```bash
anycap search --prompt 'Basic profile as JSON for the footballer named Danilo who is a Brazilian defender currently at Juventus. Fields: full_name, date_of_birth, nationality, height, position, current_club, shirt_number, national_team. Only the JSON.' \
| jq -r '.data.content'
```
Use any distinguishing context you have: nationality, position, birth year, current club, national team, World Cup squad.
**Option B -- pre-scan candidates with general search** (1 credit, no crawl):
```bash
anycap search --query "<PLAYER NAME> footballer profile club nationality" --no-crawl --max-results 6 \
| jq -r '.data.results[]? | "\(.title) -- \(.url)"'
```
Inspect titles/URLs (Wikipedia disambiguation pages, club pages) to pick the correct player, then run Step 1 with the confirmed identity, or jump to [verify.md](verify.md) to read the exact Wikipedia page.
## Step 3 -- Normalize
Map the result onto the SKILL.md output schema:
- Convert dates to `YYYY-MM-DD`.
- Use `null` (not empty string) for unknown fields.
- Record the retrieval date for volatile fields (`current_club`, `shirt_number`).
## When to escalate to verification
Escalate to [verify.md](verify.md) when:
- The user needs guaranteed accuracy (publishing, official documents).
- Grounding returns a suspicious or internally inconsistent value.
- The player recently transferred and `current_club` may be stale.
references/predict.md
# Prediction (for fun)
Turn the factual matchup layers into an optional, lighthearted call: a likely
winner, a playful scoreline, and a confidence label. This is the entertainment
layer of the skill -- it sits **after** the data, never replaces it.
> Predictions inform fun, not outcomes. They are data-informed guesses, not
> statements of fact, odds, or betting advice. Surface the reasoning; let the
> reader enjoy and judge.
## When to use
- The user explicitly wants a "prediction", "who will win", "scoreline", "your
call", or similar.
- You have already gathered the factual layers (squad quality, current form,
historical context, head-to-head) for the matchup. Do not predict from
nothing -- run the matchup workflow first.
## Method: weigh the signals, then call it
Base every prediction on the data you already retrieved. Weigh, in rough order:
1. **Quality gap** -- FIFA ranking and squad strength (key players, club level).
2. **Current form** -- recent results; a hot/cold streak shifts the call.
3. **Head-to-head** -- prior meetings, especially recent or competitive ones.
4. **Context** -- World Cup pedigree, availability/injuries, venue if relevant.
Translate the balance into a scoreline that matches the lean:
- **Lopsided** (big ranking + form gap): a comfortable margin, e.g. `2-0`, `3-1`.
- **Edge** (one side slightly ahead): a tight scoreline, e.g. `2-1`, `1-0`.
- **Even** (signals cancel out): a draw is a legitimate, honest call, e.g.
`1-1`. Do not force a winner when the data does not support one.
Attach a **confidence** label -- `Low` / `Medium` / `High` -- reflecting how
strongly the signals agree. Conflicting signals = lower confidence.
## Custom dimensions (user-defined)
The four signals above are the **default** model. Let the user shape the call by
adding, removing, or re-weighting dimensions. Treat any dimension the user names
as a first-class input.
How to handle a user-supplied dimension:
1. **Capture it.** Restate the dimension(s) and any weight the user gave (e.g.
"home advantage = high", "ignore head-to-head", "weight form 50%").
2. **Get the data if you don't have it.** If the dimension needs a fact you have
not retrieved, pull it with one grounding call before predicting -- do not
guess. Example:
```bash
anycap search --prompt 'For the <TEAM A> vs <TEAM B> match, summarize as JSON: {"home_advantage":{"host":string,"note":string},"injuries":[{"team":string,"player":string,"status":string}],"rest_days":{"team_a":int,"team_b":int},"weather":{"venue":string,"forecast":string}}. JSON only.' \
| jq -r '.data.content'
```
3. **Fold it into the weighing.** Apply the user's weights when you balance the
signals. If the user gives explicit weights (percentages or High/Med/Low),
honor them; otherwise weight reasonably and say how you weighted.
4. **Show the dimensions used.** List the final dimension set (defaults + custom)
so the reader sees what drove the call.
Common custom dimensions users ask for:
| Dimension | Typical signal |
|-----------|----------------|
| Home / host advantage | Host nation, venue familiarity, crowd, altitude |
| Injuries / availability | Key players out or doubtful |
| Rest & fatigue | Days since last match, travel, fixture congestion |
| Weather / climate | Heat, humidity, rain at the venue |
| Head coach / tactics | Managerial quality, style matchup |
| Stakes / motivation | Must-win, already qualified, dead rubber |
| Set-piece threat | Aerial strength, dangerous takers |
| "Vibes" / gut feel | Explicitly non-scientific; label it as such |
Rules for custom dimensions:
- A dimension must map to something observable. If it cannot be sourced or
reasoned about, say so and exclude it rather than inventing data.
- The user can override or drop defaults (e.g. "don't use FIFA ranking"). Respect
that, and note which defaults were dropped.
- More custom dimensions do not mean higher confidence. If user-weighted signals
conflict, lower the confidence accordingly.
- The disclaimer below is still mandatory, no matter which dimensions are used.
## Output shape
Render the prediction as its own block, separate from the factual tables:
```text
Prediction (for fun): <Winner> to win, <scoreline> · Confidence: <Low|Medium|High>
Dimensions: <defaults used> [+ <custom dimensions / weights, if any>]
Why: <one or two sentences tying the call to the dimensions above>
```
For a draw call, write `Draw, <scoreline>` instead of a winner.
## Required disclaimer
Every response that contains a prediction MUST end with this disclaimer (or a
close paraphrase in the user's language):
> **Disclaimer:** This prediction is for entertainment only. It is a
> data-informed guess, not a statement of fact, odds, or betting advice. Real
> matches are unpredictable -- please don't wager based on it.
A prediction without this disclaimer is incomplete output. Do not omit it, even
if the user asks you to.
## Guardrails
- Keep the factual layers intact and clearly labeled; the prediction is additive.
- Do not invent stats to justify a call -- use what was retrieved.
- Do not output probabilities or odds as if they were measured facts.
- Do not give betting/wagering instructions or encourage gambling.
- If asked for confidence as a percentage, you may give a casual, clearly
non-scientific number (e.g. "~60%, just vibes") and still attach the
disclaimer.
references/stats.md
# Career & World Cup Stats
Extend a basic profile with performance numbers. Stats are less stable than biographical fields -- treat them as best-effort and verify what matters.
## Grounding stats query
```bash
anycap search --prompt 'Career stats summary for footballer <PLAYER NAME>, return JSON with fields: senior_career_appearances, senior_career_goals, national_caps, national_goals, worldcup_2026_appearances, worldcup_2026_goals. Numbers only, JSON only.' \
| jq -r '.data.content'
```
Returns (example, verified shape):
```json
{
"senior_career_appearances": 300,
"senior_career_goals": 72,
"national_caps": 49,
"national_goals": 7,
"worldcup_2026_appearances": 1,
"worldcup_2026_goals": 1
}
```
## Accuracy caveats
- Numeric totals can be **approximate or slightly stale** -- they depend on what the web surfaces at call time and how the model aggregates across competitions.
- Career totals shift after every match. Always attach `_retrieved_at`.
- For figures that must be correct (reports, official use), verify against Wikipedia (career-statistics table) per [verify.md](verify.md). Do not rely on Transfermarkt crawling -- it is bot-blocked.
## Position-aware fields
Tailor stat fields to the position so the output is meaningful:
- **Goalkeepers**: prefer `clean_sheets`, `appearances`, `goals_conceded` over `goals`.
- **Defenders / midfielders**: include `assists` alongside `goals`.
- **Forwards**: `goals`, `assists`, optionally `goals_per_90`.
Adjust the requested JSON fields in the prompt accordingly.
## Combining with the basic profile
Merge stats into the basic profile object so each player is a single record:
```bash
jq -s '.[0] * .[1]' profile.json stats.json > player_full.json
```
Keep biographical fields and stats clearly grouped, and preserve `_sources` / `_retrieved_at` from both calls.
references/verify.md
# Authoritative Source Verification
Use this when accuracy matters more than speed. Cross-check the grounding profile against a crawlable, authoritative source.
## Source reliability (verified)
| Source | Crawlable via `anycap crawl`? | Use for |
|--------|-------------------------------|---------|
| Wikipedia (`en.wikipedia.org/wiki/<Player>`) | Yes -- returns full Markdown | Primary verification |
| Transfermarkt | No -- returns a `Human Verification` page (~600 chars) | Avoid crawling; use grounding instead |
| Official FA / club sites | Sometimes; check `title` and length | Secondary confirmation |
Always inspect the crawl result before trusting it:
```bash
anycap crawl "<url>" | jq -r '{title:.data.title, len:(.data.markdown|length)}'
```
If `len` is small (a few hundred chars) or `title` looks like a challenge page (`Human Verification`, `Just a moment`, `Access denied`), the page is bot-blocked -- discard it and fall back to grounding or Wikipedia.
## Workflow
### Step 1 -- Find the exact Wikipedia URL
```bash
anycap search --query "<PLAYER NAME> footballer wikipedia" --no-crawl --max-results 3 \
| jq -r '.data.results[]? | "\(.title) -- \(.url)"'
```
Pick the `en.wikipedia.org/wiki/<Player>` result (avoid disambiguation pages).
### Step 2 -- Crawl Wikipedia
```bash
anycap crawl "https://en.wikipedia.org/wiki/<Player>" | jq -r '.data.markdown' > /tmp/<player>.md
```
The infobox near the top contains date of birth, height, position, current team, and shirt number.
### Step 3 -- Reconcile
Compare the grounding profile (from [lookup.md](lookup.md)) against the Wikipedia infobox:
- **Match** -> mark field as `verified`.
- **Conflict** -> prefer the source that is more current for volatile fields (club/number); for stable fields (DOB, full name) Wikipedia is usually authoritative. Note the discrepancy.
- **Missing in grounding** -> fill from Wikipedia.
### Step 4 -- Annotate sources
For a verified profile, record where each value came from, e.g.:
```json
{
"full_name": "Jude Victor William Bellingham",
"date_of_birth": "2003-06-29",
"current_club": "Real Madrid",
"_sources": ["grounding", "https://en.wikipedia.org/wiki/Jude_Bellingham"],
"_retrieved_at": "2026-06-18"
}
```
## Cost note
Verification adds ~2 credits per player (1 query + 1 crawl) on top of the grounding call. Only verify the fields/players that need it.
SKILL.md
---
name: anycap-worldcup-predict
description: "World Cup match prediction and pre-match intel for football (soccer) fans: predict who will win and a likely scoreline, backed by structured, verifiable evidence -- player profiles, squad dossiers, current form, head-to-head records, and past-tournament history -- using AnyCap web search and crawl. Weighs FIFA ranking, recent form, head-to-head, and key players, plus any user-defined dimensions (home advantage, injuries, rest, weather, vibes), then makes a clearly-labeled for-fun call with a confidence level and a mandatory disclaimer. Built on the 'search less, not faster' strategy: narrow the search space first, retrieve only what matters, then verify against authoritative sources. Use when a fan wants a World Cup match prediction, predicted score, or who-will-win call; wants a player's profile, bio, form, or stats; wants a full World Cup squad or national-team lineup table; wants to size up two teams before a match; or wants head-to-head and past World Cup context. Trigger on: World Cup prediction, predict the score, who will win, match prediction, predicted scoreline, World Cup, World Cup squad, national team lineup, pre-match analysis, matchup, player form, footballer stats, player profile, head-to-head, or scout a team."
metadata:
version: 0.6.5
website: https://anycap.ai
license: MIT
compatibility: Requires anycap CLI (authenticated). Works with any agent that supports shell commands.
---
# AnyCap World Cup Predict
> **Read this entire file before starting.** It defines a reliable workflow for turning a player name (or a whole squad) into structured, verifiable World Cup pre-match intel using AnyCap, then optionally calling a winner and scoreline for fun.
World Cup match prediction and pre-match intel for serious football fans. Turn player names and lineups into structured, verifiable profiles, stats, and matchup briefings so you can read a World Cup matchup before kickoff -- then, if you want, finish with a for-fun prediction (likely winner + scoreline + confidence). Built for World Cup squads and national-team lineups, and works for any footballer.
This skill is about **how to retrieve and verify player data**. For CLI command reference (flags, output, jq), read the `anycap-cli` skill and its `references/search.md` / `references/crawl.md`.
> This skill surfaces **public information** (profiles, form, historical stats) and can finish with an optional **for-fun prediction** (likely winner + a playful scoreline) derived from that data. It does **not** set betting odds, output win probabilities as if they were facts, or place wagers. Every prediction must ship with the disclaimer in [predict.md](references/predict.md). Treat everything as informational and form your own judgment.
## Prerequisites
- `anycap` CLI installed and authenticated (`anycap status` to verify). Read the `anycap-cli` skill if setup is needed.
- `jq` for parsing JSON output.
## Core Principle: Search Less, Not Faster
Do not crawl the whole web for every player. Narrow the search space first, then retrieve only what matters:
1. **Grounding first** -- ask for a structured profile in one shot (`anycap search --prompt`). This is the fastest path to clean data.
2. **Disambiguate** -- when a name is shared by several players, add context (nationality, position, birth year, club) to lock onto the right one.
3. **Verify only when accuracy matters** -- cross-check against an authoritative, crawlable source (Wikipedia) instead of trusting a single answer.
4. **Prune, don't dump** -- in batch mode, fetch one structured profile per player; never crawl every search result.
## Workflow
| Goal | Route | Reference |
|------|-------|-----------|
| One player's basic info | Grounding structured JSON | [lookup.md](references/lookup.md) |
| Right player when name is shared | Add context / pre-scan with `--query` | [lookup.md](references/lookup.md) |
| High-accuracy, sourced profile | Cross-check vs Wikipedia | [verify.md](references/verify.md) |
| A whole squad / roster | Loop grounding, aggregate to table | [batch.md](references/batch.md) |
| Career + current World Cup stats | Grounding stats JSON (with caveats) | [stats.md](references/stats.md) |
| Size up a matchup (Team A vs Team B) | Build both squads via batch, compare side by side | [batch.md](references/batch.md) |
| Add past World Cup context | Format, group + knockout results, key players, team history, head-to-head | [history.md](references/history.md) |
| Call a winner + scoreline (for fun) | Weigh the gathered layers (plus any user-defined dimensions), then predict with a mandatory disclaimer | [predict.md](references/predict.md) |
For a matchup, run the squad workflow for both teams, then layer in historical context (tournament track record + head-to-head from [history.md](references/history.md)). Present three layers side by side -- **squad quality**, **current form**, **historical context** -- and highlight differences in key positions and availability. Then, if a prediction is wanted, finish with an optional **for-fun call** (likely winner + playful scoreline + confidence) per [predict.md](references/predict.md). Always keep the factual layers clearly separated from the prediction, and always attach the disclaimer.
### Fast path (single player)
```bash
anycap search --prompt 'Give the basic profile of footballer Jude Bellingham as JSON with fields: full_name, date_of_birth, nationality, height, position, current_club, shirt_number, national_team. Only the JSON.' \
| jq -r '.data.content'
```
Returns (verified):
```json
{
"full_name": "Jude Victor William Bellingham",
"date_of_birth": "2003-06-29",
"nationality": "English",
"height": "1.86 m",
"position": "Midfielder",
"current_club": "Real Madrid",
"shirt_number": 5,
"national_team": "England"
}
```
Grounding search costs 5 credits per call. General search (`--query`) and crawl cost 1 credit each.
## Output Schema
Normalize every profile to this schema so single-player and batch results are consistent:
| Field | Type | Notes |
|-------|------|-------|
| `full_name` | string | Legal/full name |
| `date_of_birth` | string | `YYYY-MM-DD`; use `null` if unknown |
| `nationality` | string | Primary nationality |
| `height` | string | e.g. `1.86 m`; `null` if unknown |
| `position` | string | e.g. `Midfielder`, `Goalkeeper` |
| `current_club` | string | Club as of retrieval date |
| `shirt_number` | int/null | Club or national-team number |
| `national_team` | string | National team |
Rules:
- Use `null` for missing fields. Never invent values.
- `current_club` and `shirt_number` change frequently -- treat them as point-in-time and note the retrieval date.
- When a field cannot be confirmed, mark it and (if accuracy matters) verify via [verify.md](references/verify.md).
## Important: Source Reliability (verified)
- **Wikipedia is reliably crawlable** (`anycap crawl https://en.wikipedia.org/wiki/<Player>` returns full Markdown). Use it as the primary verification source.
- **Transfermarkt blocks crawling** -- `anycap crawl` returns a short `Human Verification` page, not data. Do not rely on crawling it; use grounding search or Wikipedia instead.
- Other stats sites may also bot-block. Always check the crawled `title`/length before trusting content.
## Prediction (for fun)
After the factual layers, you may add an optional, clearly-labeled prediction so the briefing is fun to read. See [predict.md](references/predict.md) for the method and the required disclaimer. Non-negotiable rules:
- **Facts first, prediction last.** Never blend the guess into the data tables; put it in its own clearly-marked block.
- **Always attach the disclaimer** from [predict.md](references/predict.md). A prediction without the disclaimer is incomplete output.
- **Entertainment, not betting.** Do not present win probabilities or odds as facts, do not give wagering advice, and do not tell anyone to bet.
- **Show the reasoning.** Base the call on the gathered signals (ranking, form, head-to-head, key players), not a coin flip.
- **Let the user steer.** Users can add, drop, or re-weight prediction dimensions (e.g. home advantage, injuries, rest, weather, "vibes"). Honor their weights, retrieve any missing data first, and list the final dimension set used. See [predict.md](references/predict.md).
## Limitations
- Live data (current club, shirt number, latest stats) reflects whatever the web returns at call time and can lag real events.
- Grounding stats numbers are best-effort and can be approximate; verify critical figures against Wikipedia.
- Generic player names need disambiguation context or the wrong person may be returned.
- This skill retrieves data on demand; it is not a stored database of all players.
## Quick Reference
| Tool | Purpose |
|------|---------|
| `anycap search --prompt "...JSON..."` | Structured profile / stats in one shot (5 cr) |
| `anycap search --query "..." --no-crawl` | Find/disambiguate the right player page (1 cr) |
| `anycap crawl https://en.wikipedia.org/wiki/<Player>` | Authoritative verification source (1 cr) |
| `anycap status` | Check auth before a batch run |