Skip to main content

Multi-Provider Setup

Configure multiple providers to seamlessly switch between them. This example shows how to configure OpenAI, Anthropic, and Mistral providers.
If Bifrost receives a new provider at runtime (i.e., one that is not returned by GetConfiguredProviders() initially on bifrost.Init()), it will set up the provider at runtime using GetConfigForProvider(), which may cause a delay in the first request to that provider.

Making Requests

Once providers are configured, you can make requests to any specific provider. This example shows how to send a request directly to Mistral’s latest vision model. Bifrost handles the provider-specific API formatting automatically.

Environment Variables

Set up your API keys for the providers you want to use:

Advanced Configuration

Weighted Load Balancing

Distribute requests across multiple API keys or providers based on custom weights. This example shows how to split traffic 70/30 between two OpenAI keys, useful for managing rate limits or costs across different accounts.

Model-Specific Keys

Use different API keys for specific models, allowing you to manage access controls and billing separately. This example uses a premium key for advanced reasoning models (o1-preview, o1-mini) and a standard key for regular GPT models.

Custom Base URL

Override the default API endpoint for a provider. This is useful for connecting to self-hosted models, local development servers, or OpenAI-compatible APIs like vLLM, Ollama, or LiteLLM.
For self-hosted providers like Ollama and SGL, BaseURL is required. For standard providers, it’s optional and overrides the default endpoint.

Private Network Access

If your provider runs on a private IP address (e.g. a local vLLM or Ollama instance on 192.168.x.x or 10.x.x.x), set AllowPrivateNetwork: true in NetworkConfig. Link-local addresses (169.254.x.x) remain blocked regardless of this setting.

Managing Retries

Configure retry behavior for handling temporary failures and rate limits. This example sets up exponential backoff with up to 5 retries, starting with 1ms delay and capping at 10 seconds - ideal for handling transient network issues.
For a full explanation of how retries work, key rotation on rate limits, and how retries connect with fallbacks, see Retries & Fallbacks.

Custom Concurrency and Buffer Size

Fine-tune performance by adjusting worker concurrency and queue sizes per provider (defaults are 1000 workers and 5000 queue size). This example gives OpenAI higher limits (100 workers, 500 queue) for high throughput, while Anthropic gets conservative limits to respect their rate limits.

Custom Headers

Bifrost supports two ways to add custom headers to provider requests: static headers configured at the provider level, and dynamic headers passed per-request via context.

Static Headers (Provider Level)

Configure headers that are automatically included in every request to a specific provider using NetworkConfig.ExtraHeaders:

Dynamic Headers (Per Request)

Send custom headers with individual requests by adding them to the request context. Headers are automatically propagated to the provider:
How it works:
  • Headers are stored as map[string][]string in the context
  • Multiple values per header name are supported
  • Header names are case-insensitive and normalized to lowercase
  • Headers are accessible throughout the request lifecycle
Example use cases:
  • User identification: user-id, tenant-id
  • Request tracking: correlation-id, trace-id
  • Custom metadata: department, cost-center
  • A/B testing: experiment-id, variant

Security Denylist

Bifrost maintains a security denylist of headers that are never forwarded to providers, regardless of configuration:
This denylist is applied to both static and dynamic headers to prevent security vulnerabilities.

Setting Up a Proxy

Route requests through proxies for compliance, security, or geographic requirements. This example shows both HTTP proxy for OpenAI and authenticated SOCKS5 proxy for Anthropic, useful for corporate environments or regional access.

Send Back Raw Response

Include the original provider response alongside Bifrost’s standardized response format. Useful for debugging and accessing provider-specific metadata. Provider-level default (applies to all requests for this provider):
Per-request override (overrides the provider default for a single request):
When enabled, the raw provider response appears in ExtraFields.RawResponse:

Send Back Raw Request

Include the original request sent to the provider alongside Bifrost’s response. Useful for debugging request transformations and verifying what was actually sent to the provider. Provider-level default (applies to all requests for this provider):
Per-request override (overrides the provider default for a single request):
When enabled, the raw provider request appears in ExtraFields.RawRequest:

Store Raw Request/Response

Persist the raw provider request and response in the log record without necessarily returning them in the API response. This is orthogonal to the send-back flags - enabling this does not affect what the caller receives, and enabling send-back does not automatically store data in logs. Enable both to do both. Provider-level default (applies to all requests for this provider):
Per-request override (overrides the provider default for a single request):
StoreRawRequestResponse only has effect when the logging plugin is active - raw data is written to the log record by the logging plugin. Without it, enabling this flag captures the data but nothing persists it.StoreRawRequestResponse, SendBackRawRequest, and SendBackRawResponse are orthogonal controls - enabling any one does not imply the others. Enable any combination depending on whether you need raw data in logs, in the response, or both.

Best Practices

Performance Considerations

Keys are fetched from your GetKeysForProvider implementation on every request. Ensure your implementation is optimized for speed to avoid adding latency:
Recommendations:
  • Cache keys in memory during application startup
  • Use simple switch statements or map lookups
  • Avoid database queries, file I/O, or network calls
  • Keep complex key processing logic outside the request path

Next Steps