How to Select Different LLM Providers in Chapter CLIs
The chapter CLIs in bojieli/ai-agent-book obtain their selectable LLM providers from the centralized provider registry in agentbook/providers/registry.py, exposing them via the --provider command-line flag.
Every chapter-specific CLI in this repository shares a unified mechanism for selecting large language model backends. Rather than hardcoding provider endpoints in each script, the codebase leverages a single registry that defines canonical providers, aliases, and supported choices. This architecture allows you to switch between providers like DashScope, OpenRouter, or Moonshot using a consistent interface across all chapters.
How the Provider Registry Works
The registry located at agentbook/providers/registry.py serves as the authoritative source for all LLM provider configurations in the project. When you select a provider via command line, the CLI validates your choice against this central registry.
The PROVIDERS Dictionary
The PROVIDERS dictionary holds the canonical definitions for each supported LLM service. Each entry specifies the provider name, API endpoint, default model, and required environment variables for authentication. This dictionary acts as the single source of truth for provider capabilities and connection parameters.
Alias Mapping with _ALIASES
The _ALIASES dictionary maps short or historic names to their canonical entries. For example, the alias moonshot resolves to the canonical provider kimi, while ark and google map to their respective canonical configurations. This allows users to invoke familiar shorthand names while the system internally resolves them to standardized definitions.
SUPPORTED_PROVIDERS Tuple
The SUPPORTED_PROVIDERS tuple is pre-computed to include every canonical provider name plus every registered alias. Chapter CLIs import this tuple directly from agentbook.providers.registry and pass it to argparse as the choices parameter for the --provider argument. Because the CLIs reference this tuple dynamically, any provider added to the registry immediately becomes selectable without modifying individual CLI scripts.
Using the --provider Flag in Chapter CLIs
Every chapter CLI follows the same pattern for exposing provider selection. For example, the execution tools CLI in chapter 4 defines its provider argument as:
# chapter4/execution-tools/cli.py
parser.add_argument(
"--provider",
help="LLM 提供商(覆盖 PROVIDER,如 dashscope/qwen/bailian/kimi/doubao/siliconflow/openrouter)",
)
The choices parameter is automatically populated with SUPPORTED_PROVIDERS, restricting input to valid registry entries. You can invoke any chapter CLI with your preferred backend:
# Use the default provider (openrouter)
python -m chapter4.execution-tools.cli ...
# Switch to DashScope (Alibaba Cloud)
python -m chapter4.execution-tools.cli --provider dashscope ...
# Use the Moonshot alias (resolves to kimi)
python -m chapter4.execution-tools.cli --provider moonshot ...
# Short flag variation (if implemented in the specific CLI)
python -m chapter4.execution-tools.cli -p siliconflow ...
Step-by-Step Provider Resolution
When you specify a provider via the command line, the system executes a five-stage resolution pipeline:
-
Registry Import – The CLI imports
SUPPORTED_PROVIDERSfromagentbook.providers.registry, which evaluates the current state ofPROVIDERSand_ALIASES. -
Argument Validation –
argparsevalidates your input against thechoices=SUPPORTED_PROVIDERSconstraint, rejecting invalid names before execution continues. -
Canonicalization – The code calls
canonical_provider(name)from the registry module to resolve any alias to its canonical key (e.g., convertingmoonshottokimi). -
Specification Lookup – The canonical name is passed to
lookup(canonical), which returns the provider dataclass containing endpoint URLs, default models, and required environment variables. -
Backend Instantiation – Finally,
resolve_backend(provider, model, ...)fromagentbook/providers/resolution.pyconstructs the concrete client object, injecting API keys from environment variables and configuring the appropriate endpoint.
This resolution chain ensures that selecting different LLM providers in chapter CLIs requires only a single flag change, while the underlying machinery handles authentication and endpoint configuration automatically.
Programmatic Provider Selection
You can also select providers programmatically within chapter scripts for dynamic backend switching:
from agentbook.providers.registry import lookup, canonical_provider, SUPPORTED_PROVIDERS
from agentbook.providers.resolution import resolve_backend
# Validate user input against supported choices
user_input = "moonshot"
if user_input not in SUPPORTED_PROVIDERS:
raise ValueError(f"Provider must be one of: {SUPPORTED_PROVIDERS}")
# Resolve alias to canonical name
canonical = canonical_provider(user_input) # Returns "kimi"
# Retrieve provider specification
provider_spec = lookup(canonical) # Provider dataclass with config
# Instantiate backend client
backend = resolve_backend(canonical, model=None) # Returns configured client
Summary
- Centralized registry: All provider definitions live in
agentbook/providers/registry.py, makingPROVIDERSandSUPPORTED_PROVIDERSthe single source of truth. - Alias support: The
_ALIASESmapping allows shorthand names likemoonshotto resolve to canonical providers likekimi. - Automatic CLI updates: Chapter CLIs reference
SUPPORTED_PROVIDERSdirectly, so new providers added to the registry instantly appear as valid--providerchoices. - Canonical resolution: The
canonical_provider()function normalizes aliases beforeresolve_backend()constructs the authenticated client. - Consistent interface: Every chapter CLI (e.g.,
chapter3/dense-embedding/cli.py,chapter7/elo-leaderboard/cli.py) uses the same--providerflag pattern.
Frequently Asked Questions
Where is the provider registry defined?
The provider registry is defined in agentbook/providers/registry.py. This file contains the PROVIDERS dictionary with canonical definitions, the _ALIASES mapping for shorthand names, and the SUPPORTED_PROVIDERS tuple that chapter CLIs import to populate their --provider choices.
How do I add a custom provider alias?
To add a custom alias, modify the _ALIASES dictionary in agentbook/providers/registry.py by mapping your preferred shorthand to an existing canonical provider key. For example, adding "custom": "openrouter" would allow --provider custom to resolve to the OpenRouter configuration. No CLI code changes are required.
What happens if I pass an invalid provider name?
If you pass a provider name not present in SUPPORTED_PROVIDERS, argparse raises an error immediately during command-line parsing, displaying the valid choices. This validation occurs before any network connections or API calls are attempted.
Can different chapters use different default providers?
Yes. While all chapters import from the same registry, individual CLIs can implement logic to override the default provider based on chapter-specific requirements. However, the --provider flag is available uniformly across chapters, allowing you to override any default by explicitly specifying the desired backend when invoking the script.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →