Якщо ви – МСК0 – абсолютно нова людина в РАГ, – МSK1 – почнете з RAG пояснює і Архітектура РАГ. Це пост для того моменту, коли ви ' збудували трубопровод RAG, який переважно працює, а тепер ви платите за нього за ціною.
Що це охоплює: Архітектурна модель, яка стоїть за виробництвом РАГ. Для рукМSK1 для втілення МSK2 см. Збудувати підсумовувач Dokumentу з РАG.
Звідки воно походить: Я створив DocSummarizer ( Машина документального RAG DataSummarizer (Data RAG engineM SK1 ImageSummarizer ( Машина з зображенням RAG МSK1 AudioSummarizer (Аудио RAG двигунM SK1 і lucidRAG (multiM SK1документ QMSC2A). Те ж саме повторювалося в усіх документахMСК4 даніМСК5 зображенняM СК6 і аудіоMSК7
NOTE: Ви, можливо, по правді помітили, що семантичний пошук на цій сайті заламаний ... і так, це МSK2 проблема з конфігурацією я не мав M SK3 ще не мав часу її виправити MSC4 Не погана теорія 🤓
| Терм МSK1 Що це означає МSK2 Приклад | ||
|---|---|---|
| РАГ | ПеретягуванняM SK1 Підвиширене генерування | Дання LLM вашій компанії доксів перед відповіддю МSK3 |
| Зйомка | Розділення документів на менші частини | Перетворення PDF в абзаци МSK2 |
| Top-k | Дайте мені найкращі МSK1 найкращеM SK2 результати із пошуку | |
| Поиск вектора | Найти подібний текст, використовуючи вбудовані додатки | |
| BM25 | Поиск по ключевым словам | |
| Окно контексту | Скільки текстів можна помістити в проміжку? | |
| Сигнал МSK0 Факти, отримані без штучного інтелекту | МSK2 Створені : ♫ ♫ МSK4 ♫ |
Видобуток-Augmented Generation M SK1RAG) став одним із тих фрази, що означає все і нічого.
Для багатьох команд RAG: МСК0, МСК1, МSK2 тепер - МСК3
Це працює. Доки це не станеться
Це: МСК0 - дорого, МСК1 - важко обдумати, МSK2 - важке, М СК3 - тихо зав 'язує відповідальність за модель. МСК4 - розшифровує структуру, МТК5 - встановлює фільтри, М АК6 - вирішує, що має значення, МУК7 - змирає протиріччя, МАК8 - впевнені в цьому, МДК9
Коли люди говорять: МСК0 , РАГ галюцинує, "”", або МСК2 , а РАГ , МСк3 , не добре відфільтровує, МС К4 , вони СМСК5 , зазвичай звинувачуються у неправильному компоненті
Проблема в тому, що Проблема в тому, ліничий РАГ.
Цей пост описує інший за замовчанням: Reduced RAG - використовує LLM менше, не більшеM SK1 шляхом видобутку детермінативних сигналів наперед і лікування моделей як двигуни синтезу, не крамниці даних.
Окно контексту це:
Це не сервер даних.
Коли ви “ просто залишаєте більше в проміжку ”, виM SK2 запитуєте модель
Ось чому демонстрації RAG виглядають чудово, і системи виробництва RAG спокійно гніздять.
Reduced RAG перевертає початковий параметр.
Замість:
Візьміть текст і дозволяйте моделі вирішити, що має значення.
Ви робите
Вирішуйте, що має значення, як тільки: , зберігайте його МSK1 і застосуйте модель лише тоді, коли вам потрібна синтез .
На практиці це означає: детермінативний поглинання , дешеве відтворення, обмежена генерація.
Якщо це звучить знайомо, то це те ж саме, що і в системі Стримана неясність: дозволити можливим компонентам запропонувати; дозволити детерміністичним системам вирішити.
Перш за все, давайте подивимось на те, що роблять більшість команд. І чому це дорого
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
Проблеми:
Тепер ось тут – МСК0 – підхід Reduced RAG – МSK1
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
Головні відмінності:
| Фаза МSK1 Традиційний RAG МSK2 Reduced RAG | ||
|---|---|---|
| Поглинання | Просто відрізаємо і вставляємо МSK1 Витягуємо дати МSK2 категорії МСК3 об 'єкти М СК4 qualitative flags | |
| Фильтрування | Попросіть LLM відфільтрувати в проміжку | База даних, де clauses МSK2 |
| Поиск | Лише вектор МSK1 BMM SK2 МSK3 вектор | |
| Роль LLM | Розшифровуйте , фильтр МSK2 І відповідь МSK3 Просто синтезуйте відповідь | | |
| Ціна | Кожне запитання платить за повний контекст МSK1 Введення одного разу МSK2 дешеві питання |
У часі вживання, аналізуйте, що ви можете без LLM.
До прикладу: Система підтримки билетів
Замість того, щоб просто скопіювати квитоки в текст
Traditional: "Ticket #1234: Customer complained about slow loading..."
→ Embed entire text
→ Hope the LLM figures out it's about performance
Витягувати сигнали наперед:
// 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
};
Що ви можете отримати детерміністично:
| Тип сигналу МSK1 Приклади МSK2 Чому це важливо | ||
|---|---|---|
| Тиморальний | Data Created , Date Updated МSK2 expiry МSK3 СМСК4Only show last week ММСК5s errorsММСК6 | СМСК7 |
| Категорічні МСК0 СтатусМSK1 пріоритет, відділМСК3 продукт MСК4 МСК5Фильтер для мобільних командних билетів | ||
| Цифрове МSK0 Цена МSK1 кількість МСК2 бал М СК3 впевненість М S К4 M С К5 Розподіл по значущості М Ш К6 | М С К7 | |
| Ідентичність МСК0 АвторМSK1 ID клієнтаМСК2 SKUМ СК3 faktura MСК4 МСК5 ♫ ♫ МС К6 ♫ Всі билети від Klienta X ♫ MСК7 ♫ | ||
| Якість | впевненість в OCR МSK1 автоматичний МSK2генерований прапор | M"Виключити низький МСК5 впевненісти в ORC МСК6 \ \ |
| Провенанс | Źródłowа система , шлях до файлу МSK2 Адрес URL МSK3 M"Только з журналів виробництва МСК5 \МСК6 |
Зробіть це один раз. Утримуйте вихідні дані
Найважчою частиною RAG є: МСК0 - це модель, МСК1 - це все, що було перед моделью Для конкретних застосувань - МСК0 - см. Збудувати підсумовувач Dokumentу з РАG і DocSummarizer: Проектування трубопроводів РАG.
Замість того, щоб сприймати "chunksMSC1 як одиниця правдиM SK2 зберігати структуровані поля, сигналMST4 щільні елементиM ST5 вбудованіM st6 і направляти назад до джерелаMst7
Текст досі є частиною системи -, але він стає докази, не " незалежно від того, що ми вставляли в про prompt
Це різниця між "RAG відповіддю є вібрами " і МSK2
Ви не знаєте.
Це все, що потрібно для зберігання сирові сигнали замість LLM-розроблені підсумкиM SK1
Традиційний RAG (невелика ціна на змінуM 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!
Reduced RAG (швидше мінятиM 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')
");
Що ж сталося?
Це той самий візерунок, як ":".
Правила: Пам 'ятайте добре до цього LLM. Обновлюйте ваші "памятиM SK2 ( логіку отриманняMスク4 безкоштовноMSC5
Найголовніша перевага в галузі архітектури: ЕволюційністьM SK1 Через те, що ви зберігаєте детермінативни сигнали поруч з вмонтованими, ( не замість них ), кожна частина системи може змінюватися незалежно МSK2 Поміняти моделі вмонтування МСК3 Перезастосувати MСК4 вмонтувати без торкання сигналів М СК5 Додавати новий сигнал М סК6 обчислити його з зачуваного тексту без перезастосування M СК7 вміщати М S К8 Rangування туней М ็ С К9 Регулювати вагу сигналу та логіку оцінки без переindeksуванняМ С К10
За допомогою багатого-векторних магазинів M SK1подібно до Qdrant), ви можете навіть додати багато вбудованих елементів на кожен документ. Хочете спробувати нову модель вбудованого модуля ? Dodaj її до існуючої і поступово переходити на іншу M SK2 Випробувати як в процесі виробництва, так і в якості МSK3 порівняти якість , а потім відкинути стару MSC5 все без переindexування чи зруйнування сервісуМSK6
Кожна компонента може розвиватися, не вимушуючи повністю перебудувати трубопровод — і не зруйнуючи інших МSK1
Поміщайте все, що можна обчислити дешево і детерміністично.
Важливо: Сигнали просто короткі текстові стрічки, цифриM SK1 і bool— не гігантські структури данихM SK1 Ви' зберігаєте МSK3PerformanceMST4 МST5 charsM ST6 не M ST7Customer complained about slow loading timesM st8 ♫ M st9 ♫ wordsMst10 ♫
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: "user@example.com"
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
}
Порівняння витрат на зберігання:
| Те, що ви зберігаєте |
|---|
| Повний текст МSK0 ~5 Кб МSK2 50 MB мSK4 |
| Всі ці сигнали МSK0 ~500 bajти МSK2 ♫ ♫ МSK3 ♫ MB ♫ |
| Згенерований резюме LLM- МSK0 ~2 Кб МSK2 20 MB мSK4 |
Сигнали 10x менший ніж текст, 4x менший ніж підсумки LLM, і безмежно дешевше щоб відновити ( тому що вам не потрібні
Коли ви зрозумієте, що вам потрібний інший сигнал: Просто обчислюйте це з накопичених необроблених даних. Утримка дешеваM SK1 Введення LLM дорогого.
Ось чому: " над- витяжка " безпечна МSK3 ви платите один раз в magazynі МSK4 незрозумілива M SK5 не повторюватись в припущеннях М SK6 суттєва ).
Більшість "RAG запитів" насправді - це лише пошукові запити з обмеженнями
Традиційний РАГ (швидкийM SK1ненадійний ):
// ❌ 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
Reduced RAG (швидкийM SK1 детермінативнийМSK2
// ✅ 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}
");
Що ж сталося?
Ось чому гібридні пошукові системи важливі для виробництва. Гібридне пошук & АвтоM SK1 Індексування є найпрактичнішою частиною всієї серии RAG
Якщо питання справді безладно, їжа використовувати маленьку модель для отримання наміру/фільтри M SK1порівняти vs пояснити vs розв 'язати проблему
// 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();
Головний принцип: LLM запропонує , детермінативний шар підтверджує МSK2
Це основа Стримана неясність шаблон.
Для глибшого поглинання ефемерних шаблонів виконання, де ви використовуєте LLM тимчасово, не залишаючи їх вихідних даних, читайте Огонь і не забувай.
Лише після пошуку ви називаєте LLM. Ви даєте йому невеликийM SK1 яскравий набір фактів з точки зору доказів та чіткими інструкціями щодо невизначеності .
Модель ' робота: з 'єднати, пояснитиM SK1 порівняти. Ні нав 'язувати обмеження МСК0 вирішувати правду МSK1 розробляти структуру.
Якщо вас хвилює те, що “LLMs перетягує весь контекстний вікно в відповідь ”, ви M SK2 вже бачили режим непрацездатності Перетягування обмеженого неясного контекстуМСК0 це ’ не злодісний - Це МSK3 те, що ви попросили його зробити
Заказ-зM SK1порівняння величини з типичною системою RAG для стосунків з клієнтами:
сценарій: 10,000 билети на підтримку
| Дохід МSK1 Koszt поглинання МSK2 За МSK3Koszt запиту | Костанція щоденна | |
|---|---|---|
| Традиційний РАГ | Вставляйте МSK1 квитоки МSK2 50 фрагменти ♫ × ♫ великий контекст ♫ МSK5 ♫ ♫$75/день | |
| Reduced RAG | Вставляйте МSK1 виокремлює сигнали МSK2 5 фрагменти ♫ ♫ МSK4 ♫ маленький контекст ♫ | ♫$7.50/день |
Ордер величини: ~10x зниження витрат на день
Ще краще: З хорошими доказами та детермінативним фильтруванням, ви, напевно, не потребуєте ' взагалі кордонної моделіM SK2 локальна модель Оллами (свободнаMSC4 з невеликим набором доказів часто перевершує GPT МSK5 покритий МSK6 шматочки, які йому треба розібрати самісінько
plus: скорочення часу debuggingу , менше ескалацій підтримки МSK2 і гнучкість моделей M SK3 відхилення моделей без змін в архітектурі
Традиційний РАГ (надіюсьМSK1фільтрування на основіM SK2
// ❌ Prompt says "only UK customers" but model can ignore it
var answer = await llm.Generate(prompt); // No guarantee
Reduced RAG (вказований фильтруванняM SK1
// ✅ Database physically prevents non-UK results
var results = db.Tickets.Where(t => t.Region == "UK"); // Guaranteed
Чому це безпечніше? Фильтры встановлені перед наступним поколінням. (модель ніколи їх не власна, МSK1 не може, ♫ ♫ МSK2 ♫ не забуває про них, ♪ ♫ ), ♫ а галюцинації обмежені доказами, які ви контролюєте ♫
Традиційний РАГ: " Модель сказала: "" МSK1 "", але я не впевнена, чому чи з якого шматка вона взялася.
Reduced 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
};
Ви можете перевірити, чому кожен результат збігається, показати докази, коли рівень довіри низькийM SK1 і виправити проблеми виробництва, вивчаючи набор кандидатів перед синтезом LLM.
Якщо ви вже маєте працюючу систему RAG, тутM SK1s як мігрувати:
До:
public class Document
{
public string Id { get; set; }
public string Text { get; set; } // ← Only unstructured text
public float[] Embedding { get; set; }
}
Після:
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
}
До:
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
Після:
// ✅ 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);
Подивіться Гібридне пошук & АвтоM SK1 Індексування для повного втілення.
Прослідкувати ці показники до і після:
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
}
Якщо ваша система залежить від будь-коли- більші контекстні вікна, щоб залишатися точним , ви не маєте МSK2 у вас немає проблеми з отриманням МСК3 у Вас є проблеми з поглинанням М СК4
| Намір | Робіть RAG передбачуваним , дешевим МSK2 і деbugованим МSK3 |
| Сили | високі ціни на символи МSK1 слабке фільтрування МSK2 мовчазні галюцинації , необібрані пропони |
| Рішення | Витягувати сигнали, як тільки МSK1 встановлювати обмеження детерміністично МSK2 дістати докази → дозволити LLM синтезувати в межах бюджету ♫ |
| Наслідки | Ще більше інженерії на передній плані ; значно кращий операційний підхід МSK2 |
Снижена РАГ не є анти-', а анти-МSK1, ЛЛМ, МSK2, а проти-МСК3, МСК4, відходів, М СК5.
Подумайте ось так.
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."
Переміщення:
Примітивів:
Модель:
Це те, що відбувається, коли ви застосовуєте звичайну технічну дисципліну до систем, які включають мовні моделі
Якщо ви готові побудувати цей
Референції implementations:
Інфраструктура вже там. Потрібно просто припинити розглядати контекстне вікно як базу даних.
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.