Bifrost 是一个基于 Go 的高速 AI 网关。如果你在 LLM 提供商那里遇到了速率限制,需要池化多个 API 密钥来提升吞吐量,Bifrost 提供了一个原生的高性能路由引擎来处理负载均衡。
不过,在单个 Bifrost 节点上配置密钥池化很简单;在多节点生产环境中扩展这个配置则需要仔细的架构规划,以免冲破提供商的配额。
下面就是如何在 Bifrost 中池化 API 密钥,以及如何安全地扩展这个配置。
1. 在 Bifrost 中配置密钥池化
Bifrost 允许你为单个提供商定义多个 API 密钥,并给它们分配权重。路由引擎会根据权重和健康状态自动把传入的请求分发到这些密钥上。
为了做到 GitOps 友好、无状态的部署,你通过一个挂载到 Bifrost 容器的 config.json 文件来配置。
{
"$schema": "https://www.getbifrost.ai/schema",
"providers": {
"openai": {
"keys": [
{
"name": "openai-key-primary",
"value": "env.OPENAI_API_KEY_1",
"models": ["gpt-4o", "gpt-4o-mini"],
"weight": 0.7
},
{
"name": "openai-key-secondary",
"value": "env.OPENAI_API_KEY_2",
"models": ["gpt-4o", "gpt-4o-mini"],
"weight": 0.3
}
]
}
}
}在这个配置里,Bifrost 充当一个智能路由器。它会把大约 70% 的流量发给主密钥,30% 发给副密钥。如果主密钥从 OpenAI 收到 429 Too Many Requests,Bifrost 的内部逻辑会暂时把它标记为降级,把流量路由到副密钥。
2. 执行请求
在你的应用代码里,你把 Bifrost 当作标准 OpenAI API 来用就行。你不需要在应用里构建任何路由逻辑。
你只需要把 SDK 的 baseURL 指向你的 Bifrost 实例,并给一个占位 API 密钥(或者一个 Virtual Key,如果你启用了治理)。
import OpenAI from 'openai';
const client = new OpenAI({
apiKey: "vk-my-bifrost-key", // The gateway authenticates this
baseURL: "http://localhost:8080/v1" // Pointing to Bifrost
});
const response = await client.chat.completions.create({
model: "openai/gpt-4o",
messages: [{ role: "user", content: "Analyze this dataset..." }]
});Bifrost 拦截这个请求,根据 config.json 里的权重选出合适的物理 API 密钥,附加到 headers 上,把请求代理给 OpenAI。
3. 多节点扩展的陷阱
这个配置对单个大型 Bifrost 节点有效。问题出在你需要高可用性、在负载均衡器后面扩展到多个实例的时候。
在开源 (OSS) Bifrost 里,每个节点都是一个独立的决策引擎。
- 节点 A 加载
config.json,在本地内存里跟踪openai-key-primary的 TPM/RPM 使用情况。 - 节点 B 加载同一个
config.json,跟踪它自己的本地使用情况。
因为 OSS Bifrost 不会在节点之间实时同步运行时状态(比如实时速率限制或令牌桶),节点 A 不知道节点 B 刚才向 OpenAI 发送了多少 token。在高并发流量下,这些节点会集体冲破物理提供商的限制,导致上游 429 错误和请求被丢弃。
(注:Bifrost 提供一个付费的企业版,使用修改过的 RAFT 共识协议来同步这个状态,但这里我们专注于 OSS 架构。)
4. 如何真正扩展:把控制面外部化
如果你想在多个节点上使用 OSS Bifrost 而不超限,你必须采用三层架构。你必须把"智能"的配额执行从 Bifrost 中剥离出来,外部化到一个全局协调的控制面。
在这个架构里,Bifrost 纯粹是一个路由与执行引擎。它挑选密钥并发起网络调用。
为了执行全局速率限制,你把一个专门的配额系统(比如 OpenMeter 或一个带 Redis 速率限制的 Kong API Gateway)放在 Bifrost 前面。
流程:
- 你的应用向 Kong/Redis 层发送一个请求。
- 控制面检查 Redis:这个用户/团队在我们整个基础设施范围内还有足够的全局 TPM 容量吗?
- 如果有,它递减全局计数器,把请求转发给 Bifrost 负载均衡器。
- Bifrost 收到请求,用它的内部权重选出一个物理 API 密钥,执行调用。
通过把全局配额执行拆到 Redis,物理密钥路由留在 Bifrost,你既能得到 Bifrost 高速 Go 代理的性能,又能在任意数量的节点上保持速率限制的正确性。
下一篇我们会看 LiteLLM 如何处理这同一个问题,它采取了不同的方法,把 Redis 直接打包进它的开源代理层里。
