Was that a person or a program?
AI transparency means telling people when they are dealing with an AI system, and showing what it made. It matters because people trust a reply differently when they know a program wrote it.
Record keeping is the other half. When something goes wrong, a review needs to know what was asked, which model answered and who approved it.
By the end of this lesson
Note
I can tell people when they are dealing with AI, label what it made and keep the records a review needs.
Key words
| Word | What it means | Example |
|---|---|---|
| Disclosure | telling a person they are dealing with AI | |
| Label | a visible mark saying AI made something | |
| Record | a saved note of one AI answer | |
| Model version | the exact model that answered | v3 |
| Retention | how long a record is kept | |
| System card | a short page describing an AI feature |
The cells students fill in are left blank in this preview.
Tell people they are dealing with AI
Say it before a person relies on the reply, where they will see it. Put it at the start of a chat, beside an answer or in the first words of a call.
Add in one line what it can and cannot do, and how to reach a person. Setting expectations in depth is taught in How to set expectations for an AI feature.
Label what AI made
Text, an image or a summary made by a model carries a short label the reader can see. A label says who made it, not whether it is good.
Where a file leaves your product, put a note in its details as well. Then the label is still there after somebody copies the file.
Worked example: where to say it
| Place | What the person sees |
|---|---|
| Start of a chat | You are chatting with an AI assistant. A person can take over. |
| Under an image | Made with AI |
| Foot of an email draft | Drafted by AI, checked by Sam Ade |
| First words of a call | This is an automated assistant. |
The cells students fill in are left blank in this preview.
What a record needs to hold
A record holds what was asked, which model version answered and which person approved an action. Without the version, nobody can say which model made a mistake.
Keep a record only as long as a review needs it, and leave out personal data it does not need. Safe logging is taught in Logging safely in an AI app, and personal data in Privacy and data protection for AI apps.
A common mistake
Warning
Many people think more records are always safer, so they keep everything for ever. A record full of personal data, kept for years, is a risk of its own. Keep only the fields a review needs, for as long as it needs them.
A short system card describes the feature
A system card, or model card, is one short page about an AI feature or a model. It gives its purpose, its limits, how it was evaluated, who owns it and how to contact them.
Write it for a person who has never seen the feature. A blank field is a gap, just like a gap in a review.
Rules are asking for this more often
Rules in the EU and the UK increasingly ask builders to tell people about AI, label what it makes and keep records. What a rule asks, and from when, differs by place and changes.
This is general information, not legal advice: check the current official text or ask someone qualified. Doing these things does not by itself make a product meet any rule.
Worked example: a short system card
| Field | Order helper |
|---|---|
| Purpose | Answers questions about orders |
| Limits | Cannot change payments or addresses |
| Evaluations | 40 recorded cases, 37 passed |
| Owner | Ana Cole |
| Contact | [email protected] |
The cells students fill in are left blank in this preview.
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 records check, part 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' '' 'const KEEP_DAYS = 90; // a record older than this is deleted' '// Invented records of a support assistant. The age is a number of days, not a clock.' 'const records = [' ' { id: 1, asked: \"Where is my order?\", version: \"v3\", action: false, approvedBy: \"\", age: 12, personal: false },' ' { id: 2, asked: \"Refund order 88\", version: \"v3\", action: true, approvedBy: \"\", age: 30, personal: false },' ' { id: 3, asked: \"Change my address\", version: \"\", action: true, approvedBy: \"Sam Ade\", age: 120, personal: false },' ' { id: 4, asked: \"Why was I charged twice?\", version: \"v2\", action: false, approvedBy: \"\", age: 5, personal: true },' '];' > records.js"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Write the records check, part 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function problems(r) {' ' const found = [];' ' if (r.asked.trim() === \"\") found.push(\"no question\");' ' if (r.version.trim() === \"\") found.push(\"no model version\");' ' if (r.action && r.approvedBy.trim() === \"\") found.push(\"no approver\");' ' if (r.age > KEEP_DAYS) found.push(\"past keep date\");' ' if (r.personal) found.push(\"needless personal data\");' ' return found;' '}' >> records.js"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Write the records check, part 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' '// A short card for the feature. Every field should hold words.' 'const card = { purpose: \"Answer order questions\", limits: \"Cannot change payments\", evaluations: \"\", owner: \"Ana Cole\", contact: \"[email protected]\" };' >> records.js"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Write the records check, part 4
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' records.forEach(function (r) {' ' const p = problems(r);' ' console.log(\"Record \" + r.id + \": \" + (p.length === 0 ? \"ok\" : p.join(\", \")));' ' });' ' const empty = Object.keys(card).filter(function (k) { return card[k].trim() === \"\"; });' ' console.log(\"Card missing: \" + (empty.length === 0 ? \"nothing\" : empty.join(\", \")));' ' const q = \"Write one short sentence a chat window shows to tell a user they are talking to an AI system.\";' ' const r = await ask([{ role: \"user\", content: q }], \"You are chatting with an AI assistant. It can make mistakes, and a person can take over.\", 60);' ' console.log(\"One possible notice: \" + r.text);' '}' 'main();' >> records.js"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Run the records check
docker exec -w /home/node/project agent node records.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 |
|---|---|
| Record 1: ok | Nothing is missing |
| Record 2: no approver | A refund with no person named |
| Record 3: no model version, past keep date | Nobody knows which model answered, and it is too old |
| Record 4: needless personal data | It holds more than a review needs |
| Card missing: evaluations | The card says nothing about testing |
| One possible notice: ... | Your own call. It differs each run, or says Recorded sample |
The cells students fill in are left blank in this preview.