Chat Completion API#
POST /api/v1/chat/completions is RAGFlow's primary endpoint for sending user messages to a chat assistant (Dialog) and receiving RAG-augmented responses. It is implemented in session_completion and drives both the web UI and public API integrations.
The endpoint handles:
- Session creation/resumption and history management
- Per-request LLM and generation-parameter overrides
- Streaming (SSE) and non-streaming response modes
- Dynamic interpolation of prompt template variables (
{knowledge},{date}, custom keys)
Request Parameter Schema#
The handler normalizes the request in _normalize_completion_messages and extracts flags before forwarding.
| Parameter | Type | Default | Notes |
|---|---|---|---|
messages | array | — | Required (or question); each item must have role and content; last message must be from user |
question | string | — | Alias for messages=[{role:"user", content:...}] |
chat_id | string | — | Links request to an existing Dialog; required when session_id is provided |
session_id / conversation_id | string | — | Resumes an existing conversation; auto-created if omitted |
stream | boolean | true | Enables SSE streaming |
pass_all_history_messages | boolean | false | If true, use the messages array as the full conversation (bypass stored history) |
store_history_messages | boolean | true | Persist the exchange to the session; false requires pass_all_history_messages: true |
llm_id | string | dialog default | Override the dialog's bound model for this request; validated against tenant credentials |
legacy | boolean | false | Emit v0.23.0-style streaming that reconstructs <think>…</think> tags |
Generation overrides (temperature, top_p, frequency_penalty, presence_penalty, max_tokens) are extracted from the request body via pop_generation_config and applied to the dialog's llm_setting through merge_generation_config.
No chat_id falls back to an ephemeral dialog with direct-chat defaults (_build_default_completion_dialog), meaning no KB retrieval and an empty system prompt.
Any remaining keys in req after standard parameters are consumed are forwarded as **kwargs to the RAG agent — this is how named template variables (e.g. quote, custom {key} interpolations) reach dialog_service.py .
Request Forwarding: From HTTP to rag_agent#
After parameter extraction, the handler calls rag_agent(dia, msg, stream, session_id=session_id, **req) . The remaining req dict (stripped of routing/session parameters) is passed as **kwargs to rag_agent in dialog_service.py.
Inside rag_agent, the execution path is:
- LLM resolution — resolves the dialog's
llm_idto a model config (chat or vision), with fallback to tenant default . - Retrieval — runs vector/keyword search against linked knowledge bases using
dialog.top_n,top_k,similarity_threshold, andvector_similarity_weight. Optional sub-paths include SQL (field-map), Tavily web search, knowledge graph, and TOC-enhanced retrieval . - Prompt assembly — interpolates the system prompt template (see next section), appends citation instructions if
quote=True, trims to token budget viamessage_fit_in. - LLM inference — streams or collects the model response, yielding intermediate chunks with
answer,reference,finalkeys. - Session persistence — after streaming completes,
ConversationService.update_by_idsaves the updated message list and references .
Float sanitization: _sanitize_json_floats recursively replaces NaN/Infinity values in every outgoing SSE payload to avoid RFC 8259 violations from similarity scores .
Prompt Template Variable Interpolation#
The system prompt in dialog.prompt_config["system"] is treated as a Python format string. Named variables are declared in prompt_config["parameters"] as objects {key, optional} .
Built-in variables:
| Variable | Source | Behavior |
|---|---|---|
{knowledge} | Retrieved KB chunks joined with \n------\n | Auto-injected when KB is linked; if absent from template but chunks exist, knowledge is appended to the end of the system prompt |
{date} | datetime.now(UTC) formatted as YYYY-MM-DD HH:MM:SS | Always added as optional |
Custom variables are passed from the caller as extra keys in the request body. In rag_agent:
- Required parameters missing from
kwargsraiseKeyError: "Miss parameter: <key>". - Optional parameters missing from
kwargsare replaced with a space in the system template . - After all substitutions, the template is rendered via
prompt_config["system"].format(**kwargs).
Default prompt config for KB-backed chats includes the {knowledge} and {date} parameters pre-declared . For direct (no-KB) chats, the defaults are an empty system, no parameters, and quote: False .
When the assistant is created or updated, _apply_prompt_defaults auto-injects the knowledge parameter if {knowledge} appears in the system template and kb_ids are set .
Streaming Response Format#
When stream=true (default), the response is Content-Type: text/event-stream. Each SSE event is:
data: {"code": 0, "message": "", "data": { <answer_chunk> }}
The data field carries an accumulated (not delta) answer object: answer, reference, session_id, message_id, chat_id . The final event carries "data": true to signal stream completion.
For non-streaming (stream=false), a single JSON object is returned in {"code": 0, "message": "", "data": <answer>}.
Legacy mode (legacy: true) rebuilds the older accumulated-string format by prepending <think>…</think> markers from the start_to_think/end_to_think event flags , for clients that haven't migrated to the current streaming protocol.
OpenAI-Compatible Endpoint & Deprecated Routes#
POST /api/v1/openai/<chat_id>/chat/completions (openai_api.py) provides a drop-in OpenAI Chat Completions interface scoped to a specific chat_id.
Key differences from the native endpoint:
- URL:
chat_idis in the path, not the request body. modelfield: The literal string"model"means "use the dialog's stored model"; any other value overrides the LLM for the request .- Message content: Handles both string and array-of-parts formats (OpenAI spec).
- References: Controlled via
extra_body.reference(boolean) andextra_body.reference_metadata({include, fields}). - Response format: Returns OpenAI-shaped objects (
id,object,created,model,usage,choices) rather than the{code, message, data}envelope.
backward_compat.py maps old routes to their current equivalents :
| Deprecated | Current |
|---|---|
POST /api/v1/chats/{chat_id}/completions | POST /api/v1/chat/completions |
POST /api/v1/chats_openai/{chat_id}/chat/completions | POST /api/v1/openai/{chat_id}/chat/completions |