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

Free lesson

Vendor and model risk for AI features

After this lesson: I can say how much a feature depends on one supplier and what has no fallback.

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

What if the supplier changes tomorrow

Vendor risk is how much a feature depends on one supplier you do not control. It matters because a supplier can have an outage, raise a price or withdraw a model, and your feature then stops or costs far more.

You cannot remove the dependency, but you can see it, score it and plan a way out.

By the end of this lesson

Note

I can say how much a feature depends on one supplier and what has no fallback.

Key words

WordWhat it means
Dependencysomething the feature cannot work without
Single point of failureone dependency with no fallback
Withdrawala supplier retiring a model you use
Switching timethe days it takes to replace a dependency
Exit planthe written steps for leaving a supplier

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

List what the feature depends on

Write every dependency: the model, the data it reads, the tools it calls. For each, ask three things. Is there a fallback? How long would it take to replace? What happens to users meanwhile?

A dependency with no fallback is a single point of failure. Score it, then work from the top of the list.

Worked example: two dependencies

DependencyWeightNo fallback60 days to replaceScore
Chat model3doubles to 6adds 17
Docs search2has a fallbackonly 10 days2

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

Plan a way out before you need it

A supplier can retire a model, change its price or have a long outage. Decide now what you would do: a second model, a cache, a plainer answer, or a pause.

Write the exit plan down and test the second route sometimes. A fallback you never run may not work on the day. The module on cost, tracing and reliability shows how to choose a fallback for each failure.

A common mistake

Warning

Many people think a big supplier cannot fail, so no plan is needed. Big suppliers have outages, change prices and retire models too. Judge each dependency by what happens to your users when it goes, not by the supplier's size.

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 dependency score, part 1

Command
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' '' '// An invented design: what the feature depends on, whether a fallback exists, and the days to replace it.' 'const design = [' '  { name: \"Chat model\", kind: \"model\", fallback: false, days: 60 },' '  { name: \"Docs search\", kind: \"data\", fallback: true, days: 10 },' '  { name: \"Payments API\", kind: \"tool\", fallback: false, days: 20 },' '  { name: \"Speech to text\", kind: \"model\", fallback: true, days: 45 },' '];' 'const WEIGHT = { model: 3, data: 2, tool: 1 };' > vendor.js"

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

Write the dependency score, part 2

Command
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function score(d) {' '  let s = WEIGHT[d.kind];' '  if (d.fallback === false) s = s * 2;' '  if (d.days > 30) s = s + 1;' '  return s;' '}' >> vendor.js"

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

Write the dependency score, part 3

Command
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  let total = 0;' '  design.forEach(function (d) {' '    total = total + score(d);' '    console.log(d.name + \": \" + score(d) + (d.fallback ? \"\" : \" NO FALLBACK\"));' '  });' '  console.log(\"Total: \" + total);' '  const q = \"List three short questions to ask a supplier before a feature depends on them.\";' '  const r = await ask([{ role: \"user\", content: q }], \"1. How much notice do you give before a price change? 2. How long is an old version kept? 3. How do I export my data?\", 90);' '  console.log(\"One possible list: \" + r.text);' '}' 'main();' >> vendor.js"

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

Run the dependency score

Command
docker exec -w /home/node/project agent node vendor.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
Chat model: 7 NO FALLBACKThe highest score and a single point of failure
Docs search: 2A fallback and a short switching time
Payments API: 2 NO FALLBACKNo fallback, but a low weight
Speech to text: 4A fallback, but slow to replace
Total: 15The design as a whole
One possible list: ...Your own call. It differs each run, or says Recorded sample

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.