Jos olette aivan uusi RAG:ssä, aloittakaa RAG:n selitys ja RAG-arkkitehtuuri. Tämä postitus on kohdalle, jossa olette rakentaneet RAG-putken pääasiassa ja nyt te maksatte siitä kustannuksissa.
Mitä tämä kattaa: Valmistelun taustalla oleva rakenteellinen malli RAG. Käsien osaltaM SK1 täytäntöönpanon osalta , ks. Laatiminen asiakirjan yhteenvetoasiakirjaksi RAGin avulla.
Mistä se tulee: Olen rakentanut DocSummarizer (Document RAG-moottori DataSummarizer (Data RAG-moottori ImageSummarizer (Image RAG-moottori AudioSummarizer (Audio RAG-moottori lucidRAG (multi -asiakirja Q&AM SK3 Samat muodot nousivat yhä esiin asiakirjoissaMSC4tiedotMST5 kuvatMSV6 ja audioMSM7
PANEE MERKILLE: Olette ehkä aivan oikein pannut merkille, että semanttista hakua tällä sivustolla on häiritty...ja kyllä seM SK2on config-kysymys, jota en ole vielä korjannut ' minulla ei ole vielä aikaa korjata sitä.
| Termi | Mitä se merkitsee | ||
|---|---|---|---|
| RAG | Takaaminen-Augmented Generation | Antakaa yritystänne LLM:lle asiakirjat ennen vastausta. | |
| Englanninkielinen kieli | Asiakirjojen jakaminen pieniksi osiksi | PDF:n rikkominen kohtiin | |
| Top-k | Ottakaa hakutulokset k "parasM SK2Show me the most relevant chunks | ||
| Vektoritutkimus | Samankaltaisen tekstin löytäminen sisällytteiden avulla | SSK2Tämän virheellisen viestin kaltaiset asiakirjat löydetään | |
| BM25 | Tärkeimmät Keyword-tutkimukset | ||
| Kontexti-ikkuna | Kuinka paljon tekstiä voidaan sisällyttää kyselyyn | Tehokas ja kallis | |
| Viestit | Tietoja ilman taitotietoa | SSK2TuonnitellutM SK3 \2025-01-15", | "Priority \ : High \ |
Retrieval-Augmented Generation M SK1RAG) on yksi niistä lauseista, jotka tarkoittavat kaikki ja mikään.
Monille joukkueille RAG:n suorittaminen on nyt
Se toimii. Niin kauan kuin se ei
Se on kallis, se on vaikea perustella ja se antaa hiljaisesti vastuun mallille, se analysoi rakennetta, se panee pakotteet täytäntöön, se päättää, mikä on tärkeää, se sovittaa yhteen ristiriidat, se tekee luottamuksensa siihen
Kun ihmiset sanovat, että “ tai "RAG hallucinaoi", ” ja "M SK2" tai että RAG ei suodata hyvin, he syyttävät yleensä väärää osa-aluetta.
Ongelma on’t RAG. Ongelmana on Tyhmä RAG.
Postissa kuvataan erilaista standardia: Vähennetty RAG - käyttää LLM:itä vähemmän, ei enempääM SK1 ottamalla ennakolta käyttöön deterministisia signaaleja ja käsittelemällä malleja synteesimoottorit, ei tietovarasto.
Kontext-ikkuna on:
Se ei ole tietovarasto.
Kun “just stick more in the prompt”, youM SK2re asking the model to :
Tämän vuoksi RAG- demot näyttävät hyvältä ja tuotantojärjestelmät tuhoutuvat hiljaisesti.
Vähennetty RAG palauttaa tavanomaisen.
Sen sijaan, että:
Ottakaa teksti takaisin ja anna mallin päättää, mikä on tärkeää.
Te olette sitä mieltä
Päättäkää, mikä on tärkeää, kun se on varastoinut, , ja , sekä ottamaan malli mukaan vasta synthesin tarpeessa.
Käytännössä tämä tarkoittaa: määritelmällinen sieppaus, halpa jäljittäminenM SK1 rajattu tuotanto.
Jos tämä kuulostaa tuttulta, se on samanlainen kuin Rajoitettu epämääräisyys: sallii todennäköisten osatekijöiden ehdottaa; sallitaan määritelmäjärjestelmät päättää.
Ensinnäkin: , antaa nähdä, mitä useimmat joukkueet tekevät ja miksi se on kallis.
flowchart LR
subgraph Traditional["❌ Traditional RAG: Everything Through the LLM"]
T1[Documents] --> T2[Chunk Everything]
T2 --> T3["Embed All Chunks<br/>(once)"]
T3 --> T4[Vector Search]
T4 --> T5["Paste Top-K<br/>(per query)"]
T5 --> T6["LLM Decides<br/>(per query)"]
T6 --> T7[Answer]
end
style Traditional stroke:#ef4444,stroke-width:3px
style T6 stroke:#ef4444,stroke-width:3px
style T5 stroke:#ef4444,stroke-width:2px
Ongelmat:
Nyt tämä on vähennetty RAG-lähestymistapa
flowchart TB
subgraph Ingestion["✅ Ingestion (Once - Pay Upfront)"]
I1[Source Docs] --> I2[Parse Structure]
I2 --> I3["Extract Signals<br/>(deterministic)"]
I3 --> I4[(Structured Fields)]
I2 --> I5[Semantic Units]
I5 --> I6[(Vector Store)]
I2 --> I7[(Evidence Store)]
end
subgraph Query["Query Time (Cheap Per Query)"]
Q1[User Question] --> Q2{Extract Filters}
Q2 --> Q3["Filter Database<br/>(no LLM)"]
Q2 --> Q4["BM25 Search<br/>(no LLM)"]
Q2 --> Q5["Vector Search<br/>(no LLM)"]
Q3 --> R[Candidate Set]
Q4 --> R
Q5 --> R
R --> S["Small Evidence Pack<br/>(5 sources not 50)"]
end
subgraph Generation["LLM (Bounded Synthesis Per Query)"]
S --> L[Synthesize Answer]
L --> A[Answer + Citations]
end
style Ingestion stroke:#22c55e,stroke-width:3px
style Query stroke:#3b82f6,stroke-width:3px
style Generation stroke:#f59e0b,stroke-width:2px
style I3 stroke:#22c55e,stroke-width:3px
style Q3 stroke:#3b82f6,stroke-width:3px
style L stroke:#f59e0b,stroke-width:3px
Keskeiset erot:
| Fassi | Perinteinen RAG | Vähennetty RAG |
|---|---|---|
| Kulutus | Lyhyesti chunk and embed | Extract datesMST2 categoriesMTS3 entitiesMSS4 quality flags STS5 |
| Filtrointi | Pyydän LLM:tä suojelemaan tietojenvaihtoa. | |
| etsintä | Vain vektori | BMM SK2 SSK3 Vector + Structured filters S |
| LLM:n rooli | ParseM SK1 filter , JA vastauksena | Synthesoida vastaus |
| Kustannus | Jokainen kysymys maksaa koko kontekstin. |
Kuluttamisen aikana, analysoida, mitä voitte ilman LLM.
Esimerkki: tukilippujärjestelmä
Sen sijaan, että lippuja vain koottaisiin tekstiin
Traditional: "Ticket #1234: Customer complained about slow loading..."
→ Embed entire text
→ Hope the LLM figures out it's about performance
Poistaa signaalit etupuolelta:
// Parse once during ingestion
var ticket = new SupportTicket
{
Id = "1234",
CreatedDate = DateTime.Parse("2025-01-15"),
Category = "Performance", // ← Deterministic field
Product = "WebApp", // ← Filterable
Priority = "High", // ← Sortable
Customer = "Enterprise", // ← Segment filter
SentimentScore = -0.3, // ← Computed once
Tags = ["slow-loading", "timeout"], // ← Searchable
Text = "Customer complained about..." // ← Still keep for RAG
};
Mitä voidaan päätellä deterministisesti:
| Tunnustyypin | Esimerkkejä SSK2 Miksi se on tärkeää | ||||
|---|---|---|---|---|---|
| Väliaikainen | Laadittu päivämääräM SK1 ajantasaistettu päivämäärä | ||||
| Kategorisointi | Status, prioriteetit, department, product | "Filter to Mobile team tickets | |||
| Numeriikka | hinta, määräM SK2 tulosMST3 luottamus | SSK5Sort by severity | |||
| Identiteetti | Asiakirjan tekijäM SK1 tilaisuudenottajan tunnistus , vähimmäismäärää koskevat numerot, lasku SSK4 | "Kaikki tilausasiakkaat X | SSK7 | ||
| Laatu | OCR-luottamus | ||||
| Todisteet | Lähdejärjestelmä, tiedostotieM SK2 URL | SSK4Ainoastaan tuotantopäiväkirjoista |
Tehkää se kerran. Pidätte outputin mukana. ettäM SK2 on pohja, johon järjestelmässänne voidaan luottaa .
RAG:n kova osa ei ole ', se ei ole malli -, se on ', se kaikki ennen mallia Konkreettiset täytäntöönpanot, ovat nähtävissä Laatiminen asiakirjan yhteenvetoasiakirjaksi RAGin avulla ja DocSummarizer: Rakenne RAG-putket.
Sen sijaan, että kohdeltaisiin "chunksM SK1 todellisuuden yhdeksi yksikköksi , tallennettaisiin rakenteellisia alueita ,signaalia, -dense-yksiköitä, MSC5 sisällytteitä,, ja viittauksia takaisin alkuperään
Teksti on edelleen osa järjestelmää -, mutta siitä tulee todisteet, ei " mitä tahansa pastesimme promptiin
Tämä on ero "RAG-kysymysten välillä, sillä ne ovat vibeitäM SK1 ja "RAg-kysymykset voidaan tarkastaa
Te ette't. Ei etupäässäM SK2
Tämä on koko varastointitarkoitus raakasignaalit LLM:n sijasta
Perinteinen RAG (muutoksen hintaM SK1
// ❌ You asked the LLM to "summarize the key points"
var summary = await llm.Summarize(ticket.Text); // Expensive
await db.SaveAsync(summary); // Threw away the original structure
// Later: "Actually, we need sentiment scores too"
// 😱 Have to re-process 10,000 tickets through LLM again!
Vähennetty RAG (muuhintainen vaihtaminenM SK1
// ✅ Store raw signals extracted deterministically
var signals = new TicketSignals
{
Text = ticket.Text, // ← Keep original
WordCount = ticket.Text.Split().Length, // ← Cheap to compute
ContainsErrorCode = Regex.IsMatch(ticket.Text, @"ERR-\d+"),
MentionedProducts = ExtractProducts(ticket.Text), // ← Heuristic
SentimentWords = CountSentimentWords(ticket.Text), // ← Word lists
CreatedHour = ticket.Created.Hour // ← Maybe useful later?
};
// Later: "We need to prioritize by sentiment"
// ✅ Just add a computed column - no LLM re-run needed!
await db.ExecuteSqlAsync(@"
ALTER TABLE Tickets ADD COLUMN SentimentScore AS
(SentimentWords->>'positive' - SentimentWords->>'negative')
");
Mitä juuri tapahtui?
Tämä on sama malli kuin:
Säännös: Muistakaa hyvin ennen LLM. ajantasaistetaan tietoonne "muistiomahdollisuutenneM SK2 (jäljittämislogiikkanne
Tärkeimmät arkkitehtuurihyötyt: ElvytettävyysM SK1 Koska tallennetaan deterministisia signaaleja sisällytteiden rinnalla, ( ei niiden sijasta ), kaikki järjestelmän osat voivat vaihdella itsenäisestiM SK2 vaihtaa sisällytysmalleja? palauttaaMSC4 sijoittaa ilman signaalien koskemistaMST5 lisätä uusi signaaliMSV6 laskea se tallennettujen tekstien perusteella ilman uudelleensijoittamistaMSP7 sijoittaminenMsv8 yhdenmukaistamisjärjestelmien tärkeysasteM Sv9 mukauttaa signaalin painotusta ja tuloslogiikkaa ilman uudelleenindeksointiaMsl10
Monilla -vektorilla sijaitsevilla kaupungeissa, kuten Qdrantissa (, voidaan jopa lisätä useat sisällytykset asiakirjaa kohti. Halua yrittää uutta sisällytysmalliaM SK1 Lisätä se olemassa olevan mallin rinnalle ja siirtyä siihen asteittain . testata sekä tuotannossa että tuotannosta, vertailla laatua, poiketa vanhasta mallista |- kaikki uudelleen indeksoimatta tai häiritsemättä palvelua | .
Jokainen osatekijä voi kehittyä ilman, että pakotetaan jälleenrakentamaan koko putki - ja heikentämättä muita
tallennetaan kaikki, mitä voidaan laskea halvalla ja määrätietoisesti.
Tärkeää: Viestit ovat vain lyhyen tekstin stringit, numerot, ja booleanit—ei valtavia tietorakenteitaM SK1 Olette'varaamassa "Performance*"
public class DocumentSignals
{
// Always extract (almost free)
public int CharCount { get; set; } // Example: 1247
public int WordCount { get; set; } // Example: 203
public int ParagraphCount { get; set; } // Example: 5
public string[] UniqueWords { get; set; } // Example: ["timeout", "error", "api"]
// Structural (parse once)
public bool HasCodeBlocks { get; set; } // true/false
public bool HasLinks { get; set; } // true/false
public int HeadingCount { get; set; } // Example: 3
// Heuristic (simple patterns)
public string[] MentionedProducts { get; set; } // Example: ["WebApp", "API"]
public string[] ErrorCodes { get; set; } // Example: ["ERR-404", "ERR-500"]
public Dictionary<string, int> SentimentWords { get; set; } // { "positive": 3, "negative": 7 }
// Metadata (already available)
public DateTime Created { get; set; } // Example: 2025-01-15T14:23:00
public string Author { get; set; } // Example: "[email protected]"
public string Category { get; set; } // Example: "Performance" (not essay-length)
// Computed (cheap math)
public double ReadingTimeMinutes { get; set; } // Example: 4.2
public double KeywordDensity { get; set; } // Example: 0.034
}
varastointikustannusten vertailu:
| mitä talletatte | Taajuus asiakirjaa kohti | m10k Asiakirjat M |
|---|---|---|
| Täsmällinen teksti | ||
| Kaikki nämä signaalit | ||
| LLM-generoitu yhteenveto |
Viestit ovat 10x pienempi kuin teksti, 4x pienempi LLM:n yhteenvedot, ja loputtoman halvempi (, koska te ette tarvitse LLM:tä
Kun ymmärrätte, että tarvitsette toisen signaalin: Kertokaa se vain tallennetuista raaka-aineista. varastointi on halpaa; LLM:n johtopäätös on kallisM SK2
Tämä on syy siihen, että "overM SK1lähetys" on turvallistaMSC3 maksatte kerran varastoinnin yhteydessä (kyvytöntäMST5 ei johdanto-osana toistuvasti
Useimmat "RAG-kysymykset" ovat todellakin vain hakukysyyksiä rajoitteiden kanssa
Perinteinen RAG (
// ❌ Paste everything into prompt and hope
var chunks = await vectorSearch.SearchAsync(query, k: 50); // 50 chunks!
var prompt = $@"
Given these 50 chunks of text, answer the question but ONLY use
docs from last week and ONLY for UK customers.
Chunks: {string.Join("\n", chunks)}
Question: {userQuestion}
";
var answer = await llm.GenerateAsync(prompt); // Expensive + unreliable
Vähennetty RAG (
// ✅ Filter first, retrieve less, synthesize last
var candidates = await db.Tickets
.Where(t => t.CreatedDate > DateTime.Now.AddDays(-7)) // ← Database does this
.Where(t => t.Region == "UK") // ← Not the LLM!
.ToListAsync();
// Hybrid search on the filtered set
// (In production: push BM25 to database/index, not in-memory LINQ)
var bm25Results = candidates.Where(c => c.Text.Contains(keyword));
var vectorResults = await vectorSearch.SearchAsync(query, k: 5, filter: candidates);
// Small evidence pack
var evidence = RRF.Merge(bm25Results, vectorResults).Take(5);
// LLM only synthesizes
var answer = await llm.GenerateAsync($@"
Synthesize an answer using ONLY these 5 sources:
{FormatEvidence(evidence)}
Question: {userQuestion}
");
Mitä juuri tapahtui?
Tästä syystä hybriditutkimus on tärkeää tuotannossa. Jos ette ole vielä rakentaneet sitä, Hybridinen haku & AutoM SK1Indexointi on koko RAG-sarjan käytännönläheisin osa.
Jos kysymys on todella mutkikas, te pöytäkirja käyttäkää pientä mallia pyrkimysten saamiseksi/filtrit M SK1 verrataan vs selittää vs ratkaista ongelmat"):
// Use small model to propose filters (ephemeral - discarded after use)
var intent = await smallModel.ExtractIntent(userQuestion);
// Returns: { intent: "troubleshoot", filters: { priority: "high", product: "api" } }
// Validate the proposal against known fields (deterministic)
var validatedFilters = ValidateAgainstSchema(intent.filters);
// Use validated filters for retrieval
var results = await db.Tickets.Where(validatedFilters).ToListAsync();
Keskeinen periaate: LLM:ssä ehdotetaan
Tämä on perusta Rajoitettu epämääräisyys malli.
Jotta voisimme syvällisemmin käsitellä väliaikaisia täytäntöönpanomalleja, joissa käytetään LLM:itä tilapäisesti ilman niiden tulosten jatkumista, ks. Tuli ja Don't täysin unohtamatta.
Vasta saattamisen jälkeen kutsutte LLM:tä. Annatte sille pienen, selkeän tosiasiakokonaisuuden, johon sisältyvät todisteiden osoittimet ja selvät epävarmuutta koskevat ohjeet
Malli*'työ: Syntesize, selittääM SK1 vertailu. Ei rajoitusten täytäntöönpano, totuuden päättäminenM SK1 keksintörakenne.
Jos huolehditte siitä, että “LLMs vetää koko konteksti- ikkunan vastaukseen”, olette jo nähneet epäonnistumismuodon Rajoitettu hämärän taustan vetäminenSe ei ole pahaa.
Order--yleiskuvakuva tyypillisestä RAG-järjestelmästä, :
Scenario: 10,000 tukilippuja
| lähestymistapa | ||
|---|---|---|
| Perinteinen RAG | Siirretään 10k lippuja**$75/päivä** | |
| Vähennetty RAG | Siirretään + ekstrahoidaan signaaleja SSK2 5 osia S× pieni konteksti M | ~$7.50/päivä |
: ~10x kustannusten vähentäminen päivässä
Vielä parempi: Hyvän todisteiden ja deterministisen filtroinnin avulla, ei ole todennäköisesti tarpeenM SK1 ei tarvitse lainkaan rajamallia. paikalliset Ollama-mallit (vapaatMSC4 pienellä todisteita sisältävällä paketilla ovat usein parempia kuin GPT
Plus: vähennetty parannuskeinojen kestoM SK1 vähemmän tukevia syvennytyksiä , ja mallin joustavuus (vapaat mallit ilman rakenteellisia muutoksia
Perinteinen RAG (
// ❌ Prompt says "only UK customers" but model can ignore it
var answer = await llm.Generate(prompt); // No guarantee
Vähennetty RAG (mahdollistettu filtrointi
// ✅ Database physically prevents non-UK results
var results = db.Tickets.Where(t => t.Region == "UK"); // Guaranteed
Miksi se on turvallisempaa? Filtroinnit pakotetaan ennen sukupolven alkua (malli ei koskaan omistanut niitä, , ei voi,' ei unohda niitä,M SK3 ja hallucinaatioita rajoittavat todisteet, joita valvotte
Perinteinen RAG: "Mudelma ilmoitti tämän, mutta en ole varma, miksi tai mistä osasta se tuli.
Vähennetty RAG:
// You know exactly why each result matched
var result = new SearchResult
{
Text = "Server timeout error",
MatchedBecause = new[]
{
"Region = UK (database filter)",
"Created in last 7 days (date filter)",
"BM25 score: 4.2 (keyword 'timeout')",
"Vector similarity: 0.89 (semantic match)"
},
SourceChunks = [chunk1, chunk2], // ← Audit trail
ConfidenceScore = 0.89
};
Voitte tarkastaa, miksi kukin tulos vastasi toisiaan, osoittaa todisteita, kun luottamus on alhainenM SK1 ja poistaa virheitä tuotantoon liittyvistä kysymyksistä tarkastelemalla ehdokaskokonaisuutta ennen LLM:n synteesiä .
Jos olette jo käyttänyt toimivaa RAG-järjestelmää, täällä's miten siirretään~:
Ennen:
public class Document
{
public string Id { get; set; }
public string Text { get; set; } // ← Only unstructured text
public float[] Embedding { get; set; }
}
jälkeen:
public class Document
{
public string Id { get; set; }
public string Text { get; set; } // ← Keep for evidence
public float[] Embedding { get; set; }
// Add deterministic signals (extract once during ingestion)
public DateTime CreatedDate { get; set; } // ← Parse from metadata
public string Category { get; set; } // ← Extract from filename/tags
public string Author { get; set; } // ← From file properties
public string[] Tags { get; set; } // ← Parse from content/metadata
public double QualityScore { get; set; } // ← Compute heuristics
}
Ennen:
var prompt = "Only use docs from last month for product 'API'. Query: " + userQuery;
var chunks = await vectorStore.Search(userQuery, k: 50);
var answer = await llm.Generate(prompt + chunks); // ❌ LLM might ignore filters
jälkeen:
// ✅ Database enforces filters
var candidates = await db.Documents
.Where(d => d.CreatedDate > DateTime.Now.AddMonths(-1))
.Where(d => d.Category == "API")
.ToListAsync();
// Search only the filtered candidates
var results = await vectorStore.Search(userQuery, k: 5, filter: candidates.Select(c => c.Id));
var answer = await llm.Generate(FormatEvidence(results)); // Much smaller context
// Combine keyword and semantic search
var keywordResults = await db.Documents
.Where(d => EF.Functions.ToTsVector("english", d.Text)
.Matches(EF.Functions.ToTsQuery("english", keywords)))
.ToListAsync();
var vectorResults = await vectorStore.Search(userQuery, k: 20);
// Merge using Reciprocal Rank Fusion (RRF)
var merged = RRF.Merge(keywordResults, vectorResults, k: 5);
Ks. Hybridinen haku & AutoM SK1Indexointi täydelliseen täytäntöönpanoon.
Seuraa näitä mittareita ennen ja sen jälkeen:
public class RAGMetrics
{
public int PromptTokens { get; set; } // Should drop by 80-90%
public int CandidatesRetrieved { get; set; } // Should drop from 50+ to 5-10
public TimeSpan QueryLatency { get; set; } // Should improve
public bool FiltersEnforced { get; set; } // Should be true
public List<string> EvidenceSources { get; set; } // Should be traceable
}
Jos järjestelmänne riippuu aina-laajemmista konteksti-ohjelmista, jotta se pysyisi täsmällisenäM SK1 ette ole mukana' ettette ole vastaanottamiseen liittyvässä ongelmassa
| Intentti | Tehkää RAG:stä ennustettavissa olevaaM SK1 halpaa , ja parannuskeinojen mahdollista | ||||
| Voimat | Korkeat token-kustannuksetM SK1 heikko filtrointi , hiljaiset hallucinaatiot, jäljittämättömät pyynnöt | ||||
| Ratkaisu | Poistaa signaalit, kun → panee rajoituksia täytäntöön määrätietoisesti | → | hankkia todisteita | → | sallii LLM:n synteesin talousarviossa |
| Seuraukset | Tekninen parantaminen etupäässäM SK1 Operaatiokäytännöt parantuvat merkittävästi |
Vähennetty RAG ei ole 't-vastainen -LLM. Se 's-vastaisen M-jätteen .
Ajatelkaa sitä tällä tavalla:
Traditional RAG = "LLM, here's 50 chunks. Figure out what matters and answer."
Reduced RAG = "Database, filter to 100. BM25, find keywords. Vector, find similar.
Now LLM, here are the 5 most relevant sources. Synthesize an answer."
Muutos:
Alkuperäiset:
Muodot:
Tämä on se, mitä tapahtuu, kun sovelletaan tavanomaista ohjelmitekniikkaa järjestelmiin, jotka sisältävät kielimallit.
Jos olette valmiita rakentamaan tätä
Viiterakenteet:
Infrastruktuuri on jo olemassa. Teidän on yksinkertaisesti lakattava käsittelemästä kontekstin ikkunaa kuin tietokantaa
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.