Skip to content
Router One
Back to Blog

RAGFlow vs MaxKB vs FastGPT vs AnythingLLM on One API Key

PublishedUpdatedByRouter One TeamHow we measure

Four knowledge-base apps, one question: what changes when their chat-model calls go through Router One? Very little inside the apps. RAGFlow still parses documents with DeepDoc and answers over chunked datasets, MaxKB still builds knowledge-base assistants and agent workflows, FastGPT still runs knowledge-base workflows and reaches models through its bundled AI Proxy, and AnythingLLM still chats over your uploads from a desktop app or a container. Parsing, chunking, embeddings, rerank, the vector store, retrieval and agents all stay in the app. What changes is the chat request underneath: one sk- key, exact model IDs from /models, and one trace per model call in Dashboard → Logs with model, tokens, cost, latency, status and request_id. For an answer, only the assembled prompt, with the retrieved chunks already in it, reaches the gateway; parsing, query-time options and background features send chunk text, the question or chat history as requests of their own (listed under Hidden model calls below).

The verdicts. RAGFlow: an OpenAI-API-Compatible provider instance with https://api.router.one/v1 as Base URL, one model row per catalog ID, and Max tokens set to the model's context window. MaxKB: the OpenAI provider, with the catalog ID in Base model, not in Model name. FastGPT: one OpenAI-protocol channel in AI Proxy, plus a Model configuration entry whose Model ID is the exact catalog ID. AnythingLLM: the Generic OpenAI provider, with /v1 on the Base URL and a context window you type yourself. In all four, the embedding model stays on another provider or a local model. Everything below was checked on 2026-09-23 against RAGFlow v0.27.2, MaxKB v2.10.6-lts, FastGPT V4.17.0 and AnythingLLM v1.16.1.

Side by side

ToolWhere it runsWhere the /v1 URL goesProtocol sentModel ID entryStays in the tool
RAGFlowDocker Compose on an x86 host (4+ cores, 16 GB RAM, 50 GB disk); web UI on port 80User settings → Model providers → OpenAI-API-Compatible instance: Base URLChat Completions, through the openai Python SDKList models (from GET /v1/models, every ID tagged Chat) or Add custom model, typedDeepDoc parsing and chunking; Embedding, Rerank, ASR and TTS defaults; the document engine (Elasticsearch by default, others via DOC_ENGINE); chat assistants, search, the Agent canvas
MaxKBDocker (1panel/maxkb); web UI at http://your_server_ip:8080Models → OpenAI → Add model: API URL (API domain in the docs)Chat Completions; an ID containing codex goes to ResponsesBase model, an editable dropdown: type the ID. Model name is only a labelKnowledge bases and their embedding model; retrieval on PostgreSQL + pgvector; tools; workflow execution
FastGPTSelf-hosted from the official Docker Compose template; AI Proxy is a required service since V4.17.0Admin → Model provider → Model provider tab (Model Channels in the docs) → Added channels: Base url (Proxy URL in the docs), Protocol Type OpenAIChat Completions; an Anthropic-type channel would post to /messages insteadModel configuration → Add new model: Model ID, typed, then picked in the channel's Model fieldDatasets, with embedding and rerank models on another channel; workflow nodes; AI Proxy's Call log; FastGPT points
AnythingLLMDesktop (macOS, Windows, Linux) or Docker; http://localhost:3001Settings → AI Providers → LLM → Generic OpenAI: Base URL, or GENERIC_OPEN_AI_BASE_PATH in .envChat Completions, through the openai Node SDKSelected Model, a dropdown loaded from /models that falls back to a text boxThe embedder (built-in all-MiniLM-L6-v2), LanceDB, a native reranker, @agent skills, workspaces

All four send POST /v1/chat/completions, which serves every chat model in the catalog (GPT, Claude, Gemini, Grok and DeepSeek families), so anthropic/claude-sonnet-5 works in each of them, prefix included; none of them strips the slash out of an ID. One exception: MaxKB v2.10.6-lts ships langchain-openai 1.3.2, which sends any model ID containing codex (such as codex-auto-review) to POST /v1/responses instead, so pick such an ID in MaxKB only if its model page lists /v1/responses. Two setups end in an HTTP 400 whose message says must be called via. The first is an image-generation ID that RAGFlow's List models tagged as Chat: RAGFlow sends it to Chat Completions. The second is a GPT, Gemini or Grok ID on a FastGPT channel created with the Anthropic protocol type: that channel posts to /v1/messages, which the gateway serves only for the Claude-family and DeepSeek IDs it lists. Apart from MaxKB's codex rule, and unlike n8n in the low-code builder roundup, none of these setups sends /v1/responses. The last column is the boundary: nothing in it runs on the gateway.

RAGFlow: an OpenAI-API-Compatible instance, one row per model

Since v0.27.0, RAGFlow's model settings are built around provider instances. Open User settings → Model providers, pick OpenAI-API-Compatible under Available models and fill in the new-instance card:

# RAGFlow v0.27.2 → User settings → Model providers → OpenAI-API-Compatible
Instance name:  router-one                   # anything except "default"
Base URL:       https://api.router.one/v1
API Key:        sk-your-router-one-key
# Models → List models, or + → Add custom model
Model name:     <exact-model-id-from-/models>
Model type:     Chat                         # add VLM only for image input
Max tokens:     <context-window-from-the-model-page>
Tool call:      on only if the model page lists tool calling
# Save → Set default models → LLM: this model

v0.27.0 and later add a missing /v1, older releases do not, so type it on every version and never paste the full /chat/completions path. List models pre-adds the whole catalog as type Chat, image-generation IDs included; remove the rows you will not use. Max tokens is RAGFlow's own context budget for history and retrieved chunks, not a generation limit: it never goes out on the wire, and 0 falls back to 8192.

The first failure. Save fails with Fail to access model(OpenAI-API-Compatible/…).No valid response received, RAGFlow's generic verdict on its test chat. The gateway's answer is in docker logs -f docker-ragflow-cpu-1, on the line containing async base giving up: 401 AUTH_INVALID_API_KEY is the key, 404 not_found the path, and 400 must be called via an image-generation ID tagged Chat. Guide: RAGFlow + Router One.

MaxKB: the OpenAI provider, with the ID in Base model

MaxKB's model form has two names, and only one reaches the gateway. Model name is a display label; Base model is the value sent as model. Base model is an editable dropdown of presets, not a list fetched from Router One, so type the full catalog ID and confirm it as a new option.

# MaxKB v2.10.6-lts → Models → OpenAI → Add model
Model name:  Router One chat                   # display label only
Model type:  LLM (大语言模型)
Base model:  <exact-model-id-from-/models>     # typed, sent unchanged
API URL:     https://api.router.one/v1         # "API domain" in the docs
API Key:     sk-your-router-one-key

Choose the OpenAI provider even for an anthropic/ or google/ ID: it selects the compatible protocol, not the model family. Don't append /chat/completions to API URL.

The first failure. Saving validates the model with a real greeting, and the OpenAI LLM parameter form starts with temperature 0.7 and a maximum output of 8192 tokens, MaxKB's own defaults. A 400 that names temperature or an output-token parameter is the model rejecting it: adjust or remove it under Advanced settings or Model parameter settings, since a new key or base URL will not help. Guide: MaxKB + Router One.

FastGPT: one OpenAI-protocol channel in AI Proxy

Since V4.17.0, FastGPT requires its bundled AI Proxy and routes models through its channels (a per-model custom request URL still works but is marked for deprecation), and the old OPENAI_BASE_URL and CHAT_API_KEY variables no longer take effect. AIPROXY_API_ENDPOINT points FastGPT at AI Proxy, not at Router One; the Router One key goes only into a channel form:

# FastGPT V4.17.0 → Admin → Model provider → Model provider tab → Added channels
# (the English docs call these Model Channels and Add Channel)
Protocol Type:  OpenAI
Base url:       https://api.router.one/v1      # "Proxy URL" in the English docs
API key:        sk-your-router-one-key
Model:          <exact-model-id-from-/models>
Model Mapping:  (empty when the IDs match)
# Model configuration → Add new model → Model ID: the same exact ID
# Save → Model testing → Batch test N models

The Model dropdown only offers models that already exist under Model configuration, so register the catalog ID there first; its Model ID is what FastGPT puts in the model field. Keep /v1 in Base url: the opposite convention belongs to one-api and new-api, whose OpenAI channel type appends the whole /v1/chat/completions path itself (relay stations). Switch on Supports tool calling on the model entry only when the model page lists tool calling: the tool-call node then sends native tools, and with the switch off it describes the tools in the prompt instead; in V4.17.0, question classification and content extraction send plain prompts either way.

The first failure. The channel test passes, then an app call fails with 400 or 404: the model was enabled under a spelling that differs from the catalog ID, or Model Mapping points at a retired ID. Read the request URL in AI Proxy's Call log, then the message and request_id in Dashboard → Logs. Guide: FastGPT + Router One.

AnythingLLM: the Generic OpenAI provider, and a context window you type

AnythingLLM Desktop only has the settings form; the Docker image also reads the same keys at startup from the .env mounted at /app/server/.env.

# AnythingLLM v1.16.1 → Settings → AI Providers → LLM → Generic OpenAI
# (Docker: the matching .env key is on the right)
Base URL:              https://api.router.one/v1             # GENERIC_OPEN_AI_BASE_PATH
API Key:               sk-your-router-one-key                # GENERIC_OPEN_AI_API_KEY
Selected Model:        <exact-model-id-from-/models>         # GENERIC_OPEN_AI_MODEL_PREF
Model context window:  <context-window-from-the-model-page>  # GENERIC_OPEN_AI_MODEL_TOKEN_LIMIT
Max Tokens:            1024                                  # GENERIC_OPEN_AI_MAX_TOKENS
# .env only: LLM_PROVIDER='generic-openai'

AnythingLLM never reads a context window from the gateway: the form requires the value, and a Docker .env without GENERIC_OPEN_AI_MODEL_TOKEN_LIMIT budgets for 4096 tokens. Max Tokens is the max_tokens sent with each request (1024 by default); raise it if answers stop mid-sentence. A workspace can override the model under Workspace Settings → Chat Settings, but not the key: every workspace bills to the one system-level key.

The first failure. A 404 not_found whose message says the base URL must end in /v1. The form's placeholder shows a bare host, and the value is used exactly as typed. Guide: AnythingLLM + Router One.

Embeddings and rerank stay on another provider or a local model

For these apps Router One fills only the chat-model slot: it has no /v1/embeddings and no rerank endpoint, so a model test can pass while the first document fails at the embedding step. Each app sets these models apart:

  • RAGFlow requires a default Embedding model next to the LLM, and since v0.22.0 its image ships none: use the Compose stack's optional TEI service (the tei-cpu or tei-gpu profile in docker/.env), an Ollama or Xinference model such as bge-m3, or another provider. Never give a model in the Router One instance the Embedding or Rerank type; those post to /v1/embeddings and /v1/rerank.
  • MaxKB has each knowledge base select its own embedding model. The OpenAI provider form offers an Embedding model type, but Router One does not implement that endpoint.
  • FastGPT needs at least one language model and one embedding model to index a dataset. Only language-model rows belong in the Router One channel; embedding, rerank, TTS and STT models come from another provider's channel.
  • AnythingLLM keeps the built-in embedder (all-MiniLM-L6-v2, on CPU, no external API) unless you pick another provider under Settings → AI Providers → Embedder. Its model card lists English only, so Chinese or other non-English documents may retrieve better with another embedder; neither the Generic OpenAI embedder nor EMBEDDING_BASE_PATH may point at Router One. Vectors go into the built-in LanceDB, and the only reranker in the v1.16.1 source runs inside the app.

Choose the embedding model before you build a library. Once a RAGFlow dataset has chunks, it lets you switch only if a sampled re-embedding check scores an average cosine similarity of at least 0.9 against the old vectors; otherwise you must delete every chunk first. In AnythingLLM a switch means re-embedding every upload.

Hidden model calls that cost money

A knowledge-base app sends many more chat requests than its users send questions. Each item below is a real request on the same key, with its own row in Dashboard → Logs, and a charge whenever a model answers it:

  • Save and test buttons. RAGFlow streams a test Hi on Save and on each row's verify button, and Verify all models tests every listed model. MaxKB calls the model with a greeting when you save it. FastGPT's Model testing sends one real request per model.
  • Parsing and import. RAGFlow calls the default LLM once per chunk for each of Auto-keyword, Auto-question and Auto metadata that is enabled, so 2,000 chunks with two options on is about 4,000 requests, and Knowledge compilation allows up to 20 concurrent LLM calls per task by default. MaxKB's Generate Questions sends one request per paragraph, for a document or a whole knowledge base, to the model picked in its dialog. FastGPT's Q&A extraction mode sends one request per queued chunk to the dataset's text understanding model (File read model in the English UI), and Auto-generate supplementary indexes uses the same model.
  • Every question. In a RAGFlow chat assistant, Multi-turn optimization (from the second question on), Keyword analysis and Cross-language search each add one request per turn, and a Thinking level above Low (Medium, High or Ultra) runs an agentic retrieval loop that can add several more per answer. MaxKB's Questions Optimization adds one per turn, rewriting the question from the last three exchanges. FastGPT's Query rewriting adds one to each knowledge-base search that uses it, Guess What You Want to Ask adds one after an answer to write three follow-up questions, and a Chat title model, when one is set, adds one per new chat.
  • Agents and retries. A RAGFlow Agent component with tools can make up to (Max reflection rounds + 1) model calls in its tool loop, plus one closing call if it hits that limit. Max reflection rounds is 1 on a new Agent on the canvas, and the source falls back to 5 when it is unset. A failed call is retried up to the component's Max retry rounds (3 on a new component). The Categorize component calls the model too, and chat assistants and parsing retry rate-limit and server errors up to LLM_MAX_RETRIES (5) times. FastGPT's tool-call, classification and extraction nodes each cost a request, and AI Proxy retries failures (RETRY_TIMES: 3 in the official template). MaxKB's AI chat nodes add calls beyond the final answer. Each AnythingLLM @agent step is a request, and its document summarizer sends one per section, asking before it continues past the third.
  • In the background. Once Enable Personalization is on, AnythingLLM's Automatic Memories (on by default from then) runs every three hours by default. For each user and workspace with five or more new chats and 20 idle minutes, it runs an Observer pass and, when that pass proposes memories, a Reflector pass; each pass is an agent run of up to three rounds on the workspace chat model (else the agent model, else the system LLM). Scheduled Jobs run an agent prompt on a cron schedule with nobody watching, and they auto-approve tool calls, so the summarizer's check-in after the third section is skipped.

None of these switches is a spend cap. The cap is the key's maxSpend: once it is reached the gateway answers HTTP 402 (error codes), so the key cannot spend past that amount and your other keys keep working. Give every deployment its own key in Dashboard → API Keys, and split further where the app stores keys per connection: a second RAGFlow OpenAI-API-Compatible instance with its own key separates parsing spend from chat spend, and each MaxKB model entry carries its own API Key, so Generate Questions can run on a second entry with a second key. In FastGPT a model ID, not an app, picks the channel, so a second Router One channel with its own key separates spend only for the model IDs it serves, such as the dataset's text understanding model (never list one ID in both channels, or AI Proxy balances between them). AnythingLLM keeps one key in system settings every workspace shares, so split it by instance. Bulk parsing is also where rate limits bite: a gateway 429 with RATE_LIMIT_EXCEEDED or TOKEN_QUOTA_EXCEEDED is a rate limit, not the spend cap, and the limits start at platform defaults that can be raised on request (email support@router.one).

Verify in Dashboard → Logs

The app's own counters are not the bill. RAGFlow estimates streamed tokens locally whenever a chunk carries no usage figure, MaxKB falls back to its own token estimate whenever a response carries none (its streamed calls do not ask for one), FastGPT meters your users in FastGPT points, and AnythingLLM computes token metrics in the app unless GENERIC_OPEN_AI_REPORT_USAGE=true asks for usage in the stream. Dashboard → Logs is the charge per request, so reconcile there (cost tracking): import one small document and ask one question with only the options you plan to keep; filter Logs to that time window and the exact model ID; then match the rows to the save test, one request per chunk for each parsing option, the query-time extras and the answer. Keep the request_id of any failed row when you report it.

If a row is missing, check before you conclude that the request never arrived. Records awaiting pricing can be temporarily hidden; the app's server log, or AI Proxy's Call log in FastGPT, shows the status it actually received; and a FastGPT model ID listed in two channels may have been served by the other one. A streamed request that the app disconnects midway is recorded as HTTP 499 client_cancelled; since 1.16.0, stopping a response in AnythingLLM ends the inference instead of letting it run on. Path, key and DNS checks are in connection troubleshooting.

Which one to pick

All four reach the same catalog through the same endpoint, so choose by what surrounds the model call.

  • RAGFlow if document parsing is the hard part: DeepDoc, per-dataset parsing options and knowledge compilation templates, on a Docker stack that wants 16 GB of RAM.
  • MaxKB if you want one container for knowledge-base assistants and agent workflows, with a short model form: a label, a Base model, an API URL and a key.
  • FastGPT if your apps are workflows with classification, extraction and tool-call nodes, and you want AI Proxy's channels and Call log in front of every model provider.
  • AnythingLLM if one person or a small team wants document chat on a desktop or in one container, with the embedder and vector database built in, so for English documents the chat model is the only model service you add.
  • Dify if the knowledge base is one part of a larger app builder: see Dify + Router One and the Dify, Flowise, Langflow and n8n roundup.

Every setup guide is on /integrations.

FAQ

RAGFlow, MaxKB, FastGPT or AnythingLLM: which one should I choose? All four reach the same catalog through the same endpoint, so choose by what surrounds the model call. Pick RAGFlow if document parsing is the hard part, MaxKB for knowledge-base assistants and agent workflows in one container with a short model form, FastGPT if your apps are workflows and you want AI Proxy's channels in front of every model provider, and AnythingLLM for document chat on a desktop or in one container with the embedder and vector database built in.

Can RAGFlow, MaxKB, FastGPT or AnythingLLM use Router One for embeddings or rerank? No. Router One serves chat models on /v1/chat/completions and has no embeddings or rerank endpoint. Keep those models on another provider or a local one, such as RAGFlow's optional TEI service, an Ollama model or AnythingLLM's built-in embedder, and point only the LLM slot at the gateway.

Does the base URL need /v1 in these knowledge-base apps? Yes, in all four: https://api.router.one/v1. Each one appends /chat/completions to what you enter. RAGFlow v0.27.0 and later add a missing /v1 and older releases do not, and FastGPT's channel wants /v1 even though one-api and new-api leave it off for their OpenAI channel type. Never paste the full /chat/completions URL.

Do Claude or Gemini models need a different provider type? No. RAGFlow's OpenAI-API-Compatible provider, MaxKB's OpenAI provider, FastGPT's OpenAI protocol type and AnythingLLM's Generic OpenAI provider all send Chat Completions, which serves every chat model in the catalog. Enter the exact ID with its prefix, such as anthropic/claude-sonnet-5, and keep FastGPT's Router One channel off the Anthropic protocol type.

Why is my knowledge-base app spending tokens when nobody is chatting? Parsing and background work call the chat model too: RAGFlow's Auto-keyword, Auto-question and Auto metadata once per chunk, MaxKB's Generate Questions once per paragraph, FastGPT's Q&A extraction once per queued chunk, and AnythingLLM's Automatic Memories and Scheduled Jobs on a timer. Save and test buttons send real requests as well; each one is a row in Dashboard → Logs.

How do I cap what one knowledge-base app can spend? Create a dedicated Router One key for the deployment and set maxSpend on it. At the cap the gateway answers HTTP 402 for that key only, so a runaway parsing job stops there and cannot spend past that amount, while your other keys keep working. In RAGFlow, a second provider instance with a second key separates parsing spend from chat spend.

The model test passes, but importing a document fails. Why? The test only proves the chat model. Indexing needs an embedding model, which Router One does not serve, so check that RAGFlow's default Embedding model, the MaxKB knowledge base's embedding model, the FastGPT dataset's embedding model or AnythingLLM's Settings → AI Providers → Embedder points at another provider or a local model.

Related canonical pages

This article belongs to the LLM API Gateway and Routing cluster. These pages are the commercial page, setup docs, evidence source, and trust references.

Commercial pageRouter One API gatewayThe product homepage for unified model calls, routing, fallback, budgets, and observability.API docsRouter One API documentationOpenAI-compatible endpoints, CLI setup, and model invocation examples.EvidenceSmart routing methodologyRouting signals, the model and request ID, and the customer-visible trace field boundaries.ComparisonOpenRouter alternativeA professional comparison of global catalog breadth versus China-friendly routing and payments.TrustCiteable factsStable product facts for crawlers, AI answer engines, and customers.Data retentionData retention policyPrompt/completion retention boundaries and request metadata policy.Gateway pageUnified LLM API gatewayOne OpenAI-compatible endpoint for the whole catalog, with routing, fallback, and budgets.Routing pageSmart model routingHow candidate ranking uses latency, posted cost, and reliability signals.Fallback pageLLM provider fallbackWhat makes a request eligible for a retry on another healthy provider route.Observability pagePer-request trace logModel, request ID, tokens, latency, status, and errors for every request.Compatibility pageOpenAI-compatible endpointKeep the OpenAI SDK and change only the base URL to reach every model family.Cost tracking pageLLM cost trackingPer-key, per-model, and per-request spend attribution with hard spend ceilings.Reseller pageBuild your own LLM API serviceSpend-capped customer keys, per-key usage attribution, and an explicit list of what key-level reselling does not give you.Client integrationsSDK and client setup guidesPoint any coding agent, SDK, chat client, or LLM app platform at one endpoint — a dedicated guide for each.Model comparisonsSide-by-side model pricing and contextPer-1M rates, context windows, and capabilities rendered from the live catalog.

Related reads