AxonHub API Key Profile 实战指南:模型映射、访问限制与 Profile 切换
AI 应用API网关LLM 网关后端前端【免费下载链接】axonhub⚡️ Open-source AI Gateway — Use any SDK to call 100 LLMs. Built-in failover, load balancing, cost control end-to-end tracing.项目地址https://gitcode.com/gh_mirrors/ax/axonhub点击查看免费下载本篇指南围绕 AxonHub 的API Key ProfileAPI Key 配置档展开讲解如何通过它为单个 API Key 配置模型重命名映射、渠道限制与模型白名单并在多个 Profile 之间即时切换。你将掌握 Profile 在请求处理管线中的位置、modelMappings/channelTags/modelIDs三类核心配置的完整用法以及它们背后的源码实现与校验规则可直接用于接入层模型兼容、多客户端统一模型名和灰度放量等场景。什么是 API Key ProfileAPI Key Profile是绑定在某个 API Key 上的一组请求级配置主要提供四项能力映射模型Map models改写客户端请求中的模型名让请求按你指定的模型去处理限制渠道Restrict channels将该 API Key 限定到指定的渠道Channel范围限制模型Restrict models将该 API Key 限定到指定的模型白名单切换 ProfileSwitch profiles同一个 API Key 可以创建多个 Profile并随时切换当前生效的一个。简单来说API Key Profile 在请求入口处决定了请求首先被当作哪个模型来处理——它是整个请求处理链路中第一次也是最早一次对模型名进行干预的位置。从数据模型上看Profile 保存在 API Key 的Profiles字段中结构定义在 internal/objects/apikey.gotype APIKeyProfiles struct { ActiveProfile string json:activeProfile // 当前生效的 Profile 名 Profiles []APIKeyProfile json:profiles // Profile 列表 } type APIKeyProfile struct { Name string json:name // Profile 名称同一 API Key 内唯一 ModelMappings []ModelMapping json:modelMappings // 模型映射规则 ChannelIDs []int json:channelIDs,omitempty // 允许的渠道 ID 列表 ChannelTags []string json:channelTags,omitempty // 允许的渠道标签 ChannelTagsMatchMode ChannelTagsMatchMode json:channelTagsMatchMode,omitempty // 标签匹配模式 ModelIDs []string json:modelIDs,omitempty // 模型白名单 Quota *APIKeyQuota json:quota,omitempty // 可选的 Profile 级配额 LoadBalanceStrategy *string json:loadBalanceStrategy,omitempty // 可选覆盖负载均衡策略 TraceStickyMode *string json:traceStickyMode,omitempty // 可选覆盖 Trace 粘性模式 }其中每条映射规则ModelMapping定义在 internal/objects/channel.go只有两个字段type ModelMapping struct { From string json:from // 客户端请求中的模型名 To string json:to // AxonHub 实际使用的模型名 }API Key Profile 在请求流程中的位置API Key Profile 的模型映射是整个请求处理三层模型设置管线中的第一步。关于完整流程参见 请求处理指南。简单概括API Key Profile 重命名 → 模型关联Model Association选择渠道 → 渠道重命名 → 发往上游在 请求处理指南 中三层模型设置的定位如下层级配置位置作用通俗类比第 1 层API Key Profile改写客户端请求的模型名“请求什么”第 2 层模型关联决定由哪个渠道处理请求“去哪里”第 3 层渠道配置改写发往上游的模型名“上游叫什么”实际请求在到达渠道选择之前会先经过apply-model-mapping中间件其实现位于 internal/server/orchestrator/model_mapper.gofunc (m *apiKeyModelMappingMiddleware) OnInboundLlmRequest(ctx context.Context, llmRequest *llm.Request) (*llm.Request, error) { // 保存客户端原始请求模型名 if m.RequestModel { m.RequestModel llmRequest.Model } // 若存在生效的 Profile则应用模型映射 if m.inbound.state.APIKey ! nil { originalModel : llmRequest.Model mappedModel : m.inbound.state.ModelMapper.MapModel(ctx, m.inbound.state.APIKey, originalModel) if mappedModel ! originalModel { llmRequest.Model mappedModel } } return llmRequest, nil }值得注意的一个细节映射不仅发生在入站请求方向。在出站响应方向中间件会调用ReplaceResponseModel把响应体中的模型名替换回客户端最初请求的模型名见 model_mapper.go 与 ReplaceResponseModel从而保证客户端看到的模型名始终是它自己请求的那个映射过程对客户端完全透明。常见使用场景场景一客户端工具写死了模型名很多 AI 工具在内部写死了模型名例如某些 CLI 或 IDE 插件固定请求claude-sonnet-4-5。如果希望它们实际走其他模型不需要改工具只需在 Profile 中做模型映射{ modelMappings: [ {from: claude-sonnet-4-5, to: anthropic/claude-3.5-sonnet} ] }场景二统一多个客户端的模型名如果多个客户端分别请求gpt4、gpt-4-turbo但后端统一使用gpt-4o可以在一个 Profile 中配置多条映射将不同写法统一收拢{ modelMappings: [ {from: gpt4, to: gpt-4o}, {from: gpt-4-turbo, to: gpt-4o} ] }场景三将 Profile 限制到系统的一部分如果只想让该 Profile 走带production标签的渠道且只允许请求gpt-4o与claude-3-sonnet两个模型可以同时使用渠道标签与模型白名单{ channelTags: [production], modelIDs: [gpt-4o, claude-3-sonnet] }配置步骤第 1 步打开 Profile 配置界面登录 AxonHub 管理界面进入API KeysAPI Key 管理页面找到要配置的 API Key打开该 Key 的Actions操作菜单选择Profiles或Configure进入 Profile 配置弹窗对应前端组件 apikeys-profiles-dialog.tsx。第 2 步创建 Profile点击Add Profile添加 Profile填写 Profile 名称配置模型映射、渠道限制或模型限制。第 3 步配置模型映射每条映射包含From客户端请求中的模型名ToAxonHub 实际应使用的模型名。支持的匹配方式有两种精确匹配{from: gpt-4, to: claude-3-opus}正则匹配{from: gpt-.*, to: claude-3-sonnet}关于正则的底层行为源码 internal/pkg/xregexp/match.go 给出了精确的实现语义值得展开说明当from不含任何正则特殊字符时走精确匹配分支pattern str才算命中match.go当from为*时视为匹配任意模型match.go其余情况使用regexp2编译为自动锚定的正则等价于^(?:pattern)$见 ensureAnchored这意味着gpt-.*只会匹配完整模型名而非任意子串所有模式都会经过全局缓存globalCache高频请求不会反复编译正则match.go。上述行为均有测试用例覆盖例如 internal/server/orchestrator/model_mapper_test.go 验证了精确匹配、通配符*、正则特殊字符、非法正则如[invalid返回false等场景。第 4 步设置生效的 Profile在Active Profile生效 Profile下拉中选择一个 Profile点击Save保存变更立即生效无需重启服务。“立即生效”背后有两点保障后端UpdateAPIKeyProfiles更新成功后立即调用invalidateAPIKeyCaches失效该 Key 的缓存见 internal/server/biz/api_key.go每次请求解析生效 Profile 时通过GetActiveProfile实时按名称在 Profile 列表中查找见 internal/ent/extra.gofunc (a *APIKey) GetActiveProfile() *objects.APIKeyProfile { if a nil || a.Profiles nil || a.Profiles.ActiveProfile { return nil } for i : range a.Profiles.Profiles { if a.Profiles.Profiles[i].Name a.Profiles.ActiveProfile { return a.Profiles.Profiles[i] } } return nil }规则匹配顺序模型映射按声明顺序逐条求值第一个命中的规则生效后续规则不再参与匹配。该逻辑实现于 internal/server/orchestrator/model_mapper.go 的applyModelMappingfunc (m *ModelMapper) applyModelMapping(mappings []objects.ModelMapping, model string) string { for _, mapping : range mappings { if m.matchesMapping(mapping.From, model) { return mapping.To // 命中即返回不再继续 } } return model // 全部未命中则保持原模型名 }因此请遵循把更具体的规则放在前面更通用的规则放在后面。例如先写精确的gpt-4再写兜底的gpt-.*避免通用规则提前吞掉特定请求。如果所有规则都未命中请求模型名保持不变原样返回不会报错。深入理解渠道限制与模型白名单的执行位置除模型映射外Profile 的channelTags、channelIDs与modelIDs分别在请求管线的不同环节生效渠道限制候选渠道过滤在select-candidates阶段请求会先应用项目级 Profile作为上界过滤再应用API Key 级 Profile在项目范围内进一步收窄实现位于 internal/server/orchestrator/select_candidates.go// 项目级 Profile 过滤上界 if projectProfile : project.GetActiveProfile(); projectProfile ! nil { if len(projectProfile.ChannelIDs) 0 { selector WithSelectedChannelsSelector(selector, projectProfile.ChannelIDs) } if len(projectProfile.ChannelTags) 0 { selector WithChannelTagsFilterSelector(selector, projectProfile.ChannelTags, projectProfile.ChannelTagsMatchMode) } } // API Key 级 Profile 过滤在项目范围内进一步收窄 if profile : inbound.state.APIKey.GetActiveProfile(); profile ! nil { if len(profile.ChannelIDs) 0 { selector WithSelectedChannelsSelector(selector, profile.ChannelIDs) } if len(profile.ChannelTags) 0 { selector WithChannelTagsFilterSelector(selector, profile.ChannelTags, profile.ChannelTagsMatchMode) } }渠道标签匹配由MatchChannelTags统一实现internal/objects/apikey.go支持三种channelTagsMatchMode模式语义any默认渠道标签与允许标签任一匹配即可通过all渠道必须同时具备所有允许标签才可通过none渠道标签不得包含任何允许标签才可通过该枚举在前端表单中同样被校验见 frontend/src/features/apikeys/data/schema.tsz.enum([any, all, none])。这一机制正是“优先使用 channelTags 而非硬编码 channelIDs”这一最佳实践的底层支撑——标签让渠道范围的调整无需改动 Profile。模型限制入口模型访问控制modelIDs白名单在check-api-key-model-access中间件中执行internal/server/orchestrator/model_access.go若当前生效 Profile 配置了modelIDs请求模型不在白名单内则直接以ErrInvalidModel拒绝请求注意此时比较的是经过模型映射之后的模型名即“该 Profile 最终允许哪些模型”。profile : inbound.state.APIKey.GetActiveProfile() if profile nil || len(profile.ModelIDs) 0 { return llmRequest, nil // 未配置白名单则不做限制 } allowed : slices.Contains(profile.ModelIDs, llmRequest.Model) if !allowed { return nil, fmt.Errorf(%w: %s, biz.ErrInvalidModel, llmRequest.Model) }该行为的测试用例见 internal/server/orchestrator/model_access_test.go。进阶Profile 还能覆盖什么从 internal/objects/apikey.go 的数据结构可以看到Profile 还支持可选配置quotaProfile 级配额请求数 / 总 Token / 成本支持all_time、past_duration、calendar_duration三种周期在enforceQuota阶段按生效 Profile 检查internal/server/orchestrator/quota.goloadBalanceStrategy/traceStickyModeProfile 可覆盖默认的负载均衡策略与 Trace 粘性模式internal/server/orchestrator/retry.go。这些字段在保存时都会经过严格校验internal/server/biz/api_key.go 中的validateProfileFilters、validateProfileRoutingPolicies、validateProfileQuota。FAQQ为什么模型映射没有生效按以下顺序排查是否选中了正确的 Active Profile如果activeProfile为空或指向不存在的 ProfileMapModel会直接返回原始模型名见 model_mapper.go。后端在保存时会强制校验activeProfile必须存在于 Profile 列表中internal/server/biz/api_key.go。模型名是否真的匹配精确匹配要求完全一致正则匹配是全名锚定匹配等价^(?:...)$gpt-.*不会匹配my-gpt-4这类带前缀的字符串。正则写法是否正确非法正则如[invalid会被缓存为编译失败命中恒为false见 xregexp/match.go 与对应测试 model_mapper_test.go。QProfile 名称有什么要求在同一个 API Key 内必须唯一校验时按大小写不敏感处理Profile与profile视为重复见 internal/server/biz/api_key.go不能为空空名称会被拒绝建议使用有意义的名称。Q应该创建多少个 Profile没有硬性数量限制但建议保持精简、易于管理。需要不同行为不同模型映射、不同渠道范围、不同配额时再新建 Profile通过切换 Active Profile 即可即时变更行为无需新建 API Key。Q保存 Profile 时报 “duplicate profile name” 怎么办Profile 名称在同一 API Key 内不区分大小写地要求唯一请检查是否已有同名或仅大小写不同的 Profile重命名后重试。最佳实践使用描述性名称例如production、openrouter-mapping让人一眼看出 Profile 的用途具体规则在前映射按顺序首个命中生效把精确规则放在通用正则之前启用前先测试用测试请求验证映射结果与渠道范围符合预期后再切换为正式生效优先使用渠道标签用channelTags代替硬编码的channelIDs后续调整渠道范围时无需修改 Profile充分利用白名单做隔离给外部客户、灰度环境等分别配置modelIDs白名单从入口杜绝越权模型请求该拦截在check-api-key-model-access阶段执行早于渠道选择。相关文档模型管理指南 —— 配置模型关联选择渠道渠道管理指南 —— 配置上游渠道负载均衡指南 —— 理解渠道选择与故障转移请求处理指南 —— 查看完整请求流程赞分享AI 应用API网关LLM 网关后端前端【免费下载链接】axonhub⚡️ Open-source AI Gateway — Use any SDK to call 100 LLMs. Built-in failover, load balancing, cost control end-to-end tracing.项目地址https://gitcode.com/gh_mirrors/ax/axonhub点击查看免费下载相关推荐JSDoc注释规范详解param、return、type等15个必会标签一次学会JSDoc注释规范详解param、return、type等15个必会标签一次学会 JSDoc 是 JavaScript 开发者最常用的 API 文档生成开发工具文档AxonHub 接入 OpenCode 实战指南Anthropic 兼容端点、模型 Profile 路由与全链路追踪AxonHub 接入 OpenCode 实战指南Anthropic 兼容端点、模型 Profile 路由与全链路追踪 导读 本文是一份面向开发者的实操指南讲AI 应用API网关LLM 网关后端前端TypeScript 映射类型Mapped Types实战指南用 keyof 构建类型变换、修饰符与 key 重映射TypeScript 映射类型Mapped Types实战指南用 keyof 构建类型变换、修饰符与 key 重映射 映射类型Mapped Types文档教程上一篇VALL-E代码实现原理深入理解AR与NAR解码器的设计思想下一篇lz4命令速查常用参数与示例创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考