环境变量参考

按字母顺序排列。必需性标记基于最小可用部署。

变量必需性默认值描述

ALLOWED_ORIGINS

推荐设置

-

逗号分隔的 CORS 允许的编辑器源列表。跨域编辑器部署必需。格式、通配符和验证见 跨域请求。

DATABASE_DATABASE

是

-

数据库名称(通常为 ai_service)。

DATABASE_DRIVER

是

-

mysql 或 postgres。

DATABASE_HOST

是

-

数据库主机名或 IP。

DATABASE_PASSWORD

是

-

数据库密码。

DATABASE_PORT

否

3306 (MySQL) / 5432 (PostgreSQL)

数据库端口。

DATABASE_SCHEMA

仅 PostgreSQL

cs-on-premises

PostgreSQL schema 名称。需预先创建或设置为 public。

DATABASE_SSL_CA

否

-

数据库 TLS 的 CA 证书路径。

DATABASE_SSL_CERT

否

-

客户端证书路径。

DATABASE_SSL_KEY

否

-

客户端密钥路径。

DATABASE_USER

是

-

数据库用户。

ENABLE_METRIC_LOGS

否

false

向标准输出发送 JSON 请求日志。

ENVIRONMENTS_MANAGEMENT_SECRET_KEY

是

-

管理面板登录密钥。不用于签名用户 JSON Web Tokens (JWTs)。

LANGFUSE_BASE_URL

否

https://cloud.langfuse.com

自托管 Langfuse URL。

LANGFUSE_DEBUG

否

-

详细 Langfuse 日志。

LANGFUSE_PUBLIC_KEY

如果使用 Langfuse

-

Langfuse 公钥。

LANGFUSE_SECRET_KEY

如果使用 Langfuse

-

Langfuse 密钥。

LICENSE_KEY

是

-

AI 服务许可证密钥(来自 Tiny 的长字符串)。同一密钥可在所有部署副本中共享——无需每个 pod 单独许可。

LLM_TELEMETRY_ENABLED

否

false

主要 OpenTelemetry 开关。

LLM_TIMEOUT_MS

否

180000

每个请求的大语言模型 (LLM) 超时时间(毫秒)。对于大型自托管模型,需调大此值。

MCP_OAUTH_CALLBACK_URL

如果使用 MCP OAuth

-

集成的 Web 应用托管的 OAuth 回调页面 URL。用作所有启用 OAuth 的 MCP 服务器的 OAuth redirect_uri(除非按服务器覆盖)。参见 OAuth 2.0 认证。

MCP_SERVERS

否

-

JSON 对象;Model Context Protocol (MCP) 服务器配置。支持每个服务器的静态令牌和 OAuth 2.0 认证。参见 MCP 集成。

MODELS

是 (Azure、Bedrock、Vertex、openai-compatible);推荐所有提供商设置

-

定义暴露模型的 JSON 数组。Azure、Bedrock、Vertex 和 openai-compatible 提供商必需。推荐 OpenAI、Anthropic 和 Google 直连设置。参见 LLM 提供商。

OTEL_DEBUG

否

-

详细 OpenTelemetry Protocol (OTLP) 诊断日志。

OTEL_EXPORTER_OTLP_TRACES_ENDPOINT

如果使用 OTEL

-

OTLP 追踪端点 URL。

OTEL_TRACES_SAMPLER_ARG

否

1.0

OTLP 采样率 (0.0 至 1.0)。

PROVIDERS

是

-

JSON 对象;LLM 提供商配置。参见 LLM 提供商。

REDIS_CLUSTER_NODES

否

-

逗号分隔的 host:port[:password],用于 Redis Cluster 模式。

REDIS_DB

否

1

Redis 数据库编号。

REDIS_HOST

是

-

Redis 主机名。

REDIS_IP_FAMILY

否

-

设置为 6 表示使用 IPv6。

REDIS_PASSWORD

否

-

Redis 密码。

REDIS_PORT

否

6379

Redis 端口。

REDIS_TLS_CA

否

-

Redis TLS 的 CA 证书路径。

REDIS_TLS_CERT

否

-

Redis 客户端证书路径。

REDIS_TLS_ENABLE

否

false

启用 Redis TLS。

REDIS_TLS_KEY

否

-

Redis 客户端密钥路径。

REDIS_USER

否

-

Redis 用户名 (ACL)。

STORAGE_ACCESS_KEY_ID

如果使用 S3

-

S3 访问密钥 ID。

STORAGE_ACCOUNT_KEY

如果使用 Azure Blob

-

Azure 存储帐户密钥。

STORAGE_ACCOUNT_NAME

如果使用 Azure Blob

-

Azure 存储帐户名称。

STORAGE_BUCKET

如果使用 S3

-

S3 存储桶名称。

STORAGE_CONTAINER

如果使用 Azure Blob

-

Azure 容器名称。

STORAGE_DRIVER

是

-

database、filesystem、s3 或 azure。

STORAGE_ENDPOINT

否

-

自定义端点 (S3 兼容或 Azure 兼容)。

STORAGE_LOCATION

如果使用 filesystem

-

filesystem 存储的挂载点。必须可由容器用户写入。

STORAGE_REGION

如果使用 S3

-

S3 区域。

STORAGE_SECRET_ACCESS_KEY

如果使用 S3

-

S3 秘密访问密钥。

WEBRESOURCES_ENABLED

否

false

启用网页抓取端点转发。请参阅网页抓取。

WEBRESOURCES_ENDPOINT

如果已启用 web resources

-

抓取器 URL。

WEBRESOURCES_REQUEST_TIMEOUT

否

-

抓取器请求超时时间(毫秒)。

WEBSEARCH_ENABLED

否

false

启用网页搜索转发。请参阅网页搜索。

WEBSEARCH_ENDPOINT

如果已启用网页搜索

-

搜索 URL。

WEBSEARCH_HEADERS

否

-

冒号 CSV 格式 (Header-Name: value, Another: value)。发送到搜索端点的额外标头。请勿使用 JSON — 请参阅网页搜索。

WEBSEARCH_REQUEST_TIMEOUT

否

-

搜索请求超时时间(毫秒)。

完整的 docker run 参考

一个包含最小化生产部署 (MySQL、OpenAI、S3 存储) 所需所有环境变量的单个命令:

docker run --init -d -p 8000:8000 \
  --name ai-service \
  -e LICENSE_KEY='<license-key>' \
  -e ENVIRONMENTS_MANAGEMENT_SECRET_KEY='<management-secret>' \
  -e DATABASE_DRIVER='mysql' \
  -e DATABASE_HOST='<database-host>' \
  -e DATABASE_PORT='3306' \
  -e DATABASE_USER='<database-user>' \
  -e DATABASE_PASSWORD='<database-password>' \
  -e DATABASE_DATABASE='ai_service' \
  -e REDIS_HOST='<redis-host>' \
  -e REDIS_PORT='6379' \
  -e PROVIDERS='{"openai":{"type":"openai","apiKeys":["<openai-api-key>"]}}' \
  -e MODELS='[{"id":"gpt-4.1","provider":"openai","name":"GPT-4.1","features":["conversations","reviews","actions"]}]' \
  -e STORAGE_DRIVER='s3' \
  -e STORAGE_BUCKET='<s3-bucket-name>' \
  -e STORAGE_REGION='<aws-region>' \
  -e STORAGE_ACCESS_KEY_ID='<s3-access-key>' \
  -e STORAGE_SECRET_ACCESS_KEY='<s3-secret-key>' \
  -e ALLOWED_ORIGINS='https://<your-app-domain>' \
  -e ENABLE_METRIC_LOGS='true' \
  registry.containers.tiny.cloud/ai-service-tiny:<version>

对于 PostgreSQL,将 DATABASE_DRIVER 更改为 'postgres' 并添加 -e DATABASE_SCHEMA='cs-on-premises' (或 'public')。对于 Redis 身份验证,添加 -e REDIS_PASSWORD='<redis-password>'。对于 Redis TLS,添加 -e REDIS_TLS_ENABLE='true'。

API 端点参考

方法路径身份验证描述

GET

/health

无

活跃度探测。返回 {"serviceName":"on-premises-http","uptime":<seconds>}。不进行指标记录。

GET

/docs/

无

重定向(HTTP 301)到 /v1/api/docs。

GET

/v1/api/docs

无

ReDoc 渲染的 API 文档。

GET

/v1/api/doc.json

无

OpenAPI 3 JSON 规范。

GET

/panel/

管理密钥(登录表单)

管理面板用户界面。通过浏览器登录表单使用 ENVIRONMENTS_MANAGEMENT_SECRET_KEY 登录。

GET

/v1/models/1

JWT

列出当前令牌可用的模型。兼容性版本标识符 1 是唯一可接受的值;v1、v2、latest 均返回 500。

POST

/v1/conversations

JWT

创建对话。请求体必须包含客户端提供的 id。

GET

/v1/conversations

JWT

列出当前 sub 的对话。

GET

/v1/conversations/{id}

JWT

读取一个对话。

POST

/v1/conversations/{id}/messages

JWT

发送消息。返回 Server-Sent Events (SSE) 流。

POST

/v1/conversations/{id}/web-resources

JWT

通过配置的抓取端点获取网页。请求体:{"url":"https://…​"}。成功返回 201,抓取失败返回 422。需要 WEBRESOURCES_ENABLED='true'。参见 网页抓取。

GET

/v1/conversations/{id}/web-resources

JWT

列出为某对话获取的网页资源。

DELETE

/v1/conversations/{id}/web-resources/{webResourceId}

JWT

从对话中移除网页资源。

POST

/v1/conversations/{id}/files

JWT

以 multipart/form-data 格式上传文件到对话。

DELETE

/v1/conversations/{id}/files/{fileId}

JWT

从对话中移除文件。

POST

/v1/conversations/{id}/documents

JWT

向对话添加文档。

GET

/v1/conversations/{id}/documents/{documentId}

JWT

读取一个对话文档。

DELETE

/v1/conversations/{id}

JWT

删除对话。

POST

/v1/actions/system/{actionName}/calls

JWT

运行内置快速操作,例如 fix-grammar。请求体格式:{"content":[{"type":"text","content":"…​"}]},其中恰好包含一个 text 部分(无 modelId)。返回 SSE 流。

POST

/v1/reviews/system/{reviewName}/calls

JWT

运行内置评审,例如 correctness。返回 SSE 流。内容格式请参见 API 参考。

POST

/v1/actions/custom/calls

JWT

使用提示和模型运行自定义操作。返回 SSE 流。

POST

/v1/reviews/custom/calls

JWT

使用提示和模型运行自定义评审。返回 SSE 流。

GET

/v1/mcp/oauth/status

JWT

所有启用 OAuth 的 MCP 服务器的连接状态。参见 OAuth REST 端点。

POST

/v1/mcp/oauth/{serverName}/initialize

JWT

启动 OAuth 授权流程。

POST

/v1/mcp/oauth/{serverName}/complete

JWT

使用授权码完成 OAuth 流程。

DELETE

/v1/mcp/oauth/{serverName}

JWT

撤销调用用户的 OAuth 连接。

OAuth 端点仅在至少一个 MCP 服务器配置了 oauth 块时可用。位于 /v1/api/docs 的交互式 API 文档可能不包含这些端点;它们记录在 MCP OAuth 部分。
环境管理(创建、读取、更新、删除)通过位于 /panel/ 的管理面板用户界面处理。

Server-Sent Events 参考

该消息端点返回 Content-Type: text/event-stream。事件使用命名类型。下表列出了主要事件。有关每个事件及其有效负载,请参阅 API 参考。

事件有效负载形状含义

message-metadata

{"messageId":"…​"}

在每条消息开始时发送一次。

text-delta

{"textDelta":"…​"}

增量文本片段。编辑器会连接这些片段。

mcp-tool-result

{"toolName":"...","result":"...","success":true}

当 MCP 工具调用完成时发出。result 是一个字符串。

error

{"message":"…​","cause":{…​}}

提供方错误。HTTP 状态仍为 200;错误在流内。

没有流结束事件。当服务关闭响应时,流结束。

正常流示例:

event: message-metadata
data: {"messageId":"abc123"}

event: text-delta
data: {"textDelta":"Hello "}

event: text-delta
data: {"textDelta":"there!"}

错误流示例:

event: message-metadata
data: {"messageId":"abc123"}

event: error
data: {"message":"Incorrect API key provided","cause":{"providerStatusCode":401}}

浏览器客户端解析说明:

  • 每个事件有两行:event: <name> 和 data: <json>,与下一个事件之间用空行分隔。

  • data 始终是有效的 JSON。

  • 未知的 event 类型带有信息性有效负载,出于向前兼容性考虑可以忽略。

  • text-delta 带有可见的回复文本,modification-delta 带有建议的文档修改文本。

action 和 review 端点也返回 SSE 流,并有自己的事件。有关 操作 和 审查,请参阅 API 参考。

错误代码参考

在 HTTP 4xx 响应中和 SSE event: error 有效负载内返回的错误代码。

每个错误响应都带有一个 traceId。请参阅 追踪失败的请求。

代码来源可能的原因解决方法

invalid-jwt-signature

JWT 验证器

API Secret 错误,或使用了 ENVIRONMENTS_MANAGEMENT_SECRET_KEY,或使用 RS256 签名

使用正确的 API Secret 重新以 HS256 签名

invalid-jwt-payload

JWT 验证器

aud 与真实的环境 ID 不匹配,或者环境是通过原始 API 创建的,而不是通过面板 UI 创建的

从 /panel/ 重新复制环境 ID,或者通过面板 UI 重新创建环境

invalid-jwt

JWT 验证器

令牌在 exp 之后超过 60 秒

签发生命周期更短的令牌,并更早地刷新

Environment not found

AI 运行时

与 invalid-jwt-payload 的第二个子原因相同

通过面板 UI 重新创建环境

missing-permissions

权限检查器

auth.ai.permissions 数组不涵盖请求的操作

添加缺失的权限字符串

invalid-request-data

输入验证器

字段验证失败(最常见的是 100,000 字符的提示上限)

修复请求体。请参阅错误消息

environment-not-found

AI 运行时

与 Environment not found 相同。编辑器将此错误显示为 Invalid API key provided in JWT token (aud) claim。

通过面板 UI 重新创建

conversation in use

对话运行时

流中止留下了陈旧的状态

开始一个新的对话

conversation does not exist

对话运行时

对 conversation in use 的后续操作

开始一个新的对话

NoValidApiKeysFoundError (HTTP 500)

Bedrock / Vertex 适配器

缺少内联凭据

在 PROVIDERS 中内联 credentials

AccessDeniedException

Bedrock

缺少模型访问权限或 IAM 权限

启用 Bedrock 模型访问;附加来自 LLM 提供方 的 IAM 策略

INVALID_PAYMENT_INSTRUMENT

Bedrock

在没有 Marketplace 订阅的情况下在 Bedrock 上使用 Anthropic

通过 AWS Marketplace 订阅

ValidationException

Bedrock

模型 ID 格式错误(区域 ID 而不是跨区域 ID)

使用 Claude 4.x 的推理配置文件 ID

DeploymentNotFound

Azure

MODELS[].id 与 Azure 部署名称不匹配

将 MODELS[].id 设置为确切的部署名称

invalid_grant

Vertex

private_key 的换行符格式损坏

通过 SA 密钥的 json.dumps() 构建 PROVIDERS

SERVICE_DISABLED

Vertex

aiplatform.googleapis.com 未启用

gcloud services enable aiplatform.googleapis.com

API_KEY_INVALID

Vertex

与账户绑定的 API 密钥被组织策略阻止

授予策略例外

Incorrect API key provided

OpenAI / Anthropic / Google

API 密钥无效

更新 PROVIDERS 并使用 --force-recreate

Wrong license key.

AI 服务启动

许可证密钥被截断或包含空白字符

重新粘贴为单行

已知限制

限制项值说明

最大提示长度

100,000 字符

服务强制执行的硬性限制。超过此限制的请求将返回 invalid-request-data。在超过此阈值之前,请对源内容进行摘要或缩短。

会话创建

需要客户端提供 id

插件会自动生成 tiny-<uuid>。原始 API 调用者必须在创建请求体中提供唯一的 id。

流中止恢复

停止按钮会留下陈旧状态

下一条消息将返回 409 conversation in use,然后返回 404 conversation does not exist。恢复方法:启动新会话或重新加载。

内置速率限制

无

使用 nginx limit_req 或 ALB 速率限制规则作为服务前端。参见 速率限制。

文件支持(OpenAI 兼容提供商)

仅支持图像(image/*)

PDF、文本和 Office 文件不会转发给 OpenAI 兼容提供商。对于非图像文件附件,请使用非 OpenAI 兼容的提供商。

MCP 工具可用性

仅在会话中可用

MCP 工具在审查或快速操作中不可用。

MCP 身份验证

静态令牌或 OAuth 2.0,每个服务器独立配置

静态令牌使用 headers 字段(所有用户共享,部署时固定)。通过 OAuth 2.0(授权码与 PKCE)支持用户级身份验证。参见 OAuth 2.0 身份验证。

PostgreSQL 默认 schema

cs-on-premises(带连字符)

使用 CREATE SCHEMA "cs-on-premises"; 预先创建,或设置 DATABASE_SCHEMA=public。

/v1/models/{compatibilityVersion}

仅接受 1

诸如 v1、v2 或 latest 之类的值会返回 500。

通过原始 API 创建环境

不支持

始终通过管理面板 UI 创建环境。

Bedrock 凭据

仅支持内联

不会使用 SDK 默认凭据链(服务账户 IAM 角色 (IRSA)、实例角色、AWS_PROFILE)。

Vertex 凭据

仅支持内联

不会使用 Application Default Credentials、GOOGLE_APPLICATION_CREDENTIALS 和元数据服务器。

Azure MODELS[].id

必须等于部署名称

没有单独的 deploymentName 字段。ID 就是部署名称。

OpenAI 兼容 baseUrl

必须包含 /v1 后缀

省略该后缀会产生“Not Found”SSE 错误。