oracle / docs /TEACH_MODE.md
vivek gangadharan
docs updated
22555c9
|
Raw
History Blame Contribute Delete
4.26 kB
# How Teach / discovery mode works
Teach mode is where the Oracle **learns**. When it meets something not in its
database, the player tells it what they were thinking of, and the model reasons out
that item's attributes and saves them โ€” so next time, the Oracle just knows.
All of this lives in `discovery.py`, exposed through `app.py`'s `@app.api("learn")`
endpoint and the Teach UI in `index.html`.
## When it triggers
1. **The Oracle runs out of candidates** โ€” `engine.filter_candidates()` returns 0,
so `next_turn` returns `action: "giveup"` and the UI shows the Teach panel.
2. **The Oracle guesses wrong** โ€” the player clicks "No", which opens Teach.
3. **The ๏ผ‹ Teach button** โ€” the player adds something any time, no game needed
(a category picker appears so they can choose animal / fruit / vegetable).
## The learn flow
```mermaid
flowchart TD
A[player names the item] --> B[_canonical: resolve aliases]
B --> C{already in DB?}
C -->|yes| D[find_contradictions โ†’ explain wrong answers]
C -->|no| E[gather attributes from 3 sources]
E --> F[add_item โ†’ write JSON, persist, refresh cache]
F --> G[learned!]
```
`discovery.learn_item(category, name, history)` is the entry point.
### 1. Resolve the name
`_canonical()` maps aliases and spelling variants to the canonical DB name โ€”
`chilli`/`chili` โ†’ `chili pepper`, `aubergine` โ†’ `eggplant`, `courgette` โ†’
`zucchini`, etc. This stops the app from creating junk duplicates of things it
already knows.
### 2. If it's already known โ†’ explain the mistake
If the item exists, the Oracle didn't lack the data โ€” the player's answers steered
it wrong. `find_contradictions()` compares each in-game answer to the item's **true**
attributes and reports the genuine mismatches with a plain-English reason from
`ATTR_REASON`:
> โœ— You answered **No** to "Is it starchy?", but a potato is starchy โ€” it should
> have been **Yes**.
Only real contradictions are flagged; correct answers and "I'm not sure" are
ignored.
### 3. If it's new โ†’ fill every attribute from three sources
A learned item must be **complete** (define every attribute) or it can't be told
apart from others. Attributes are gathered in order of trust:
1. **The player's own in-game answers** โ€” `attributes_from_history()`. They were
thinking of it, so their yes/no answers are ground truth for their item.
2. **The model** โ€” `derive_attributes()` asks the Llama model (via `llm.py`) to
fill the category's attribute table as true/false/unknown, optionally grounded
by a short **Wikipedia** summary (`fetch_web_context()`, controlled by
`ORACLE_DISCOVERY_WEB`). The model's answers overlay the player's.
3. **The existing database** โ€” `complete_attributes()` fills anything still unknown
by majority vote among the most similar known items (nearest-neighbour). Fully
offline and deterministic.
The result is always a full attribute set, even with no model and no network.
### 4. Save it
`add_item()` appends the record to the category's JSON file, persists it (in
`ORACLE_DATA_DIR` / the mounted bucket, so it survives restarts), and clears the
engine cache so the next game sees the new item immediately โ€” no restart.
## Why this design
- **The model does real reasoning here** โ€” turning "rambutan" + a Wikipedia blurb
into a structured attribute profile is genuine work a lookup table can't do. This
is the part of the app where the tiny model is most load-bearing.
- **It never corrupts the truth** โ€” known items are explained, not overwritten; new
items are completed from multiple sources and then validated.
## Validate after teaching
Run the database checker any time you've added items (it's also a great guard for
hand-edits):
```bash
python check_db.py # COMPLETE ยท UNIQUE ยท GUESSABLE ยท BALANCED
```
It confirms every item defines every attribute, no two items are identical, and a
simulated game can still guess each one.
## Related env vars
| Var | Effect |
|-----|--------|
| `ORACLE_QUESTION_LLM=1` | use the model to derive attributes for new items |
| `ORACLE_DISCOVERY_WEB=1` | allow Wikipedia grounding while learning |
| `ORACLE_DATA_DIR=/data` | persist learned items to a mounted Storage Bucket |