将症状与下面的修复方法进行匹配。如果症状不属于任何部分,请连同 docker logs ai-service --tail 200 的输出和 PROVIDERS 值的脱敏副本一起提交至 Tiny Support。

快速分诊

按此列表逐步排查以确定症状范围:

  1. 容器是否在运行? 运行 docker ps 进行检查。如果容器已退出或无法拉取,请参阅容器启动失败。

  2. /health 是否返回 200? 运行 curl -fsS http://localhost:8000/health。如果超时或返回 5xx,请参阅容器启动失败。

  3. API 是否返回认证错误? 如果响应为 401、allowed:false 或 invalid-jwt-*,请参阅 API 和 JSON Web Token (JWT) 认证。

  4. SSE 流是否携带来自 LLM 的 event: error? 如果是,请参阅大语言模型 (LLM) 提供商错误。

  5. 编辑器端是否损坏? 工具栏缺失、token 401 或流挂起?请参阅编辑器和前端。

  6. 负载下缓慢、超时或失败? 请参阅性能。

  7. 关于扩容、升级或部署的问题? 请参阅 生产部署。

  8. 需要了解服务日志消息的含义? 请参阅日志参考。

如果上述都不匹配,请参阅诊断配方,然后提交至 Tiny Support。

容器启动失败

首先运行 docker logs ai-service。以下所有条目均假设日志输出可用。

错误 / 症状原因修复

Wrong license key.

密钥被截断、包含换行符或周围有空格

将密钥粘贴为一行无间断的字符串。对照原始密钥验证前八位和后八位字符。

EACCES: permission denied, mkdir '/var/storage'

STORAGE_LOCATION 指向容器用户无法写入的路径

切换到 STORAGE_DRIVER=database,或挂载可写卷并将 STORAGE_LOCATION 指向该卷(例如 /tmp/ai-storage)。

Not enough permissions to access database. Missing privileges: …​

MySQL 用户在 AI 服务数据库上缺少列出的权限。全局授予的权限(ON *.*)或通过角色(例如 Cloud SQL 上的 cloudsqlsuperuser)授予的权限不满足启动检查。

在 AI 服务数据库本身上授予权限(ON ai_service.*)。有关 GRANT 语句,请参阅 数据库用户权限。

schema "cs-on-premises" does not exist

Postgres schema 未预先创建

运行 CREATE SCHEMA "cs-on-premises";(需要双引号),或设置 DATABASE_SCHEMA=public。请参阅 数据库、Redis 和存储。

尽管用户和授权正确,PostgreSQL Error: No permissions to connect to the database

托管的 PostgreSQL 服务器需要 TLS(Amazon RDS 上的 rds.force_ssl=1,Azure Database for PostgreSQL Flexible Server 上的 require_secure_transport=ON),而 AI 服务在没有 TLS 的情况下进行了连接。服务器端日志显示 no pg_hba.conf entry …​ no encryption。

请参阅 托管数据库 TLS。

首次启动时出现 duplicate key value violates unique constraint "pg_class_relname_nsp_index"

多个副本同时针对新数据库启动并并发运行了 schema 迁移。

副本会自动重启并恢复。为避免此错误,先启动一个副本,等待其健康,然后再扩容。请参阅 升级过程。

[MY-000067] unknown variable 'default-authentication-plugin'

mysql:8 标签现在指向最新的 MySQL,该版本已移除此变量

在 compose 文件中固定使用 mysql:8.0 并运行 docker compose up -d --force-recreate mysql。

Following models have invalid provider: <model IDs>

MODELS 条目命名了一个 provider 键,该键在 PROVIDERS 中不存在。服务会在启动时停止。

更正 provider 值,或将缺失的键添加到 PROVIDERS。键区分大小写。

出现带有压缩标识符的 [FATAL] …​ is not a constructor

PROVIDERS 条目形状错误,例如 Vertex AI 条目缺少 type 和 name 字段,并且使用 client_email 和 private_key 而非 clientEmail 和 privateKey。

从 LLM 提供商页面上的提供商示例开始,逐字段添加。

容器退出且无有用日志

缺少必需的环境变量,或 PROVIDERS / MODELS 中的 JSON 格式错误

运行 docker inspect ai-service | jq '.[0].Config.Env' 并与环境变量参考进行对比。使用 echo "$PROVIDERS" | jq . 验证 JSON

Pod 在 Amazon EKS Auto Mode 上一直处于未就绪状态,在存活探针失败后重启,且 kubectl logs 对当前或上一个容器无输出

数据库和 Redis 安全组允许来自节点安全组的入站流量,但 EKS Auto Mode 将集群主安全组附加到 Pod 上。

允许来自集群主安全组的入站数据库和 Redis 流量。请参阅基础设施建议。

尽管启动成功,但 /health 超时

缺少端口映射

在 docker run 中添加 -p 8000:8000,或在 compose 中添加 ports: ["8000:8000"]。使用 docker port ai-service 进行确认。

getaddrinfo EAI_AGAIN mysql 或 getaddrinfo ENOTFOUND redis

AI 服务与数据层处于不同的 Docker 网络上

使用 docker compose(共享网络),或设置 DATABASE_HOST=host.docker.internal。在 Linux 上,向 AI 服务添加 extra_hosts: ["host.docker.internal:host-gateway"]。

API 和 JSON Web Token (JWT) 认证

这些假设容器正在运行且 /health 返回 OK。

错误 / 症状原因修复方法

invalid-jwt-signature

使用错误的密钥对令牌进行签名。最常见的是,使用 ENVIRONMENTS_MANAGEMENT_SECRET_KEY 而不是每个访问密钥的API 密钥进行签名

从 /panel/ 的 Management Panel 重新复制 API 密钥,并重新对令牌进行签名。

invalid-jwt-payload

aud 声明与已知 Environment ID 不匹配,或者 aud 是数组而不是字符串

从 /panel/ 复制 Environment ID。将 aud 设置为字符串,而不是数组。仅通过 Panel UI 重新创建环境。

invalid-jwt(已过期)

令牌已超过其 exp 声明

颁发具有合理生存期(例如 exp = now + 3600)的令牌,并在过期前刷新。使用 Network Time Protocol (NTP) 同步时钟。

Environment not found(在编辑器中显示为 Invalid API key provided in JWT token (aud) claim)

未通过 Management Panel UI 创建环境

通过 /panel/ 删除并重新创建环境。更新 .env 中的 AI_ENV_ID。

JWT 被静默拒绝

令牌使用 RS256 而不是 HS256 签名

使用 algorithm: 'HS256' 和 API 密钥重新签名。请参阅JWT 认证。

409 conversation in use 然后 404 conversation does not exist

流中止导致临时状态阻塞对话

开始新对话或重新加载页面。自定义 UI 应在取消后创建新对话。

每个端点上均显示 allowed: false

auth.ai.permissions 是字符串、简写形式或形状错误

使用显式数组形式:

{
  "auth": {
    "ai": {
      "permissions": [
        "ai:conversations:*",
        "ai:models:agent",
        "ai:actions:system:*",
        "ai:reviews:system:*"
      ]
    }
  }
}

常见错误:"permissions": "ai:admin"(字符串简写形式)、"permissions": "*"、"useAllFeatures": true,或将单个权限作为字符串而不是数组。有关完整权限目录,请参阅JWT 认证。

大语言模型 (LLM) 提供商错误

大多数错误在 SSE 流中显示为 event: error,并且 HTTP 响应仍为 200。NoValidApiKeysFoundError 是例外:消息请求失败并返回 HTTP 500,原因显示在容器日志中。

云提供商(OpenAI、Anthropic、Google)

错误修复方法

Incorrect API key provided

更新 PROVIDERS 中的密钥,然后执行 docker compose up -d --force-recreate ai-service。

AWS Bedrock

错误修复方法

NoValidApiKeysFoundError

在 PROVIDERS 的 credentials 中内联 accessKeyId 和 secretAccessKey,或设置 apiKeys。不使用 AWS SDK 默认凭证链。请参阅LLM 提供商。

AccessDeniedException

在 Bedrock console → Model access 中启用模型访问权限。附加包含 bedrock:InvokeModel、bedrock:InvokeModelWithResponseStream、bedrock:Converse 和 bedrock:ConverseStream 的 IAM policy。

INVALID_PAYMENT_INSTRUMENT

在 Bedrock console → Model access → Anthropic 中完成 AWS Marketplace 对 Anthropic 的订阅。

ValidationException(不支持模型调用)

使用带有区域前缀的 inference profile ID(例如 us.anthropic.claude-sonnet-4-…​)。请参阅 LLM providers。

Google Vertex AI

错误解决方法

NoValidApiKeysFoundError

在 PROVIDERS 中的 credentials 里内联 clientEmail 和 privateKey,或将 apiKeys 设置为绑定账户的 API 密钥。Google Application Default Credentials (ADC) 不会被使用。请参阅 LLM providers。

服务账号有效但出现认证错误

private_key 的换行符在复制粘贴过程中损坏了。请使用脚本(对 SA JSON 文件使用 json.dumps())构建 PROVIDERS,而不是手动编辑。

SERVICE_DISABLED

运行 gcloud services enable aiplatform.googleapis.com --project=<PROJECT_ID>。

被 GCP 组织策略阻止

检查 iam.disableServiceAccountCreation、iam.disableServiceAccountKeyCreation 以及绑定账户的 API 密钥策略。将 AI 服务项目从这三项中豁免。

Azure OpenAI

错误解决方法

找不到模型 / DeploymentNotFound

MODELS[].id 必须与 Azure deployment 名称完全匹配。

API 错误但没有 provider 消息

显式设置 apiVersion。请参阅 Microsoft 的 API 版本矩阵。

OpenAI-compatible (Ollama, vLLM, LM Studio)

错误解决方法

SSE 错误中显示 "Not Found"

baseUrl 缺少 /v1 后缀。Ollama 默认值:http://host.docker.internal:11434/v1。

Linux 上出现 ECONNREFUSED

使用 OLLAMA_HOST=0.0.0.0:11434 ollama serve 启动 Ollama。在 AI 服务的 compose 条目中添加 extra_hosts: ["host.docker.internal:host-gateway"]。

"不支持工具"

使用官方模型(ollama pull qwen3:0.6b)而不是裸 GGUF。自定义模型需要带有 TEMPLATE 和工具支持的 Modelfile。请参阅 LLM providers。

createMessage 卡住约 180 秒然后超时

模型对于默认超时时间来说太慢了。将 LLM_TIMEOUT_MS 设置得更高,使用更轻量的量化,或者使用更小的模型。

编辑器和前端

在排查编辑器问题之前,请确认 /health 正常且直接对 /v1/conversations 执行 curl 可以正常工作。

症状解决方法

工具栏中没有 AI 按钮

确保加载了 TinyMCE 8+,设置了 plugins: 'tinymceai',并且工具栏字符串包含 tinymceai。验证 API 密钥是否启用了 AI 功能。

Token 获取返回 401

Token 端点自身的认证中间件拒绝了请求。在浏览器网络选项卡中检查会话 cookie、跨域资源共享 (CORS) 凭据以及 bearer token。

Token 返回但被 AI 服务拒绝

请参阅上面的 API 和 JSON Web Token (JWT) 认证:密钥错误、aud 错误、算法错误(RS256 而不是 HS256)或权限结构错误。

AI 响应在浏览器中卡住

反向代理正在缓冲 SSE 流。在 nginx 中设置 proxy_buffering off; 和 proxy_cache off;(或负载均衡器的等效设置)。

/v1/conversations 出现 CORS 错误

将编辑器的 origin(scheme + host + port)添加到 ALLOWED_ORIGINS 环境变量中。

编辑器渲染后消失 (Next.js / Nuxt / SvelteKit)

TinyMCE 在加载时会引用 window。仅在客户端加载编辑器:在 Next.js 中使用 dynamic(() ⇒ import('./Editor'), { ssr: false }),在 Nuxt 中使用 <ClientOnly>,在 SvelteKit 中使用 onMount。请参阅 TinyMCE integration。

tinymceai_token_provider 在紧密循环中被调用

Token 端点返回了无效的 JWT 或非 JSON 响应。使用 curl -X POST http://localhost:3000/api/ai-token 进行测试,并验证响应是否为 {"token":"eyJ..."}。

性能

症状解决方法

通过 AI 服务的自托管模型比直接使用 curl 要慢

将推理服务器与 AI 服务部署在同一位置。使用更小或更多量化的模型。在开发期间禁用遥测(LLM_TELEMETRY_ENABLED=false)。

容器出现 OOM 或 MySQL 启动时间超过 60 秒(Colima)

默认的 Colima 虚拟机太小。运行 colima stop && colima start --cpu 4 --memory 8 --disk 100。

日志参考

使用 docker logs ai-service 读取 AI 服务日志,或在 Kubernetes 上使用 kubectl logs。要将多个实例的日志收集到一个地方,请参阅 分布式日志记录。

日志格式

错误和致命条目是 JSON 对象,每行一个:

字段内容

level

严重程度,用数字表示:50 表示错误,60 表示致命错误,致命错误会导致 AI 服务停止。

time

条目的时间,采用 ISO 8601 格式,以 UTC 表示。

msg

消息内容。错误和致命消息以 [ERROR] 或 [FATAL] 开头。

data

可选。条目的详细信息,例如错误的 name 和 message。

stack

可选。错误的堆栈跟踪。

例如,没有所需架构的 PostgreSQL 部署会以此条目停止:

{"level":60,"time":"2026-05-05T11:19:07.634Z","msg":"[FATAL] PostgreSQL Error: schema \"cs-on-premises\" does not exist","data":{"name":"PostgreSQL Error","message":"PostgreSQL Error: schema \"cs-on-premises\" does not exist"}}

要仅显示错误和致命条目,请使用 jq 过滤日志。fromjson? 过滤器会跳过任何不是 JSON 的行:

docker logs ai-service 2>&1 | jq -R -c 'fromjson? | select(.level >= 50)'

重要的日志消息

启动失败会记录带有 [FATAL] 前缀的消息,并会导致 AI 服务停止。有关这些消息及其解决方法,请参阅容器启动失败。有关 MCP 和网络搜索消息,请参阅 MCP 故障排除。

消息含义操作

Server is listening on port 8000.

AI 服务已启动并接受请求。

无需操作。

[ERROR] The user did not create a message. Reason: No valid API keys found for provider '<provider>'

消息请求失败,返回 HTTP 500。data.name 字段为 NoValidApiKeysFoundError。

为提供者添加内联凭据。请参阅大语言模型 (LLM) 提供者错误。

[ERROR] The user did not upload a file. Reason: Invalid argument.

文件上传失败,返回 HTTP 500。通过 S3 兼容 API 使用 Google Cloud Storage 时,启用了统一存储桶级访问权限的存储桶会导致此错误。

关闭存储桶的统一存储桶级访问权限。请参阅 GCP (GKE)。

跟踪失败的请求

来自 AI 服务的每个错误响应都带有一个 traceId,用于标识该请求。有关错误响应的结构,请参阅 错误响应。

TinyMCE AI 插件会在浏览器控制台中将每个错误打印为 TinyMCE AI Error: 条目,后面跟着状态代码、Trace ID: 行和错误代码。

诊断方案

展开以获取可直接复制的诊断命令

跟踪日志:

docker logs ai-service --tail 200 -f

实时检查:

curl -fsS http://localhost:8000/health

解码 JWT(检查有效负载而不进行验证):

python3 -c "import jwt,sys,json; print(json.dumps(jwt.decode(sys.argv[1], options={'verify_signature': False}), indent=2))" <token>

环境变量更改后重新创建:

docker compose up -d --force-recreate ai-service

检查有效的环境变量:

docker inspect ai-service | jq '.[0].Config.Env'

验证 PROVIDERS JSON:

echo "$PROVIDERS" | jq .

测试容器内的数据层连接:

docker exec ai-service /bin/sh -c "nc -zv mysql 3306"
docker exec ai-service /bin/sh -c "nc -zv redis 6379"

将 mysql 和 redis 替换为在 DATABASE_HOST 和 REDIS_HOST 中配置的实际主机名。如果 AI 服务是通过 docker compose 而不是独立的 docker run 启动的,请使用 docker compose exec ai-service。

端到端冒烟测试(从令牌生成到流式响应):

TOKEN=$(curl -s -X POST http://localhost:3000/api/ai-token | jq -r '.token')

curl -s -X POST http://localhost:8000/v1/conversations \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id":"smoke-1","title":"Smoke test"}'

# 将'agent-1'替换为MODELS中的模型ID,如果明确配置
curl -N -X POST http://localhost:8000/v1/conversations/smoke-1/messages \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"prompt":"Say hi in five words.","model":"agent-1"}'

相关页面