Appendix B — Model Access
Every setting this book needs, in one place: which server answers, which models fill which roles, what each chapter spends, and what to check when nothing answers.
The package resolves its configuration in a fixed order, weakest first: built-in defaults, then the config file at ~/.hands-on-ai/config.json, then environment variables, which win over everything. handsonai doctor prints the resolved result and probes the server. handsonai config shows and edits the file layer. handsonai models lists what your server reports. When in doubt, run the doctor before touching code; it reads the same configuration your scripts will, in the same order.
B.1 The Settings
| Variable | Role | Default |
|---|---|---|
HANDS_ON_AI_SERVER |
Chat, embedding, and vision server address | http://localhost:11434 |
HANDS_ON_AI_API_KEY |
Key for every server above | unset (local servers ignore it) |
HANDS_ON_AI_MODEL |
Chat model | llama3 |
HANDS_ON_AI_EMBEDDING_MODEL |
Retrieval embeddings, Chapter 6 | nomic-embed-text |
HANDS_ON_AI_VISION_MODEL |
Vision model, Chapter 13 | moondream |
HANDS_ON_AI_STT_SERVER |
Speech-to-text server, Chapter 14 | the main server |
HANDS_ON_AI_STT_MODEL |
Transcription model | whisper-1 |
HANDS_ON_AI_TTS_SERVER |
Text-to-speech server, Chapter 14 | the main server |
HANDS_ON_AI_TTS_MODEL |
Speech model | kokoro |
HANDS_ON_AI_CACHE |
Response cache directory | unset, caching off |
HANDS_ON_AI_LOG |
Set to debug for verbose logging |
unset |
Each row has a matching key in the config file (server, api_key, model, embedding_model, vision_model, stt_server, stt_model, tts_server, tts_model) for settings you want to survive terminal sessions. Environment variables still take precedence.
B.2 The Free Local Path
Ollama covers chat, embeddings, and vision from one install at http://localhost:11434 with no account and no key. The pulls this book needs:
ollama pull llama3 # chat (Parts I to IV)
ollama pull nomic-embed-text # retrieval (Chapter 6)
ollama pull moondream # vision (Chapter 13)Audio is the local exception. Transcription and speech typically come from a small separate server that speaks the same /v1/audio/ dialect: speaches or whisper.cpp serving a Whisper model for speech-to-text, Kokoro or Piper for text-to-speech. Point HANDS_ON_AI_STT_SERVER and HANDS_ON_AI_TTS_SERVER at them and Chapter 14 works untouched. Local everything is the private, offline, per-call-free route; its costs are your hardware’s limits on model size and patience, felt most in Parts III and V.
B.3 Hosted Providers
Any service exposing the OpenAI-compatible chat and embeddings endpoints can drive most of the book through the three variables from Chapter 4. The package documentation carries worked examples; the shapes are uniform:
export HANDS_ON_AI_SERVER="https://api.openai.com" # OpenAI
export HANDS_ON_AI_SERVER="https://openrouter.ai/api" # OpenRouter
export HANDS_ON_AI_SERVER="https://api.groq.com/openai" # Groq
export HANDS_ON_AI_API_KEY="your-key-here"
export HANDS_ON_AI_MODEL="the-provider's-model-name"Audio and vision coverage varies by provider, so check the endpoints you need before a Part V weekend. Free tiers come and go and are deliberately not enumerated here; the package documentation and the providers are the live sources. One classroom pattern: one shared local or hosted server behind a key, the three variables issued to students, and the cache (below) warmed before the lesson so a network failure cannot fail thirty exercises at once.
B.4 What Each Chapter Spends
Local calls cost time; hosted calls cost money per token. Either way, the shape of the spend per build is knowable in advance:
| Build | Calls, roughly |
|---|---|
| Part I scripts | 1 per line you run |
Conversation |
1 per turn, over a resent transcript that grows |
| Indexing, Chapter 6 | 1 embedding call for all chunks, then 1 per question plus its embedding |
| One agent run | 1 per iteration, up to max_iterations |
| One judged loop iteration | 1 step call + 1 judge call |
| One ratchet proposal | 1 step call + 1 scoring call, plus 1 to score the start |
| One vision question | 1, carrying a large payload, on a slow clock |
| One voice turn | 1 transcription + 1 chat + 1 synthesis |
Budgets in the chapters (max_iters, max_iterations) are counted in iterations, not calls. Multiply before you fund a run.
B.5 The Response Cache
Setting HANDS_ON_AI_CACHE to a directory turns on a plain-text reply cache for get_response: identical model, system prompt, and question return the stored answer without contacting a server, and with token usage reported as None. Warm it once for a classroom and reruns become reproducible, offline-capable, and free. Clear it by deleting the directory. Remember from Chapter 4 that it is also a folder of transcripts on disk, and that a model or prompt change does not invalidate old entries until the name inside the lookup changes. Note its scope: the cache sits in get_response, so direct Conversation turns and vision calls bypass it.
B.6 Troubleshooting
| Symptom | Likely cause | First check |
|---|---|---|
❌ Error: Connection error. |
Server off, wrong address, blocked network | handsonai doctor; read the resolved server aloud |
| Error naming a model | Model never pulled, or name mismatch | handsonai models; compare with your settings exactly |
| 401 or 403 from a hosted server | Missing or wrong key | HANDS_ON_AI_API_KEY present in this terminal |
| Chat works, Chapter 6 fails | Embedding model missing | ollama pull nomic-embed-text, or the embedding setting |
| Chapter 13 fails, chat fine | Vision model missing or not vision-capable | vision_model setting; pull moondream |
| Chapter 14 fails, all else fine | Audio needs its own server | STT/TTS server variables actually set |
| Answers never change however you edit | The cache is serving stored replies | Unset HANDS_ON_AI_CACHE or delete the directory |
| Agent replies look unstructured | Small model in the text format | Let format="auto" choose, as Chapter 8 discussed |
| Everything worked yesterday | Settings were terminal-session exports | Put durable choices in ~/.hands-on-ai/config.json |
One habit resolves most rows: run the doctor, read what it resolved, and argue with settings before arguing with scripts. The scripts in this book are short and seldom the problem; when they are, the error strings Part I taught you to read will usually say which line to look at.