Simon Willison just shipped version 0.33 of LLM, his open-source command-line tool for talking to large language models. According to Simon Willison, this release cleans up plumbing under the hood and hands users two features worth caring about: per-call API keys for embeddings and the ability to stack prompt templates. This follows a quick 0.32.1 hotfix he pushed a day earlier, which he calls the rough version of a fix that’s now done properly.
What stands out here is how these changes make the tool more flexible for people juggling multiple models and keys. Let’s go through what actually landed.
🔑 What’s new in LLM 0.33
- Per-call keys for embeddings. The
llm embedandllm embed-multicommands now accept a--keyflag. On the Python side,EmbeddingModel.embed(),embed_multi(), and the matchingCollectionmethods take akey=argument too. That resolved key gets passed straight to embedding plugins without touching shared model state, which matters if you’re switching between accounts or providers mid-script. Credit goes to contributor ChrisJr404 for this one. - Backward compatibility built in. Willison notes that existing plugins reading
self.keykeep working through a compatibility fallback. So plugin authors don’t have to scramble to update anything. Embedding models now handle keys the same way regular LLM models already do, which removes an inconsistency that’s been there for a while. - Stackable prompt templates. The
-t/--templateflag onllm promptcan now be repeated, combining templates in order. This means you can pull model configuration and options from one template and the actual prompt from another. It’s a small change that unlocks a genuinely useful pattern. - Package a model with its defaults. Here’s the pattern Willison highlights. You save one template that bundles a model plus its options, like
llm -m gpt-5.6-luna -o reasoning_effort high --save lhigh. You save another that holds just a prompt, like the SVG pelican example he saves aspelican. Then you run them together withllm -t lhigh -t pelican. Model config lives in one place, the prompt lives in another, and you mix and match. - Dependency upgrades under the hood. The release moves to the OpenAI Python library 3.x and swaps the HTTP client from httpx to httpx2. This is the maintenance work that keeps the tool current with the libraries it leans on.
🎯 Why it matters
The template-stacking feature is the practical star here. If you’re testing different models that each provide their own imitation of the OpenAI Responses API, you can now keep your model setups and your prompts as separate, reusable building blocks. Willison points to exactly this use case: exercising multiple models without rewriting your prompts every time.
The per-call key support is quieter but solves a real headache. Anyone running embeddings across different providers or billing accounts no longer has to fiddle with shared model state to swap credentials. And because old plugins keep working, nobody gets left behind on the upgrade.
LLM is free and open source, so anyone can grab this release and use it today. It runs local models and hosted APIs alike, which makes it a favorite for developers who want one consistent interface across the whole model landscape.
🔭 What comes next
These incremental releases are how LLM stays sharp. Each one files down a rough edge, and 0.33 files down two that power users bump into often: key handling and template reuse. The dependency bumps also signal the tool is keeping pace with the fast-moving OpenAI library, which reduces the odds of breakage down the road.
If you’re already running LLM, the upgrade is worth it just for the template stacking. Full details on every change, including the linked GitHub issues, are available at the original source.