LangBot 对接 FastGPT:从配置到 `appId is empty` 故障排查与修复

4

LangBot 对接 FastGPT:从配置到 appId is empty 故障排查与修复

前言

本文记录一次 LangBot 对接 FastGPT 的完整过程,包括服务检查、模型提供商配置、错误复现、根因定位、配置修复和端到端验证。

本次环境的核心组件为:

  • LangBot v4.10.6,使用 Docker 运行;
  • FastGPT v4.15.3;
  • LangBot 通过 OpenAI 兼容接口调用 FastGPT;
  • LangBot 使用 SQLite 保存模型提供商和流水线配置;
  • 两个服务位于同一内网环境。

安全说明:本文所有 API Key、App ID、Token、账号口令和内网地址均已脱敏。请勿将真实密钥写入文档、Git 仓库或公开日志。

一、调用链路

对接后的调用链路如下:

用户 / IM 平台
      ↓
LangBot 流水线
      ↓
LangBot Local Agent Runner
      ↓  OpenAI-compatible API
FastGPT /api/v1/chat/completions
      ↓
FastGPT 应用工作流
      ↓
大模型回复

这里最容易混淆的地方是:LangBot 中的“模型”和 FastGPT 中的“应用”并不是同一个概念。FastGPT 必须先确定要运行哪个应用,然后才会执行应用内的工作流。

二、部署后的基础检查

对接前先确认两端服务都在正常运行。

1. 检查容器

docker ps

应当能看到 LangBot 主容器、插件运行时、Box 容器,以及 FastGPT 的主应用、MongoDB、PostgreSQL、Redis 等容器。

2. 检查 LangBot

curl http://<LANGBOT_HOST>:5300/healthz

正常情况下应返回:

{"code":0,"msg":"ok"}

3. 检查 FastGPT

在浏览器中打开:

http://<FASTGPT_HOST>:3000

登录后确认目标应用可以在 FastGPT 内部正常调试,并记录以下信息:

  • FastGPT API Key;
  • 目标应用的 App ID;
  • FastGPT OpenAI 兼容接口地址。

三、在 LangBot 中配置 FastGPT

进入 LangBot 的模型管理页面,创建一个 OpenAI 兼容的模型提供商。

建议配置如下:

  • 提供商类型:LM Studio / OpenAI-compatible Chat Completions;
  • Base URL:http://<FASTGPT_HOST>:3000/api/v1
  • API Key:先不要只填原始 Key,应使用后文的组合格式;
  • 模型名称:可以填写 App ID,便于识别。

Base URL 必须包含 /api/v1。如果只填 FastGPT 首页地址,LangBot 调用时可能拿到 HTML 页面,并出现 NotFoundError 或“模型或路径无效”。

四、失败现象

初始配置中,Base URL 已经修正为:

http://<FASTGPT_HOST>:3000/api/v1

API Key 也是 FastGPT 中新建的有效 Key,但 LangBot 流水线仍返回:

模型请求失败:
litellm.APIError:
Error building chunks for logging/streaming usage calculation

这条错误容易把排查方向引到流式输出、Token 统计或 LiteLLM 解析上。但它实际上只是 LangBot/LiteLLM 在处理 FastGPT 错误响应时产生的二次错误,并不是最底层的根因。

五、找到真正的错误

在 LangBot 发起调用时,同时查看 FastGPT 容器日志:

docker logs --tail 200 fastgpt-app

或直接用原始 API Key 请求 FastGPT:

export FASTGPT_BASE_URL='http://<FASTGPT_HOST>:3000/api/v1'
export FASTGPT_API_KEY='fastgpt-***'
export FASTGPT_APP_ID='<YOUR_APP_ID>'

curl "$FASTGPT_BASE_URL/chat/completions" \
  -H "Authorization: Bearer $FASTGPT_API_KEY" \
  -H 'Content-Type: application/json' \
  -d "{
    \"model\": \"$FASTGPT_APP_ID\",
    \"messages\": [
      {\"role\": \"user\", \"content\": \"请回复连通测试\"}
    ],
    \"stream\": false
  }"

FastGPT 返回的真正错误是:

{
  "code": 500,
  "statusText": "error",
  "message": "appId is empty",
  "data": null
}

这说明:

  1. LangBot 已经能访问 FastGPT;
  2. /api/v1/chat/completions 路径正确;
  3. API Key 能被 FastGPT 识别;
  4. FastGPT 无法确定本次请求要调用哪个应用。

六、根因:FastGPT 不使用 model 选择应用

在 FastGPT 4.15 的 OpenAPI 调用规则中,model 字段不负责选择 FastGPT 应用。客户端必须使用以下任意一种方式传递 App ID:

  1. 在请求 Body 中增加 appId
  2. 将 Authorization 中的 Key 改成 API Key-App ID 组合形式。

LangBot 当前使用的 OpenAI 兼容 requester 会发送 modelmessages 和 API Key,但不会自动在 Body 中增加 FastGPT 专用的 appId

因此,最简单、无需修改 LangBot 源码的方案是使用组合鉴权值。

七、正确的 Key 格式

原始 Key:

fastgpt-********************************

App ID:

<FASTGPT_APP_ID>

在 LangBot 中实际填写的 API Key:

fastgpt-********************************-<FASTGPT_APP_ID>

即:

API Key + "-" + App ID

再次直连测试:

curl "$FASTGPT_BASE_URL/chat/completions" \
  -H "Authorization: Bearer ${FASTGPT_API_KEY}-${FASTGPT_APP_ID}" \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "placeholder",
    "messages": [
      {"role": "user", "content": "connection test"}
    ],
    "stream": false
  }'

修正后 FastGPT 返回 HTTP 200 和标准 OpenAI Chat Completions 结构,说明 App ID 已被正确识别。

八、修改 LangBot 配置

方法一:在 WebUI 中修改

推荐优先使用 LangBot WebUI:

  1. 进入“模型”或“模型提供商”;
  2. 打开 FastGPT 对应的提供商;
  3. 确认 Base URL 以 /api/v1 结尾;
  4. 将 API Key 替换为 API Key-App ID
  5. 保存后运行模型测试。

方法二:备份后修改 SQLite

如果 WebUI 不方便使用,可以直接修改 LangBot SQLite。操作前必须做一致性备份。

数据库常见位置:

/app/data/langbot.db

宿主机映射路径可能是:

/opt/langbot/docker/data/langbot.db

可使用 Python sqlite3.Connection.backup() 创建在线一致性备份,再更新 model_providers.api_keys 字段。示例:

import datetime
import json
import sqlite3

database = "/app/data/langbot.db"
provider_uuid = "<PROVIDER_UUID>"
app_id = "<FASTGPT_APP_ID>"

connection = sqlite3.connect(database)
api_keys_json = connection.execute(
    "SELECT api_keys FROM model_providers WHERE uuid = ?",
    (provider_uuid,),
).fetchone()[0]

api_keys = json.loads(api_keys_json)
old_key = api_keys[0]
new_key = old_key if old_key.endswith("-" + app_id) else old_key + "-" + app_id

timestamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
backup = sqlite3.connect(f"{database}.bak-fastgpt-{timestamp}")
connection.backup(backup)
backup.close()

with connection:
    connection.execute(
        "UPDATE model_providers "
        "SET api_keys = ?, updated_at = CURRENT_TIMESTAMP "
        "WHERE uuid = ?",
        (json.dumps([new_key]), provider_uuid),
    )

修改后只需重启 LangBot 主容器:

docker restart langbot

九、流水线配置

在 LangBot 流水线中选择 Local Agent Runner,并将主模型指向刚创建的 FastGPT 模型。

需要特别检查:

  • local-agent.model.primary 不能为空;
  • 引用的模型 UUID 必须存在;
  • 模型必须归属于正确的 FastGPT 提供商;
  • 流水线修改后需要保存。

如果主模型没有配置,LangBot 会直接返回:

No LLM model configured for local-agent runner

这个错误和 FastGPT 鉴权错误是两个独立问题,需要分别处理。

十、端到端验证

修复后不要只做端口检查,建议完成三层验证。

第一层:FastGPT 直连测试

使用组合 Key 请求 /api/v1/chat/completions,确认返回 HTTP 200。

第二层:LangBot 模型测试

在 LangBot 模型页面运行模型测试,或调用对应的模型测试接口,确认 LangBot 能够通过已保存的提供商配置访问 FastGPT。

第三层:真实流水线调用

在 LangBot 流水线调试窗口发送一条真实消息,并同时观察两侧日志:

docker logs -f langbot
docker logs -f fastgpt-app

一次正常调用应该能观察到:

  1. LangBot 收到用户消息;
  2. FastGPT 收到 POST /api/v1/chat/completions
  3. FastGPT 日志中的 sourceId 为目标 App ID;
  4. FastGPT 返回 HTTP 200;
  5. LangBot 收到 assistant 回复并继续执行后置流水线阶段。

本次实际验证中,FastGPT 识别到了正确的 App ID,chat/completions 在约 3.34 秒后返回 HTTP 200,LangBot 收到了完整的文本回复。

十一、一个容易混淆的非阻断告警

调试过程中,LangBot 还可能输出类似下列告警:

Outbound attachment collection failed
Unable to find image 'rockchin/langbot-sandbox:latest' locally

这通常是服务器无法从 Docker Hub 拉取 LangBot Sandbox 镜像造成的,与 FastGPT 文本调用失败不是同一个问题。

如果流水线已经正常返回文本,这条告警不会阻断纯文本对话。但如果后续需要使用文件、附件或沙箱工具,则应当提前拉取对应镜像,或配置可用的镜像加速源。

十二、排查清单

如果你遇到同类问题,可按以下顺序检查:

  • [ ] LangBot 和 FastGPT 容器都处于运行状态;
  • [ ] LangBot 容器可以访问 FastGPT 主机和端口;
  • [ ] Base URL 以 /api/v1 结尾;
  • [ ] FastGPT API Key 未过期、未被删除;
  • [ ] Authorization 使用 API Key-App ID 格式;
  • [ ] App ID 对应的 FastGPT 应用确实存在;
  • [ ] FastGPT 应用内的工作流本身可以正常运行;
  • [ ] LangBot 流水线已设置 local-agent.model.primary
  • [ ] 修改 SQLite 前已完成备份;
  • [ ] 修改配置后已重启或重新加载 LangBot;
  • [ ] 同时检查 LangBot 和 FastGPT 日志,不只看 LiteLLM 的上层错误。

总结

这次故障的关键并不是网络、Base URL 或 API Key 失效,而是 FastGPT 没有从 LangBot 发送的 OpenAI 兼容请求中获得 App ID。

最终解决方案可以概括为一句话:

将 LangBot 中的 FastGPT API Key 改为“API Key-App ID”组合鉴权格式。

排查这类兼容接口问题时,最有效的方法是将调用链路拆成“FastGPT 直连”、“LangBot 模型测试”和“真实流水线”三层,并将两侧日志按时间对齐。这样能够快速区分网络问题、鉴权问题、应用路由问题和流水线配置问题。