上游与模型字段
本章讲怎么在控制台配置上游服务(模型供应商)和模型。这是网关能转发请求的前提。
入口:控制台 → 上游服务(仅 admin)。每个上游下挂若干模型。
上游服务管理
新建上游
控制台 → 上游服务 → 新建,填下表字段:
| 字段 | 说明 | 示例 |
|---|---|---|
| 名称 | 上游唯一标识,模型引用它 | openai |
| 协议 | 决定执行器与请求 schema | openai / anthropic / google / aws_converse / dashscope / openai_response / openai_images / openai_embeddings / openai_audio / openai_rerank / passthrough |
| 基础 URL | 上游真实地址,结尾不带 / | https://api.openai.com/v1 |
| API Key | 上游密钥,可加多把;按权重确定性加权分布,同一调用方粘同一把 | sk-... |
| 启用 | 关闭则不参与路由 | ✓ |
| 自定义头 | 额外请求头,支持 {{var}} 与 {{alt1|alt2}} 回退链 | |
| User-Agent | 覆盖全局 UA,支持模板 | |
| 代理 | 上游出站代理 | |
| DNS | per-upstream DNS(DoH/DoT/UDP 自动识别)+ TTL | |
| 请求体规则 | 请求体改写规则(path/value/mode) | |
| 请求/响应脚本 | JS 脚本变换(详见 脚本 API 参考) | |
| 脚本错误模式 | log-and-continue(默认)/ log-and-reject | |
| 脚本位置 | after(默认,规则后)/ before | |
| Token 计数 | upstreamApi / tiktoken | |
| 限流 | 上游级限流(rpm/并发/tpm) |
多密钥与权重
一个上游可配多把 API Key。选择算法是确定性加权分布 + 粘性绑定,不是轮询:
- 首次选择用 FNV-1a 对
(调用方 access_key, upstream 名)哈希,按各 key 的weight占总权重的比例落到累计权重区间。不同调用方按权重比例分散到不同 key——weight=2的 key 拿到weight=1的两倍流量。 - 同一个调用方 access_key 黏到同一把 key(绑定存入内存中的会话-密钥绑定表,仅内存、不跨节点共享——各节点各自维护本地 prompt-cache 黏性),保证上游 prompt cache 与签名一致性。绑定带空闲 TTL(
KEY_BINDING_TTL_SECS,默认 1800 秒 / 30 分钟,0= 永久):该调用方在 TTL 内无新请求即过期,下次重新选择。 - 配置 reload 不再整体清空绑定,失效由指纹驱动:每条绑定记录其 upstream 候选 key 集的指纹(按各 key 的位置与权重算出)。读取绑定时若指纹与当前候选集不符,视为失效、重新选择。因此——原地轮换某把 key 的值(同一位置换值)不破坏黏性;而增删、重排 key 或改权重会改变指纹、触发重选。与工业级网关(Envoy / AWS ALB)的最小扰动(minimum-disruption)语义一致。
weight = 0是备用 key:仅当所有weight > 0的 key 都试过失败后才启用,且不存绑定。- 某把 key 请求失败时,网关在该 upstream 内轮换到下一把未试过的 key 重试,但不覆盖首次粘性绑定——后续该调用方的请求仍从原绑定 key 起步。
这是单 upstream 内多 key 的选择机制,与负载均衡器 entry 选择(Smooth WRR 平滑加权轮询,见 负载均衡字段)是两套独立机制:LB entry 在 handler 层选、跨 upstream;upstream 内多 key 在 dispatch 层选、同 upstream 内。两者正交叠加(LB 选中某 entry → 该 entry 的 upstream 内再按本节粘性选 key)。
在控制台看实时绑定:上游列表 → 该上游某模型行的 监控(Monitor)图标 → 「模型监控」面板。Access Key Bindings 标签页逐行列出每个可经分组 ACL 访问该模型的 access key,以及它当前粘到哪把上游 key:来源为 binding 表示存在活跃粘性绑定;为 prediction 表示此刻无活跃绑定、所示上游 key 是按本模型候选集算出的确定性加权预测(同一上游的不同模型预测可能不同,因为各模型候选集各自计算)。指纹列与当前候选集不符的绑定标 stale——仍展示,但下次请求即重选(与派发真相一致)。上方的 上游 keys 名册作为图例,悬停某绑定行会高亮其对应上游 key。该视图是单节点的(两种存储模式下绑定表都在内存、不跨节点共享),面板底部带本实例标识。限流仪表在 Rate Limit 标签页;该模型未配限流时该页显示空态,不影响绑定视图。完整选择/切换语义即上文所述(确定性加权哈希 + 指纹失效 + 空闲 TTL)。
删除上游
若该上游下还有模型引用,删除返回 422(先删或迁移模型再删上游)。
自定义 Header 与 User-Agent
为上游所有请求附加自定义 header,支持模板变量。完整变量清单与各配置处的可用范围见 模板变量速查;此上下文可用的变量:
| 变量 | 来源 |
|---|---|
{{request_access_key_name}} | 匹配的访问密钥名 |
{{request_access_key_group}} | 访问密钥分组名 |
{{request_id}} | 客户端 z-request-id 头 |
{{access_key_hash}} | 访问密钥名 SHA-256 哈希前 16 字节 base64 |
{{system_prompt_hash}} | system 提示词内容的 SHA-256(协议无关) |
{{header:Key}} | 客户端请求头的值(不区分大小写) |
回退链语法:{{var1|var2}} 按顺序取第一个可用的变量;全部为空则该 header 被省略(不发送空字符串)。
示例 — 在 User-Agent 中包含访问密钥名以便上游日志关联(控制台 → 上游服务 → 编辑该上游):
- User-Agent 字段填
gatellm/key-{{request_access_key_name}}。 - 自定义头 区域添加两条:
- 头名
X-Request-Access-Key,值{{request_access_key_name}}。 - 头名
X-Request-Group,值{{request_access_key_group}}。
- 头名
Per-Upstream DNS 解析器
每个上游可配独立 DNS 服务器,绕过容器/OS 层 DNS 缓存,解决上游 ALB IP 轮换后旧 IP 被缓存导致的持续 503/504:
| Scheme | 协议 | 端口 |
|---|---|---|
| (无) | UDP 标准 DNS | 53 |
udp:// | UDP + TCP 回退 | 53 |
tls:// | DNS-over-TLS | 853 |
https:// | DNS-over-HTTPS | 443 |
在控制台 → 上游服务 → 编辑该上游 → DNS 字段填入服务器列表(scheme 决定协议,见上表):
- 用阿里 DNS(UDP):
223.5.5.5、223.6.6.6。 - 用 Cloudflare DNS-over-TLS:
tls://1.1.1.1、tls://1.0.0.1。
模型管理
在上游列表点该行 展开,看到该上游下的模型子表,可新建/编辑/删除/测试。
新建模型
| 字段 | 说明 | 示例 |
|---|---|---|
| 名称 | 对外暴露给客户端的模型名,可自定义 | gpt-4o |
| 上游 | 所属上游 | openai |
| 上游模型 ID | 发往上游的真实模型名 | gpt-4o |
| 别名 | 额外可用的名字(与模型名共享全局唯一空间) | gpt4o |
| 隐藏主名 | hide_name=true 时主名不可访问(404),只能用别名或经负载均衡 | |
| 协议覆盖 | 不填用上游协议;填了则该模型用别的协议 | |
| 基础 URL 覆盖 | 不填用上游 base_url;direct_path 时把此值当完整端点 URL | |
| 类型 kind | DashScope 等协议的变体标识 | |
| inference_profile | Bedrock 的推理配置 ARN | |
| 请求体规则 | 模型级请求体改写规则(覆盖上游级) | |
| 请求/响应脚本 | 该模型级脚本(覆盖上游级) | |
| 限流覆盖 | inherit(继承上游)或具体值 | |
| Token 计数覆盖 | 覆盖上游级 | |
| 启用 | ✓ |
名称 vs 上游模型 ID:客户端调的是「名称」,网关发往上游用的是「上游模型 ID」。两者不同就实现了模型别名/重命名。
aliases是额外的可用名。
测试连接
模型列表 → 该模型 → 测试,发起一次真实调用验证上游通不通。POST /console/api/models/test。
模型别名与隐藏名称
别名(aliases)
为模型定义多个可访问的名称。控制台 → 模型 → 新建/编辑 kimi-2.6-20250514,依次填:
- 上游 选
anthropic。 - 上游模型 ID 填
kimi-2.6-20250514。 - 别名 填
kimi-2.6-0711、kimi-2.6(两个,与主名共享全局唯一空间)。
客户端用 kimi-2.6-0711 或 kimi-2.6 都能访问到同一个模型。
注意:密钥组的模型 ACL 只匹配规范名称(
name字段),不解析别名。如果模型规范名是kimi-2.6-20250514,密钥组模型列表必须列出kimi-2.6-20250514,不能写别名。
隐藏主名(hide_name)
设置 hide_name = true 后,客户端无法用规范名访问模型(返回 404),只能用别名。控制台 → 模型 → 新建/编辑 qwen3.6-plus,依次填:
- 上游 选
openai。 - 上游模型 ID 填
qwen-plus。 - 别名 填
kimi-k2-0711。 - 勾选 隐藏主名(
hide_name)。
效果:
- 客户端只能用
kimi-k2-0711访问 /v1/models列表只列出别名,不列出qwen3.6-plus- 负载均衡器可以引用
qwen3.6-plus(隐藏模型可作为 LB 的 entry) - 统计、日志、凭证过滤仍使用规范名
适用场景:
- 白标:以品牌名称暴露模型,隐藏真实上游模型 ID
- 迁移:暴露稳定别名,变更底层模型名
- 负载均衡专用:隐藏底层模型,仅通过 LB 名称暴露
hide_name = true时aliases可以为空。此时模型对外部 API 不可见,但仍可被负载均衡器引用。
请求体修改(Request Payload)
在请求发送到上游前修改 JSON 请求体。修改规则在协议转换之后应用,影响最终上游请求体。
规则格式
每个规则包含:
| 字段 | 类型 | 说明 |
|---|---|---|
path | String | 点分隔的 JSON 路径(如 temperature、messages.0.content) |
value | JSON | 要设置、追加或删除的值 |
mode | String | 必填,见下方模式表 |
condition | Object | 部分模式需要的条件 |
路径语法
| 语法 | 示例 | 说明 |
|---|---|---|
| 对象键 | temperature | 顶层字段 |
| 嵌套键 | response_format.type | 深入嵌套对象 |
| 数组索引 | messages.0.content | 访问索引 0 的元素 |
| 通配符 | messages.*.content | 匹配数组所有元素 |
⚠️
messages[].content、messages[*].content是非法的。通配符用messages.*.content,具体索引用messages.0.content。
模式一览
| 模式 | 说明 | 示例 |
|---|---|---|
overwrite | 替换目标路径的值 | {"path": "temperature", "value": 0.7, "mode": "overwrite"} |
remove | 删除目标路径的键 | {"path": "temperature", "value": null, "mode": "remove"} |
add-if-absent | 仅当键不存在时设置值 | {"path": "top_p", "value": 0.9, "mode": "add-if-absent"} |
append | 无条件追加到数组 | {"path": "tools", "value": {...}, "mode": "append"} |
append-if-missing | 条件追加(见下) | |
remove-matching | 条件移除数组元素(见下) | |
strip-lines | 从字符串中移除匹配行 | |
filter-content-types | 从 content 数组中移除指定类型块 | |
filter-tools | 过滤 tools 数组 | |
inject-system-prompt | 在协议对应位置注入 system 提示(value 为提示文本) | {"value": "Be concise.", "mode": "inject-system-prompt"} |
switch-route | 不修改 body;在协议转换前按客户端形状评估 when,任一谓词成立时把本次请求改投到 use_model(立即切换,支持跨协议)。零脚本开销,谓词不读二进制、大 body 磁盘暂存保持开启 | 见下 |
常用示例
简单覆盖参数 —— 控制台 → 模型详情(或上游的「默认请求体规则」)→ 请求体规则 → + 添加规则,加三条:
| 路径 | 模式 | 值 |
|---|---|---|
temperature | overwrite | 0.3 |
max_tokens | overwrite | 4096 |
response_format.type | overwrite | json_schema |
追加 system 消息(不存在时) —— 控制台 → 请求体规则 → + 添加规则,填:
- 模式 选
append-if-missing。 - 路径 填
messages。 - 值 填
{"role": "system", "content": "You are a helpful assistant."}。 - 条件:scope 填
messages;加一条 where——路径role、等于system(即「messages 里已有 role=system 的元素时跳过,否则追加」)。
追加 thinking block(不存在时) —— 控制台 → 请求体规则 → + 添加规则,填:
- 模式 选
append-if-missing。 - 路径 填
messages。 - 值 填
{"type": "thinking", "thinking": {"budget_tokens": 10000}}。 - 条件:scope 填
messages;加一条 where——路径type、等于thinking。
移除 thinking block —— 控制台 → 请求体规则 → + 添加规则,填:
- 模式 选
remove-matching。 - 路径 填
messages。 - 值 留空。
- 条件:scope 填
messages;加一条 where——路径type、等于thinking(即「删掉 messages 里 type=thinking 的元素」)。
检测图片/联网→切多模态模型(switch-route,零脚本开销):
不读写 body,在协议转换前按客户端形状评估 when,谓词成立时把本次请求改投到 use_model(翻译前 立即切换,支持跨协议)。谓词只做结构/小值检查、不读二进制内容,因此含 base64 的大请求体仍以 占位符 + 磁盘临时文件 留在文件里,不会像 after 槽脚本那样整段读入脚本引擎内存而 OOM。这是「检测图片→切模型」类脚本的原生替代。
在控制台怎么配(不用写 JSON): 模型详情(或上游的「默认请求体规则」)→ 请求体规则 → + 添加规则 → 模式下拉选 switch-route → 该行会展开两个控件:在「切换到模型 (use_model)」下拉选目标模型(可同协议或跨协议);在「命中条件 when」逐条加判定,每条填字段路径(按客户端协议形状写),等于留空表示「字段存在即命中」、填值表示「值相等才命中」,多条之间是「或」。
例:use_model 下拉选 qwen-vl-max,加三条判定——
- 路径
messages.*.content.*.image_url,「等于」留空(OpenAI Chat 客户端图像块,存在性) - 路径
messages.*.content.*.type,「等于」填image(Anthropic 客户端图像块) - 路径
tools.*.type,「等于」填web_search_20250305(联网搜索工具)
when 为 OR 语义:省略 eq 是字段存在性检查,给出 eq 是相等检查;* 通配取存在性语义。switch-route 按客户端形状评估,故路径要按调用方的协议写——上例并列了 OpenAI Chat(messages.*.content.*.image_url)与 Anthropic(messages.*.content.*.type 等于 "image")两种客户端形态,OR 任一命中即切换;要兼容更多客户端协议就在 when 里继续并列对应形态(DashScope 客户端为 input.messages.*.content.*.image)。use_model 可与当前路由同协议或跨协议(翻译前 立即切换会重翻译 body)。切到的目标视为管理员指定的内部路由:网关不再对 use_model 目标重新校验调用方所属分组的模型 ACL(模型 ACL 只在请求入口对客户端原始请求的模型校验一次)。完整退役案例见 配置索引。
用表达式写动态值(缓存键)
默认规则写入 value 里的固定值。若希望值随请求变化——例如给上游的私有缓存字段注入"同一会话用同一键"的动态值——把 value 写成表达式即可:字符串值含 {{...}} 时按模板解析,| 连接回退链取首个非空结果。例如"会话头优先、system 哈希兜底":
控制台 → 模型详情 → 请求体规则 → + 添加规则,填:模式 overwrite、路径 prompt_cache_key、值 {{header:x-claude-code-session-id|system_prompt_hash}}。
解析结果:① 请求头 x-claude-code-session-id 存在且非空 → 用头值(同一会话的多次请求带同一头值,即得同一缓存键,命中上游缓存);② 头缺失或为空 → 落到 system_prompt_hash,即 system 提示词内容的 sha256 哈希(同一份 system 提示词得同一哈希,也能命中缓存;协议无关,兼容 Anthropic system、OpenAI messages[role=system]、DashScope input.messages[role=system]、Google system_instruction);③ 头缺失且无 system 提示词 → system_prompt_hash 退化为 sha256("") 的固定值,若希望此时完全不注入,则不要把哈希放进链——整条链全空时本次写入被省略。头名大小写不敏感,头值前后空白视为缺失。该上下文还可用的变量:request_id、request_access_key_name、request_access_key_group(access_key_hash 在此为空,缓存键兜底请用 system_prompt_hash)。不含 {{ 的字符串作字面量、非字符串值原样写入,老规则不受影响。该规则通常挂在模型上(哪个模型需要缓存键是模型级策略);规则在协议转换之后应用,故写入的上游私有字段不会被翻译丢弃。在控制台表单里,直接在规则行的"值"输入框写表达式即可(占位提示已说明语法)。完整变量清单与各配置处的可用范围见 模板变量速查。
过滤内容类型
从消息内容数组中移除指定类型(如 image、video)的内容块。控制台 → 请求体规则 → + 添加规则,填:模式 filter-content-types、路径 messages、值 image。
从所有已知路径移除多种类型(自动展开) —— 控制台 → 请求体规则 → + 添加规则,填:模式 filter-content-types、路径 留空(即所有已知内容路径)、值 填 image、video(数组)。
移除图片块时会自动注入占位文本提示模型用户曾附带图片,可通过数据库直接配置 hint 字段自定义。
模型级规则
模型级规则优先级高于上游级。上游规则先应用,然后模型规则覆盖或扩展。控制台 → 模型 → 新建/编辑 qwen3.6-plus-strict,上游 选 openai,在请求体规则(模型级)里加两条:
| 路径 | 模式 | 值 |
|---|---|---|
temperature | overwrite | 0 |
response_format.type | overwrite | json_schema |
模型级 base_url 覆盖
在模型上设置 base_url 覆盖上游的默认值。控制台 → 模型 → 新建/编辑 custom-model,依次填:上游 openai、上游模型 ID qwen3.6-plus、基础 URL 覆盖 https://custom-proxy.example.com/v1。
凭证(API Key)仍来自上游配置,仅改变请求的目标端点。适用于将特定模型路由到独立代理、vLLM 实例或自定义端点。
direct_path 模式
设置 direct_path = true 时,模型的 base_url 被作为完整的端点 URL 使用,不追加任何路径。控制台 → 模型 → 新建/编辑 my-model,依次填:
- 上游 选
azure-openai。 - 协议覆盖 选
openai_images。 - 勾选 direct_path。
- 基础 URL 覆盖 填
https://{resource}.openai.azure.com/openai/deployments/my-model/images/generations?api-version=2025-04-01-preview。
模型级协议覆盖
模型可通过 protocol 字段覆盖上游的协议,让同一组凭据为不同 API 格式的模型服务。控制台 → 模型 → 新建/编辑 glm-5,依次填:上游 aws-global、上游模型 ID zai.glm-5、协议覆盖 openai、基础 URL 覆盖 https://bedrock-runtime.us-west-2.amazonaws.com/openai/v1/。
Upstream Inference Profile
upstream_inference_profile 覆盖发送给上游的模型 ID,源自 AWS Bedrock 的应用推理配置,可用作通用模型 ID 覆盖。控制台 → 模型 → 新建/编辑 glm-5,依次填:上游 aws-global、上游模型 ID zai.glm-5、inference_profile arn:aws:.../abcd1234。
设置后,该值在所有请求中作为上游模型 ID 使用,upstream_model_id 作为备用。
DashScope 模型配置
DashScope 不同类型模型有不同端点,通过 kind 字段选择:
| kind | 端点 | 适用模型 |
|---|---|---|
| (默认) | /api/v1/services/aigc/text-generation/generation | qwen-turbo、qwen-plus、qwen-max |
dashscope-multimodal | /api/v1/services/aigc/multimodal-generation/generation | qwen-vl-chat-v1、qwen-vl-plus、qwen-audio、fun-asr-flash |
dashscope-text-embedding | /api/v1/services/embeddings/text-embedding/text-embedding | text-embedding-v4 |
dashscope-rerank | 文本重排序端点 | gte-rerank |
dashscope-audio-asr | 异步语音 ASR | fun-asr |
文本生成
控制台 → 模型 → 新建/编辑 qwen-turbo,依次填:上游 dashscope、上游模型 ID qwen-turbo、协议覆盖 dashscope。
视频生成(direct_path)
视频生成等异步模型需要 direct_path = true。控制台 → 模型 → 新建/编辑 wanx2.1-t2v,依次填:
- 上游 选
dashscope。 - 上游模型 ID 填
wanx2.1-t2v。 - 协议覆盖 选
dashscope。 - 勾选 direct_path。
- 基础 URL 覆盖 填
https://dashscope.aliyuncs.com/api/v1/services/aigc/video-generation/video-synthesis。
异步模型还需在 extra_config 设置:{"dashscope": {"async_mode": true}}
文本向量(kind 选择端点)
文本向量模型使用百炼 MaaS 域名,需配置独立 upstream。控制台 → 模型 → 新建/编辑 text-embedding-v4,依次填:上游 dashscope-maas、上游模型 ID text-embedding-v4、协议覆盖 dashscope、类型 kind dashscope-text-embedding。
客户端用标准 OpenAI /v1/embeddings 协议发请求,网关自动翻译为 DashScope 格式。
重排序
两种路径:
DashScope 翻译(百炼模型)—— 控制台 → 模型 → 新建/编辑 gte-rerank,依次填:上游 dashscope-maas、上游模型 ID gte-rerank、协议覆盖 dashscope、类型 kind dashscope-rerank。
OpenAI 兼容上游(vLLM/Cohere/Jina)—— 控制台 → 模型 → 新建/编辑 bge-reranker-v2-m3,依次填:上游 vllm-rerank、上游模型 ID BAAI/bge-reranker-v2-m3、协议覆盖 openai_rerank。
语音转写(OpenAI 兼容)
qwen-audio、fun-asr-flash 等同步音频模型通过 kind = "dashscope-multimodal" 配置,支持 OpenAI /v1/audio/transcriptions 接口。控制台 → 模型 → 新建/编辑 qwen-audio,依次填:上游 dashscope、上游模型 ID qwen-audio、协议覆盖 dashscope、类型 kind dashscope-multimodal。
客户端用标准 OpenAI multipart 上传音频,网关自动翻译到 DashScope 格式。
异步语音 ASR
异步 ASR 需 kind = "dashscope-audio-asr" + extra_config.dashscope.async_mode = true。控制台 → 模型 → 新建/编辑 fun-asr,依次填:上游 dashscope-maas、上游模型 ID fun-asr、协议覆盖 dashscope、类型 kind dashscope-audio-asr、extra_config 填 {"dashscope": {"async_mode": true}}。
客户端向 POST /v1/services/{*rest} 提交,轮询 GET /v1/services/{model}/tasks/{task_id}。
OpenAI Images 模型配置
通过 openai_images 协议 + direct_path = true 配置图片生成/编辑。控制台 → 模型 → 新建/编辑 dall-e-3,依次填:
- 上游 选
openai-images。 - 上游模型 ID 填
dall-e-3。 - 协议覆盖 选
openai_images。 - 勾选 direct_path。
- 基础 URL 覆盖 填
https://api.openai.com/v1/images/generations。
Gemini 图片模型用 protocol = "google"(非 openai_images),网关自动翻译。控制台 → 模型 → 新建/编辑 gemini-3-pro-image-preview,依次填:上游 google-gemini、上游模型 ID gemini-3-pro-image-preview、协议覆盖 google。
模型脚本配置
每个上游和模型可配 JavaScript 脚本对请求/响应体做自定义变换:
| 字段 | 说明 | 默认值 |
|---|---|---|
request_transform_before | 翻译前请求体脚本 | 无 |
request_transform_after | 翻译后请求体脚本 | 无 |
response_transform | 响应体脚本 | 无 |
script_error_mode | log-and-continue / log-and-reject | log-and-continue |
内联脚本 —— 控制台 → 模型详情(或上游)→ 请求/响应脚本 → 在翻译后请求体(request_transform_after)槽黏贴:
function transform(body, context) { body.model = context.upstreamModel; return body; }文件脚本 —— 控制台的脚本编辑器只接受内联内容。引用外部 .js 文件(如 {"file": "scripts/inject-thinking.js"})只能通过 Console API 设置;UI 会原样保留已设置的文件引用,直到你在该槽输入内联内容覆盖它。详见 写第一个脚本变换。
脚本级别:
| 级别 | 作用范围 | 适用场景 |
|---|---|---|
| 上游 | 经过此上游的所有模型 | 协议适配、公共字段注入 |
| 模型 | 仅此模型 | 模型特定调整、参数调优 |
模型级脚本覆盖上游级。详细语法、内置函数、执行顺序见 脚本 API 参考。
常见脚本示例 — 注入 System Prompt:
function transform(body, context) {
if (body.messages.length === 0 || body.messages[0].role !== "system") {
const systemMsg = { role: "system", content: "You are a helpful assistant." };
body.messages = [systemMsg, ...body.messages];
}
return body;
}根据访问密钥分组执行条件逻辑:
function transform(body, context) {
if (context.accessKeyGroup === "premium") {
body.max_tokens = 8192;
} else {
body.max_tokens = 4096;
}
return body;
}常见问题
Q:模型设了 hide_name 后调主名返回 404? 是的,这是设计。hide_name=true 的模型只能用别名或经负载均衡器访问,主名不出现在 /v1/models 列表。
Q:同一个模型想配多个上游(故障转移)? 用负载均衡器,见 负载均衡字段。把多个上游+模型作为 entries 加进去。
Q:上游密钥快到期了怎么换? 编辑上游 → 改 API Key(轮换),旧值立即失效。或加一把新 key、删旧 key。
Q:DashScope 模型怎么配? 协议选 dashscope,基础 URL 填 DashScope 地址。文本生成模型无需 direct_path;视频/图像等异步模型需 direct_path = true + 完整 URL + extra_config.dashscope.async_mode = true。DashScope 客户端可走 /v1/services/{*rest}(透传)或 /v1/chat/completions(翻译模式)。
Q:request_payload 和脚本(request_transform_before/after)怎么选? 简单字段增删改用 request_payload(声明式规则,在网关内部直接改写请求体,不经过脚本引擎的序列化,性能最好);复杂逻辑、条件分支、跨字段计算用脚本。「检测图片/联网→切模型」这类纯路由决策用 request_payload 的 switch-route(零脚本开销,谓词不读二进制、大 body 不读入内存,同协议或跨协议皆可——它在翻译前按客户端形状判定并 立即切换;脚本路径因懒投影也已不再整段物化 body,但纯路由决策无需脚本);只有需要跨字段计算等复杂判定时才用脚本。详见 脚本 API 参考。
Q:模型级和上游级的 request_payload 冲突怎么办? 上游规则先应用,模型规则后应用。模型规则可覆盖或扩展上游的同路径规则。
下一步:单上游够用时本章即可;要多上游故障转移/负载均衡看 负载均衡字段;脚本变换看 脚本 API 参考;模板变量看 模板变量速查。
