Mentions in the teachers' chatbot
Teachers pick learners and subjects from a list while they type, like @file in a coding assistant. What that gives the agents behind the chatbot, and what it does not.
During the focus groups for the dashboards of Konsolidation (KDo), ten secondary school teachers asked a chatbot 66 questions about their learners. It turns each question into SQL on the attempts and scores. The chatbot is the exploration half of a double approach that Esther Félix and I wrote up together: teachers validate prototypes, then explore with a chatbot (Saurel & Félix, 2026).
Most questions contain a name, and a name typed as a word causes two problems. The roster may hold two Jeans. And the name goes to a hosted model (the agents call the Mistral API) while the learners are minors. The fix, borrowed from coding assistants: the teacher types a trigger, picks the name in a list, and the prompt carries that exact learner or subject.
Typing a mention
@ opens the learners and # the subjects, like @ for files in Claude Code. This input follows the rules of the app, with a made-up roster.
- A trigger opens a list when it starts the text or follows a space. A space closes it.
- Picking writes the name in the input and remembers the pick on the side.
- On send, each remembered pick becomes a tag, like
<subject>Pythagoras</subject>. A name typed by hand is left as plain text.
The input above adds a few things the app does not have: arrow keys, accent-insensitive search, and the id in the tag, like <subject id="2">Pythagoras</subject>. A name cannot tell two learners apart, an id can.
From question to answer
The same question goes through the chain twice. The bottom row is the chatbot as it is. The top row is what mentions make possible: learners become labels before any model reads them, and the names come back at the end.
Both traces are written by hand, not recorded runs. The app answers in French, so the texts are translated.
Who did worst on Pythagoras between Jean, Marie and Pierre?
- Local · step 1Anonymizernames to labelsnames found...Names stay as typed.Sends onWho did worst on Pythagoras between Jean, Marie and Pierre?Matching the roster by text fails on two Jeans.
- LocalName tablelabel to learnerentries...Empty.Mistral API · step 2Clarificationmoderates, rewritesseesnamesRewrites the question.Hands onAmong the learners Jean, Marie and Pierre, which one has the lowest average score on the subject Pythagoras?SQL-gen reads this version: the tags must survive it.
- Mistral API · step 3SQL-genwrites and runs SQLseesnamesWrites and runs the SQL.
SELECT l.name, AVG(r.score) AS averageFROM response rJOIN attempt a ON a.id = r.attempt_idJOIN learner l ON l.id = r.learner_idJOIN subject s ON s.id = a.subject_idWHERE s.name LIKE '%Pythagoras%' AND (l.name LIKE 'Jean%' OR l.name LIKE 'Marie%' OR l.name LIKE 'Pierre%')GROUP BY l.idORDER BY average ASC;The names are matched by guess. - Mistral API · step 4Explanationrows into a sentenceseesnamesTurns the rows into a sentence.RowsJean Moreau2.0Jean Martin5.5Pierre Roux6.0WritesJean Moreau did worst on Pythagoras, with an average of 2.0/10.
- Local · step 5Re-identifierlabels back to namesputs back...Nothing to put back.Hands onJean Moreau did worst on Pythagoras, with an average of 2.0/10.Mistral API · step 5Evaluatorrelevant or notseesnamesChecks the answer is on topic.RelevantIt does not check the data: a wrong Jean passes.
- Local · step 6Replyto the teachershows...Sent if the Evaluator accepts it.Jean Moreau did worst on Pythagoras, with an average of 2.0/10.It passes, and nothing warns of the wrong Jean.
- Free text can be neither exact nor private. "Jean" fits two learners, and spotting names by matching the roster misses nicknames and typos. Today the names, in the question and in the rows, go to Mistral.
- A mention is exactly the name. Swapping the tag for a label, and back, is a plain replacement. SQL-gen then filters on ids and has nothing to guess.
- The last agent cannot catch a wrong Jean. The Evaluator only rejects off-topic answers, and an answer about Jean Moreau is on topic. The check has to happen while the teacher types.
Three ways to name someone
Free text
PartlyThe teacher types "Jean" and the agents work out which one.
Ask back
PartlyThe chatbot notices two Jeans and asks which one is meant.
Mentions
WorksThe teacher types @Je and picks "Jean Martin".
What I do not know yet
- Whether it works. No comparison has run. A fair one sends the same questions with and without mentions through the same agents and checks the SQL, the kind of loop MAESTRO-bench is built for.
- Whether the models keep the tags and labels. SQL-gen reads the question as Clarification rewrote it, and the names only come back if the labels survive. A missing label must fail loudly, not show a wrong name.
What else to point at
Teachers also ask about an evaluation and a time span, or about a set of learners ("make needs-based groups from the learners who failed"). The dashboard already filters by group, subject, tag and number of attempts. A mention is a filter written inside a sentence, so one list of things could feed both.
References
- Saurel, R., & Félix, E. (2026). Une double approche pour la co-conception de tableaux de bord d'apprentissage : validation avec des prototypes, exploration avec un chatbot. RJC EIAH 2026. https://hal.science/hal-05641999