配置参考¶
网关的全部配置都是环境变量,统一以 JEV_ 开头。没有配置文件——不存在的变量直接用
默认值,所以空环境下也能启动。仓库里的 .env.example 是带注释的模板,cp .env.example
.env 即可;.env 本身在 .gitignore 里,你填的地址和 key 不会进版本库。
Docker Compose 会自动读取同目录的 .env。本地跑的时候把变量导进 shell 即可:
也可以完全不建文件,直接在命令行上给:
空值等于未设置,所以 JEV_BACKEND_MODEL= 和不写这个变量效果一样。值不合法直接
报错,并且在错误信息里点名是哪个变量——拼写错误在启动时失败,而不是被静默忽略。
完整对照¶
| 变量 | 默认值 | 说明 |
|---|---|---|
JEV_SERVER_HOST |
0.0.0.0 |
|
JEV_SERVER_PORT |
8000 |
|
JEV_BACKEND_TYPE |
openai |
唯一支持的协议 |
JEV_BACKEND_BASE_URL |
http://127.0.0.1:8080 |
|
JEV_BACKEND_MODEL |
空(自动探测) | 为空时用后端自报模型名 |
JEV_BACKEND_API_KEY |
空 | 仅托管 API 需要 |
JEV_BACKEND_TIMEOUT_SECONDS |
30.0 |
单问题超时 |
JEV_BACKEND_MAX_CONCURRENCY |
32 |
单网关实例并发上限 |
JEV_BACKEND_TOP_LOGPROBS |
128 |
16 – 4096;窗口外候选按下界截断 |
JEV_BACKEND_SUPPORTS_IMAGES |
auto |
true / false 强制指定 |
JEV_BACKEND_EXTRA_HEADERS |
{} |
JSON 对象;云 API key、租户标识 |
JEV_BACKEND_EXTRA_BODY |
{} |
JSON 对象;「关思考」开关写这里 |
JEV_REQUEST_MAX_QUESTIONS |
64 |
单次请求 1 – 64 个问题 |
JEV_REQUEST_TOTAL_TIMEOUT_SECONDS |
60.0 |
整次请求预算 |
JEV_REQUEST_PROMPT_LAYOUT |
fused |
fused | split |
JEV_MULTIMODAL_ENABLED |
true |
为 false 时任何 assets 都报 400 |
JEV_MULTIMODAL_MAX_IMAGES |
4 |
单次请求的图片数 |
JEV_MULTIMODAL_MAX_IMAGE_BYTES |
5242880(5 MiB) |
单图,base64 解码后计算 |
JEV_MULTIMODAL_ALLOWED_MIME_PREFIXES |
image/ |
逗号分隔 |
JEV_LOGGING_LEVEL |
INFO |
JEV_BACKEND_BASE_URL 末尾的斜杠会被去掉,所以 http://127.0.0.1:8080/ 和
http://127.0.0.1:8080 等价。
布尔值接受 true / false、1 / 0、yes / no、on / off,不区分大小写。
JEV_BACKEND_SUPPORTS_IMAGES 额外接受 auto。
各段说明¶
服务器¶
JEV_SERVER_HOST / JEV_SERVER_PORT 是监听地址,默认 0.0.0.0:8000,容器镜像和 Docker
Compose 模板用的就是这个。
后端 JEV_BACKEND_*¶
TYPE 恒为 openai——网关只说一种协议。不同服务之间只有 BASE_URL 会变,见
后端。
MODEL 留空表示自动探测:网关会问服务的 /v1/models 并取它报告的第一个模型。会报出
多个模型的服务,或要求客户端指明用哪个的服务(vLLM、开了多个 served model 的 SGLang),
应显式固定。
TOP_LOGPROBS 是 next-token 窗口的大小。两到四个候选时默认的 128 已经相当宽裕;看到
候选结果不稳定时可提高,取值范围 16 – 4096。窗口外候选会被内部截断,API 响应不暴露此诊断。
服务端都有自己的上限,默认 128 可能直接让所有请求失败
OpenAI 规范把 top_logprobs 上限定在 20,而不少服务端的上限比这更低。超限时后端
不报错,只是把 logprobs 变成 null,表现为
BACKEND_PROTOCOL_ERROR: backend response contained no logprobs object。这是换后端时
最难查的故障,因为它返回 HTTP 200、日志里也没有任何错误信息。
换新后端时先用 20 / 24 / 32 / 64 / 128 试出上限(见
后端),再把能用的最大值填进这个变量。
SUPPORTS_IMAGES=auto 即「自动」:假定后端能接收图片,图片缺失时就不投递。模型没有
视觉塔时显式设为 false,图片请求会以 BACKEND_CAPABILITY_UNSUPPORTED 快速失败,而
不会打到后端。
EXTRA_HEADERS 会作为 HTTP 头合并进每个请求——云 API key、租户 id、项目名。值是一个 JSON
对象,shell 里记得给引号:
EXTRA_BODY 同理合并进 JSON body;服务端「关思考」的开关就写在这里:
推理模型漏出的 reasoning 字段会占用 max_tokens: 1 里唯一那个 token,于是 logprobs
变成 null。不同后端认的写法不同(llama.cpp / vLLM 认 chat_template_kwargs,
OpenRouter 的 openrouter/qwen/* 只认 reasoning: {effort: "none"}),不确定时可以两种
都写,不认识的 key 会被静默忽略:
JEV_BACKEND_EXTRA_BODY='{"chat_template_kwargs": {"enable_thinking": false}, "reasoning": {"effort": "none"}}'
两者都无法覆盖 messages、max_tokens、logprobs 和 top_logprobs。
请求 JEV_REQUEST_*¶
MAX_QUESTIONS 限制单次请求能带多少问题(1 – 64)。超出的请求以 INVALID_REQUEST 拒绝。
TOTAL_TIMEOUT_SECONDS 是整次请求的总预算,所有问题加起来。由于问题并发执行,一个 64
问题、60 秒预算的请求,耗时大致仍等于最慢的那一个问题——除非后端已经饱和。
PROMPT_LAYOUT 可选 fused(默认,与参考网关逐字节兼容)或 split(对缓存友好)。
两者都在工作方式里有说明。
多模态 JEV_MULTIMODAL_*¶
| 变量 | 默认值 | 含义 |
|---|---|---|
ENABLED |
true |
为 false 时任何 assets 都报 400 |
MAX_IMAGES |
4 |
单次请求的图片数 |
MAX_IMAGE_BYTES |
5242880(5 MiB) |
单图,base64 解码后计算 |
ALLOWED_MIME_PREFIXES |
image/ |
逗号分隔的 MIME 前缀 |
日志 JEV_LOGGING_LEVEL¶
接受标准 Python 日志级别:DEBUG、INFO、WARNING、ERROR。默认 INFO。
每个响应本来就带 x-request-id,日志用的也是同一个 id,排查时直接 grep 它即可。
Prompt 布局一句话版¶
fused——单条 user message 含{evidence, criterion, options},与参考网关逐字节兼容, 在托管 API 上测出的校准结论可以直接迁移。split——证据(及图片)放第一条 user message,指令与选项放第二条。第一条在同一次请求 的所有问题之间完全相同,llama.cpp 可复用视觉编码和状态 prefill。延迟优先于字节兼容时用。