Embedding Pipeline#
Overview#
RAGFlow's embedding pipeline converts document chunks into dense vectors for storage in the search index. It spans two layers:
EmbeddingService— async orchestrator that drives batch encoding for a task, handles title/content weighting, and reports progressembedding_model.pyprovider classes — synchronous, provider-specific adapters that implement the actual API calls
Batch Size Configuration#
The top-level batch size is read from settings.EMBEDDING_BATCH_SIZE, which defaults to 16 and can be overridden via the EMBEDDING_BATCH_SIZE environment variable . EmbeddingService.__init__ accepts an explicit embedding_batch_size override; if not supplied, it falls back to the setting .
EmbeddingService.embed_chunks Flow#
Entry point: EmbeddingService.embed_chunks(docs, embedding_model, parser_config)
- Text extraction —
EmbeddingUtils.prepare_texts_for_embedding(docs)returns(titles, contents). Content is pulled fromquestion_kwd>content_with_weight; titles fromdocnm_kwd. - Title encoding — The first title is encoded once and tiled across all chunks (cost: 1 API call for the whole batch).
- Content batch loop — Contents are sliced into chunks of
_embedding_batch_sizeand dispatched viathread_pool_exec(_batch_encode_wrapper, ...). Each batch is rate-limited throughctx.embed_limiter. - Truncation — Before each content batch is sent to the model, every text is truncated to
embedding_model.max_length - 10tokens viatruncate(). - Vector assembly —
EmbeddingUtils.stack_vectors()vstack-combines per-batch arrays;EmbeddingUtils.combine_title_content_vectors(tts, cnts, title_weight)applies a weighted blend (DEFAULT_TITLE_WEIGHT = 0.1, i.e. 10% title / 90% content). - Attachment —
EmbeddingUtils.attach_vectors(docs, vects)writes each vector to the chunk dict under the keyq_<N>_vec. - Return —
(total_token_count, vector_size)
Provider-Level: Base._batched_encode#
The shared template for OpenAI-style providers is Base._batched_encode(texts, call_fn, *, batch_size, truncate_to=None). It:
- Optionally truncates each text to
truncate_totokens before issuing any calls. - Runs a loop of
ceil(len(texts) / batch_size)calls to the provider-suppliedcall_fn(batch) -> (embeddings, token_count)closure. - Accumulates vectors into a single
np.ndarrayand sums token counts. - Wraps any non-
ModelExceptionin a unifiedEmbeddingError, ensuring callers see a consistent exception type.
Response ordering is guaranteed by _sorted_by_index(), which sorts SDK result items by their .index attribute before extracting embeddings.
Provider Batch Sizes and Truncation Limits#
| Provider | Batch Size | Client-Side Truncation (truncate_to) |
|---|---|---|
| OpenAI / Azure / OpenAI-API-Compatible | 16 | 8191 tokens |
ZhipuAI embedding-2 | 16 | 512 tokens |
ZhipuAI embedding-3 | 16 | 3072 tokens |
| QWen (DashScope) | 4 | 2048 tokens (inline) |
| Gemini | 16 | 2048 tokens |
| Bedrock (Titan/Cohere) | 1 | DEFAULT_MAX_TOKENS (8192) |
| Ollama | 16 | Server-side (truncate=True) |
| Cohere | 16 | Server-side (truncate="END") |
| NVIDIA NIM | 16 | Server-side ("truncate": "END") |
| Jina | 16 | Server-side ("truncate": true) |
| SiliconFlow | 16 | Model-specific (256–4096 tokens, inline in _clean_batch) |
| Perplexity | 512 | None |
| BuiltinEmbed (TEI) | 16 | Server-side |
Sources:
DEFAULT_MAX_TOKENS = 8192 is the standard ceiling for most 8K-context providers .
DashScope URL Resolution#
QWenEmbed requires the DashScope native HTTP API (/api/v1) rather than the OpenAI-compatible path. _dashscope_native_http_api_url(base_url) detects known DashScope hostnames and maps them to the correct endpoint (international: dashscope-intl.aliyuncs.com, domestic: dashscope.aliyuncs.com). A context manager _dashscope_native_api_url_scope temporarily patches dashscope.base_http_api_url to minimize concurrency exposure.
Key Source Files#
| File | Purpose |
|---|---|
rag/svr/task_executor_refactor/embedding_service.py | Async batch orchestrator |
rag/llm/embedding_model.py | All provider adapters + Base._batched_encode |
rag/svr/task_executor_refactor/embedding_utils.py | Text prep, vector stacking/combining/attaching |
common/settings.py | EMBEDDING_BATCH_SIZE default |