Skip to content
Level 5 · Agentic EngineerProjectCapstone · page 3 of 790 minSXMN 8 GB
90Minutes
3Tools
3Sources
All fourTracks
Tools used on this page3

Capstone 2: The Inference Service

Validated on: written from the documentation cited above and from Parts 7, 9, 10 and 23; not yet validated on hardware on any track. The pieces were each built in those parts; this project assembles them and asks you to prove each one.

By the end of this project you will have a language-model service that somebody other than you can use, and a checklist in which every row names the command you ran and what it printed rather than what you intended to configure.

The distinction between this and the labs it is built from is that nothing here counts until it has been checked. Part 9 built the gateway, Part 7 put a front-end and a reverse proxy in front of an engine, Part 23 taught dashboards, security, backup and upgrades. The capstone version of all of that is one service with evidence attached, and the two rows people skip are the ones with dates in them: the backup you have restored, and the upgrade you have rolled back.

Five layers, and each fails in its own way. Drawing them out is worth the minute because almost every question in the troubleshooting section is really “which layer is this”.

One service, five layers

  1. Clientsa browser, an editor, an agent loop, a phone on the house networkknow one address, one key, one model name
  2. Reverse proxy with TLSthe only listener anything outside the machine can reachyou control this
  3. Gatewaypermanent model names, one key per application, limits, fallbacks, usage loggingthe front door
  4. Model switchloads and unloads engines on demand so that memory is a schedule rather than a raceoptional on a large machine
  5. Enginesone process per resident model, bound to the loopback address onlynever addressable directly
  6. Machinememory, accelerator, model library, metrics exportersthe budget from Capstone 1
Observability sits beside the whole stack rather than inside one layer: the engines expose their own metrics, the machine exposes its memory and power, and the dashboard reads both. The layer that is easiest to get wrong is the second from the bottom, because an engine that is reachable directly makes every key above it decorative.

Every track needs the plan from Capstone 1, the gateway from Part 9’s project, the front-end and reverse proxy from Part 7’s lab, and the monitoring stack from Part 23’s lab. About ninety minutes if those are in place, and considerably more if one of them was left half-configured, which is what this project is for. The memory floor is whatever the smallest model in your plan needs; the service itself adds little.

Track S — NVIDIA DGX Spark

All of it applies, with room to keep more than one model resident. The interesting question on this track is whether you need a model switch at all: with a large unified memory you may be able to keep the chat, coding and embedding models loaded together, in which case the switch layer collapses and the checklist should say so with the arithmetic from Capstone 1 behind it.

Track X — AMD Ryzen AI Max+ 395

All of it applies. Record which backend each engine was built against in the engine table, because the two available paths on this chip do not have the same working-memory appetite and the checklist’s memory row will differ between them. If the memory split between processor and graphics device is configurable on your machine, the value you set belongs in the checklist too.

Track M — Apple silicon

All of it applies, with two notes. This is usually somebody’s working machine as well as their server, so the row about what else the machine is doing is not a formality. And a Mac that sleeps stops serving: whatever you do about that belongs in the restart row of the checklist, along with what you observed rather than what you configured.

Track N — NVIDIA desktop or laptop

All of it applies, and this is the track where the model switch usually earns its place, because device memory is the scarce resource and two resident models is frequently one too many. If you are running under WSL2, add a row for what happens to the service when the host sleeps or the distribution shuts down.

Working directory and terminal roles

Prepare the course execution workspace once before this procedure. It includes this part's scripts, data and shared Python helpers. In the client or training terminal, select this directory:

RunnableAll tracks

select this part’s execution directory
export LABS_ROOT="${LABS_ROOT:-$HOME/llm-course/labs}"
export LAB_DIR="$LABS_ROOT/capstone"
cd "$LAB_DIR"
pwd
test -f "inference-service-checklist.md"

Expected result: pwd ends in capstone and the file check returns successfully. If it does not, finish workspace preparation before continuing. Activate the environment in the requirements for your track. Bare script and data filenames below are relative to this directory; paths to earlier experiments must point at the artefacts you actually retained.

Keep each foreground server in a separate terminal and send requests from this terminal. Reapply lesson-specific environment variables in each new shell. Stop at the first failed checkpoint and retain its output; the execution guide explains how to distinguish missing files, endpoint failures and capacity problems.

1. Start from the checklist, not from the terminal

Section titled “1. Start from the checklist, not from the terminal”

Fragment — not complete on its own

inference-service-checklist.md
# Inference service checklist — <the service you are building>
<!--
Purpose: the deliverable of Capstone 2. Not a list of intentions: every row names the
check that proves the item is true, the command that produced it and what it
printed. A row whose check has not been run is unfinished, and marking it so is
the useful state.
Platform: all
Minimum memory: 8 GB for the smallest configuration; the memory floor is whichever model
your service serves, from the Capstone 1 plan
Assumes: the gateway from Part 9's project, the front-end and reverse proxy from Part 7's
lab, the monitoring stack from Part 23's lab, and the backup and upgrade practice
from Part 23. This checklist assembles them into one service rather than teaching
them again.
Status values: "done" with evidence, "partial" with what is missing, or "not done" with
the reason. Delete every comment block, including this one.
No address, hostname or key belongs in this file if you intend to show it to anybody.
-->
**Author:** <you> · **Date:** <YYYY-MM-DD> · **Service name:** <name> ·
**Machines:** <from the Capstone 1 plan>
---
## 1. Engines, one row per model instance
| Machine | Engine and version | Model | Quantisation | Context configured | Started by | Check that it serves | What the check printed | Status |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| <name> | <e.g. llama.cpp bNNNN> | <id> | <e.g. Q4_K_M> | <n tokens> | <service unit, container, script> | <a request for the model list, and one completion> | <the model id it reported> | <done/partial/not done> |
**Key-value cache reported at startup, per instance:** <the figure the engine logged, in
tokens> · **Maximum concurrency it implies at your context:** <cache tokens ÷ context>
<Those two numbers are the capacity of your service and they cost nothing to read. Record
them here before any load test, because the load test will only confirm what they said.>
**Restart behaviour:** <what happens to an in-flight request when an engine restarts, and
whether the engine comes back by itself.>
## 2. The gateway
| Item | Value | Check | What it printed | Status |
| --- | --- | --- | --- | --- |
| Software and version | <LiteLLM, llama-swap, or both> | <version command> | | |
| Address it listens on | <loopback or the private interface; not written here> | <listening-socket listing> | | |
| Model names it exposes | <the permanent aliases, e.g. chat, coder, embed> | <the model-list endpoint> | | |
| Which engine each name reaches | <table or config file reference> | <one completion per name> | | |
| Keys, one per application | <how many, and what each is for> | <a request with the wrong key> | <the refusal> | |
| Per-key limits | <requests or tokens per minute, budgets, expiry> | <a request past the limit> | <the refusal> | |
| Fallbacks | <what happens when the first backend is down> | <stop a backend, send a request> | | |
| Usage logging | <where it goes and how long it is kept> | <a log line for a known request> | | |
<The gateway is the only thing a client should ever address, which is what makes the
permanent names worth more than the software: a model can be replaced underneath a name
without touching a single client.>
## 3. The front-end
| Item | Value | Check | Status |
| --- | --- | --- | --- |
| Software and version | <e.g. Open WebUI> | <version> | |
| Accounts | <how many, and whether registration is open> | <a second account's first login> | |
| Which gateway name it uses | <alias> | <a conversation that reaches the right engine> | |
| Context length per conversation | <n tokens, and what happens past it> | <a conversation long enough to find out> | |
| Where its data lives | <path or volume> | <its size> | |
## 4. Dashboards and alerts
**The questions the dashboard answers, written before the panels were built:**
1. <e.g. is the service up and answering?>
2. <e.g. how long is a request waiting?>
3. <e.g. how full is the key-value cache?>
4. <e.g. how much memory is each machine using?>
5. <e.g. how much power is each machine drawing?>
6. <e.g. what failed, and when?>
| Question | Panel | Metric source | Status |
| --- | --- | --- | --- |
| <1> | <panel name> | <the engine's metrics endpoint, the node exporter, the accelerator exporter> | |
| Alert | Condition | For how long | Where it goes | Proved to fire on | Status |
| --- | --- | --- | --- | --- | --- |
| <name> | <in words, not the query> | <duration> | <log, file, notification> | <YYYY-MM-DD, and what you did to trigger it> | |
<An alert that has never fired is an untested alert. Part 23's lab asks you to trigger one
deliberately; do it again here, on this service, and write the date.>
## 5. Authentication and transport security
| Item | Value | Check | What it printed | Status |
| --- | --- | --- | --- | --- |
| What is reachable from another machine | <the reverse proxy only> | <listening sockets on every machine> | | |
| TLS in front | <software, certificate kind: internal authority or public> | <a request from another device> | | |
| Certificate renewal | <automatic, and what happens if it fails> | <the expiry date the server reports> | | |
| Authentication on the gateway | <keys, one per application> | <an unauthenticated request> | <the refusal> | |
| Authentication on the front-end | <accounts; registration open or closed> | <an anonymous visit> | | |
| Engines reachable directly? | <they should not be> | <a request straight to an engine port from another machine> | <connection refused> | |
| Secrets | <where they live; never in a committed file> | <a search of the repository for the key> | | |
| Model provenance | <hash recorded beside each file; safetensors preferred> | <the verification command> | | |
<The row that matters most is the one about engines being reachable directly. A gateway
with keys in front of an engine that anybody on the house network can also address is not
an authenticated service; it is an authenticated service and an unauthenticated one.>
## 6. Backup and rollback
| Item | Value | Check | Status |
| --- | --- | --- | --- |
| What is backed up | <configuration, adapters, evaluation sets, the notebook, dashboards, front-end data> | <the archive's contents listing> | |
| What is not, deliberately | <model weights, replaced by repository, revision and hash> | <the manifest> | |
| Where it goes | <destination, and whether it survives the machine's failure> | | |
| Schedule | <how often, and what triggers it> | | |
| **Restore performed on** | <YYYY-MM-DD, into a scratch location> | <the comparison that showed it was intact> | |
| Version pinning | <container digests, not moving tags; package versions> | <the recorded digests> | |
| **Rollback performed on** | <YYYY-MM-DD> | <the upgrade, the return, and the request that worked afterwards> | |
<A backup that has not been restored is a hypothesis. Both dated rows above are the point
of this section, and both are commonly skipped.>
## 7. The service as a whole
| Question | Answer | Evidence |
| --- | --- | --- |
| What does a client have to know to use it? | <one address, one key, one model name> | |
| What happens when the machine reboots? | <which parts come back by themselves> | <a reboot, and what was running afterwards> |
| What happens when a model file is missing? | | |
| What is the slowest thing a user will notice? | | <a measurement label> |
| Who else uses it, and did it work for them? | <the household test> | <what they said> |
## 8. What is not done, and why
<Every "partial" and "not done" above, one line each, with the reason. This section is the
one a reader trusts the rest of the checklist on the strength of, and a checklist with
nothing in this section is a checklist that has not been read carefully.>

Download inference-service-checklist.md136 lines

RunnableAll tracks

start from the checklist
cp inference-service-checklist.md inference-service.md

Read it through before you configure anything. Half of the rows will already be true from earlier labs and can be filled in with the check you ran at the time, provided you re-run the check now rather than trusting your memory of it. The other half is the work.

Fill in status honestly as you go: “done” with evidence, “partial” with what is missing, or “not done” with the reason. A checklist with everything marked done and no evidence column is worth nothing, and the final section of the document is where the partials earn their keep.

2. Bring up the engines the plan asked for

Section titled “2. Bring up the engines the plan asked for”

One engine process per resident model, each bound to the loopback address, each with the context length from your Capstone 1 budget rather than whatever the engine defaults to.

Fragment — not complete on its own

Terminal window
llama-server \
--model "$MODELS/<the file from your plan>" \
--alias chat \
--host 127.0.0.1 \
--port 8081 \
--ctx-size 8192 \
--parallel 4 \
--metrics

Three things to record in the engine table as each one starts.

The key-value cache size the engine reports at startup, in tokens. Part 9 introduced this figure and every serving page since has asked for it, because it answers the capacity question before a single request arrives. Divide it by your configured context length and you have the number of conversations this instance can hold at once.

The peak memory the process actually occupies, against the arithmetic in your plan. Write both. The gap between them is one of the more interesting lines in Capstone 6.

How it is started, meaning the service unit, the container or the script, and whether it comes back by itself after a reboot. “I ran it in a terminal” is a legitimate answer for a machine you are sitting at and a bad one for a service other people use, and the checklist wants the truth rather than the intention.

3. Put the gateway in front and give the models permanent names

Section titled “3. Put the gateway in front and give the models permanent names”

The gateway is the only thing a client should ever address. Part 9’s project built it; this step is about the properties that make it a service rather than a convenience.

Permanent names. Three at minimum, from your plan: a chat name, a coding name and an embedding name. Clients learn the name, never the model behind it, which is what lets you replace the model in Capstone 4 without touching a single configuration file anywhere else.

One key per application, not one key. The front-end has its own, each agent has its own, and your own experiments have another. LiteLLM’s virtual keys documentation covers the properties that make this worth doing: per-key spending budgets, requests-per-minute and tokens-per-minute limits, an expiry duration, and rotation. A key you cannot revoke without breaking everything else is a key you will never revoke.

Limits with a number in them. Pick a requests-per-minute figure that your capacity arithmetic supports and set it. The point is not to ration your household; it is that a runaway agent loop is the most likely cause of your service falling over, and the limit turns that from an outage into a refusal.

A fallback, and a test of it. Stop one engine and send a request. What the client sees is a property of your service, and you should know it before somebody else finds out.

Fragment — not complete on its own

Terminal window
curl -sS "$GATEWAY/v1/models" \
-H "Authorization: Bearer $A_KEY_FROM_YOUR_ENVIRONMENT"

Record what the model list printed. Every name in your plan should be there, and nothing should be there that is not in your plan.

4. The front-end, and a person who is not you

Section titled “4. The front-end, and a person who is not you”

Bring up the front-end from Part 7’s lab against the gateway’s chat name. Then do the part that is easy to skip: create a second account for somebody in your household, and have them use it from their own device.

This is the only test in the capstone that finds a whole category of problem. Certificates that your machine trusts and theirs does not. A context length that truncates a long conversation without saying so. A model that answers your questions well and theirs badly. A registration page open to anybody on the network. None of those show up when the author tests their own service.

Record what they did, what worked and what they asked you about. The questions are the useful part.

5. Dashboards that answer questions you wrote down first

Section titled “5. Dashboards that answer questions you wrote down first”

Part 23’s lab asks for six questions before any panel is built. Write yours into the checklist before you open the dashboard, and then build one panel per question.

The six that most household services need: is it up and answering; how long is a request waiting; how full is the key-value cache; how much memory is each machine using; how much power is it drawing; and what failed and when. Yours may differ, and the point is that they were chosen rather than inherited from an example dashboard.

Every panel names its metric source in the checklist: the engine’s own metrics endpoint, the machine exporter, or the accelerator exporter for your track. A panel with no source named is a panel nobody will be able to fix in six months.

The Prometheus project’s guidance on alerting is to alert on symptoms associated with somebody’s actual pain rather than on every possible cause of it, and to leave enough slack that a small blip does not wake anybody. For a household service that usually means two rules: the service is not answering, and requests are taking far longer than the budget in your requirement.

Write the condition in words in the checklist rather than as a query. Then trigger it deliberately: stop the engine, or send enough concurrent requests to push the latency past your threshold, and watch the rule change state. Record the date, what you did, and how long it took to fire.

7. Authentication and transport security, checked from another machine

Section titled “7. Authentication and transport security, checked from another machine”

Five checks, and the order matters because each one can hide the failure of the one below.

  1. What is listening, on every machine. List the listening sockets and read the addresses. Engines should be on the loopback address only. If an engine is bound to every interface, everything above it is decorative.
  2. A request straight to an engine port from another device. It should be refused. This is the check that proves the previous one rather than merely reading it.
  3. An unauthenticated request to the gateway. It should be refused, and you should record what the refusal looks like.
  4. A request over TLS from another device. Caddy’s automatic HTTPS documentation is clear about which names it will and will not obtain a public certificate for: local and internal names, and addresses, get a certificate from its own internal authority, which the other devices in your house have to be told to trust. Whichever route you took in Part 7, record what a client has to do to trust it, because that is what your household will ask.
  5. A search of your own files for the key. Secrets live in the environment or in a file that is not committed. This check takes seconds and is the one that saves you from publishing a key alongside a configuration file.

Add the supply-chain row while you are here: prefer weights in a format that is not executable, record a hash beside every model file, and keep the repository and revision with it. Part 23 made the case; the checklist is where your service records that it was done.

8. A backup you have restored, and an upgrade you have rolled back

Section titled “8. A backup you have restored, and an upgrade you have rolled back”

Two rows with dates in them, and they are the two most commonly skipped in this whole part.

The restore. Take the backup, then restore it into a scratch location and compare. What is in it: configuration, adapters, evaluation sets, the notebook, the dashboards and their alert rules, the front-end’s data. What is deliberately not in it: model weights, replaced by the repository, the revision and the file hash, because copying gigabytes you can fetch again is not a backup strategy. Write the date you last restored, not the date you last backed up.

The rollback. Upgrade one engine, run a request, then go back to the previous version and run it again. Pin container images by digest rather than by a moving tag so that “the previous version” means something. Record the date and what worked afterwards.

9. Finish the checklist, including what is not done

Section titled “9. Finish the checklist, including what is not done”

Fill in the last section: every “partial” and “not done”, one line each, with the reason.

This section is not an apology. It is what a reader trusts the rest of the checklist on the strength of, and a service document with nothing in it is one that has not been read carefully. In Capstone 6 these lines go straight into the report’s section on what is not true here.

Prove the service from a user’s entry point

Section titled “Prove the service from a user’s entry point”

Use the exact artefacts and limits from the hardware plan. Start engines first, verify their required features, then add the gateway and front end. Keep the direct engine ports within the intended boundary and test the authenticated user path from another device.

Complete both positive and negative checks: permitted chat works, missing or invalid credentials fail, forbidden direct access is blocked and an oversized request receives the intended response. Run the representative load and capture latency, failures and memory. Trigger one alert and confirm recovery clears it.

Restore the backup into an isolated instance and verify a known user-visible record plus a model request. Test an upgrade and rollback with the same acceptance suite. Record operator steps and elapsed recovery time. Keep the checklist linked to actual logs and result files rather than marking boxes from memory. The service deliverable is complete when another operator can identify the model behind every alias, start and stop the stack, diagnose an unavailable worker and recover the intended state. A health endpoint and a successful screenshot alone do not establish those service properties.

  • inference-service.md has a status and an evidence column filled for every row.
  • Every engine row carries the key-value cache size the engine reported at startup and the peak memory the process occupied.
  • The gateway’s model list, fetched with a key, contains exactly the names in your plan.
  • A request with a wrong or missing key is refused, and the refusal is recorded.
  • A request from another device straight to an engine’s port is refused.
  • A request from another device over TLS to the reverse proxy succeeds, and the checklist says what that device had to do to trust the certificate.
  • A person who is not you has used the front-end from their own device.
  • Each of the six dashboard questions has a panel, and each panel names its metric source.
  • At least one alert has a date in the “proved to fire” column, with what you did to trigger it.
  • The backup has a restore date and the comparison that showed it was intact.
  • One engine has been upgraded and rolled back, both dated.
  • The final section lists every incomplete row with its reason.

A service your household uses, and a document in which every claim about it points at something you ran. The shape below is what the checklist commits to; the evidence column in your own copy holds the command output or the notebook label.

Pending validationWhat a finished service commits to — the shape, to be filled in with your own
LayerWhat is provedThe check that proves it
Enginescapacity, in conversations, before any load testthe key-value cache size in the startup log, divided by the configured context
Enginesnot reachable from another machinea refused request to the engine port from a second device
Gatewaythe names clients use are the names in the planthe model list, fetched with a key
Gatewaya wrong key is refused and a runaway client is limiteda refused request, and a request past the rate limit
Front-endsomebody other than the author can use ita second account, used from their own device
Observabilitysix questions have six panelsthe dashboard, with a metric source named per panel
Observabilityan alert firesa deliberately induced condition, with the date
Transportonly the proxy is reachable, and it is over TLSthe listening sockets, and a request from another device
Backupthe archive restoresa restore into a scratch location, with the comparison
Upgradesa version can be undonean upgrade and a rollback, both dated

the machines in your Capstone 1 plan · the engines your plan chose the versions recorded in your checklist · the models behind your gateway names, as the plan states · 8,192 tokens of context · 2026-09-09

This table describes a service rather than measuring it. Every row is a check with a result, and the results go in your own checklist rather than here.

Two services count as finished. One is a single machine running three engines behind a gateway behind a proxy, used by two people, with a dashboard on a second screen. The other is several machines with the same shape spread across them. The document is the same in both cases, and so is the standard: every row has a check, and the checks were run.

Everything works for you and nothing works for anybody else. Almost always the certificate or the address. The other device has not been told to trust your internal certificate authority, or it is resolving a name your machine resolves differently. Part 7’s lab covers both; the reason it turns up here is that the author’s own machine is the one device that never exercises the path.

The gateway returns a model that is not in your plan. Something is configured from an earlier lab and still loaded. Reconcile the model list against the plan and delete what does not belong; an alias nobody knows about is a model that will surprise somebody in six months.

The second model fails to load when the first is resident. A Capstone 1 arithmetic error, an allowance that was too small, or fragmentation. Record the two numbers and either introduce the model switch layer so that memory becomes a schedule, or reduce a context length with the arithmetic to say by how much.

The alert does not fire when you stop the engine. Check that the rule’s target still exists when the engine is gone. A rule written against a metric that simply disappears has nothing to evaluate, which is a different condition from the one you meant to catch, and it is the commonest reason a monitoring stack is quiet during an outage.

Requests hang rather than failing. A missing timeout somewhere in the chain: the proxy, the gateway or the client. Decide what your service should do when an engine is wedged and configure it, because the default in several of these layers is to wait a very long time.

The restore test overwrote something. Restore into a scratch directory. If it is too late, this is the moment the estate manifest from Part 23 earns its place, and it is worth writing what happened into the checklist’s final section.

Leave the service running: the next three deliverables use it. What to tidy is the scaffolding around the checks. Remove the scratch directory the restore went into, revoke any temporary key you created for testing, stop the load you generated for the alert, and delete the second account if the person who tested it does not want to keep it.

If you are stopping here for now, write in the checklist what is running and how to stop it cleanly. A service nobody knows how to stop is one that will be stopped badly.

  • A check beats an intention. The whole difference between this project and the labs it reuses is that every row names something you ran and what it printed.
  • Capacity is in the startup log. The key-value cache size divided by your context length answers “how many people at once” before any load test, and it costs one launch.
  • One key per application is what makes revocation possible. A single shared key is a key that will never be rotated, and the limits and expiry attached to per-application keys are what turn a runaway loop into a refusal.
  • The engines must not be reachable. Authentication in front of an open port is decorative, and the only way to know is to try it from another machine.
  • A backup is a hypothesis until it is restored. So is a rollback. Both rows have dates for that reason.
  • Somebody else using it finds things you cannot. The household test is the cheapest quality check in the capstone.

Record in the notebook: the key-value cache size and the peak memory for every engine, the gateway names and what each one resolves to today, the date of the restore and the date of the rollback, and one sentence on the thing that was broken and you did not know about.

Check your understanding

Question 1. Your gateway requires a key, and your engines listen on every interface. What is true?
Show the answer and why

Answer: The service offers both an authenticated path and an unauthenticated one, and clients will eventually find the second

Access control at one layer is not access control if a layer below is reachable directly. This is why the checklist asks for a refused request to an engine port from a second machine: reading the configuration is not the same as testing it.

Question 2. Where does the capacity of an engine instance, in concurrent conversations, come from?
Show the answer and why

Answer: The key-value cache size the engine reports at startup, divided by the context length you configured

Every conversation holds its whole key-value state until its answer finishes, so the cache divided by the context is the number of conversations that fit. A load test confirms it; the startup log tells you before you run one, which is why Part 9 and every serving page since has asked for that figure.

Question 3. Which rows on the checklist require a date? Select all that apply.
Show the answer and why

Answer: The backup restore, The rollback of an upgrade, The alert being proved to fire

All three are things that decay: a backup that restored a year ago may not restore today, a rollback path breaks when a tag moves, and an alert stops matching when a metric is renamed. The model behind a name is recorded but does not need a date, because changing it is a deliberate act you would notice.

Question 4. The Prometheus project advises alerting on symptoms rather than on every possible cause. Applied to a household model service, which rule follows that advice best?
Show the answer and why

Answer: Alert when requests are not being answered, or are taking far longer than the budget in your requirement

The symptom is somebody waiting or being refused. Processes restart, memory rises and individual requests fail for many reasons that nobody needs to be told about; a rule for each cause produces noise that trains you to ignore the one that mattered. The project also advises enough slack that a small blip does not fire.

Question 5. True or false: because you can download the model weights again at any time, they do not need to be in the backup.
Show the answer and why

Answer: True

True, and it is Part 23's explicit practice: back up the irreplaceable small things, and replace the weights with a repository, a revision and a file hash. What that requires is that the repository, the revision and the hash are actually recorded, which is the row of the checklist that makes this substitution honest rather than merely convenient.

Sources for this lesson

3 verified · checked 2026-09-09

  1. 01LiteLLM — Virtual Keys§ Budgets; rate limits; key expiry and rotationdocs.litellm.ai/docs/proxy/virtual_keys2026-09-09
  2. 02Caddy — Automatic HTTPS§ Local certificate issuance; which names qualify for public certificatescaddyserver.com/docs/automatic-https2026-09-09
  3. 03Prometheus — Alerting practices§ What to alert on; symptom-based alertingprometheus.io/docs/practices/alerting2026-09-09

Every technical claim on this page was checked against the official documentation of the tool, vendor or model publisher on the date shown, at the version pinned for the course. Where the course disagrees with folklore, the source is how you can tell which one to trust.