Noisy Text in RAG: Typos, OCR, and the Gap Classical Spell-Check Leaves

Noisy Text in RAG: Typos, OCR, and the Gap Classical Spell-Check Leaves

The user types “assurance décénale” and the document says “décennale.” One missing letter, and a literal search finds nothing. Real questions arrive with typos, and real documents have their own; before retrieval can match anything, someone has to fix the spelling on both sides.This article is a bonus in Enterprise Document Intelligence, a series that builds an enterprise RAG system from four bricks. It tackles noisy text across the pipeline: user typos, fast-typing transcription noise, OCR character errors, what classical spell-check fixes, and what embeddings have to carry.🧭 New to the series? Every article in this series sits on our two Towards Data Science author pages, Angela Shi and Kezhan Shi. That is the shortest way to see what is covered and where this one sits.where this article sits in the series: a bonus article alongside the numbered spine - Image by author📓 Runnable companion notebooks are on GitHub: doc-intel/notebooks-vol1.The public companion-code repo at doc-intel/notebooks-vol1 - Image by authorThe same problem shows up on both sides of a pipeline. On the question side, type “wat is teh covarge for fyre damge?” into a chatbot built over a company knowledge base: three typos and a missing letter, and the chatbot returns nothing useful until the question is retyped carefully. On the document side, dump 50,000 customer support tickets into the same pipeline for retrieval: half of them are written in fragments, abbreviations, mixed case, with the same kind of errors, and the pipeline that worked for clean queries against clean documents starts returning noise.This is the noisy-text problem in enterprise RAG. It looks like a spell-check problem from the outside, but the actual cause splits three ways. The user mistyped a word (a typo). The user typed under pressure on mobile and scrambled boundaries, dropped accents, abbreviated (transcription noise). The document came through OCR and a scanner silently replaced O with 0, broke a fi ligature, split policyholder into policy holder (OCR noise). All three end with the same symptom downstream: a token in the query or in the document does not literally match what it should, even though the meaning is intact. The classical spell-correction toolbox was built for one of the three. The other two are the ones that hurt enterprise pipelines, and the ones embeddings are quietly built to absorb.Three noise sources, one symptom: a token that does not literally match, and spell-check catches only the first - Image by author1. Forty years of classical spell-correctionBefore embeddings and LLMs, spell-correction was a solved engineering problem. Five techniques cover most of what ran in production between 1980 and today, all with mature Python libraries (rapidfuzz, jellyfish, symspellpy, pybktree). The next subsections walk through each, then close with the case where this toolbox solves the problem.1.1 Levenshtein distanceThe minimum number of single-character edits (insert, delete, substitute) needed to turn one word into another. The foundation under almost every spell-checker built in the last forty years.A misspelled word’s “best correction” is the dictionary entry with the smallest Levenshtein distance, broken by frequency in case of ties. The full algorithm runs in O(n·m) time: fast on a single word, but on a 50,000-word document it means one comparison matrix per word pair, which adds up quickly.1.2 BK-treeA Levenshtein query against a million-word dictionary is too slow if you compute distance to every entry. The Burkhard-Keller tree (1973) indexes the dictionary so that all words within distance k of a query are reachable in roughly O(log n).This makes aspell and hunspell feel instant. No machine learning, no GPU, just a clever index built on triangle inequality.1.3 Soundex and MetaphonePhonetic codes. They map words that sound alike to the same key regardless of spelling. Designed in the 1910s for U.S. census name matching, still useful today for surname lookup, drug-name disambiguation, voice-to-text post-processing.Run on six near-homophone pairs, the two coders mostly agree but disagree on the harder spellings, which is why production systems carry both keys:Soundex and Metaphone match most near-homophone pairs; mismatches like Catherine / Kathryn show why systems keep both keys - Image by authorPhonetic matching catches the kind of variation that Levenshtein misses: a French speaker writing Stéphane as Stefan, an English speaker writing Catherine as Kathryn. The price is that any two unrelated words that happen to sound alike collide.1.4 SymSpellThe modern fast variant. Precomputes all deletes within distance k for every dictionary word and stores them in a hash. Lookup becomes a hash join, sub-millisecond on a 100k-word dictionary on a single CPU core.Frequency breaks ties. The dictionary is best built from the target corpus itself, not a generic word list, so corrections land on terms that appear in the documents the user is searching.1.5 Character n-gramsIndex every word as a set of overlapping n-character substrings, then score similarity by Jaccard overlap (the fraction of substrings two words share: eight matching trigrams out of nine gives 0.89) on those sets. Catches near-matches even when the misspelled word is not in the dictionary.The basis of every modern fuzzy-search index that does not rely on a curated dictionary (Elasticsearch’s edge-ngram analyzer, pg_trgm in PostgreSQL).1.6 Where this all worksHand the toolbox a single misspelled word with a clear correction in the dictionary, and it solves the problem every time, in microseconds. Take a typical RAG query with a single typo:The computed distances confirm the ordering: coverage lands at distance 1 alone, every other valid candidate sits at 2 or more.coverage wins at distance 1, overage sits at 2: the textbook case where classical spell-correction works - Image by authorcoverage wins by a clear margin, fast and deterministic, with no GPU. For this shape of problem, classical methods are still the right tool.The trouble starts when the shape of the input no longer fits this assumption.2. Where the classical playbook breaksClassical spell-correction was built around three assumptions: the user typed one word at a time, the typo produced a non-word, and the dictionary was the ground truth. Real enterprise queries violate all three.2.1 The typo produced a valid wordThis is the biggest hole in the classical toolbox. When a typo lands on another correctly-spelled word, no spell-checker flags it as an error: there is nothing to flag, both spellings are valid. The mistake is not in the orthography but in the fit between word and context.The six pairs side by side with their distances and meanings make the trap visible:Each typo produces another valid word with a different meaning, so disambiguation needs the context, not the dictionary - Image by authorA user types “what is the overage on my homeowner policy?” in an insurance chatbot. They almost certainly meant coverage (the amount the policy will pay out), not overage (the excess amount they owe past a limit). A classical spell-checker has nothing to flag: overage is in the dictionary, the SymSpell lookup returns it as the best-confidence match for itself, and the retrieval layer happily fetches documents about paying overages on usage caps, not coverage limits. The user gets a confident wrong answer.The reason classical methods cannot catch this is structural. They score similarity against the dictionary. Whether the word fits the query’s domain is a different question entirely. Answering it requires reading the surrounding text and knowing that “homeowner policy” and “coverage” co-occur in the corpus far more often than “homeowner policy” and “overage” do. That is what embeddings encode (Article 2). It is also what no Levenshtein-style method has any way to access.2.2 Word boundaries are wrong, not the lettersThe other assumption the classical toolbox makes is that the input is a sequence of well-separated words. When users type fast (especially on mobile, especially under stress), they scramble word boundaries. They write policy holder as policyholder, or non-employee labor as nonemployeelabor, or split homeowner into home owner. Sometimes they merge two questions into one fragment with no punctuation.OCR adds the same problem from the document side. A scanned PDF passed through Tesseract or AWS Textract returns text with broken word boundaries on tight kerning, missed accents, and stray punctuation. A 1% character error rate on a 500-page PDF is 25,000 broken tokens. Many of those broken tokens are valid words after the boundary error: policyholder becomes policy holder becomes the trigram set of two unrelated words.The unit a classical spell-checker is built to fix is one word at a time. The unit that breaks in fast typing or noisy OCR is a sequence of terms. As soon as the boundaries are unreliable, Levenshtein has nothing to anchor to. This is the gap classical spell-correction never closed.2.3 OCR replaces letters with other lettersBoundary scrambling is the loud OCR failure, but the silent one is worse. Modern OCR engines confuse certain glyph pairs in ways the human eye barely notices, and the result is text that looks almost right but does not match anything a literal search would look for. The original character is gone, replaced by a near-identical one. No misspelling rule flags it, because nothing was misspelled. The character was misread.A handful of glyph confusions cause most OCR noise, reading fine to a human but failing literal lookup - Image by authorNow stack this against grep, the literal-search baseline every enterprise has on top of its file shares:A distance of 4 on a 27-character phrase is the borderline the classical playbook cannot survive. Raise the fuzzy-search threshold to 4 and false positives explode (any unrelated 27-character phrase at distance 4 matches too). Drop it to 2 and the genuine OCR’d form is missed. There is no setting of the threshold that holds both ends.Longer search terms accumulate more OCR errors, pushing the distance into the false-positive zone that Levenshtein cannot survive - Image by authorThe asymmetry is the point. OCR distributes noise per character. Search terms in enterprise queries are per phrase. The two scale differently, and Levenshtein has nothing to bridge the gap. The next section shows what cosine similarity does with the same corrupted phrases.3. Embeddings and LLMs handle this naturally, but for different reasonsArticle 2 of the series showed that embeddings (dense numerical representations of text, trained on large corpora) tolerate typos by design. polciy and policy land close in vector space because the embedding model has seen both, in similar contexts, during training. phone number and telephone land close for the same reason. The embedding does not correct the typo. It just does not care about it as much as a literal-token matcher would.How much does it not care, in practice? A short calibration on real text-embedding-ada-002 calls, comparing two regimes on the same kind of input the retrieval layer sees (full questions, not single words). The helper takes a thin wrapper around the OpenAI embeddings endpoint, the same one the rest of the series uses.Run the same helper on six representative pairs (three typos, three look-alikes) and the contrast becomes visible:Typos cluster above 0.95 cosine, while look-alikes vary with context: 0.91 for coverage/overage, 0.99 for affect/effect - Image by authorTwo readings of this table matter.Embeddings handle typos reliably: Every typo pair sits above 0.95, regardless of how many letters were flipped. The retrieval layer that runs on embeddings treats covarge and coverage as the same query, which is what we want.Embeddings handle look-alikes only when the surrounding context disambiguates. In insurance text, “coverage” and “overage” mean different things often enough that the model has learned to separate them: the cosine drops to 0.91. In a generic sentence, “affect” and “effect” frequently appear in interchangeable contexts, and the model has no signal to keep them apart: the cosine stays at 0.99. The expert keyword dictionary from Article 6 is what catches the cases the embedding does not.Embeddings rescue OCR noise on long phrases, where Levenshtein gave up. The same compare() helper applied to the OCR-corrupted phrases from section 2.3 returns the verdict cleanly. The literal distance is 2-4 (already in the false-positive zone for Levenshtein), but the cosine lands between 0.86 and 0.97 in every case, comfortably inside the band a retrieval layer would treat as a match. Concrete cosine numbers depend on the embedding model and the corpus. text-embedding-ada-002 produces the values below; other models (text-embedding-3-small, bge, e5, …) sit on different scales but show the same ordering.Edit distance 2-4 is false-positive territory for Levenshtein, yet cosine stays at 0.86-0.97 and retrieval still matches - Image by authorThe reason this works is that the embedding sees the phrase as a whole. Per-character noise on one token shifts the vector a little; the rest of the phrase pins the meaning in place. When the noise spreads across several words (as in non-ernployee labor agreernent), each word stays close to its clean form, the surrounding tokens carry the meaning, and the cosine sits at typo level (0.95+). When it concentrates in one short word (as in po1icyho1der, where two l → 1 substitutions wreck the same token), the cosine drops further (0.86) but still sits firmly in the retrieval band. The contrast with Levenshtein is the point: Levenshtein has nothing to fall back on past the threshold; the embedding always has the rest of the phrase.The real test: the OCR’d term sits inside a noisy chunk. A retrieval pipeline does not embed the query against another phrase; it embeds the query against document chunks that have the relevant term sitting in a noisy neighbourhood (other OCR errors, mangled identifiers, random codes, dates, garbage tokens). The honest question is whether the embedding still separates a chunk that contains the term from a chunk that does not, when both are noisy.The relevant chunk ranks first, only narrowly above a related noisy chunk: exactly where an LLM-confirm step helps - Image by authorThe relevant chunk wins, but only by 0.028 over a noisy chunk that happens to share one related word. Two facts keep this useful in practice.Retrieval is top-k, not threshold-based. The pipeline pulls the top 10 (or top 50) chunks by cosine, not “every chunk above 0.85”. The relevant chunk sits at rank 1; even if a related-but-irrelevant chunk lands just below it, both fall into the top-k together and the next stage decides. A thin margin is only a problem if the right chunk falls out of the top-k, which it does not here, and which rarely happens on real corpora as long as the chunks are kept small. Chunk size is a knob the pipeline owns.Chunk granularity matters: line-level concentrates the signal, page-level dilutes it. The cosines above are for line-level chunks (about 100 characters each). Embed a whole page and the result is a different story.The target line scores highest, the three-line window lower, the whole page lower still as noise dilutes it - Image by authorThe line-level vector is dominated by the target tokens, so it scores high. Add eight or ten unrelated lines (premiums, deductibles, network terms, exclusions) and the page vector averages the signal across all of them. The cosine drops below even a noisy chunk that shared a single related word in figure 22. Line-level chunking is the lever that keeps the relevant signal strong enough for top-k retrieval to find it. Article 2 of the series went through this in detail on clean text; the same conclusion holds, more sharply, under OCR noise.The numbers from figures 22 and 23 paint a picture more easily seen than tabulated:Green line-level chunks cluster near the query, amber diluted chunks sit further out, the red unrelated chunk farthest - Image by authorFor the borderline cases that remain, an LLM confirms. This is the natural next layer: take the top-k chunks the embedding returned, ask a small LLM to read each and confirm whether it answers the query. The embedding does the cheap filter (millions of chunks down to ten); the LLM does the expensive judgement on the few that remain. This is also where the OCR’d token can be repaired in context: the model reads po1icyho1der next to identification number and infers the original policyholder, even though no spell-checker would.LLMs go further still. Hand a chat-completion call a question with five typos and a missing word, and the model understands the intent. The internal representation is built on context, not on tokens being well-formed. The model has read enough text written by tired humans to build robustness into its inner layers.So one might conclude: stop bothering with spell-correction, the embedding and the LLM cover it. That is the wrong conclusion in enterprise RAG, for two reasons.The embedding tolerates typos for fuzzy matching, not for keyword matching. When the retrieval method is cosine similarity over chunk embeddings, a small typo barely shifts the cosine score (Article 2). When the retrieval method is exact keyword matching (BM25: classical lexical search that weights rare terms more heavily, or the expert keyword dictionary from Article 6), a typo means a missed match. Most enterprise pipelines do both. The keyword side breaks on typos that the embedding side absorbs.The LLM tolerates typos in the prompt, not in the corpus. The chat-completion call sees the question and the retrieved chunks. If the retrieval missed because of a typo, the LLM cannot recover what it did not get. Errors in the question are absorbed by the LLM at generation time. Errors in the documents must be handled before retrieval, or the right chunks never reach the model.So the question splits in two.4. Two enterprise problems, not one4.1 Spelling errors in the questionUsers misspell words. They abbreviate. They write in caps. They drop accents. The right place to handle this is question parsing (Article 6), not retrieval. A parsed question goes through a normalization step before any keyword matching: lowercasing, accent stripping, expansion of abbreviations against the company glossary, and a spell-check pass against the corpus vocabulary. The output is a clean canonical form of the user’s intent, plus a list of expert-validated keywords (concept_keywords_df from Article 6). The keyword-matching layer downstream sees only the clean form.The choice of clean form matters. Spell-correcting against a generic dictionary (Levenshtein against the French Wiktionary) often loses domain terms: insurance jargon, internal acronyms, product codes. The right dictionary is the corpus vocabulary itself, weighted by frequency in the company’s own documents. SymSpell against a corpus-built index runs in microseconds and corrects to terms that appear in the documents the user is searching.For the keyword layer, this is essential. A misspelled keyword in the user’s question maps to a correctly-spelled keyword from the company’s vocabulary, and the BM25 / exact-match index returns hits. For the embedding layer, the correction is less critical (the embedding already absorbs the typo), but applying it does not hurt and makes downstream debugging easier.The normalization step is a small composition of cheap operations, each of which can be skipped on a per-corpus basis:The order matters. Stripping accents before lookup means the user’s résiliation and the corpus’s resiliation (after the same strip) collide on the same key: a corpus-built SymSpell index keyed on stripped tokens does the right thing. Expanding abbreviations before spell-correction means the SymSpell pass sees the expanded form (comite reglement police), which is far more likely to have a clean dictionary entry than the acronym (crp).4.2 Spelling errors in the documentsMost enterprise reference documents are clean. Insurance policies, employment contracts, regulatory filings, internal procedures: all written, reviewed, signed off. The spelling-error rate is close to zero.The exceptions matter though, because they cluster around the corpora that engineers most often want to make searchable:Customer support tickets: Free-form text, written under pressure, often by users for whom the language is not native. Mixed case, no punctuation, abbreviations, the whole catalogue.Customer reviews and feedback: Same shape, plus deliberate informality.Internal chat logs and emails: Looser than reference documents, full of fast-typing artefacts.Scanned documents passed through OCR. Even good OCR engines (Tesseract, AWS Textract, Azure Document Intelligence) introduce errors: 0 for O, 1 for l, broken word boundaries on tight kerning, missed accents on non-Latin scripts. A 1% character error rate on a 500-page PDF is 25,000 broken tokens.These are the corpora where document-side spelling errors hurt retrieval. The strategy depends on how important the documents are.5. The strategy fork: clean what matters, fuzz around the restTwo paths, picked per corpus, not per document.Put the engineering effort on the corpus side (one-time clean) or the retrieval side (noise-tolerant volume search) - Image by author5.1 Important reference documents: clean them onceWhen the corpus is the canonical source of truth (the standard contracts, the technical specifications, the regulatory texts the company is bound by), the right move is to clean it once, properly. Spend the engineering hours upfront and never deal with the noise again.Concretely, this means a parsing pass that combines:A spell-correction sweep against the corpus vocabulary, with confidence thresholds (auto-correct above T_high, flag-for-review between T_low and T_high, leave alone below T_low).A LLM cleanup pass on the flagged sections, with short context windows so the model fixes typos without inventing content.An expert review pass on the highest-stakes sections (the table of coverage limits, the indemnity clauses, the policy numbers).The cleaned corpus is the new source of truth. Downstream retrieval, embedding indexing, and keyword extraction all run against the cleaned text. The cost is one-time per document version. The benefit compounds across every query for the lifetime of the document.The threshold values are tunable per corpus. On contracts and regulatory filings, t_high = 0.95 keeps the auto-correct conservative because a wrong correction in a legal clause is expensive. On internal procedures and training materials, t_high = 0.85 lets the system clean more aggressively because the downside of a missed correction (a worse retrieval hit) is cheaper than the cost of human review.5.2 Volume documents: optimise the search insteadWhen the corpus is large, fast-changing, and the per-document value is low (tickets, reviews, chat logs, OCR’d scans), cleaning every document is not worth the cost. Here the strategy is the opposite: leave the documents as they are, and design retrieval to work around the noise.The shape of that retrieval is a coarse-to-fine cascade: page, then line, then LLM. Each stage narrows the candidate set, and just as importantly, the unit of comparison shrinks with it.Millions of chunks shrink to ten pages, then ten lines, then one line an LLM confirms cheaply - Image by authorThe recipe falls out of the cascade:Embed at the line level, not the page level (Article 2 section 3.1). The shorter the chunk, the less noise dilutes the signal of the few correctly-spelled tokens that do exist. Stage 2 of the cascade is the point of this rule.Use embeddings as the primary retrieval method, not BM25. Embeddings absorb most of the typos; BM25 amplifies them. Both stages 1 and 2 of the cascade run on embeddings.Keep an expert keyword dictionary that maps clean canonical forms to all the variants seen in the corpus (coverage → covarge, covrage, coveerage, coverag, …). The dictionary is built incrementally by the experts as they encounter new variants, not all at once at index time.Let an LLM read the top-k lines the embedding returned (stage 3 of the cascade). At line granularity the model call costs a fraction of a cent per candidate, and the model is the only step in the pipeline that reads the meaning. The function below is one variant of stage 3: rather than verify each line, it kicks the LLM in as a query-correcting fallback when retrieval came back empty. The verify-each-line shape is the same call applied per candidate instead of per query.The log_correction call makes the fallback an asset rather than a workaround. Every time the LLM fixes a spelling error the embedding could not absorb, the corrected form is written to a log. After a few weeks, the most frequent corrections become candidates to add to the corpus’s SymSpell index, the expert keyword dictionary, or the abbreviation map. The fallback gradually becomes redundant for the patterns that show up often.This is not a permanent solution. It is a working approach that lets the team start serving queries while the cleaning project happens (or is descoped indefinitely).The Levenshtein substitution trap. The retrieval-time LLM call costs a few cents per top-k batch, and on a million-chunk corpus that adds up. The reflex is to replace the LLM with Levenshtein, which is free and local. Tried on the same noisy chunks as figure 22, the result is sobering.Levenshtein orders chunks correctly, but every distance sits in a length-tied 60-90 band, so no threshold separates them - Image by authorThe 63 / 70 / 90 distances are not “wrong” as a ranking, but they are unusable as a retrieval signal. Any retrieval system based on Lev < T would either retrieve every chunk in the corpus (T = 90) or none of them (T = 50). The fundamental issue is that Levenshtein scales with length difference, not with semantic distance, and on a real corpus the chunk lengths vary far more than the contents do. Adding boundary-aware tokenisation gets you out of the length-scaling problem only to drop you back into the multi-word alignment problems of section 2.2.Levenshtein is the right tool for one comparison at a time, a word against a dictionary, the section 1.6 case. It is not the retrieval primitive. The pragmatic answer to LLM cost is not to replace the LLM but to let the embedding cut the corpus from millions of chunks to ten candidates first. At that point the LLM verification call on a single line costs a fraction of a cent, and it is the only step in the pipeline that reads the meaning.5.3 Data quality is a continuous-improvement problemThe trap is treating data quality as a one-time cleanup project. “We will fix all the spelling, then build the RAG.” The corpus changes faster than any cleanup project finishes. New tickets land daily. New scanned PDFs appear weekly. New product names enter the vocabulary monthly.The continuous-improvement framing: the system launches with whatever cleaning has been done, plus the dictionary the experts have built so far. Every failed query is a signal of either a missing dictionary entry, a missing alias, or an unhandled OCR pattern. The expert curates the fix. The dictionary grows. Next month’s queries do better than last month’s. Six months in, the team has built up a corpus-specific spelling-correction layer that no off-the-shelf tool would have produced.This is the same pattern as the broader argument of the series: amplify the expert, do not try to replace them. Expert knowledge of what the variants of “non-employee labor” are in our contracts is exactly the kind of domain-specific information no embedding model and no spell-checker has, and that the human team can encode incrementally.6. ConclusionThere is no single “spelling problem” in enterprise RAG. There are three sources of noise feeding the same symptom. Classical spell-correction (Levenshtein, BK-tree, Soundex, SymSpell) handles the first one well: a single misspelled word against a dictionary. It struggles with the other two: fast-typing transcription noise (scrambled boundaries, dropped accents, look-alike substitutions where the typo is a real word), and OCR character noise (l becomes 1, rn becomes m, ligatures break) where the edit distance compounds with phrase length and grep returns nothing at all. Embeddings carry both: the cosine on a typo or an OCR-corrupted multi-word phrase sits in the same retrieval band as a clean match, because the embedding sees a phrase as a whole and per-character noise on one token barely moves the vector when the surrounding tokens hold the meaning. The exact numbers depend on the embedding model and the corpus; the ordering is what matters.The practical split for enterprise RAG: spell-correct the question at parse time against the corpus vocabulary; clean the canonical reference documents once; lean on embeddings for the volume corpora the team will never finish cleaning. The orthographic layer is a continuous improvement system the experts grow alongside the corpus, not a once-and-done project.7. Sources and further readingThe edit-distance + unigram-frequency baseline the article uses is Norvig’s How to Write a Spelling Corrector (2007). The pre-computed-deletion lookup trick that makes the corpus-vocabulary path O(1) is Garbe’s SymSpell (2012). The phonetic-matching layer is Philips’s Metaphone (1990), still used for surname and drug-name matching. The article’s framing is the two-path normalisation cascade: SymSpell + Metaphone against the corpus vocabulary first (deterministic, O(1), auditable), LLM fallback only for the residue where the corpus has no spelling at all.Earlier in the series:Document Intelligence: series intro. What the series builds, brick by brick, and in what order.What works, what breaksBaseline Enterprise RAG, from PDF to highlighted answer. The four-brick pipeline end to end: PDF in, highlighted answer out.Embeddings Aren’t Magic: The Predictable Failure Modes of RAG Retrieval. Where embedding similarity wins (synonyms, typos, paraphrase), where it predictably breaks (unknown terms, negation, term-vs-answer relevance), and how to use it anyway.RAG is not machine learning, and the ML toolkit solves the wrong problem. Why chunk-size sweeps and finetuning optimize the wrong thing; route by question type instead.From regex to vision models: which RAG technique fits which problem. Two axes, document complexity and question control, that pick the technique for each case.10 common RAG mistakes we keep seeing in production. Ten production mistakes, organized brick by brick, with the fix for each.Document parsingBuilding Document Structure with Loop Engineering: Recovering a PDF’s Outline from Body Typography for RAG. Rebuilding the outline from body typography when the PDF ships no contents page at all: six signals, one bounded loop.Before Full Agentic RAG: Know How You Decide, and the Parsing Methods You Pick From. The parsing methods as a catalogue, and the decision of which to run, before handing the loop to an agent.GenerationLoop Engineering for RAG Generation: Iterate top-k One at a Time. Reading the retrieved pages one at a time instead of all at once, and what that buys when the answer sits in only one of them.Most RAG Hallucinations Are Extraction Errors: Seven Patterns for a Typed Generation Contract. Seven recurring ways a model gets the extraction wrong, and the typed contract that catches each one.Loop engineering for RAG generation: an LLM cascade from a cheap local model up to a hosted flagship. Starting on a cheap local model and escalating only when the answer does not hold up, measured.One-document pipelinesPrompt Engineering Isn’t Enough: How Four Bricks of Context Engineering Stop RAG Hallucinations. Why a better prompt does not fix a wrong page, and what each of the four bricks contributes to the context instead.Cut an Enterprise RAG Pipeline’s Latency and Cost by Calling the LLM Less, Not by Buying a Faster Model. Cutting a pipeline’s latency and cost by calling the model less often and cheaper, not by buying a faster one.RAG workflow and loop engineering: the dispatcher that decides when to loop and when to stop. Feedback loops, bounded iteration, and the dispatcher, composed into one workflow.Loop engineering for RAG: the small loops inside each step, the big loops across the pipeline. The two scales of loop: small bounded loops inside each brick, big generation-triggered loops across them.Model and dataset notes. The cosine numbers shown across sections 3 and 5.2 come from real calls to text-embedding-ada-002, an OpenAI proprietary embedding model governed by OpenAI’s Terms of Use. Other embedding models (text-embedding-3-small, bge, e5, …) produce different absolute cosines on the same pairs but preserve the relative ordering the article relies on.

Original Source

Read the full article at Towardsdatascience →

KhanList aggregates and links to publicly available news content. We do not host full articles from third-party sources. Always verify important information with original sources.