Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

Making AI features accessible

After this lesson: I can make an AI feature usable by people with different needs.

60 min lesson7 commandsAI coding agent lab: use opencode to explain and fix code, and check its work

Right, and still no use

A bank chat feature gives a correct answer in one long paragraph of hard words. One customer reads slowly. Another uses a screen reader. A third has a poor signal and waits ten seconds.

A right answer that a person cannot use is still a failure. Access is part of the quality of a feature.

By the end of this lesson

Note

I can make an AI feature usable by people with different needs.

Key words

WordWhat it meansExample
Screen readersoftware that reads a page out loud
Plain languageshort sentences and everyday words
Jargona hard word only experts knowsubsequently
Reading timehow long a reply takes to read
Alternativeanother way to do the same job

The cells students fill in are left blank in this preview.

Plain language can be checked by rule

Plain language is not a feeling. You can set rules. No sentence over 12 words. No word from a short list of jargon. No reply over 40 words.

A rule can be run over every recorded reply. The ones that break it are the ones to rewrite.

Time, waits and other ways in

Work out the reading time: words times 60, divided by words a minute. A 40 word reply at 120 words a minute takes 20 seconds. Slow readers need longer.

Show a visible wait for a slow reply, and let people stop it. Offer an alternative to chat: a button, a form or a phone number.

A common mistake

Warning

Many people think access is only about disability, so it can wait. It is about everyone: a tired person, a new reader, a bad signal. Test the rules on every reply and offer another way in, not only a chat box.

Write the model helper, part 1

Command
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

Command
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 plain language checker, part 1

Command
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'const RULES = { maxSentence: 12, maxWords: 40, jargon: [\"utilise\", \"subsequently\", \"parameter\"], wpm: 120 };' 'const REPLIES = [' '  { id: \"r1\", text: \"Press the green button. Then pick a date.\" },' '  { id: \"r2\", text: \"You should subsequently utilise the parameter menu to change the date before confirming.\" },' '  { id: \"r3\", text: \"Your order is on its way. It should arrive on Friday. If it does not, tell us and we will look into it.\" },' '];' > access.js"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Write the plain language checker, part 2

Command
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function words(text) {' '  return text.split(\" \").filter(function (w) { return w.length > 0; });' '}' 'function sentences(text) {' '  return text.split(\".\").map(function (s) { return s.trim(); }).filter(function (s) { return s.length > 0; });' '}' >> access.js"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Write the plain language checker, part 3

Command
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function problems(text) {' '  const out = [];' '  const longest = Math.max.apply(null, sentences(text).map(function (s) { return words(s).length; }));' '  if (longest > RULES.maxSentence) out.push(\"long sentence\");' '  if (words(text).length > RULES.maxWords) out.push(\"too long\");' '  const hard = words(text.toLowerCase()).filter(function (w) { return RULES.jargon.includes(w); });' '  if (hard.length > 0) out.push(\"hard words\");' '  return out;' '}' >> access.js"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Write the plain language checker, part 4

Command
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  for (const r of REPLIES) {' '    const secs = Math.ceil((words(r.text).length * 60) / RULES.wpm);' '    console.log(r.id + \" \" + words(r.text).length + \" words, \" + secs + \" s, \" + JSON.stringify(problems(r.text)));' '  }' '  const msg = \"Rewrite in plain words: You should subsequently utilise the parameter menu to change the date.\";' '  const reply = await ask([{ role: \"user\", content: msg }], \"Next, use the menu to change the date.\", 30);' '  console.log(\"plain: \" + reply.text);' '}' 'main();' >> access.js"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Run the plain language checker

Command
docker exec -w /home/node/project agent node access.js

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

One possible output

LineWhat it shows
r1 8 words, 4 s, []Short and plain, so no problems
r2 13 words, 7 s, ["long sentence","hard words"]One long sentence with two hard words
r3 23 words, 12 s, []Under every limit, so it passes

The cells students fill in are left blank in this preview.

About this lab and its source: AI coding agent lab: use opencode to explain and fix code, and check its work

Teaching a class? Set this module for your students with a teacher guide, marked assignments and a lab for every student.