swap-llm
Change which language model the AI service uses (Anthropic, OpenAI, another provider, a local model, or an LLM gateway such as LiteLLM), or add a fallback. Use when the user decides on a different or
Files1
View on GitHubSKILL.md.claude/skills/swap-llm/SKILL.md
GitHubSwap the model
- Seam: a Pydantic AI model name.
create_model(name, fallback)inapps/ai/app/assistant.pybuilds the assistant's model (aFallbackModelwhen a fallback is set);create_summariesinapps/ai/app/documents.pyuses the same setting for document summaries. - Today:
local:extractivelocally (quotes the best passage, no model or key; refused in production byapps/ai/app/settings.py). - Env:
AI_MODEL,AI_FALLBACK_MODEL, and the provider's own key, which Pydantic AI reads from the environment (e.g.ANTHROPIC_API_KEY,OPENAI_API_KEY). Budgets:AI_MONTHLY_TOKENS_PER_ORG,AI_TOKENS_PER_RUN. UnsetAI_MODELturns the assistant off.
Swap
- Any provider Pydantic AI supports: set
AI_MODEL(e.g.anthropic:claude-sonnet-5,openai:gpt-5) and its key: locallybun run env:set, deployed in the ai service's SOPS Secret (rotate-secrets skill). No code. - A gateway with an OpenAI-compatible API (LiteLLM and most routers):
AI_MODEL=openai:<model the gateway serves>, withOPENAI_BASE_URLandOPENAI_API_KEYpointing at the gateway. No code. - Something Pydantic AI doesn't support: add a branch in
create_modelreturning apydantic_ai.models.Model, like_local_extractive(). - Measure before switching production:
bun run --cwd apps/ai evalsagainst the new model (CI runs them nightly with theEVAL_MODELvariable).
Tests
apps/ai/tests/test_units.py and apps/ai/tests/test_service.py run on
local:extractive; apps/ai/tests/test_evals.py checks the evals themselves.
Finish
- The verify skill.
- Ask the
revieweragent to review the change, and thesecurity-revieweragent: a new implementation brings its own credentials and sends data somewhere new. If you wrote a migration, themigration-revieweragent too. The change is in apps/ai, so thepython-revieweragent as well. - Update the seam's row in the README's "Scaling path" table if what's "Now" changed.