语言简体中文

AI 网关

从您的个人应用程序中使用连接到您自己的 AirCode Ø 实例的 AI 帐户。 提供您的实例的 Base URL,一个单独的 应用代币,以及一个准确的 模型 ID。 该实例调用其连接的提供商 CLI ,并通过文本的聊天完成子集和图像的图像子集返回答案。

Your application's backend
  → your instance URL + application token
    → a connected native provider account
      → validated answer + available usage counters

网站仅托管文档。 API 请求直接到您的实例; aircodezero.com 不会收到您的实例地址、代码或提示。 仅为自己的应用程序和帐户使用此服务。 供应商条款、订阅访问和配额仍然适用。

设置实例

  1. 在 AI 使用中连接兼容的本地提供商帐户。 门口 列出了安装实例支持的帐户模型; API-key 和 管理信贷连接被排除在外。
  2. 在桌面或网页打开 设置 → AI gateway,在手机打开 更多 → AI gateway。在 创建访问权限 下开启 允许私人连接。
  3. 复制显示的 Base URL。 它以 /api/ai-gateway/v1结束。
  4. 在 创建令牌 中选择 应用,输入应用名称,然后选择 创建令牌。令牌只显示一次,请及时复制。此选项允许应用通过 AI API 使用文本和图像,但不能启动跨实例会话。
  5. 在您的应用程序中配置以下服务器侧环境变量:
变量 值
AIRCODE_AI_BASE_URL 完整的基础 URL 复制从实例中,没有额外的 /v1
AIRCODE_AI_TOKEN 您刚刚创建的应用程序代币
AIRCODE_AI_MODEL 来自 id 的确切 兼容型号 或 GET /models

将代币保存在后端的秘密配置中,而不是浏览器代码、移动应用程序包、存储库、 URL 或共享对话中。 示例阅读环境变量,而不是嵌入证书。 永远不要在 API-key 字段中使用实例密码或所有者登录代码。

该实例必须继续运行并可从应用程序的后端访问。 localhost 指运行该后端的计算机。 使用该实例的 HTTPS 地址进行远程访问,或使用您可信的本地/私人网络连接。 网关不创造公共来源。 /models 未列出的提供商不能通过发明 ID来选择。

身份验证和模型发现

在每次通话中发送 Authorization: Bearer YOUR_APPLICATION_TOKEN 。 用 JSON 发送 Content-Type: application/json。 未支持查询参数或 Cookie 身份验证。 跨源浏览器呼叫不受支持;使用您的后端。

GET {BASE_URL}/models 返回具有 object: "list" 和 data 数组的对象。 每个模型都提供了一个 id展出 label, engine, engineLabel, provider, connectionLabel, efforts 和 capabilities: chat.completions 对于文本模型来说, images.generations 和 images.edits 对于图像模型来说。 返回的 id 保持不变;它可能已经包含百分比编码。 当帐户、提供商访问或安装的模型发生变化时,该列表可能会发生变化。

对于 OpenAI兼容的应用程序的配置,请选择 聊天完成,使用完整的 Base URL,将应用程序代币放入其 API 键域 ,并复制返回的模型 ID 之一。 图像使用下文描述的图像子集。 需要响应、工具或不支持的采样参数的应用程序与当前网关不兼容。

生成回复

POST {BASE_URL}/chat/completions 接受以下字段。 未知的字段被拒绝,而不是默默地忽略。

字段 支持的值
model 所需的精确模型 ID 由 /models 返回
messages 需要 1 到 100 条消息的数组;至少有一条非空用户消息
messages[].role system, developer, user 或 assistant
messages[].content 一个字符串,或一组 { "type": "text", "text": "..." } 块
reasoning_effort 选用值从所选型号的 efforts;将其放弃为默认值
stream 可选的布尔式;默认为 false
stream_options 只有 { "include_usage": true } 或 false 对于该旗帜,与 stream: true
n 忽略或使用 1
store 忽略或使用 false

消息只包含 role 和 content。 文本块与新闻稿相连。 零字符被拒绝。 正常化的消息数组必须在 UTF-8 JSON的64 KiB范围内,整个 HTTP 的体积仅限于80 KiB。 验证的答案限于49152个JavaScript字符串代码单元。 这些是网关限制,而不是提供商的背景窗口或输出容量的承诺。

在每个电话中提供完整的相关对话。 若要继续对话,请附上前一个助理的答案和下一个用户的消息。 网关不会创建或保留对话、会话或完成历史记录。 代币不允许访问实例项目、文件、终端、会话或所有者设置。

一个正常的答案有 object: "chat.completion";阅读从 choices[0].message.content的文本。 它还包括 id, created, 所请求的 model, 和 finish_reason: "stop"。 在 usage 中,本地计数出现,当完成足以报告时。 aircode_usage 扩展将保留会计详细信息和不完整的估计。 缺少的计数器或价格是未知的,从来没有零。 API-equivalent估计不是额外的订阅费用。

流媒体

stream: true 设置为接收 Content-Type: text/event-stream。 目前的实现使用 缓冲流量:它在提供商运行时发送初始的等待评论和 keepalive 评论,然后在验证后发送完整的答案。 不是 流词或代币,因为它们被生成。

一个成功的流体包含:

  1. SSE 评论开始于 : 等待;忽略它们。
  2. 一个 data: JSON chat.completion.chunk 与助手角色和完成 文本为 choices[0].delta.content。
  3. 一个带空分裂和 finish_reason: "stop"的片段。
  4. choices: [], usage (可能 null) 和 aircode_usage 当 stream_options.include_usage 是真的时。
  5. data: [DONE].

一旦流量开始,失败就会作为一个 SSE data: 事件包含 error· 不要治疗 HTTP 单身200个成功 一个失败的流没有成功标记就关闭了。 SSE 框架可以分成传输块;使用 SDK 或 SSE 分析器,而不是将每个网络块作为 JSON分析。

关闭连接会取消其活跃的请求。 撤销一个代币、禁用网关或停止实例也取消了匹配的工作。 没有自动重播或复制。 长期的请求需要适当的客户端和反向代理时间;保留程序不能超过网络的绝对请求时间限制。

生成图像

图像模型列出,而实例的原始 Codex 帐户可以使用自己的图像工具,这需要一个包含图像生成的 ChatGPT 计划。 它的 id 是 codex/image-generation。 Codex 决定使用哪个图像模型;门口不会选择一个。

  • POST {BASE_URL}/images/generations 接收 JSON 接收 model, prompt (最多为 32000 个字符)和可选的 size, n: 1 和 response_format: "b64_json".
  • POST {BASE_URL}/images/edits 使用相同字段的 multipart/form-data 和 image 或 image[]中的 1 到 4 个参考图像。 每个必须是 PNG 或 JPEG 最多为 4 MiB。 其他文件域,例如 mask被拒绝。

size 是 64 到 4096 像素之间的 auto 或 WIDTHxHEIGHT 。 它作为指导传递给模型;响应报告了实际大小。 任何其他领域都被拒绝,而不是忽略。

curl -sS "$AIRCODE_AI_BASE_URL/images/edits" \
  -H "Authorization: Bearer $AIRCODE_AI_TOKEN" \
  -F model=codex/image-generation \
  -F "prompt=Place this product in a premium studio shot on a stone pedestal." \
  -F size=1024x1536 \
  -F image=@product.png

一个响应载有 created,一个 data[0].b64_json,一个 output_format (png, jpeg 或 webp),实际的 size 和 aircode_usage。 会计涵盖了驱动图像工具的代理人;提供商不报告图像工具的成本,因此 costComplete 始终是 false。 一代通常需要一到三分钟,通过短信通话共享下面的限制,并在客户端断开连接时被取消。 当模型没有图像响应时, 422 AI_GATEWAY_NO_IMAGE 和模型的句子,如果它给出了一个,呼叫失败。

自动连接保存的 AirCode Ø 应用程序

一个存储在 Apps 的应用程序运行自己的服务器,可以获得此访问,而无需复制代币。 在应用程序页面上,打开 设置 → 访问 → AI 帐户 并打开它。 AirCode Ø 如下:

  1. 打开私人 AI 网关,如果它被关闭;
  2. 重新启动应用程序,并在每次启动时给其服务器一个新的代币。 自己,撤销前一开始的代币;
  3. 设置 AIRCODE_AI_BASE_URL (实例听取的地址上的网关), AIRCODE_AI_TOKEN和,如果可用, AIRCODE_AI_MODEL (文本模型) 和 AIRCODE_AI_IMAGE_MODEL (图像模型)。

应用程序的发布版本也以同样的方式获得了自己的代币。 关闭 AI 帐户会立即撤销应用程序的代币。 从应用程序的服务器拨打网关,并在那里保留代币:任何可以打开应用程序的人都可以通过它使用您的帐户,并且它们的使用对您的计划产生影响。

报价,代币生命周期和错误

该网关允许在整个实例中进行两次活跃的呼叫,每代币一次活跃的呼叫,每代币每分钟30次接受的生成请求。 电话没有排队。 这些局部限制不取代供应商配额。 代币在90天后到期;创建一个替代品,更新您的应用程序,然后撤销以前的代币。 禁用网关将保留代币,但暂停其使用。 恢复实例状态会禁用网关并清除代币权限;创建新代币。

错误使用 error.message, error.type, error.code 和 error.param。 阅读代码以及 HTTP 状态。 不要自动重复一代未知的结果:它可能已经消耗了供应商配额。 示例禁用 SDK 重复。

状态/代码 该怎么做
401, AI_GATEWAY_AUTH_REQUIRED 检查代币、到期、撤销和目标实例
403, AI_GATEWAY_DISABLED 在目标实例上启用网关
403, AI_GATEWAY_ORIGIN_FORBIDDEN 来自您的后端的呼叫,而不是外部浏览器的来源
AI_GATEWAY_ACCESS_REFUSED 检查实例的访问/订阅要求
400,不支持的参数或努力 删除不受支持的字段;使用所选模型的广告努力
404/409, AI_GATEWAY_MODEL_UNAVAILABLE 更新 /models 并明确选择可用的 ID
413, AI_GATEWAY_INPUT_TOO_LARGE 减少提供的历史、提示或参考图像;超大 HTTP 机体也被拒绝
415 在 /images/edits 发送 multipart/form-data
422, AI_GATEWAY_NO_IMAGE 模型没有图片回答;阅读其句子并更改请求
429, AI_GATEWAY_BUSY 等待正在进行的呼叫结束,然后再试一次
429, AI_GATEWAY_RATE_LIMIT 停止即时回调并等待本地分钟窗口
SAFE_STRUCTURED_AI_QUOTA_EXHAUSTED 等待供应商配额恢复; error.resets_at 可能是 null
409, 取消 将呼叫视为取消;不要自动恢复
502/503, 供应商/不可用错误 检查帐户连接和实例状态,然后再进行明确的审查

未知的提供者重置时间仍然未知。 永远不要从模型名称或无关的供应商的配额时间表中提取一个。

使用应用程序中的另一个实例

外部应用可使用另一自有实例的 Base URL 和该实例签发的令牌访问它。每个令牌仅属于签发它的实例。若要让 B 上的代理处理 A 的项目,请在 B 创建令牌时选择 另一实例,并参阅远程会话。默认情况下,文件和命令仍留在 A。在 A 保存该连接,在 新会话 → 运行于 中选择 B,并保留 项目位置 → 此实例。若要使用 B 上的项目,则在 B 创建令牌时选择 此实例 和对应项目,并在 A 启动时选择 项目位置 → 远程实例。两种方式都实时传送事件。普通令牌支持文本和图像,但不会将客户端登录为远程实例的所有者。Responses、Anthropic Messages 和 Chat Completions 的工具调用不属于文本 API 的支持范围。

有关 AI辅助整合的信息,请参阅 文档 AI, 原始 Markdown 指南, OpenAPI 方案,以及 整合技能。

代码示例

在运行示例之前,设置上面的三个环境变量。 这些片段也可在设置和原始 Markdown 指南中使用。

cURL

Bash, curl and jq. List models first, then use the exact model ID you selected.

set -euo pipefail
# The token is read from standard input, not a command-line argument.
curl --fail-with-body --silent --show-error --location --max-redirs 0 \
  "$AIRCODE_AI_BASE_URL/models" --header @- <<EOF
Authorization: Bearer $AIRCODE_AI_TOKEN
EOF

body=$(jq -n --arg model "$AIRCODE_AI_MODEL" \
  '{model: $model, messages: [{role: "user", content: "Hello!"}]}')
curl --fail-with-body --silent --show-error --location --max-redirs 0 \
  "$AIRCODE_AI_BASE_URL/chat/completions" \
  --header 'Content-Type: application/json' \
  --header @- --data "$body" <<EOF
Authorization: Bearer $AIRCODE_AI_TOKEN
EOF

Python

Install the OpenAI Python SDK 3 with python -m pip install "openai>=3,<4".

import os
from openai import OpenAI, DefaultHttpx2Client

client = OpenAI(
    base_url=os.environ["AIRCODE_AI_BASE_URL"],
    api_key=os.environ["AIRCODE_AI_TOKEN"],
    max_retries=0,
    http_client=DefaultHttpx2Client(follow_redirects=False),
)

for model in client.models.list():
    print(model.id)

response = client.chat.completions.create(
    model=os.environ["AIRCODE_AI_MODEL"],
    messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)

JavaScript streaming

Node.js and the OpenAI SDK: npm install openai. This is buffered SSE: the complete validated answer arrives at the end.

import OpenAI from "openai";

function required(name) {
  if (!process.env[name]) throw new Error("Set " + name + " first.");
  return process.env[name];
}

const client = new OpenAI({
  baseURL: required("AIRCODE_AI_BASE_URL"),
  apiKey: required("AIRCODE_AI_TOKEN"),
  maxRetries: 0,
  fetchOptions: { redirect: "error" },
});

const stream = await client.chat.completions.create({
  model: required("AIRCODE_AI_MODEL"),
  messages: [{ role: "user", content: "Hello!" }],
  stream: true,
  stream_options: { include_usage: true },
});

try {
  for await (const chunk of stream) {
    process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
    if (chunk.usage) console.error("Tokens:", chunk.usage.total_tokens);
  }
  process.stdout.write("\n");
} finally {
  stream.controller.abort();
}

SDK 配置参照:OpenAI Python SDK 应用程序和 OpenAI JavaScript SDK 编辑器. 此网关支持上面文档中的子集。