The ClientRegistry allows you to create and configure LLM clients at runtime, enabling dynamic model selection, parameter tuning, and client overrides without modifying your BAML files.
Quick Start
If you just need to change which client a function uses, use the simpler client option:
result = await b.ExtractResume("...", baml_options={"client": "GPT4"})
For more complex scenarios, use the full ClientRegistry:
import os
from baml_py import ClientRegistry
from baml_client import b
async def run():
cr = ClientRegistry()
# Create a new client
cr.add_llm_client(
name='MyAmazingClient',
provider='openai',
options={
"model": "gpt-5-mini",
"temperature": 0.7,
"api_key": os.environ.get('OPENAI_API_KEY')
}
)
# Set as primary client
cr.set_primary('MyAmazingClient')
# Use the custom client
res = await b.ExtractResume("...", { "client_registry": cr })
Common Use Cases
Dynamic Model Selection
Choose models based on runtime conditions like user tier, request complexity, or cost constraints:
from baml_py import ClientRegistry
from baml_client import b
async def process_request(content: str, user_tier: str):
cr = ClientRegistry()
if user_tier == "premium":
cr.add_llm_client(
name='PremiumModel',
provider='openai',
options={"model": "gpt-4o", "temperature": 0.3}
)
cr.set_primary('PremiumModel')
else:
cr.add_llm_client(
name='StandardModel',
provider='openai',
options={"model": "gpt-4o-mini", "temperature": 0.5}
)
cr.set_primary('StandardModel')
return await b.ExtractResume(content, {"client_registry": cr})
A/B Testing Different Models
Test different models or configurations without modifying BAML files:
import random
from baml_py import ClientRegistry
async def ab_test_models(input: str):
cr = ClientRegistry()
# Randomly select variant
variant = random.choice(['A', 'B'])
if variant == 'A':
cr.add_llm_client(
name='VariantA',
provider='anthropic',
options={"model": "claude-opus-4-5"}
)
cr.set_primary('VariantA')
else:
cr.add_llm_client(
name='VariantB',
provider='openai',
options={"model": "gpt-4o"}
)
cr.set_primary('VariantB')
result = await b.ExtractResume(input, {"client_registry": cr})
# Log variant for analysis
print(f"Used variant: {variant}")
return result
Using OpenAI Responses API
Create clients that use specialized provider APIs:
cr = ClientRegistry()
# Standard OpenAI client
cr.add_llm_client(
name='StandardOpenAI',
provider='openai',
options={"model": "gpt-4o"}
)
# OpenAI Responses API client
cr.add_llm_client(
name='ResponsesClient',
provider='openai-responses',
options={"model": "gpt-4.1"}
)
cr.set_primary('ResponsesClient')
Fallback Strategies
set_primary selects one client from the registry - it doesn’t automatically create a fallback chain. To use fallbacks, define a fallback client in BAML and select it via the registry.
Define a fallback client in BAML:
function ExtractResume(input: string) -> Resume {
client "openai/gpt-5-mini" // Default client
prompt #"
Extract from this content: {{ input }}
{{ ctx.output_format }}
"#
}
// Fallback client configuration
client<llm> GptOpusFallback {
provider fallback
options {
strategy ["openai/gpt-5", "anthropic/claude-opus-4-1-20250805"]
}
}
Activate the fallback at runtime:
cr = ClientRegistry()
cr.set_primary("GptOpusFallback")
res = await b.ExtractResume("...", {"client_registry": cr})
API Reference
ClientRegistry Methods
Import ClientRegistry from baml_py (Python) or @boundaryml/baml (TypeScript), not from baml_client. A more type-safe interface directly in baml_client is planned - see GitHub issue #766.
add_llm_client / addLlmClient
Adds an LLM client to the registry.
Parameters:
name (string, required): Client identifier
provider (string, required): Provider name (e.g., “openai”, “anthropic”)
options (object, required): Client configuration including model, API key, etc.
retry_policy (string, optional): Name of a retry policy defined in BAML files
Using the same name as an existing BAML client will override that client when the registry is used.
set_primary / setPrimary
Selects which client the function should use.
Parameters:
name (string, required): Name of the client to use (can be from add_llm_client or existing BAML client)
OpenAPI Support
Pass client registry via __baml_options__ in the request body:
{
"resume": "John Doe's resume...",
"__baml_options__": {
"client_registry": {
"clients": [
{
"name": "OpenAI",
"provider": "openai",
"retry_policy": null,
"options": {
"model": "gpt-5-mini",
"api_key": "sk-..."
}
}
],
"primary": "OpenAI"
}
}
}
curl -X POST http://localhost:2024/call/ExtractResume \
-H 'Content-Type: application/json' -d @body.json
Best Practices
- Environment Variables: Always use environment variables for API keys, never hardcode them
- Registry Reuse: Create registries once and reuse them across multiple calls when possible
- Client Naming: Use descriptive client names that indicate their purpose (e.g., “FastModel”, “AccurateModel”)
- Fallback Testing: Test fallback strategies thoroughly to ensure graceful degradation
- Monitoring: Track which clients are being used in production for optimization insights