[{"data":1,"prerenderedAt":736},["ShallowReactive",2],{"blog-multimodal-rag-colpali-en":3},{"slug":4,"published":5,"minutes":6,"category":7,"tags":8,"keywords":14,"about":25,"sources":35,"cover":72,"og":73,"expertise":74,"locales":75,"lang":76,"title":79,"description":80,"coverAlt":81,"metaTitle":82,"takeaways":83,"faq":89,"toc":105,"blocks":133,"others":483},"multimodal-rag-colpali","2026-10-01",10,"rag",[9,10,11,12,13],"ColPali","Multimodal RAG","Late interaction","Multi-vector embeddings","Visual document retrieval",[15,16,9,17,18,19,20,21,22,23,24],"multimodal RAG ColPali","multimodal RAG","visual document retrieval","ColQwen2","ColQwen3","late interaction MaxSim","multi-vector embeddings","ViDoRe benchmark","page image embeddings","multivector vector database",[26,29,32],{"name":27,"url":28},"Retrieval-augmented generation","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FRetrieval-augmented_generation",{"name":30,"url":31},"Vector database","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FVector_database",{"name":33,"url":34},"Vision-language model","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FVision-language_model",[36,39,42,45,48,51,54,57,60,63,66,69],{"title":37,"url":38},"ColPali: Efficient Document Retrieval with Vision Language Models (arXiv:2407.01449)","https:\u002F\u002Farxiv.org\u002Fabs\u002F2407.01449",{"title":40,"url":41},"ViDoRe V2 benchmark (arXiv:2505.17166)","https:\u002F\u002Farxiv.org\u002Fabs\u002F2505.17166",{"title":43,"url":44},"ViDoRe V3 benchmark (arXiv:2601.08620)","https:\u002F\u002Farxiv.org\u002Fabs\u002F2601.08620",{"title":46,"url":47},"EVIE: storage and benchmark analysis for ColQwen-family models (arXiv:2610.11553)","https:\u002F\u002Farxiv.org\u002Fhtml\u002F2610.11553v1",{"title":49,"url":50},"Vespa: scaling ColPali to billions","https:\u002F\u002Fblog.vespa.ai\u002Fscaling-colpali-to-billions\u002F",{"title":52,"url":53},"Qdrant documentation: vectors, multivectors and the max_sim comparator","https:\u002F\u002Fqdrant.tech\u002Fdocumentation\u002Fconcepts\u002Fvectors\u002F",{"title":55,"url":56},"Qdrant: ColPali optimization with pooling and two-stage retrieval (2024)","https:\u002F\u002Fqdrant.tech\u002Fblog\u002Fcolpali-qdrant-optimization",{"title":58,"url":59},"Qdrant: turbo4 multivector search tutorial","https:\u002F\u002Fqdrant.tech\u002Fdocumentation\u002Ftutorials-search-engineering\u002Fturbo4-multivector-search\u002F",{"title":61,"url":62},"Sentence Transformers v6.0.0 release notes","https:\u002F\u002Fgithub.com\u002Fhuggingface\u002Fsentence-transformers\u002Freleases\u002Ftag\u002Fv6.0.0",{"title":64,"url":65},"illuin-tech\u002Fcolpali repository and model table","https:\u002F\u002Fgithub.com\u002Filluin-tech\u002Fcolpali",{"title":67,"url":68},"MUVERA: multi-vector retrieval via fixed dimensional encodings (NeurIPS 2024)","https:\u002F\u002Fproceedings.neurips.cc\u002Fpaper_files\u002Fpaper\u002F2024\u002Ffile\u002Fb71cfefae46909178603b5bc6c11d3ae-Paper-Conference.pdf",{"title":70,"url":71},"VectorChord documentation: indexing with MaxSim operators","https:\u002F\u002Fdocs.vectorchord.ai\u002Fvectorchord\u002Fusage\u002Findexing-with-maxsim-operators.html","\u002Fimages\u002Fblog\u002Fmultimodal-rag-colpali\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fmultimodal-rag-colpali\u002Fog.jpg","ai-engineer",[76,77,78],"en","de","hu","Multimodal RAG with ColPali: page images, multi-vector costs, and when they win","Multimodal RAG with ColPali: page-image embeddings, MaxSim scoring, multi-vector storage costs, compression options and when they beat parsed text.","A page split into small patches, a few linked to a magnifying glass.","Multimodal RAG with ColPali · Balázs Csorba",[84,85,86,87,88],"Page-image retrieval replaces OCR, layout detection, captioning and chunking with one vision-language encoder and a patch-level index.","MaxSim sums, for each query token, its best dot product over the page’s vectors. That makes scores explainable, but storage becomes the main cost.","A ColPali-style page carries about 1,030 vectors; in float16 that is roughly 257.5 KB per page, about 30 times a BGE-M3 chunk.","Pooling, binary or 4-bit quantization and a two-stage design of candidates then rerank bring the index into a workable range.","Page images win on tables, figures and scans; parsed text still wins on clean born-digital documents, exact filters and cheap citations.",[90,93,96,99,102],{"q":91,"a":92},"What is multimodal RAG with ColPali?","It is retrieval over rendered page images. A vision-language model such as PaliGemma encodes each page into about 1,030 patch vectors, and a query is scored against them with late-interaction MaxSim. For visually rich documents it replaces OCR, layout parsing and chunking.",{"q":94,"a":95},"How much storage does a ColPali index need?","The ColPali paper reports 257.5 KB per page in float16, roughly 30 times a BGE-M3 chunk. A million-page index with 1,024 vectors of 128 dimensions at float32 needs about 512 GB, and Qdrant’s quantization examples bring that to 16 GB at 1-bit before rescoring.",{"q":97,"a":98},"Is ColPali better than RAG over parsed text?","On ViDoRe v1 it scored 81.3 nDCG@5 against 67.0 for the best parsed-text pipeline in the paper, with the largest gaps on tables, figures and infographics. On clean born-digital text, parsed chunks are often as good and much cheaper to index and query.",{"q":100,"a":101},"Which vector databases support MaxSim?","Qdrant has a native multivector field with a max_sim comparator since v1.10.0, and Vespa expresses MaxSim as a tensor ranking expression. In Postgres, a MaxSim operator comes from the VectorChord extension, because pgvector has no native multivector type.",{"q":103,"a":104},"Can you use HNSW with multi-vector embeddings?","Not in the usual way. Qdrant’s docs note that HNSW is usually disabled for multivectors, so MaxSim scoring runs brute force over the candidates. Two-stage designs use a pooled or binary candidate stage and reserve exact MaxSim for the rerank.",[106,109,112,115,118,121,124,127,130],{"id":107,"title":108},"what-multimodal-rag-colpali-changes","What does multimodal RAG with ColPali replace?",{"id":110,"title":111},"how-late-interaction-maxsim-works","How does late-interaction MaxSim scoring work?",{"id":113,"title":114},"why-multivector-storage-explodes","Why does multi-vector storage get so large?",{"id":116,"title":117},"compression-and-two-stage-retrieval","How do you make multi-vector retrieval affordable?",{"id":119,"title":120},"serving-multivector-models","Which tools serve these models in 2026?",{"id":122,"title":123},"when-page-images-win-and-when-to-stay-text","When do page images beat parsed text?",{"id":125,"title":126},"vector-store-support","Which vector stores support multivectors?",{"id":128,"title":129},"decision-checklist","How do you decide, and what do you test first?",{"id":131,"title":132},"sources","Sources",[134,142,145,148,151,159,165,168,169,172,179,182,185,186,189,192,239,242,243,246,279,282,286,287,306,307,310,313,320,323,324,343,400,403,404,407,421,444,445],{"type":135,"content":136},"paragraph",[137,141],{"tag":138,"children":139},"strong",[140],"Multimodal RAG with ColPali"," changes the first stage of retrieval for documents whose meaning lives in layout: scanned forms, slide decks, tables and charts. Instead of parsing each page into text and chunks, you render the page as an image, run it through a vision-language model, and keep one embedding vector per image patch. A query is matched against those patch vectors with a late-interaction score called MaxSim. The pipeline loses its OCR, layout detection, captioning and chunking steps, and it gains a much larger index and a heavier query path.",{"type":135,"content":143},[144],"The trade is real in both directions. On ViDoRe v1, the page-level benchmark that ColPali introduced, the model scores 81.3 nDCG@5 against 67.0 for the best parsed-text pipeline in the paper, and the gap is widest on figures, infographics and tables. The same design costs roughly 260 KB of float16 storage per page and forces brute-force scoring at query time. This article walks through the mechanism, the storage math, the compression options that make it practical, the vector stores that support it, and the cases where parsed text still wins. Figures are as of October 2026 unless a source is dated otherwise.",{"type":146,"level":147,"id":107,"text":108},"heading",2,{"type":135,"content":149},[150],"It replaces the parse pipeline for visually rich pages. A conventional PDF pipeline runs layout detection, OCR, figure captioning and then chunking before a text embedding model sees anything. Each step adds latency and errors, and each is a place where a table can lose its column headers. The ColPali approach skips all of that. The page image goes straight into a vision-language model, and the output is a set of vectors that stay tied to image regions.",{"type":135,"content":152},[153,154,158],"The paper’s indexing numbers show the scale of the change. On one GCP g2-standard-8 machine with an NVIDIA L4, the parse path (layout 0.81 s, OCR 2.67 s, captioning 3.71 s, encoding 0.03 s) takes 7.22 s per page. ColPali takes 0.39 s per page and the SigLIP baseline 0.12 s. Skipping parsing is the single largest cost saving, and it also removes the OCR errors that would otherwise be baked into the index (",{"tag":155,"href":38,"children":156},"a",[157],"ColPali paper",").",{"type":160,"src":161,"alt":162,"wide":163,"caption":164},"image","\u002Fimages\u002Fblog\u002Fmultimodal-rag-colpali\u002Fdiagram-5.webp","Page-image indexing path Four boxes from left to right: the rendered page image goes into a vision-language encoder, which outputs about 1,030 vectors of 128 dimensions per page; these are stored as the page index for MaxSim scoring. No OCR, layout or chunking step appears.",true,"Indexing without parsing: one encoder pass per page produces a patch-vector matrix that MaxSim scores at query time.",{"type":135,"content":166},[167],"The trade is not free. The same page now produces about a thousand vectors instead of one or a few chunks, and the query side needs a vision-language encoder too. In the paper, query encoding takes about 30 ms at batch size one, against about 2 ms for BGE-M3, while late-interaction scoring adds roughly 1 ms per 1,000 pages. Indexing gets cheaper and queries get more expensive, and storage cost sits between the two.",{"type":146,"level":147,"id":110,"text":111},{"type":135,"content":170},[171],"MaxSim scores a query against a page by letting every query token find its best match among the page’s vectors, then summing those best matches. For each query token, take the maximum dot product over all page vectors, and add the maxima together. Pages are encoded once, offline. At query time only the query is encoded, and matching runs against the stored patch vectors. That is why the design is called late interaction: query and page meet only at scoring time, not inside the encoder.",{"type":135,"content":173},[174,175,178],"In ColPali, PaliGemma-3B with a SigLIP-So400m vision encoder splits each page into a 32 × 32 grid of 1,024 patches. Six instruction tokens are appended, and each of the 1,030 vectors is projected to 128 dimensions. The ",{"tag":155,"href":50,"children":176},[177],"Vespa write-up"," describes the same layout. The core of the scoring is short:",{"type":180,"code":181},"code","import numpy as np\n\ndef maxsim(query_vecs, page_vecs):\n    # query_vecs: (query_tokens, 128), page_vecs: (patches, 128)\n    sims = query_vecs @ page_vecs.T      # (query_tokens, patches)\n    return sims.max(axis=1).sum()        # best patch per query token, summed",{"type":135,"content":183},[184],"Because the score is a sum over query tokens of per-token maxima, it can also be inspected. You can see which patch won each query token and draw a heatmap over the page. That helps when debugging retrieval, and it shows a reader why a page was returned, which matters when the answer has to be cited.",{"type":146,"level":147,"id":113,"text":114},{"type":135,"content":187},[188],"A single-vector index stores one vector per document, so its size grows with the number of documents. A multi-vector index stores one vector per token or patch, so its size grows with documents times vectors per document. The ColPali paper reports 257.5 KB per page in float16, against 8.60 KB for a BGE-M3 chunk embedding. That is roughly 30 times the text figure, and the paper itself points to pooling and binarization as the remedy.",{"type":135,"content":190},[191],"Scale that to a million pages and the table shows the spread. The figures come from the storage analysis in the EVIE paper (arXiv 2610.11553), which compares current ColQwen-family checkpoints with a single 2048-dimension baseline.",{"type":193,"head":194,"rows":203},"table",[195,197,199,201],[196],"Index",[198],"Vectors per page",[200],"Dimension",[202],"Storage for 1M pages",[204,213,222,230],[205,207,209,211],[206],"single-vector baseline",[208],"1",[210],"2048",[212],"3.81 GiB",[214,216,218,220],[215],"colqwen3.5-4.5B-v3",[217],"768",[219],"320",[221],"457.76 GiB",[223,225,227,228],[224],"tomoro-colqwen3-embed-8b",[226],"1,280",[219],[229],"762.94 GiB",[231,233,235,237],[232],"nemotron-colembed-vl-8b-v2",[234],"2,304",[236],"4,096",[238],"17,578 GiB",{"type":135,"content":240},[241],"Two things follow. First, the vector count per page, not the dimension alone, drives cost, so a model with 2,304 vectors of 4,096 dimensions sits in a different storage class from one with 768 vectors of 320 dimensions. Second, HNSW graphs handle MaxSim poorly. The Qdrant docs note that HNSW is usually disabled for multivectors, so queries score candidates directly instead of walking a graph. That is workable for a few hundred candidate vectors per query and expensive for a full scan of a large corpus.",{"type":146,"level":147,"id":116,"text":117},{"type":135,"content":244},[245],"Three levers do most of the work: fewer vectors per page, fewer bits per vector, and a cheap first stage that narrows the candidate set before exact MaxSim runs. In practice teams combine them.",{"type":247,"ordered":248,"items":249},"list",false,[250,255,260,265,274],[251,254],{"tag":138,"children":252},[253],"Token pooling."," Averaging neighbouring patch vectors shrinks the count. ColPali’s own measurement shows that pool factor 3 removes 66.7% of vectors and keeps 97.8% of performance. Sentence Transformers v6 ships hierarchical token pooling as a first-class option; on its 4,874-passage NQ example, a pool factor of 3 cuts 608,414 vectors to 204,407 (311.5 MB to 104.7 MB, float32).",[256,259],{"tag":138,"children":257},[258],"Quantization."," Qdrant’s example of a million-document index with 1,024 × 128 vectors needs 512 GB at float32, and 16 GB at 1-bit, 21.3 GB at 1.5-bit and 32 GB at 2-bit, before rescoring. Qdrant’s turbo4 datatype stores vectors at 4 bits per dimension on disk; on five BEIR datasets with ColBERT multivectors it keeps 99.6% of float32 NDCG@20 through the same MaxSim rescoring path. Stacking 1-bit quantization on top of turbo4 cost more quality (recall@20 down 4.1%) and added 27.5% median latency.",[261,264],{"tag":138,"children":262},[263],"Binary with Hamming distance."," Vespa reports that binary vectors with Hamming distance save 32 times the storage and run about 3.5 times faster than float dot products. On DocVQA nDCG@5, the float baseline scores 52.4, binary-only 49.5, and binary with a float rerank 51.6.",[266,269,270,158],{"tag":138,"children":267},[268],"PLAID."," ColBERTv2’s residual compression engine, PLAID, cuts the late-interaction space footprint six to tenfold (",{"tag":155,"href":271,"children":272},"https:\u002F\u002Farxiv.org\u002Fabs\u002F2112.01488",[273],"ColBERTv2, arXiv 2112.01488",[275,278],{"tag":138,"children":276},[277],"MUVERA."," The NeurIPS 2024 paper converts each multi-vector set into a fixed-dimensional encoding, so a single-vector MIPS index can fetch candidates, followed by an exact MaxSim rerank. It reports about 10% higher recall and about 90% lower latency than PLAID.",{"type":135,"content":280},[281],"Two-stage retrieval is the shape that works. A 2024 Qdrant experiment on 20,000 pages pooled each page’s 1,030 vectors to 38, retrieved the top 200, and reranked those with full-resolution MaxSim. The post reports a 13x retrieval speedup. Treat that as one vendor’s 2024 benchmark rather than a universal constant. The structure is the point: the cheap stage decides recall, and the exact stage decides order.",{"type":160,"src":283,"alt":284,"wide":163,"caption":285},"\u002Fimages\u002Fblog\u002Fmultimodal-rag-colpali\u002Fdiagram-21.webp","Two-stage visual retrieval Four boxes from left to right: query tokens are encoded as one vector each and sent to a candidate stage that uses pooled or binary page vectors; the top 200 candidates go to a full-resolution MaxSim rerank, and the top 20 pages go to the generator.","Two-stage retrieval: a cheap candidate stage sets recall, and exact MaxSim sets the final order.",{"type":146,"level":147,"id":119,"text":120},{"type":135,"content":288},[289,290,293,294,297,298,301,302,305],"The paper’s own library, colpali-engine, is deprecated, and new projects are pointed to Sentence Transformers v6. Its ",{"tag":180,"children":291},[292],"MultiVectorEncoder"," loads ColPali, ColQwen2, PyLate and ColBERTv2 checkpoints and computes MaxSim with ",{"tag":180,"children":295},[296],"maxsim"," or ",{"tag":180,"children":299},[300],"meanmaxsim",". Sentence Transformers v6.0.0 requires transformers v5 and torch 2.2 or later. For serving at scale, vLLM has a ColQwen3 implementation with ",{"tag":180,"children":303},[304],"token_embed"," pooling and MaxSim scoring, so the encoder can run behind the same inference stack as the rest of the RAG system. Check licences before you ship: ColPali is under Gemma terms, the ColQwen2 and ColQwen2.5 checkpoints and colSmol are Apache-2.0, and the TomoroAI colqwen3 models are Apache-2.0.",{"type":146,"level":147,"id":122,"text":123},{"type":135,"content":308},[309],"Page images win when the answer depends on layout or on non-text content: a figure, a chart legend, a table with merged headers, a scanned form. On ViDoRe v1 the ColPali paper reports 79.1 against 35.7 on ArxivQA, 81.8 against 71.9 on InfoVQA and 83.9 against 69.1 on TabFQuAD (nDCG@5). That benchmark deliberately tests figures and tables, so the gaps reflect what it measures.",{"type":135,"content":311},[312],"The benchmarks have moved on. ViDoRe v1 is close to saturated, with top models above 90 nDCG@5. ViDoRe v2 adds blind contextual queries, long and cross-document queries, and four multilingual datasets. ViDoRe v3 (ACL 2026) is much harder: 10 datasets, about 26,000 pages and 3,099 human-verified queries in six languages. Visual retrievers beat textual ones and late interaction improves ranking, but current models still fail on non-textual elements and fine-grained visual grounding. The best reported score is about 66.75 nDCG@10 (EVIE-8B), against 61.60 for tomoro-colqwen3-embed-8b. Those are paper numbers. Check the model cards and the benchmark pages before quoting a leaderboard, because live views change.",{"type":314,"variant":315,"title":316,"body":317},"callout","warn","Stay with text when",[318],[319],"the text is born-digital and cleanly structured, you need exact keyword or field logic, you need citable text snippets, there is no GPU budget, or the corpus is small. A good parser and BM25 are cheaper to run and easier to debug in those cases. A hybrid is common: parsed text for the fields, page images for the tables and figures.",{"type":135,"content":321},[322],"Stay-with-text cases are real. Born-digital PDFs with clean text layers rarely need a vision model to find the right paragraph, and exact-match or field-level filters are easier to reason about over text. Parsed chunks also give you a span to cite. A few thousand pages on a CPU-only box is a poor fit for a multi-vector index. Scripts that stress OCR are a case to test, not a measured win. No ViDoRe split is a CJK corpus, so test those on your own pages.",{"type":146,"level":147,"id":125,"text":126},{"type":135,"content":325},[326,327,331,332,335,336,339,340,158],"Support is uneven. Qdrant has a native multivector field with a max_sim comparator since v1.10.0, and it enforces a limit where sub-vectors times dimensions stay below 1,048,576, which a 128-dimension ColPali page meets easily. Vespa expresses MaxSim as a tensor ranking expression and supports binary vectors with Hamming distance. In Postgres, pgvector has no native multivector type; its feature request, ",{"tag":155,"href":328,"children":329},"https:\u002F\u002Fgithub.com\u002Fpgvector\u002Fpgvector\u002Fissues\u002F970",[330],"issue 970",", documents the workarounds of one row per token and application-side MaxSim. VectorChord provides the production route, with vector arrays, an ",{"tag":180,"children":333},[334],"@#"," MaxSim operator and a ",{"tag":180,"children":337},[338],"vchordrq"," index (",{"tag":155,"href":71,"children":341},[342],"VectorChord docs",{"type":193,"head":344,"rows":355},[345,347,349,351,353],[346],"Store",[348],"Multi-vector primitive",[350],"Scoring",[352],"Index or compression",[354],"Caveat",[356,367,378,389],[357,359,361,363,365],[358],"Qdrant",[360],"multivector field, max_sim comparator (v1.10.0+)",[362],"MaxSim",[364],"HNSW usually off (m=0); quantization down to 1 bit, turbo4",[366],"sub-vectors × dimensions must stay below 1,048,576",[368,370,372,374,376],[369],"Vespa",[371],"tensor fields and ranking expressions",[373],"MaxSim as a tensor expression",[375],"binary vectors with Hamming distance",[377],"no PLAID; centroid selection does not suit real-time indexing",[379,381,383,385,387],[380],"Postgres with VectorChord",[382],"vector(n)[] columns",[384],"@# operator",[386],"vchordrq index",[388],"an extension, not core Postgres",[390,392,394,396,398],[391],"pgvector",[393],"no native type",[395],"MaxSim in the application (one row per token)",[397],"none",[399],"issue 970 documents the workarounds",{"type":135,"content":401},[402],"The table reflects only what the linked sources document. Check the current release of each product before you commit to a feature.",{"type":146,"level":147,"id":128,"text":129},{"type":135,"content":405},[406],"Start with your own pages, not a leaderboard. Build a small evaluation set of 100 to 300 real questions with page-level labels, run parsed text and page images through the same retrieval harness, and compare recall at the cut-off your generator actually uses. Then check these items:",{"type":247,"ordered":163,"items":408},[409,411,413,415,417,419],[410],"Corpus size and growth: multiply pages by vectors per page and bytes per vector before you pick a store.",[412],"Page mix: how many pages depend on tables, figures or scans, and how many are clean born-digital text.",[414],"GPU budget: in the paper’s setup, query encoding costs roughly 15 times the text path, so plan for it on the query path, not only at indexing.",[416],"Reranking: decide whether a candidate stage with pooled or binary vectors will feed an exact MaxSim rerank.",[418],"Licences: confirm the checkpoint’s licence allows your use.",[420],"Citations: confirm the answer can point to a page region, and return the page image alongside the answer.",{"type":135,"content":422},[423,424,429,430,434,435,438,439,443],"If I built a demo of this, I would start with a search box over rendered pages on my own Nuxt site, where I already run LLM features. That is a plan, not a running system. For the text baseline, read ",{"tag":425,"to":426,"children":427},"link","\u002Fblog\u002Fpdf-document-parsing-for-rag",[428],"parsing PDFs for RAG"," and ",{"tag":425,"to":431,"children":432},"\u002Fblog\u002Fembedding-quantization-binary-matryoshka",[433],"embedding quantization with binary and Matryoshka",". For the store side, ",{"tag":425,"to":436,"children":437},"\u002Fblog\u002Fqdrant",[358]," covers the single-vector setup that remains the default. My AI engineering work is summarized on the ",{"tag":425,"to":440,"children":441},"\u002Fexpertise\u002Fai-engineer",[442],"AI engineer"," page.",{"type":146,"level":147,"id":131,"text":132},{"type":247,"ordered":163,"items":446},[447,450,453,456,459,462,465,468,471,474,477,480],[448],{"tag":155,"href":38,"children":449},[37],[451],{"tag":155,"href":41,"children":452},[40],[454],{"tag":155,"href":44,"children":455},[43],[457],{"tag":155,"href":47,"children":458},[46],[460],{"tag":155,"href":50,"children":461},[49],[463],{"tag":155,"href":53,"children":464},[52],[466],{"tag":155,"href":56,"children":467},[55],[469],{"tag":155,"href":59,"children":470},[58],[472],{"tag":155,"href":62,"children":473},[61],[475],{"tag":155,"href":65,"children":476},[64],[478],{"tag":155,"href":68,"children":479},[67],[481],{"tag":155,"href":71,"children":482},[70],[484,560,617,675],{"slug":485,"published":486,"minutes":487,"category":7,"tags":488,"keywords":494,"about":507,"sources":517,"cover":554,"og":555,"expertise":74,"locales":556,"lang":76,"title":557,"description":558,"coverAlt":559},"embedding-model-selection-2026","2026-10-17",9,[489,490,491,492,493],"Embeddings","RAG","MTEB","Vector search","Model selection",[495,496,497,498,499,500,501,502,503,504,505,506],"best embedding model 2026","how to choose an embedding model","embedding model comparison","MTEB leaderboard explained","RTEB benchmark","open source embedding model","multilingual embedding model","voyage-4 vs openai embeddings","Qwen3-Embedding","EmbeddingGemma","embedding model for RAG","switching embedding models re-embed",[508,511,514],{"name":509,"url":510},"Word embedding","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FWord_embedding",{"name":512,"url":513},"Information retrieval","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FInformation_retrieval",{"name":515,"url":516},"Discounted cumulative gain","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FDiscounted_cumulative_gain",[518,521,524,527,530,533,536,539,542,545,548,551],{"title":519,"url":520},"Enevoldsen et al.: MMTEB, Massive Multilingual Text Embedding Benchmark (2025)","https:\u002F\u002Farxiv.org\u002Fabs\u002F2502.13595",{"title":522,"url":523},"Hugging Face: Introducing RTEB, a new standard for retrieval evaluation (Oct 2025)","https:\u002F\u002Fhuggingface.co\u002Fblog\u002Frteb",{"title":525,"url":526},"OpenAI: Vector embeddings guide","https:\u002F\u002Fdevelopers.openai.com\u002Fapi\u002Fdocs\u002Fguides\u002Fembeddings",{"title":528,"url":529},"OpenAI: API pricing","https:\u002F\u002Fdevelopers.openai.com\u002Fapi\u002Fdocs\u002Fpricing",{"title":531,"url":532},"Voyage AI: The Voyage 4 model family, shared embedding space with MoE architecture (Jan 2026)","https:\u002F\u002Fblog.voyageai.com\u002F2026\u002F01\u002F15\u002Fvoyage-4\u002F",{"title":534,"url":535},"Voyage AI: Text embeddings documentation","https:\u002F\u002Fdocs.voyageai.com\u002Fdocs\u002Fembeddings",{"title":537,"url":538},"Voyage AI: Pricing","https:\u002F\u002Fdocs.voyageai.com\u002Fdocs\u002Fpricing",{"title":540,"url":541},"Google: Gemini API embeddings documentation","https:\u002F\u002Fai.google.dev\u002Fgemini-api\u002Fdocs\u002Fembeddings",{"title":543,"url":544},"Google: Gemini API pricing","https:\u002F\u002Fai.google.dev\u002Fgemini-api\u002Fdocs\u002Fpricing",{"title":546,"url":547},"Cohere: Embed models documentation","https:\u002F\u002Fdocs.cohere.com\u002Fdocs\u002Fcohere-embed",{"title":549,"url":550},"Qwen: Qwen3-Embedding-8B model card","https:\u002F\u002Fhuggingface.co\u002FQwen\u002FQwen3-Embedding-8B",{"title":552,"url":553},"Google Developers Blog: Introducing EmbeddingGemma (Sep 2025)","https:\u002F\u002Fdevelopers.googleblog.com\u002Fen\u002Fintroducing-embeddinggemma\u002F","\u002Fimages\u002Fblog\u002Fembedding-model-selection-2026\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fembedding-model-selection-2026\u002Fog.jpg",[76,77,78],"Choosing an embedding model in 2026: leaderboards, costs and a bake-off on your own data","How to pick an embedding model for RAG in 2026: what MTEB and RTEB tell you, hosted vs open weights, prices, dimensions, and a one-week bake-off.","Three columns of stacked blocks, the middle tallest, each measured by a short bar and a wide bracket.",{"slug":561,"published":486,"minutes":6,"category":7,"tags":562,"keywords":566,"about":578,"sources":586,"cover":611,"og":612,"expertise":74,"locales":613,"lang":76,"title":614,"description":615,"coverAlt":616},"contextual-retrieval-late-chunking",[490,563,489,564,565],"Chunking","Contextual retrieval","Late chunking",[567,568,569,570,571,572,573,574,575,576,577],"contextual retrieval","anthropic contextual retrieval","late chunking","contextual chunk embeddings","contextual embeddings rag","contextual bm25","chunk context rag","voyage-context-3","voyage-context-4","late chunking vs contextual retrieval","rag chunking context loss",[579,580,583],{"name":27,"url":28},{"name":581,"url":582},"Okapi BM25","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FOkapi_BM25",{"name":584,"url":585},"Sentence embedding","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FSentence_embedding",[587,590,593,596,599,602,605,608],{"title":588,"url":589},"Anthropic: Introducing Contextual Retrieval (Sep 2024)","https:\u002F\u002Fwww.anthropic.com\u002Fnews\u002Fcontextual-retrieval",{"title":591,"url":592},"Günther et al.: Late Chunking, Contextual Chunk Embeddings Using Long-Context Embedding Models (2024, rev. 2025)","https:\u002F\u002Farxiv.org\u002Fabs\u002F2409.04701",{"title":594,"url":595},"Jina AI: Late Chunking in Long-Context Embedding Models (Aug 2024)","https:\u002F\u002Fjina.ai\u002Fnews\u002Flate-chunking-in-long-context-embedding-models\u002F",{"title":597,"url":598},"Voyage AI: Introducing voyage-context-3 (Jul 2025)","https:\u002F\u002Fblog.voyageai.com\u002F2025\u002F07\u002F23\u002Fvoyage-context-3\u002F",{"title":600,"url":601},"Voyage AI: voyage-context-4 (Jun 2026)","https:\u002F\u002Fblog.voyageai.com\u002F2026\u002F06\u002F29\u002Fvoyage-context-4\u002F",{"title":603,"url":604},"Voyage AI: Contextualized chunk embeddings documentation","https:\u002F\u002Fdocs.voyageai.com\u002Fdocs\u002Fcontextualized-chunk-embeddings",{"title":606,"url":607},"Anthropic: Claude API pricing","https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fabout-claude\u002Fpricing",{"title":609,"url":610},"Qu, Tu and Bao: Is Semantic Chunking Worth the Computational Cost? (2024)","https:\u002F\u002Farxiv.org\u002Fabs\u002F2410.13070","\u002Fimages\u002Fblog\u002Fcontextual-retrieval-late-chunking\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fcontextual-retrieval-late-chunking\u002Fog.jpg",[76,77,78],"Contextual retrieval and late chunking: giving RAG chunks back their context","Chunks lose their document. How contextual retrieval, late chunking and contextualized embedding models fix that, what each costs, and when to skip it.","Four loose square pieces gathered by a wide bracket below, each joined upward to a large sheet.",{"slug":618,"published":486,"minutes":487,"category":7,"tags":619,"keywords":623,"about":636,"sources":644,"cover":669,"og":670,"expertise":74,"locales":671,"lang":76,"title":672,"description":673,"coverAlt":674},"rag-access-control-permissions",[490,620,621,622,492],"Access control","Security","Multi-tenancy",[624,625,626,627,628,629,630,631,632,633,634,635],"rag access control","permission aware rag","document level security rag","rag multi tenancy","vector database access control","pgvector row level security","security trimming azure ai search","openfga rag authorization","qdrant multitenancy","pinecone namespaces multitenancy","owasp llm08 vector and embedding weaknesses","rag data leakage",[637,640,643],{"name":638,"url":639},"Access-control list","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FAccess-control_list",{"name":641,"url":642},"Multitenancy","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FMultitenancy",{"name":27,"url":28},[645,648,651,654,657,660,663,666],{"title":646,"url":647},"OWASP GenAI Security Project: LLM08:2025 Vector and Embedding Weaknesses","https:\u002F\u002Fgenai.owasp.org\u002Fllmrisk\u002Fllm082025-vector-and-embedding-weaknesses\u002F",{"title":649,"url":650},"PostgreSQL documentation: Row Security Policies","https:\u002F\u002Fwww.postgresql.org\u002Fdocs\u002Fcurrent\u002Fddl-rowsecurity.html",{"title":652,"url":653},"pgvector README: filtering and iterative index scans","https:\u002F\u002Fgithub.com\u002Fpgvector\u002Fpgvector",{"title":655,"url":656},"Qdrant: Multitenancy and partitions guide","https:\u002F\u002Fqdrant.tech\u002Fdocumentation\u002Fguides\u002Fmultiple-partitions\u002F",{"title":658,"url":659},"Pinecone: Implement multitenancy using namespaces","https:\u002F\u002Fdocs.pinecone.io\u002Fguides\u002Findex-data\u002Fimplement-multitenancy",{"title":661,"url":662},"Microsoft Learn: Document-level access control in Azure AI Search","https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fazure\u002Fsearch\u002Fsearch-document-level-access-overview",{"title":664,"url":665},"OpenFGA: RAG authorization use case","https:\u002F\u002Fopenfga.dev\u002Fdocs\u002Fuse-cases\u002Frag-authorization",{"title":667,"url":668},"Morris et al.: Text Embeddings Reveal (Almost) As Much As Text (EMNLP 2023)","https:\u002F\u002Farxiv.org\u002Fabs\u002F2310.06816","\u002Fimages\u002Fblog\u002Frag-access-control-permissions\u002Fcover.webp","\u002Fimages\u002Fblog\u002Frag-access-control-permissions\u002Fog.jpg",[76,77,78],"Access control for RAG: permission-aware retrieval without leaking documents","How RAG assistants leak documents and how to stop it: ACLs on every chunk, pre-filtering, row-level security in pgvector, permission sync and leak tests.","Seven cards in a row, six with a lock badge, one bare card sending an arrow outward.",{"slug":676,"published":486,"minutes":6,"category":7,"tags":677,"keywords":682,"about":694,"sources":702,"cover":729,"og":730,"expertise":731,"locales":732,"lang":76,"title":733,"description":734,"coverAlt":735},"rag-product-catalog-pim-data",[490,678,679,680,681],"PIM","Product data","B2B e-commerce","Metadata filtering",[683,684,685,686,687,688,689,690,691,692,693],"rag product catalog","rag pim data","llm product data","product catalog chatbot","akeneo rag","pimcore ai search","rag structured data","metadata filtering rag","product attributes embeddings","b2b product assistant","etim classification ai",[695,698,699],{"name":696,"url":697},"Product information management","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FProduct_information_management",{"name":27,"url":28},{"name":700,"url":701},"ETIM (standard)","https:\u002F\u002Fwww.etim-international.com\u002Fclassification\u002F",[703,706,709,712,714,717,720,723,726],{"title":704,"url":705},"Akeneo API: Products, product values, metric values and product models","https:\u002F\u002Fapi.akeneo.com\u002Fconcepts\u002Fproducts.html",{"title":707,"url":708},"Akeneo Help Center: What about products with variants?","https:\u002F\u002Fhelp.akeneo.com\u002Fserenity-take-the-power-over-your-products\u002Fserenity-what-about-products-with-variants",{"title":710,"url":711},"Pimcore documentation: Classification Store","https:\u002F\u002Fdocs.pimcore.com\u002Fplatform\u002FPimcore\u002FObjects\u002FObject_Classes\u002FData_Types\u002FClassification_Store\u002F",{"title":713,"url":701},"ETIM International: Classification",{"title":715,"url":716},"ETIM International: ETIM releases and the IXF format","https:\u002F\u002Fetim-international.com\u002F?p=754",{"title":718,"url":719},"Reddy et al.: Shopping Queries Dataset, a large-scale ESCI benchmark for improving product search (2022)","https:\u002F\u002Farxiv.org\u002Fabs\u002F2206.06588",{"title":721,"url":722},"Amazon Science: esci-data repository","https:\u002F\u002Fgithub.com\u002Famazon-science\u002Fesci-data",{"title":724,"url":725},"Qdrant documentation: Filtering","https:\u002F\u002Fqdrant.tech\u002Fdocumentation\u002Fconcepts\u002Ffiltering\u002F",{"title":727,"url":728},"Sui et al.: Table Meets LLM, can large language models understand structured table data? (WSDM 2024)","https:\u002F\u002Farxiv.org\u002Fabs\u002F2305.13062","\u002Fimages\u002Fblog\u002Frag-product-catalog-pim-data\u002Fcover.webp","\u002Fimages\u002Fblog\u002Frag-product-catalog-pim-data\u002Fog.jpg","b2b-ecommerce-developer",[76,77,78],"RAG over product catalogues: turning PIM data into answers that hold","Product data is structured, so chunking it like PDFs fails. How to serialize PIM attributes, route spec questions to filters and keep answers exact.","A frame of nine squares with tiny symbols, funnelling down to one card.",1792337027755]