CONTRACT
兼容的是 Gemini 原生请求形状,不是 Google 控制面的复制
JBB 接受 Gemini 原生 v1beta 路由与核心 JSON 字段。公开目录当前声明 11 个模型带有 Gemini endpoint 标记,但这不是每个模型对流式、工具、多模态、安全设置或缓存均可用的证明。
对话使用 contents[].parts[],系统指令、生成配置与安全设置保持 Gemini 字段名。
生成、流式与 token 计数均到达 TokenAuth 并返回 401;没有有效 Key 或付费调用记录。
路由存在不等于响应形状、SSE、工具循环、usage 与计费已端到端通过。
Gemini-compatible 是协议兼容描述,不代表 JBB 与 Google 存在官方合作、授权、背书或完整功能等价关系。
ENDPOINT EVIDENCE
生成、流式与计数已到认证边界,成功响应仍未验证
2026-07-15 的源码、公开价格目录与生产探测确认了以下边界。本轮 未使用有效 Key、未发起付费调用,逐模型 E2E 未验证;401 只说明请求进入认证链。
| 端点 | 证据级别 | 当前边界 |
|---|---|---|
GET /v1beta/models | 路由已验证 | 源码注册 Gemini 模型列表;无有效凭证返回 401。公开目录当前声明 11 个 Gemini endpoint 模型。 |
POST /v1beta/models/{model}:generateContent | 认证边界 | 原生 relay 路由与字段 DTO 已确认;无凭证生产请求返回 401,未验证模型成功响应。 |
POST /v1beta/models/{model}:streamGenerateContent?alt=sse | 仅路由 / 认证 | 请求返回 401;SSE Content-Type、事件增量与终止行为没有使用有效 Key 验证。 |
POST /v1beta/models/{model}:countTokens | 仅路由 / 认证 | 请求返回 401;只证明 route/auth,不证明模型级 token 计数结果。 |
GET / POST /v1beta/cachedContents | 当前 404 | 独立缓存资源的 list/create 均返回 404,不得宣传 standalone cachedContents 管理。 |
OPTIONS ...:generateContent | 当前 404 | 不要假设浏览器 CORS 预检可用;生产调用应从服务端发起。 |
Base URL 固定为站点 origin:https://jbbt.pages.dev。把 /v1beta/models/... 放在每个 REST route 中,不要把 /v1beta 全局追加到 Base URL。
AUTH & DIRECT REST
优先发布 direct REST;三种 JBB Key 传递方式均可用
原生 Google 文档通常使用 x-goog-api-key 或 ?key=;JBB 的 TokenAuth 还接受 Authorization: Bearer。Key 只放在服务端环境变量中,查询参数可能进入代理日志,优先使用 header。
export JBB_API_KEY="<YOUR_API_KEY>"
export JBB_BASE_URL="https://jbbt.pages.dev"
export JBB_MODEL="<E2E_TESTED_GEMINI_MODEL_ID>"
curl "$JBB_BASE_URL/v1beta/models/$JBB_MODEL:generateContent" \
-H "x-goog-api-key: $JBB_API_KEY" \
-H "content-type: application/json" \
-d '{
"systemInstruction": {"parts": [{"text": "Answer concisely."}]},
"contents": [{"role": "user", "parts": [{"text": "Reply with OK"}]}],
"generationConfig": {"temperature": 0.2, "maxOutputTokens": 128}
}'
import json
import os
import urllib.parse
import urllib.request
base = os.getenv("JBB_BASE_URL", "https://jbbt.pages.dev")
model = urllib.parse.quote(os.environ["JBB_MODEL"], safe="")
url = f"{base}/v1beta/models/{model}:generateContent"
body = {
"contents": [{"role": "user", "parts": [{"text": "Reply with OK"}]}],
"generationConfig": {"temperature": 0.2, "maxOutputTokens": 128},
}
request = urllib.request.Request(
url,
data=json.dumps(body).encode(),
headers={
"content-type": "application/json",
"x-goog-api-key": os.environ["JBB_API_KEY"],
},
)
with urllib.request.urlopen(request, timeout=60) as response:
print(response.read().decode())
const base = process.env.JBB_BASE_URL ??
"https://jbbt.pages.dev";
const model = encodeURIComponent(process.env.JBB_MODEL);
const response = await fetch(
`${base}/v1beta/models/${model}:generateContent`,
{
method: "POST",
headers: {
"content-type": "application/json",
"x-goog-api-key": process.env.JBB_API_KEY,
},
body: JSON.stringify({
contents: [{ role: "user", parts: [{ text: "Reply with OK" }] }],
generationConfig: { temperature: 0.2, maxOutputTokens: 128 },
}),
},
);
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
console.log(await response.json());
?key=$JBB_API_KEY可作为查询参数认证,但要评估 URL 日志泄漏风险。Authorization: Bearer $JBB_API_KEY是 JBB 兼容选项,不是 Gemini 原生文档的默认 API-key 写法。- 不要把 Google Gen AI SDK custom base URL 示例发布成“已验证 JBB 集成”;本页只给 direct REST 路径。
NATIVE ENVELOPE
核心结构是 contents / parts,系统指令与控制项位于顶层
原生 JSON 使用 camelCase systemInstruction。JBB DTO 同时接收 system_instruction,但 raw REST 示例应保持官方 camelCase。字段被 DTO 接收不代表每个上游模型都会执行这些能力。
{
"systemInstruction": {
"parts": [{"text": "Answer in Chinese."}]
},
"contents": [{
"role": "user",
"parts": [{"text": "Explain retry with jitter."}]
}],
"generationConfig": {
"temperature": 0.2,
"maxOutputTokens": 256
},
"safetySettings": []
}
contents[]表示对话 turn;每个 turn 的有序parts[]可承载 text 等原生 Part。systemInstruction不放入 OpenAImessages[]或 Claudesystemblock。generationConfig与safetySettings已进入 DTO;具体参数、类别和模型行为逐项验证。- 多模态 Part 字段存在于协议并不证明 JBB 的每个 Gemini endpoint 模型均端到端支持。
STREAM · COUNT · TOOLS · CACHE
高级字段可以进入请求;执行、命中和返回形状仍需实测
curl --no-buffer \
"$JBB_BASE_URL/v1beta/models/$JBB_MODEL:streamGenerateContent?alt=sse" \
-H "Authorization: Bearer $JBB_API_KEY" \
-H "content-type: application/json" \
-d '{"contents":[{"role":"user","parts":[{"text":"Count to three"}]}]}'
curl "$JBB_BASE_URL/v1beta/models/$JBB_MODEL:countTokens?key=$JBB_API_KEY" \
-H "content-type: application/json" \
-d '{"contents":[{"role":"user","parts":[{"text":"Count these tokens"}]}]}'
{
"contents": [{"role": "user", "parts": [{"text": "上海现在几点?"}]}],
"tools": [{
"functionDeclarations": [{
"name": "get_time",
"description": "Return local time for an IANA timezone",
"parameters": {
"type": "object",
"properties": {"timezone": {"type": "string"}},
"required": ["timezone"]
}
}]
}]
}
streamGenerateContent?alt=sse只完成 route/auth 探测;上线前验证 SSE Content-Type、增量事件、终止与错误帧。countTokens目前只验证 route/auth;不得写成模型级计数已通过。- 模型可返回
functionCall;客户端负责校验参数、执行函数,再发送functionResponse。JBB 或模型不会替应用执行声明的函数。 - standalone
cachedContentscreate/list 当前返回 404。请求字段cachedContent虽被 DTO 接收,但创建、命中、usage 与计费未端到端验证。
DIFFERENCES
Gemini 原生、OpenAI-compatible 与 Claude-compatible 是三套入口
- Gemini 原生
使用
/v1beta/models/{model}:action与contents[].parts[];API Key 常用x-goog-api-key或?key=。 - OpenAI-compatible
使用
/v1/chat/completions等路由、Bearer 认证与messages[]。迁移规则见OpenAI-compatible 页面。 - Claude-compatible
使用
/v1/messages、x-api-key、Anthropic version 与 Claude content blocks。边界见Claude-compatible 页面。 - 模型与能力
同一个模型名称出现在目录中,不代表三套协议的所有字段、stream、tools 与计费行为完全等价。
- SDK 边界
官方 SDK 暴露 custom base URL 配置,不等于 JBB 已验证其路径拼接、认证注入、SSE、缓存、文件和工具全流程。
ERRORS & RETRIES
先分清认证、路径、请求形状与上游错误,再决定重试
- 401认证失败
检查 JBB Key、header 名、查询参数、余额和权限。当前 401 证据不代表模型调用成功。
- 404路径或资源不存在
检查 Base URL 是否错误追加
/v1beta;standalonecachedContents与 OPTIONS 当前明确返回 404。 - 400请求形状或模型不接受
核对 camelCase 字段、
contents、Part 类型、工具 Schema、模型 ID 与参数范围。 - 429额度或频率受限
核对 Key 与分组限制;只对幂等或可安全重放的请求做有上限的指数退避与 jitter。
- 5xx网关或上游失败
保存请求 ID 和错误正文;设置连接与总超时,有限重试并避免重复产生副作用。
PRODUCTION GATE
上线前完成九项检查
- JBB Key 只存于服务端环境变量或 Secret Manager,不放入浏览器 bundle。
- Base URL 固定为
https://jbbt.pages.dev,每条 route 自带/v1beta。 - 优先使用
x-goog-api-key或 Bearer header;使用?key=时控制 URL 日志。 - 目标模型已用最小额度完成
generateContent端到端验证并保存响应。 - 流式逐项验证 SSE Content-Type、增量、终止、取消和错误处理。
countTokens的输入形状与返回值按目标模型实测,不依赖本轮 401。- 工具参数按不可信输入处理;设置 Schema、权限、超时、大小和循环上限。
- 不依赖 standalone
cachedContents;如使用cachedContent字段,先验证创建链、命中、usage 与计费。 - 记录请求 ID、HTTP 状态、模型、关键参数、usage、延迟与实际计费;429/5xx 使用有限退避。