把 AnythingLLM 的 Generic OpenAI provider 接到 Router One
AnythingLLM 是开源的聊天与文档问答(RAG)应用,有桌面版和 Docker 镜像两种形态,能基于你上传的文档作答,也能用 @agent 调用工具。它的 Generic OpenAI provider 发送的是 Chat Completions 请求,所以一把 Router One Key 就能让所有工作区用上目录里的任意聊天模型,每次请求在 Dashboard → Logs 都有成本 Trace。负责文档问答的 embedder 和向量库仍留在 AnythingLLM 内部,因为 Router One 只提供聊天接口。本指南覆盖 Settings → LLM 表单和 Docker .env 两种配置方式、上下文窗口与 Max Tokens 两个字段,以及文档和 Agent 场景的注意事项。
启动 AnythingLLM 并创建专用 Key
桌面版(macOS、Windows、Linux)或 Docker 镜像都可以。下面是官方 Docker 命令:它把数据持久化到本机,并把一个 .env 文件挂载到容器内的 /app/server/.env,启动后在浏览器打开 http://localhost:3001。桌面版不需要 .env,直接用设置表单。在 Router One 为这个实例单独创建一把 Key 并设置 maxSpend:AnythingLLM 所有工作区的请求都用 provider 里配置的这一把 Key 发出。
export STORAGE_LOCATION=$HOME/anythingllm && \
mkdir -p $STORAGE_LOCATION && \
touch "$STORAGE_LOCATION/.env" && \
docker run -d -p 3001:3001 \
--cap-add SYS_ADMIN \
--name anythingllm \
-v ${STORAGE_LOCATION}:/app/server/storage \
-v ${STORAGE_LOCATION}/.env:/app/server/.env \
-e STORAGE_DIR="/app/server/storage" \
mintplexlabs/anythingllm把 AnythingLLM 配置到 Router One base URL
下面这份 .env 就是 Docker 命令挂载到 /app/server/.env 的那个文件(用 docker-compose 构建时读取的是 docker/.env);改完需要重启容器,这些变量在启动时读取。LLM_PROVIDER='generic-openai' 选择 Generic OpenAI provider。GENERIC_OPEN_AI_BASE_PATH 填带 /v1 的 base URL:provider 会把它原样交给官方 openai Node SDK,由 SDK 拼接 /chat/completions,所以每次聊天请求都是 POST /v1/chat/completions。GENERIC_OPEN_AI_API_KEY 填 Router One Key,GENERIC_OPEN_AI_MODEL_PREF 填目录里的精确模型 ID,ID 自带的前缀也要保留。GENERIC_OPEN_AI_MODEL_TOKEN_LIMIT 是该模型的上下文窗口,从模型详情页复制;AnythingLLM 用它分配历史、系统提示和用户输入的 token 预算,源码在未设置时回退为 4096。GENERIC_OPEN_AI_MAX_TOKENS 是每次请求携带的 max_tokens(源码默认 1024),回复经常被截断就调大。桌面版,或不想改文件的 Docker 用户,在 Settings → LLM 页面填 Base URL、API Key、Selected Model、Model context window 和 Max Tokens,写入的是同样这几个键:
# Docker: the file mounted at /app/server/.env (docker/.env for a docker-compose build) # Desktop: enter the same values in Settings → LLM instead of editing a file LLM_PROVIDER='generic-openai' GENERIC_OPEN_AI_BASE_PATH='https://api.router.one/v1' GENERIC_OPEN_AI_API_KEY=sk-your-router-one-key GENERIC_OPEN_AI_MODEL_PREF='<exact-model-id-from-/models>' # Context window of that model, copied from its detail page on /models GENERIC_OPEN_AI_MODEL_TOKEN_LIMIT=<context-window-from-the-model-detail-page> # max_tokens sent with every request; the source default is 1024 GENERIC_OPEN_AI_MAX_TOKENS=1024 # Keep the built-in embedder: Router One serves no embeddings endpoint EMBEDDING_ENGINE='native' EMBEDDING_MODEL_PREF='Xenova/all-MiniLM-L6-v2' # Restart the container after editing; the variables are read at startup
设置表单字段与 .env 键的对应关系
两种方式写入的是同一份配置:桌面版只能用设置表单,Docker 两种都可以。填好 Base URL 和 API Key 后,Selected Model 会立即请求网关的 /models 端点,把目录里的模型 ID 做成下拉列表;请求失败时它会变成文本框,直接填精确 ID 即可。AnythingLLM 不会从网关读取模型的上下文窗口,这一栏始终要你自己填;API Key 填上一步创建的专用 Key:
| Settings → LLM 字段 | .env 键 | 填什么、核对什么 |
|---|---|---|
| Base URL | GENERIC_OPEN_AI_BASE_PATH | https://api.router.one/v1,要带 /v1;SDK 会拼接 /chat/completions |
| Selected Model | GENERIC_OPEN_AI_MODEL_PREF | /models 里的精确 ID;模型详情页必须列出 POST /v1/chat/completions |
| Model context window | GENERIC_OPEN_AI_MODEL_TOKEN_LIMIT | 模型详情页标注的上下文窗口;未设置时回退为 4096 |
| Max Tokens | GENERIC_OPEN_AI_MAX_TOKENS | 每次请求的 max_tokens,源码默认 1024;需要长回复就调大 |
| Settings → Embedder | EMBEDDING_ENGINE | 保留 native(内置 embedder)或任一 embedding provider;不能指向 Router One |
文档、Agent,以及真正到达网关的请求
文档问答是 AnythingLLM 内部的 RAG:embedder 把上传内容转成向量,向量库(内置 LanceDB)负责存储,最终只有拼好检索上下文的提示词会以 Chat Completions 请求发到 Router One。embedder 是全局设置,官方文档建议文档一旦开始嵌入就不要再更换,因为换掉意味着全部重新嵌入;内置的 all-MiniLM-L6-v2 在 CPU 上运行、不调用任何外部 API,但它主要基于英文语料训练,中文资料检索不理想时可换成 AnythingLLM 支持的其他 embedding provider。@agent 会话执行的是 AnythingLLM 自己的技能,网页浏览、网页抓取都在应用内完成;provider 默认把工具调用视为可用,除非 PROVIDER_DISABLE_NATIVE_TOOL_CALLING 里列出了 generic-openai,所以要选详情页确认支持 Chat Completions 工具调用的模型。每一步 Agent 调用和每一轮对话都是独立请求,在 Dashboard → Logs 各有自己的 Trace、费用和 request_id,这才是计费依据:流式回复的 token 统计由 AnythingLLM 在应用内自行计算,除非设置 GENERIC_OPEN_AI_REPORT_USAGE=true 要求在流中返回 usage。所有工作区共用系统级的那一把 Key,想分开预算就按实例拆分,或直接按 Trace 核账,而不是按工作区。
AnythingLLM 该填哪个模型 ID?
从 /models 页复制精确的模型 ID,保留大小写、连字符和版本后缀,不要用展示名称代替。打开该模型的详情页,核对支持的 API 端点、上下文窗口和工具调用等能力,再与 AnythingLLM 当前选择的 provider 和功能对应。模型出现在目录里,不等于当前客户端能调用它的所有功能。建议为每个工具单独建 API Key,并设置 maxSpend 消费上限。
AnythingLLM 用的是哪种 API 协议?
OpenAI 兼容描述的是接口格式,不能据此推断 Chat Completions(/v1/chat/completions)、Responses(/v1/responses)和 Anthropic Messages(/v1/messages)可以互换。先核对工具当前版本、provider 配置和实际请求路径,再查模型详情与 API 兼容性事实页。一次普通对话成功,也不能证明服务端工具、历史状态或文件编辑功能都受支持。
在 trace 里验证 AnythingLLM 的调用
先在 AnythingLLM 发出一次简单文本请求,再到 Dashboard → Logs 按时间、模型和 request_id 核对 trace:tokens、花费、延迟和状态码。成功后再分别验证流式输出、工具调用和多轮历史。失败时保留实际请求路径、完整错误消息及 request_id;没有对应日志时,先查客户端配置和网络,不能仅凭客户端报错认定是网关或上游故障。
常见问题
Base URL 该填 https://api.router.one/v1 还是主机根地址?
填带 /v1 的形式。AnythingLLM 把这个值原样交给 openai SDK,由 SDK 拼接 /chat/completions;官方 docker/.env.example 里的示例 base path 也以 /v1 结尾。若只填主机根地址,请求会发到 /chat/completions,网关返回 404 的 not_found 错误,消息里会直接说明 base URL 需要以 /v1 结尾。表单占位符显示的是不带路径的主机名,但你填什么就用什么。两处都不要再加 /chat/completions。
聊天正常,但上传文档时报 embedding 错误,为什么?
embedder 和 LLM 是两个独立设置,而 Router One 没有 embeddings 端点:embedder 若指向网关,聊天照常、上传必败。到 Settings → Embedder 保留内置 embedder(EMBEDDING_ENGINE='native'),或选 AnythingLLM 支持的任一 embedding provider;Generic OpenAI 这个 embedder 选项和 EMBEDDING_BASE_PATH 都不要指向 Router One。向量按文档存储,事后更换 embedder 需要删除并重新嵌入所有上传内容,所以建库前就定好。
每个工作区能用不同模型或不同 Key 吗?
模型可以。官方文档区分 System LLM、只在该工作区生效的 Workspace LLM,以及 @agent 会话用的 Agent LLM:在 Workspace Settings → Chat Settings 把 Workspace LLM Provider 设为 Generic OpenAI,再在 Workspace Chat model 里选一个目录 ID(留空则沿用系统设置);Agent 会话在 Agent Configuration 里单独设置。Key 不可以:provider 的 Base URL 和 API Key 都读自系统设置,所有工作区都记在同一把 Router One Key 上。要分开预算,就分实例部署,各用各的 Key 和 maxSpend。
AnythingLLM 能通过网关用哪些模型?
选用当前目录中同时支持 AnythingLLM 所用端点和所需功能的模型。精确 ID、当前单价与能力以 /models 及模型详情为准;不要仅按 GPT、Claude 等系列名判断兼容性。客户端能列出模型,只证明模型发现成功,仍需验证实际调用。
能列出模型,但调用报 400 或 404,怎么办?
先记录实际请求路径和错误消息,再核对精确模型 ID。400 可能是参数、工具类型或模型与端点不匹配;404 可能是请求路径或资源不存在,不能直接判定模型下线。若错误提示 must be called via,按它指明的端点调整客户端 provider,或换用支持当前端点的模型。不要在所有工具里统一增删 /v1 或 /chat/completions。
中国大陆能直连吗?
能。网关在大陆可直连、无需 VPN,配置与全球环境完全一致。
报 401/402/403/429 怎么排查?
先到 Dashboard → Logs 核对请求及错误消息。401 查 Key 是否传入和有效;402 查钱包余额与 maxSpend;403 查 Key 权限和访问限制;429 查请求频率、token 限额及上游限流,按错误来源处理。保留 request_id,再按错误码速查页逐项排查。