LangBot 对接 FastGPT:从配置到 `appId is empty` 故障排查与修复
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
}
这说明:
- LangBot 已经能访问 FastGPT;
/api/v1/chat/completions路径正确;- API Key 能被 FastGPT 识别;
- FastGPT 无法确定本次请求要调用哪个应用。
六、根因:FastGPT 不使用 model 选择应用
在 FastGPT 4.15 的 OpenAPI 调用规则中,model 字段不负责选择 FastGPT 应用。客户端必须使用以下任意一种方式传递 App ID:
- 在请求 Body 中增加
appId; - 将 Authorization 中的 Key 改成
API Key-App ID组合形式。
LangBot 当前使用的 OpenAI 兼容 requester 会发送 model、messages 和 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:
- 进入“模型”或“模型提供商”;
- 打开 FastGPT 对应的提供商;
- 确认 Base URL 以
/api/v1结尾; - 将 API Key 替换为
API Key-App ID; - 保存后运行模型测试。
方法二:备份后修改 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
一次正常调用应该能观察到:
- LangBot 收到用户消息;
- FastGPT 收到
POST /api/v1/chat/completions; - FastGPT 日志中的
sourceId为目标 App ID; - FastGPT 返回 HTTP 200;
- 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 模型测试”和“真实流水线”三层,并将两侧日志按时间对齐。这样能够快速区分网络问题、鉴权问题、应用路由问题和流水线配置问题。