[{"data":1,"prerenderedAt":718},["ShallowReactive",2],{"blog-knowledge-graph-extraction-llm-en":3},{"slug":4,"published":5,"updated":6,"minutes":7,"category":8,"tags":9,"keywords":15,"about":26,"sources":36,"cover":73,"og":74,"expertise":75,"locales":76,"lang":77,"title":80,"description":81,"coverAlt":82,"metaTitle":83,"takeaways":84,"faq":90,"toc":106,"blocks":137,"others":463},"knowledge-graph-extraction-llm","2026-09-25","2026-10-12",8,"rag",[10,11,12,13,14],"Knowledge graphs","GraphRAG","Entity resolution","RAG","Neo4j",[16,17,18,19,20,21,22,23,24,25],"knowledge graph extraction with LLMs","GraphRAG indexing","entity resolution knowledge graph","triple extraction prompt","ontology design for LLM extraction","entity deduplication embeddings","knowledge graph provenance","incremental knowledge graph updates","GraphRAG cost","Neo4j SimpleKGPipeline",[27,30,33],{"name":28,"url":29},"Knowledge graph","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FKnowledge_graph",{"name":31,"url":32},"Record linkage","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FRecord_linkage",{"name":34,"url":35},"Ontology (information science)","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FOntology_%28information_science%29",[37,40,43,46,49,52,55,58,61,64,67,70],{"title":38,"url":39},"Microsoft GraphRAG: default dataflow","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fgraphrag\u002Fblob\u002Fmain\u002Fdocs\u002Findex\u002Fdefault_dataflow.md",{"title":41,"url":42},"Microsoft GraphRAG on GitHub","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fgraphrag",{"title":44,"url":45},"Microsoft Research: LazyGraphRAG (Nov 2024)","https:\u002F\u002Fwww.microsoft.com\u002Fen-us\u002Fresearch\u002Fblog\u002Flazygraphrag-setting-a-new-standard-for-quality-and-cost\u002F",{"title":47,"url":48},"Microsoft Research: GraphRAG auto-tuning (Sep 2024)","https:\u002F\u002Fwww.microsoft.com\u002Fen-us\u002Fresearch\u002Fblog\u002Fgraphrag-auto-tuning-provides-rapid-adaptation-to-new-domains\u002F",{"title":50,"url":51},"neo4j-graphrag-python on GitHub","https:\u002F\u002Fgithub.com\u002Fneo4j\u002Fneo4j-graphrag-python",{"title":53,"url":54},"Neo4j GraphRAG: knowledge graph builder guide","https:\u002F\u002Fneo4j.com\u002Fdocs\u002Fneo4j-graphrag-python\u002Fcurrent\u002Fuser_guide_kg_builder.html",{"title":56,"url":57},"Splink on GitHub","https:\u002F\u002Fgithub.com\u002Fmoj-analytical-services\u002Fsplink",{"title":59,"url":60},"Google LangExtract on GitHub","https:\u002F\u002Fgithub.com\u002Fgoogle\u002Flangextract",{"title":62,"url":63},"KGGen (arXiv 2502.09956)","https:\u002F\u002Farxiv.org\u002Fabs\u002F2502.09956",{"title":65,"url":66},"GraphEval (arXiv 2407.10793)","https:\u002F\u002Farxiv.org\u002Fabs\u002F2407.10793",{"title":68,"url":69},"Zep temporal knowledge graph (arXiv 2501.13956)","https:\u002F\u002Farxiv.org\u002Fabs\u002F2501.13956",{"title":71,"url":72},"Kùzu on GitHub","https:\u002F\u002Fgithub.com\u002Fkuzudb\u002Fkuzu","\u002Fimages\u002Fblog\u002Fknowledge-graph-extraction-llm\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fknowledge-graph-extraction-llm\u002Fog.jpg","ai-engineer",[77,78,79],"en","de","hu","Knowledge graph extraction with LLMs: ontology, entity resolution, provenance","Building a knowledge graph with LLMs: a minimal ontology, extraction prompts, entity resolution, provenance, incremental updates, evaluation and storage.","Nodes leave a stack of pages and form a network where two circles merge into one.","Knowledge graph extraction with LLMs · Balázs Csorba",[85,86,87,88,89],"Building a graph with an LLM is parse, chunk, extract, resolve and load; the ontology and entity resolution decide quality far more than the model does.","The schema sets the size of the graph: on one podcast corpus, GraphRAG’s default prompt produced 1,796 entities and auto-tuned prompts 4,896.","GraphRAG’s built-in resolution is an exact match on title and type; real corpora need fuzzy or embedding matching plus an LLM or human decision for the uncertain pairs.","Keep the source text unit on every node and edge, so you can audit, delete and re-extract only what changed instead of rebuilding the whole graph.","Full GraphRAG indexing is expensive: Microsoft puts LazyGraphRAG indexing at 0.1 percent of its cost, so check whether a graph is worth it before paying for extraction.",[91,94,97,100,103],{"q":92,"a":93},"How do you build a knowledge graph with an LLM?","Split documents into text units, ask an LLM to extract entities and relationships from each unit against a defined schema, merge and deduplicate the entities, and load the result into a graph store with a link from every node and edge back to its source text. The schema and the deduplication step decide most of the quality.",{"q":95,"a":96},"What is entity resolution in a knowledge graph?","Deciding which extracted mentions refer to the same real-world entity, for example \"Siemens AG\", \"Siemens\" and \"the Munich-based supplier\". Options range from exact name matching through fuzzy and embedding similarity to LLM or human adjudication of uncertain pairs. Without it the graph fills with duplicate nodes.",{"q":98,"a":99},"How much does GraphRAG indexing cost?","Microsoft gives no absolute price, only relative figures: LazyGraphRAG indexing costs about the same as vector RAG and 0.1 percent of full GraphRAG indexing. Full indexing makes several LLM calls per text unit, so measure it on a sample of your corpus before indexing everything.",{"q":101,"a":102},"Should I let the LLM invent the schema?","Start with a small, fixed ontology of the entity and relation types you will actually query, and let the LLM fill it. Free-form extraction produces many types and near-duplicate relations that are hard to query. Neo4j’s pipeline can derive a schema once from the text and then reuse it for every chunk.",{"q":104,"a":105},"How do I keep a knowledge graph up to date?","Store the source text unit and document id on every node and edge, extract only new or changed documents, and resolve new entities against the existing graph rather than rebuilding it. Neo4j’s resolvers accept a filter query so re-runs touch only unresolved entities.",[107,110,113,116,119,122,125,128,131,134],{"id":108,"title":109},"what-it-takes-to-build-one","What it takes to build one",{"id":111,"title":112},"start-with-a-minimal-ontology","Start with a minimal ontology",{"id":114,"title":115},"the-extraction-step-in-practice","The extraction step in practice",{"id":117,"title":118},"entity-resolution-and-deduplication","Entity resolution and deduplication",{"id":120,"title":121},"provenance-and-incremental-updates","Provenance and incremental updates",{"id":123,"title":124},"cost","What it costs",{"id":126,"title":127},"evaluating-extraction-quality","Evaluating extraction quality",{"id":129,"title":130},"storage-choices","Storage choices",{"id":132,"title":133},"a-build-checklist","A build checklist",{"id":135,"title":136},"sources","Sources",[138,146,160,163,171,177,183,186,187,194,213,214,219,231,234,236,237,245,256,259,270,271,274,290,293,294,301,305,306,316,319,322,323,387,394,397,398,417,424,425],{"type":139,"content":140},"paragraph",[141,145],{"tag":142,"children":143},"strong",[144],"Knowledge graph extraction with LLMs"," turns unstructured documents into entities and typed relationships that a graph query or a GraphRAG system can use. The extraction call is the easy part; any capable model returns plausible triples. What decides whether the graph is useful is everything around it: a schema small enough to query, entity resolution that merges the same supplier written three ways, provenance that links every edge back to a sentence, and a cost model that survives re-extraction.",{"type":139,"content":147},[148,149,154,155,159],"This article covers the construction side: a minimal ontology, the extraction step, entity resolution, provenance and incremental updates, evaluation and storage. Whether you need a graph at all, rather than vector retrieval, is argued in ",{"tag":150,"to":151,"children":152},"link","\u002Fblog\u002Fgraphrag-knowledge-graph-rag",[153],"GraphRAG versus vector RAG",", and Microsoft’s tool is reviewed end to end in ",{"tag":150,"to":156,"children":157},"\u002Fblog\u002Fgraphrag",[158],"the GraphRAG review",". Versions and numbers are as of October 2026.",{"type":161,"level":162,"id":108,"text":109},"heading",2,{"type":139,"content":164},[165,166,170],"Every LLM-built graph follows the same pipeline: parse documents, split them into text units, extract entities and relationships per unit, merge and resolve duplicates, and load the result. Microsoft GraphRAG’s default dataflow is a clear reference: 1,200-token text units, per-unit extraction, merging of entities with identical title and type, summarized descriptions, optional claim extraction, then community detection and reports (",{"tag":167,"href":39,"children":168},"a",[169],"GraphRAG dataflow","). The text units are referenced by every extracted item, “providing provenance back to the original source text”.",{"type":172,"src":173,"alt":174,"wide":175,"caption":176},"image","\u002Fimages\u002Fblog\u002Fknowledge-graph-extraction-llm\u002Fdiagram-4.webp","Knowledge graph build pipeline Five steps from left to right: documents are split into text units, each with a provenance id; an LLM extracts entities and relationships per unit against a fixed schema; extracted items are merged and their descriptions summarized; entity resolution matches duplicates, first exactly, then fuzzily or by embeddings, with uncertain pairs adjudicated by an LLM or a person; and the clean graph is loaded with source ids on every node and edge.",true,"Quality is decided at two points: the schema before extraction and entity resolution before loading.",{"type":139,"content":178},[179,180,182],"Two stages decide most of the quality: the ontology, which defines what can be extracted, and entity resolution, which defines whether the result is one graph or a pile of near-duplicate nodes. The extraction model matters less than either. GraphRAG itself is now largely in maintenance mode, with its README describing it as a demonstration rather than an officially supported offering and warning that indexing can be expensive (",{"tag":167,"href":42,"children":181},[11],").",{"type":139,"content":184},[185],"A graph is worth building when the questions are about relationships rather than passages: which suppliers deliver parts certified to a given standard, which contracts reference a withdrawn regulation, which plants share a component. Vector retrieval answers “find text like this”; a graph answers “follow these links”. If your users mostly ask the first kind of question, the extraction cost below buys little.",{"type":161,"level":162,"id":111,"text":112},{"type":139,"content":188},[189,190,193],"Start with the few entity and relationship types you will actually query, because the schema determines both the size and the usefulness of the graph. Microsoft’s auto-tuning post shows how strongly: on the same podcast corpus with GPT-4-Turbo, GraphRAG’s default news-shaped prompt produced 1,796 entities, 2,851 relationships and 352 communities, while prompts auto-tuned to the domain produced 4,896, 8,210 and 1,027 (",{"tag":167,"href":48,"children":191},[192],"auto-tuning","). More is not automatically better; it is only better if the extra entities are ones your questions need.",{"type":139,"content":195},[196,197,201,202,205,206,209,210,212],"Neo4j’s official GraphRAG package makes the schema explicit: node types, relationship types and allowed patterns such as ",{"tag":198,"children":199},"code",[200],"(\"Supplier\",\"SUPPLIES\",\"Product\")",". With ",{"tag":198,"children":203},[204],"schema=\"EXTRACTED\"",", the default, an LLM derives a schema from the text once and reuses it for every chunk; with ",{"tag":198,"children":207},[208],"schema=\"FREE\""," there is no grounding at all (",{"tag":167,"href":54,"children":211},[14],"). For production, write the schema yourself, keep it under version control and treat a change as a migration. My Jira MCP server works on the same principle from the other side: a model given a small, typed surface of 20 tools stops guessing.",{"type":161,"level":162,"id":114,"text":115},{"type":139,"content":215},[216,217,182],"The extraction step is one LLM call per text unit that returns entities and relationships in a structured format, sometimes followed by extra passes to catch what the first one missed. Use structured output where the provider supports it: Neo4j’s pipeline validates results against a Pydantic graph model when the model offers structured output, instead of repairing JSON afterwards, and its graph pruner drops nodes and relationships that violate the schema or have no properties (",{"tag":167,"href":54,"children":218},[14],{"type":139,"content":220},[221,222,225,226,230],"Grounding is the other safeguard. Google’s LangExtract maps every extraction to its exact character span in the source, and an extraction the model cannot locate in the input gets no character interval and is meant to be filtered out (",{"tag":167,"href":60,"children":223},[224],"LangExtract","). That single rule removes most invented relations. The same pattern applies to product data, where a value without a source span should not reach the catalog, see ",{"tag":150,"to":227,"children":228},"\u002Fblog\u002Fllm-product-data-enrichment",[229],"LLM product data enrichment",".",{"type":139,"content":232},[233],"Chunk size matters more than it looks. Smaller units give the model less to read per call and tend to raise recall of entities, but they split relationships whose two ends sit in different paragraphs; larger units keep those together and cost more per call. GraphRAG’s default of 1,200 tokens is a reasonable start; adjust it only after measuring how many relationships cross unit boundaries in a sample of your documents.",{"type":198,"code":235},"# Sketch with neo4j-graphrag: fixed schema, extraction, then resolution limited to new entities\nfrom neo4j_graphrag.experimental.pipeline.kg_builder import SimpleKGPipeline\nfrom neo4j_graphrag.experimental.components.resolver import SinglePropertyExactMatchResolver\n\nschema = {\n    \"node_types\": [\"Supplier\", \"Product\", \"Standard\", \"Plant\"],\n    \"relationship_types\": [\"SUPPLIES\", \"COMPLIES_WITH\", \"PRODUCED_AT\"],\n    \"patterns\": [(\"Supplier\", \"SUPPLIES\", \"Product\"),\n                 (\"Product\", \"COMPLIES_WITH\", \"Standard\"),\n                 (\"Product\", \"PRODUCED_AT\", \"Plant\")],\n}\npipeline = SimpleKGPipeline(llm=llm, driver=driver, embedder=embedder, schema=schema, from_pdf=False)\nawait pipeline.run_async(text=document_text)            # chunks keep their ids in the lexical graph\n\nresolver = SinglePropertyExactMatchResolver(driver, filter_query=\"WHERE NOT entity:Resolved\")\nawait resolver.run()                                    # only touches entities from this run",{"type":161,"level":162,"id":117,"text":118},{"type":139,"content":238},[239,240,242,243,182],"Entity resolution decides whether “Siemens AG”, “Siemens” and “the Munich-based supplier” become one node or three. GraphRAG’s built-in logic merges only entities with an identical title and type (",{"tag":167,"href":39,"children":241},[169],"), which is fine for a demo and insufficient for real corpora. Neo4j’s package offers three resolvers: exact match on a property, semantic match with spaCy embeddings and cosine similarity, and fuzzy match with RapidFuzz, which is faster and less precise (",{"tag":167,"href":54,"children":244},[14],{"type":139,"content":246},[247,248,251,252,230],"A layered approach works best: merge exact matches automatically, propose fuzzy and embedding matches above a threshold, and send the uncertain middle band to an LLM with both candidates’ context or to a person. For entities with several structured fields, Splink’s probabilistic record linkage is mature and links about a million records on a laptop in about a minute, but its README notes it is not designed for a single column containing a “bag of words”, so name-only entity nodes are outside its sweet spot (",{"tag":167,"href":57,"children":249},[250],"Splink","). The same matching problem appears in product catalogs, see ",{"tag":150,"to":253,"children":254},"\u002Fblog\u002Fpim-data-quality-llm",[255],"PIM data quality with LLMs",{"type":139,"content":257},[258],"Blocking keeps resolution affordable. Comparing every entity with every other grows quadratically, so first group candidates by a cheap key such as entity type plus a normalized name prefix, or by nearest neighbours in embedding space, and compare only within those groups. Then decide the threshold on a labelled sample of pairs rather than by intuition, because the right cut-off differs for company names, product codes and people.",{"type":260,"variant":261,"title":262,"body":263},"callout","warn","Resolvers replace nodes",[264],[265,266,269],"Neo4j’s resolvers replace the nodes written by the pipeline, so resolution is not a read-only step. Run it in a way you can repeat: mark resolved entities, pass a filter query such as ",{"tag":198,"children":267},[268],"WHERE NOT entity:Resolved"," so re-runs only touch new ones, and keep the original mentions and their text units so a wrong merge can be undone.",{"type":161,"level":162,"id":120,"text":121},{"type":139,"content":272},[273],"Provenance is the spine that makes a graph maintainable. Keep the text unit id and the document id on every node and edge, so an answer can cite its sentence, a deleted document can remove exactly its contributions, and a changed document can be re-extracted without touching the rest. GraphRAG’s text units and Neo4j’s lexical graph, which links chunks to the entities extracted from them, both provide this structure.",{"type":139,"content":275},[276,277,281,282,285,286,230],"I could not confirm a documented incremental indexing mode in GraphRAG’s current docs; what is documented is bringing your own graph and running only the community workflows on it (",{"tag":167,"href":278,"children":279},"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fgraphrag\u002Fblob\u002Fmain\u002Fdocs\u002Findex\u002Fbyog.md",[280],"BYOG","). In practice, incremental means extracting only new or changed documents and resolving their entities against the existing graph. Graphs that track facts over time add a validity window per edge; Zep’s Graphiti engine maintains historical relationships this way for agent memory (",{"tag":167,"href":69,"children":283},[284],"Zep paper","), covered in ",{"tag":150,"to":287,"children":288},"\u002Fblog\u002Fzep",[289],"the Zep review",{"type":139,"content":291},[292],"Re-extraction is the cost to plan for. A change to the schema or the extraction prompt invalidates every triple produced under the old one, so pin prompts like code, record the prompt version on each extracted item, and budget a full re-extraction as a migration rather than a surprise.",{"type":161,"level":162,"id":123,"text":124},{"type":139,"content":295},[296,297,300],"Microsoft publishes no absolute price per document for GraphRAG, only relative figures, and they are large. LazyGraphRAG indexing costs about the same as vector RAG and 0.1 percent of full GraphRAG indexing, and LazyGraphRAG queries cost more than 700 times less than GraphRAG global search at comparable quality (",{"tag":167,"href":45,"children":298},[299],"LazyGraphRAG","). The practical rule is to extract a representative sample, measure tokens per document yourself, and multiply before committing to the full corpus.",{"type":172,"src":302,"alt":303,"wide":175,"caption":304},"\u002Fimages\u002Fblog\u002Fknowledge-graph-extraction-llm\u002Fdiagram-26.webp","Relative cost of building and querying a graph Four horizontal bars relative to LazyGraphRAG indexing. Vector RAG indexing costs about the same as LazyGraphRAG indexing, shown as one unit. Full GraphRAG indexing costs about a thousand times as much, since LazyGraphRAG is 0.1 percent of it. On the query side, GraphRAG global search costs more than 700 times a LazyGraphRAG query of comparable quality. A note says that a prompt or schema change means paying the extraction cost again.","Relative costs from Microsoft’s LazyGraphRAG post, on a log scale; no absolute price per document is published.",{"type":161,"level":162,"id":126,"text":127},{"type":139,"content":307},[308,309,312,313,182],"Extraction quality is an open research problem, not a solved one. KGGen’s authors note that automatically extracted graphs are of questionable quality and that human-made graphs to compare against are scarce; they add entity clustering to reduce sparsity and publish the MINE benchmark for text-to-graph extraction (",{"tag":167,"href":63,"children":310},[311],"KGGen","). GraphEval represents content as triples to locate likely hallucinations at triple level (",{"tag":167,"href":66,"children":314},[315],"GraphEval",{"type":139,"content":317},[318],"For your own graph, a simple protocol works: sample 50 triples per run, have a person mark each as correct, wrong or unsupported by its source span, and track that precision across prompt and schema versions. An LLM judge can pre-screen, but calibrate it against the human labels first. Log per run the number of entities, relationships, merges, rejected ungrounded triples and the prompt version, so a sudden jump is visible.",{"type":139,"content":320},[321],"Evaluate the graph on the questions it exists for, too. Write ten to twenty relationship questions with known answers, run them through your graph queries or GraphRAG search after each rebuild, and compare. Triple precision tells you whether the extraction is correct; question accuracy tells you whether the schema and resolution produced a graph that can answer what you built it for.",{"type":161,"level":162,"id":129,"text":130},{"type":324,"head":325,"rows":335},"table",[326,328,330,332,334],[327],"Component",[329],"Role",[331],"License",[333],"Provenance",[12],[336,347,358,367,376],[337,339,341,343,345],[338],"Microsoft GraphRAG 3.3",[340],"full pipeline, maintenance mode",[342],"MIT",[344],"text units",[346],"exact title and type",[348,350,352,354,356],[349],"neo4j-graphrag",[351],"composable KG builder",[353],"Apache-2.0",[355],"lexical graph",[357],"exact, spaCy semantic, fuzzy",[359,360,362,363,365],[224],[361],"grounded extraction",[353],[364],"character spans",[366],"none built in",[368,369,371,372,374],[250],[370],"record linkage",[342],[373],"n\u002Fa",[375],"probabilistic, multi-field",[377,379,381,383,385],[378],"Neo4j, Kùzu, NetworkX",[380],"graph storage",[382],"varies; Kùzu archived",[384],"as properties",[386],"via your pipeline",{"type":139,"content":388},[389,390,393],"For storage, Neo4j is the common server choice and the one the official GraphRAG package targets. Kùzu, an MIT-licensed embedded graph database that was attractive for local pipelines, has been archived, with its README announcing the team is working on something new (",{"tag":167,"href":72,"children":391},[392],"Kùzu","), so do not start new work on it. For small graphs or experiments, NetworkX in memory with Parquet files on disk is enough, and GraphRAG itself writes Parquet tables you can load into any of them.",{"type":139,"content":395},[396],"Whichever store you pick, keep the extracted entities and relationships as plain files next to it, with their prompt version and source ids. That export is what lets you rebuild the store, switch engines or rerun resolution without paying for extraction again.",{"type":161,"level":162,"id":132,"text":133},{"type":399,"ordered":175,"items":400},"list",[401,403,405,407,409,411,413,415],[402],"Write a minimal schema from the questions you will ask, and version it.",[404],"Pin extraction prompts like code and record the version on every item.",[406],"Use structured output and drop triples without a source span.",[408],"Resolve entities in layers and keep the original mentions.",[410],"Keep text unit and document ids on every node and edge.",[412],"Measure precision on 50 sampled triples per run.",[414],"Price extraction on a sample before indexing the whole corpus.",[416],"Extract only new or changed documents and resolve against the existing graph.",{"type":139,"content":418},[419,420,230],"If you are building a knowledge graph from documents and want it to stay clean after the first demo, see my ",{"tag":150,"to":421,"children":422},"\u002Fexpertise\u002Fai-engineer",[423],"AI engineering work",{"type":161,"level":162,"id":135,"text":136},{"type":399,"ordered":175,"items":426},[427,430,433,436,439,442,445,448,451,454,457,460],[428],{"tag":167,"href":39,"children":429},[38],[431],{"tag":167,"href":42,"children":432},[41],[434],{"tag":167,"href":45,"children":435},[44],[437],{"tag":167,"href":48,"children":438},[47],[440],{"tag":167,"href":51,"children":441},[50],[443],{"tag":167,"href":54,"children":444},[53],[446],{"tag":167,"href":57,"children":447},[56],[449],{"tag":167,"href":60,"children":450},[59],[452],{"tag":167,"href":63,"children":453},[62],[455],{"tag":167,"href":66,"children":456},[65],[458],{"tag":167,"href":69,"children":459},[68],[461],{"tag":167,"href":72,"children":462},[71],[464,539,599,657],{"slug":465,"published":466,"minutes":467,"category":8,"tags":468,"keywords":473,"about":486,"sources":496,"cover":533,"og":534,"expertise":75,"locales":535,"lang":77,"title":536,"description":537,"coverAlt":538},"embedding-model-selection-2026","2026-10-17",9,[469,13,470,471,472],"Embeddings","MTEB","Vector search","Model selection",[474,475,476,477,478,479,480,481,482,483,484,485],"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",[487,490,493],{"name":488,"url":489},"Word embedding","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FWord_embedding",{"name":491,"url":492},"Information retrieval","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FInformation_retrieval",{"name":494,"url":495},"Discounted cumulative gain","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FDiscounted_cumulative_gain",[497,500,503,506,509,512,515,518,521,524,527,530],{"title":498,"url":499},"Enevoldsen et al.: MMTEB, Massive Multilingual Text Embedding Benchmark (2025)","https:\u002F\u002Farxiv.org\u002Fabs\u002F2502.13595",{"title":501,"url":502},"Hugging Face: Introducing RTEB, a new standard for retrieval evaluation (Oct 2025)","https:\u002F\u002Fhuggingface.co\u002Fblog\u002Frteb",{"title":504,"url":505},"OpenAI: Vector embeddings guide","https:\u002F\u002Fdevelopers.openai.com\u002Fapi\u002Fdocs\u002Fguides\u002Fembeddings",{"title":507,"url":508},"OpenAI: API pricing","https:\u002F\u002Fdevelopers.openai.com\u002Fapi\u002Fdocs\u002Fpricing",{"title":510,"url":511},"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":513,"url":514},"Voyage AI: Text embeddings documentation","https:\u002F\u002Fdocs.voyageai.com\u002Fdocs\u002Fembeddings",{"title":516,"url":517},"Voyage AI: Pricing","https:\u002F\u002Fdocs.voyageai.com\u002Fdocs\u002Fpricing",{"title":519,"url":520},"Google: Gemini API embeddings documentation","https:\u002F\u002Fai.google.dev\u002Fgemini-api\u002Fdocs\u002Fembeddings",{"title":522,"url":523},"Google: Gemini API pricing","https:\u002F\u002Fai.google.dev\u002Fgemini-api\u002Fdocs\u002Fpricing",{"title":525,"url":526},"Cohere: Embed models documentation","https:\u002F\u002Fdocs.cohere.com\u002Fdocs\u002Fcohere-embed",{"title":528,"url":529},"Qwen: Qwen3-Embedding-8B model card","https:\u002F\u002Fhuggingface.co\u002FQwen\u002FQwen3-Embedding-8B",{"title":531,"url":532},"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",[77,78,79],"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":540,"published":466,"minutes":541,"category":8,"tags":542,"keywords":546,"about":558,"sources":568,"cover":593,"og":594,"expertise":75,"locales":595,"lang":77,"title":596,"description":597,"coverAlt":598},"contextual-retrieval-late-chunking",10,[13,543,469,544,545],"Chunking","Contextual retrieval","Late chunking",[547,548,549,550,551,552,553,554,555,556,557],"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",[559,562,565],{"name":560,"url":561},"Retrieval-augmented generation","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FRetrieval-augmented_generation",{"name":563,"url":564},"Okapi BM25","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FOkapi_BM25",{"name":566,"url":567},"Sentence embedding","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FSentence_embedding",[569,572,575,578,581,584,587,590],{"title":570,"url":571},"Anthropic: Introducing Contextual Retrieval (Sep 2024)","https:\u002F\u002Fwww.anthropic.com\u002Fnews\u002Fcontextual-retrieval",{"title":573,"url":574},"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":576,"url":577},"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":579,"url":580},"Voyage AI: Introducing voyage-context-3 (Jul 2025)","https:\u002F\u002Fblog.voyageai.com\u002F2025\u002F07\u002F23\u002Fvoyage-context-3\u002F",{"title":582,"url":583},"Voyage AI: voyage-context-4 (Jun 2026)","https:\u002F\u002Fblog.voyageai.com\u002F2026\u002F06\u002F29\u002Fvoyage-context-4\u002F",{"title":585,"url":586},"Voyage AI: Contextualized chunk embeddings documentation","https:\u002F\u002Fdocs.voyageai.com\u002Fdocs\u002Fcontextualized-chunk-embeddings",{"title":588,"url":589},"Anthropic: Claude API pricing","https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fabout-claude\u002Fpricing",{"title":591,"url":592},"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",[77,78,79],"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":600,"published":466,"minutes":467,"category":8,"tags":601,"keywords":605,"about":618,"sources":626,"cover":651,"og":652,"expertise":75,"locales":653,"lang":77,"title":654,"description":655,"coverAlt":656},"rag-access-control-permissions",[13,602,603,604,471],"Access control","Security","Multi-tenancy",[606,607,608,609,610,611,612,613,614,615,616,617],"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",[619,622,625],{"name":620,"url":621},"Access-control list","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FAccess-control_list",{"name":623,"url":624},"Multitenancy","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FMultitenancy",{"name":560,"url":561},[627,630,633,636,639,642,645,648],{"title":628,"url":629},"OWASP GenAI Security Project: LLM08:2025 Vector and Embedding Weaknesses","https:\u002F\u002Fgenai.owasp.org\u002Fllmrisk\u002Fllm082025-vector-and-embedding-weaknesses\u002F",{"title":631,"url":632},"PostgreSQL documentation: Row Security Policies","https:\u002F\u002Fwww.postgresql.org\u002Fdocs\u002Fcurrent\u002Fddl-rowsecurity.html",{"title":634,"url":635},"pgvector README: filtering and iterative index scans","https:\u002F\u002Fgithub.com\u002Fpgvector\u002Fpgvector",{"title":637,"url":638},"Qdrant: Multitenancy and partitions guide","https:\u002F\u002Fqdrant.tech\u002Fdocumentation\u002Fguides\u002Fmultiple-partitions\u002F",{"title":640,"url":641},"Pinecone: Implement multitenancy using namespaces","https:\u002F\u002Fdocs.pinecone.io\u002Fguides\u002Findex-data\u002Fimplement-multitenancy",{"title":643,"url":644},"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":646,"url":647},"OpenFGA: RAG authorization use case","https:\u002F\u002Fopenfga.dev\u002Fdocs\u002Fuse-cases\u002Frag-authorization",{"title":649,"url":650},"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",[77,78,79],"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":658,"published":466,"minutes":541,"category":8,"tags":659,"keywords":664,"about":676,"sources":684,"cover":711,"og":712,"expertise":713,"locales":714,"lang":77,"title":715,"description":716,"coverAlt":717},"rag-product-catalog-pim-data",[13,660,661,662,663],"PIM","Product data","B2B e-commerce","Metadata filtering",[665,666,667,668,669,670,671,672,673,674,675],"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",[677,680,681],{"name":678,"url":679},"Product information management","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FProduct_information_management",{"name":560,"url":561},{"name":682,"url":683},"ETIM (standard)","https:\u002F\u002Fwww.etim-international.com\u002Fclassification\u002F",[685,688,691,694,696,699,702,705,708],{"title":686,"url":687},"Akeneo API: Products, product values, metric values and product models","https:\u002F\u002Fapi.akeneo.com\u002Fconcepts\u002Fproducts.html",{"title":689,"url":690},"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":692,"url":693},"Pimcore documentation: Classification Store","https:\u002F\u002Fdocs.pimcore.com\u002Fplatform\u002FPimcore\u002FObjects\u002FObject_Classes\u002FData_Types\u002FClassification_Store\u002F",{"title":695,"url":683},"ETIM International: Classification",{"title":697,"url":698},"ETIM International: ETIM releases and the IXF format","https:\u002F\u002Fetim-international.com\u002F?p=754",{"title":700,"url":701},"Reddy et al.: Shopping Queries Dataset, a large-scale ESCI benchmark for improving product search (2022)","https:\u002F\u002Farxiv.org\u002Fabs\u002F2206.06588",{"title":703,"url":704},"Amazon Science: esci-data repository","https:\u002F\u002Fgithub.com\u002Famazon-science\u002Fesci-data",{"title":706,"url":707},"Qdrant documentation: Filtering","https:\u002F\u002Fqdrant.tech\u002Fdocumentation\u002Fconcepts\u002Ffiltering\u002F",{"title":709,"url":710},"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",[77,78,79],"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.",1792342719218]