The app that promised too much
A revision app says: "Ask anything and get the right answer." A student trusts it the night before a test. It gives a wrong date and they learn it.
The app did not break. It promised more than it could do. This lesson is about the words and screens that set what a person expects.
By the end of this lesson
Note
I can tell a person what a feature can and cannot do before they rely on it.
Key words
| Word | What it means | Example |
|---|---|---|
| Expectation | what a person thinks a feature will do | |
| Claim | a statement about what the feature does | always right |
| Limit | a thing the feature cannot do | |
| Scope | the jobs a feature is made for | |
| Failure example | a real case where it gets it wrong |
The cells students fill in are left blank in this preview.
Say what it is for and not for
A person decides how far to trust a feature in the first few seconds. Give them three short things: what it is for, what it is not for, and one example where it fails.
The failure example is the part teams skip. It is also the part people remember.
A good blurb for a notes tool
| Part | Example words |
|---|---|
| For | Turns your notes into a short summary |
| Not for | Checking facts, or advice about health or law |
| Fails when | Your notes hold two different dates for one event |
The cells students fill in are left blank in this preview.
Some claims can never be backed
A claim you cannot back is one a single wrong answer proves false. Words like always, never wrong, guaranteed and 100% are the usual ones. So is any question, because nobody can test every question.
Swap each for something you can count, such as "correct on 9 of 10 test questions". Module 68 shows how to measure that.
A common mistake
Warning
Many people think a small note saying "may be wrong" at the bottom is enough. People do not read it, so it sets no expectation. Say the limit next to the answer, where the person is looking, at the moment they would rely on it.
Write the model helper, part 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' '// The token counts of a reply, or null when the reply carries none.' 'function count(data, name) {' ' return data.usage && typeof data.usage[name] === \"number\" ? data.usage[name] : null;' '}' > model.js"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Write the model helper, part 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function ask(messages, sample, max) {' ' try {' ' const res = await fetch(base + \"/v1/chat/completions\", {' ' method: \"POST\",' ' headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' ' body: JSON.stringify({ model: \"lab\", messages: messages, max_tokens: max || 100 }),' ' signal: AbortSignal.timeout(30000),' ' });' ' if (res.ok === false) throw new Error(\"status \" + res.status);' ' const data = await res.json();' ' const text = data.choices[0].message.content;' ' return { text, inTokens: count(data, \"prompt_tokens\"), outTokens: count(data, \"completion_tokens\"), recorded: false };' ' } catch (error) {' ' console.log(\"Recorded sample: no model answered (\" + error.message + \").\");' ' return { text: sample, inTokens: null, outTokens: null, recorded: true };' ' }' '}' 'module.exports = { ask };' >> model.js"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Write the claim checker, part 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'const BANNED = [\"always\", \"never wrong\", \"guaranteed\", \"100%\", \"any question\"];' 'const TEXTS = [' ' { id: \"a\", text: \"Ask any question and get a guaranteed answer.\" },' ' { id: \"b\", text: \"Drafts a reply from your notes. It may be wrong, so check it.\" },' ' { id: \"c\", text: \"Always right, 100% of the time.\" },' ' { id: \"d\", text: \"Summarises a page. Not for medical advice.\" },' '];' > expect.js"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Write the claim checker, part 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function claims(text) {' ' const low = text.toLowerCase();' ' return BANNED.filter(function (b) { return low.includes(b); });' '}' 'function hasLimit(text) {' ' const low = text.toLowerCase();' ' return low.includes(\"may be wrong\") || low.includes(\"not for\");' '}' >> expect.js"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Write the claim checker, part 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' let fail = 0;' ' for (const t of TEXTS) {' ' const found = claims(t.text);' ' let verdict = \"warn\";' ' if (found.length > 0) verdict = \"fail\";' ' else if (hasLimit(t.text)) verdict = \"pass\";' ' if (verdict === \"fail\") fail++;' ' console.log(t.id + \" \" + verdict + \" \" + JSON.stringify(found));' ' }' ' console.log(\"fails \" + fail + \" of \" + TEXTS.length);' ' const msg = \"Write one short line saying what a note summary tool cannot do.\";' ' const reply = await ask([{ role: \"user\", content: msg }], \"It cannot check facts that are not in your notes.\", 30);' ' console.log(\"limit line: \" + reply.text);' '}' 'main();' >> expect.js"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Run the claim checker
docker exec -w /home/node/project agent node expect.jsShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
One possible output
| Line | What it shows |
|---|---|
| a fail ["guaranteed","any question"] | Two claims nobody can back |
| b pass [] | No claims, and it says it may be wrong |
| c fail ["always","100%"] | Two more claims |
| d pass [] | It says what it is not for |
| fails 2 of 4 | Half of these texts need rewriting |
The cells students fill in are left blank in this preview.