大模型 OpenAI 服务网关
大模型服务网关是为了代理多个 OpenAI 接口,并且在代理中实现认证、限流、接口输入输出的修正、监控等功能而设计的。
实现源码:
myapp/views/view_llm_ingress.py(路由前缀route_base='/llm/api',对外接口/<ingress_id>/v1/chat/completions)。

认证方式
网关支持以下认证方式(auth_method,见 view_llm_ingress.py:292):
- 不认证(no):不校验秘钥。
- 数据库匹配(db_match):从秘钥位置获取到的秘钥跟服务网关设定的秘钥完全一致。
- 正则匹配(regex):从秘钥位置获取到的秘钥要符合服务网关设定的秘钥正则表达式。
- JWT 认证(jwt-HS256):从秘钥位置获取到的秘钥要能使用服务网关设定的秘钥 key 进行 JWT 解码(HS256 算法)。
秘钥位置
secret_position,格式为 position:key(默认 header:Authorization,见 view_llm_ingress.py:279-285)。
其中 position 为秘钥获取方法:header 表示从 http header 头中读取,body 表示从 json 请求体中读取,arg 表示从请求的 url 参数中读取。
key 为对应位置处的 key 值,比如:
header:Authorization表示从 header 头中读取Authorization的值作为秘钥;body:user_id表示从 json 请求体中读取user_id的值作为秘钥;arg:key表示从 url 请求参数中读取参数key的值作为秘钥。
秘钥
根据认证方法,可自己设定,也会随机生成。
过期时间
expires_at,网关的过期时间,超过该时间后,对访问请求返回"该网关已过有效期"的应答。
token 额度
quota,整数或者 no-limit,是问答总 token 的最大累加和(默认 no-limit;填整数时要求大于 10000,见 view_llm_ingress.py:303-307)。
服务列表
services,平台内创建的、自己有权限访问的 OpenAI 接口服务,但并不一定是当前上线的 llm 服务。在正式访问时会查询代理的 llm 服务是否上线中,再根据是否上线决定应答。
外部服务
external_services,外部 OpenAI 兼容上游列表(含 /v1、不含 /chat/completions,见 view_llm_ingress.py:173、405-410),与内部推理服务一起按权重随机做负载均衡。
失败重试
retry,请求大模型 OpenAI 接口报错后重试的次数。
限速
limit_rate,访问速率限制(见 view_llm_ingress.py:339-344):
no-limit:没有限制。ingress:n/minuteingress:n/houringress:n/day:针对该网关(所有调用总和),限制最近 1 分钟/小时/天最多访问 n 次。secret:n/minutesecret:n/hoursecret:n/day:针对每个秘钥(用户),限制最近 1 分钟/小时/天最多访问 n 次。secret:n(token)/hoursecret:n(token)/day:针对每个秘钥,按 token 数 限制最近 1 小时/天的累计用量。ip:n/minuteip:n/hourip:n/day:针对每个客户端 IP,限制最近 1 分钟/小时/天最多访问 n 次。
其中 n 为整数。
白名单
whitelist,如果设置了白名单,在白名单范围内的就放行,不在白名单范围内的就不放行,优先级高于黑名单。每行一个白名单规则(默认 ip:0.0.0.0/0、secret:.*、time:0~24,见 view_llm_ingress.py:346-348)。
每行的书写规则:type:value,其中 type 可为:
ip:客户端的访问 ip 范围,值为 ip 网段;secret:访问者的秘钥,值为秘钥的正则表达式;time:访问的时间,值为时间范围段(如0~24)。
黑名单
blacklist,书写规则同白名单,访问流量符合黑名单规范就阻拦,优先级低于白名单。
激活
active,可控制当前网关是否有效。
联网搜索
search,JSON 格式配置(见 view_llm_ingress.py:368-374)。enable=true 时按配置调用联网搜索(默认走 Tavily),字段示例:
{
"enable": false,
"endpoint": "https://api.tavily.com/search",
"search_depth": "basic"
}
enable=false 时整个联网搜索插件不生效;未配置字段使用平台默认值。
说明:原文档曾标注联网搜索"暂时无效",当前代码已提供可用的 JSON 配置开关,故据代码更新此节。
内容安全
security,JSON 格式配置(见 view_llm_ingress.py:360-365)。enable=true 时按配置的 url/阈值调用安全检测服务;enable=false 时整个内容安全插件不生效,开启后 url 必填。
说明:原文档曾标注内容安全"暂时无效",当前代码已提供可用的 JSON 配置开关,故据代码更新此节。
深度思考 / 数据脱敏
⚠️ 待核实:
- 深度思考:模型字段
deepseek(myapp/models/model_llm_ingress.py:35,Boolean,默认True)。请求流中确有逻辑引用它:当not ingress.deepseek且模型名含deepseek时,会注入extra_body.chat_template_kwargs.enable_thinking=False关闭思考(view_llm_ingress.py:1012-1024、1099、1148)。但该字段未出现在add_columns/edit_columns(view_llm_ingress.py:426-448),界面无法修改;默认True下"关闭思考"分支永不触发,实际等同未向用户开放。请确认是否有意如此。- 数据脱敏(
desensitization):表单字段存在(在ops_columns中,view_llm_ingress.py:430)但默认空、description仅为"数据脱敏配置",请求流中未检索到对应的脱敏处理逻辑(输出侧敏感信息拦截由"内容安全"的sensitive阈值承担),疑为占位未实现,请确认。
提示词模板
prompt,最终发给大模型的问题。如果当前服务网关配置了提示词模板,其中一定要包含 {{query}},比如:
CubeStudio是开源一站式机器学习平台,请你的回答尽可能专业。请问:{{query}}
那么最终发给大模型的问题就是上面这一整段话,其中 {{query}} 被替换为用户最原始的问题。我们可以通过这种方式添加一些问答限制。
参数值映射
value_map,对推理服务的 json 请求体的 value 进行映射,格式为 "key":["old_value","new_value"]。
例如 "model":["deepseek","deepseek-qwen2-7b"],可以将请求 deepseek 的模型全部代理到 deepseek-qwen2-7b 模型服务上。
参数值固定
value_fixed,对推理服务的 json 请求体的 value 进行固定,格式为 "key":"new_value"。
例如 "model":"deepseek-qwen2-7b",可以将任何模型请求全部代理到 deepseek-qwen2-7b 模型服务上。
调用测试
当配置了服务网关,网关会对外提供 OpenAI 接口,代理用户的请求到下面的 OpenAI 模型接口上。对外接口路径为 /llm/api/<ingress_id>/v1/chat/completions(见 view_llm_ingress.py:210、763)。
在外部智能体平台,主要需要配置如下环境变量:
API_SECRET_KEY = "sk-xxxxxxxx"
BASE_URL = "http://xx.xx.xx.xx/llm/api/xx/v1"
也可以自己写 API 调用示例代码:
curl -X POST http://xx.xx.xx.xx/llm/api/xx/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-xxxxx" \
-d '{
"model": "xxxx",
"messages": [
{
"role": "user",
"content": "你是谁?"
}
],
"temperature": 0.7,
"stream": false
}'
参数说明:
model:替换为你的模型名称(当前可访问模型名取决于该网关代理的、且在线的大模型服务);messages:对话历史,包含role(user / assistant / system)和content(消息内容);temperature:控制生成文本的随机性(0~2,值越大越随机)。
监控
客户端可以进行调用访问,每次调用访问,服务网关都会监控当前已使用 token 数目,和今日每小时的调用次数。
