Галоўная / Артыкулы / Практычныя прытамулкі: Чаго такое RAG: як дапрацоўкі даюць ШІ доступ да сваіх дадзенняў

Практычныя прытамулкі: Чаго такое RAG: як дапрацоўкі даюць ШІ доступ да сваіх дадзенняў

Практычныя прыказкі: Чаму RAG? Как аплікацыі даюць ШІ доступ да своіх дакументаў: кантрактаў, пераказоў і спецыяльных слотаў для коду, якія выкарыстоўваюць команды, якіе праектуюць такія рашэнні.

2693 слоў

Існавайце гэта як перапрацоўаны варыянт ідэй з матеріалу “RAG Explained: How Applications Give AI Access to Their Own Data” для працавальнікаў: чыстыя этапы, аранжаваныя блакі для коду і прыметкі з восстанавлення, якія застаюцца пасля перадачы задання. Этап Аналізу работае найэфектывней, калі яго розглядаць як мерыябельную паверхню. Запісаце адна ідеальная транскрыпцыя, адзін прыклад неудачы і прыметкі з вярнення да пачатковага стану прычаму, перш чым расширваць масштаб задання. Валідзіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшаў, прычына неудачы павінна вказываць на адную адпаведальнасць, а не на заплутаны ланцюг задач.

Што такое Retrieval-Augmented Generation (RAG)?

Для стадіі «Што такое генераванне з дапамогай прыемленьня інфармацыі» неабходна прадзеяванне вхідных дадзеных, абяранніка крока і крэтарыяў завершэння працы перад зменым коду. Аперацыйныя працавнікі должны магчымае запускаць крок з вядомай точкі контролю, не падозрываючы прыхованы стан. Спрыяйце цій стадіі як на даговоры межа вхідных дадзеных і перакананых выходных рэзультатаў. Даўце назвы артыфактаў, прадзеяванне крэтарыяў успеху і адмовіцеся ад бяспрэчнага частковага завершэння. Указуйце тыя часткі тексту, якія фактычна лежалі в основе адпаведнай адказу. Без цых цытатаў аперацыйныя працавнікі не зможуць адразніць галюцинацыю ад прасоў у індэксаванні.

Without RAG:
[User Question] ──> [LLM] ──> [Answer based on generic training data]
With RAG:
[User Question] ──> [Search Engine / Vector DB]
                          │
                          └──> [Relevant Documents]
                                     │
[User Question] + [Relevant Documents] ──> [LLM] ──> [Factual Answer]

Чаму RAG мае значэнне: проблемы, якія ён рашае

Кабы разумець, чаму RAG мае значэнне, спачатку неабяжна визначыць даныя, адпаведальнага за кожны крок і критэрыі завершэння пры змяне коду. Аператары должны магчымаць перзапуск кроку з вядомай точкі контролю, не прабуючы спадарацца прыватны стан. Запісваюць час выконання і кост токеноў або запытаў разам з функцыйнальнымі рэзультатамі. Відразлівасць костаў з самага пачатку запобегае неспакойным рахункам, калі процес пераходзіць з дэмовай среды ў спяльнаныя сераўы. Наводзіць трэба тые часткі тексту, якія фактычна сталі падставай для адпаведнага адказу. Без ціх цитатаў аператары не можаць розразліць галюцинацію ад прычыны, зв’язанай з недастаткам індэксацыі.

Як фактычна працуе RAG у тылу?

Для этапа «Як працюе RAG» неабяжна прадзефінавацыя вхідных дадзеных, адпраўніка крока і крэтарыяў завершэння працы перад зменым коду. Аперацыйныя працавнікі павінны магчымае перапрацаваць крок з вядомай точкі контролю, не падозрываючы прыхованы стан. Конфігурацыю трэба залічыць праза код аплікацыі. Файлы сераўнавання, хранільнікі секрэтных дадзеных і флагі функцый павінны знаходзіцца ў адном месцы, якое працавнікі можуць пераглядаць, не чытаючы весь ланцуг аператаў. Паказваць трэба тыя часткі тексту, якія фактычна лежаць у падставе адпаведнай адказы. Без ціх цитатаў працавнікі не можуць адразніць галюцинацыю ад працягу індексавання. Для этапа «Як працюе RAG» неабяжна прадзефінавацыя вхідных дадзеных, адпраўніка крока і крэтарыяў завершэння працы перад зменым коду. Аперацыйныя працавнікі павінны магчымае перапрацаваць крок з вядомай точкі контролю, не падозрываючы прыхованы стан. Лепш выбіраць маленькія, тэставаныя елементы замест большых скрыптов. Калі крок не выйшоў, прычына неудачы павінна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцуг аператаў.

1. Ingestion Pipeline (Offline / Background):
[Raw Documents] ──> [Chunking] ──> [Embedding Model] ──> [Vector Database]
2. Query Pipeline (Runtime):
[User Question] ──> [Embedding Model] ──> [Vector Search in DB]
                                                  │
                                                  ▼
[User Question] + [Top Matching Chunks] ──> [LLM] ──> [Final Answer]

1. Разбіўка на часткі

Працюючы на стадіўцы разбіўкі на часткі, спачатку запішыце контракт: неабходныя вхідныя даны, сигнал успеху та тое, што відбуваецца у разы частковай невдачы. Такі список переконвае ў тым, што пазнейшыя зміны коду будуць чэстнымі. Вважайце гэтую стадію контрактом межа вхіднымі данымі та перакананымі выходнымі результатамі. Дайце назвы артефактам, запрацюйце критэрыя успеху та не падтрымайце беззвучную частковую завершэння задання. Перад налаштаваннем запитоў пераканайцеся ў рівні запам’ятовування на фіксаваным наборы пытанняў. Частае зменшэнне запитоў рэдка калі выправляе слабкую эфективнасць адзysку інформацыі.

2. Ембеддынгі

Калі працюеце над стадзіяй 2 Embeddings, спачатку запісайце умовы: неабяжлівыя даннэ, сігнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі список дапамагае заліцьварыцца пад пазнейшыя змены коду. Запісвайце час выканання і кост токенаў або запытаў праза функцыйнае рэзультат. Відразлівасць костаў з самага пачатку запобегае неспакойным рахункам, калі працэс пераходзіць з дэмавай версіі ў спяльныя среды. Замерьце рэкалі на фіксаванай сэтке запытаў прычым падлашоўвання прамптав. Частыя змены прамптав рэдка калі вядуць да павышэння якасці адналёгчэння інфармацыі.

3. Векторныя сховішчы

Калі працуеце над 3-м стадзіям сховвання вектараў, спачатку запішыце умовы вярбунка: неабходныя данні, сигнал пра успех і тое, што выходзіць пад частковым нявыпаннем. Такі список дапамагае заліцвачыць пазнейшыя змены ў кодзе. Зберагаюце настройкі паза кодам прыемлі. Файлы сераўнавання, сховішчы секрэтных дадзеных і флагі функцыйяў должны знаходзіцца ў аднам месцы, куды аператары можаюць адбавіць аудыт без неабходнасці чытання всей структуры. Перад налаштаваннем запитоў пераканайцеся ў рэкале на фіксаваным наборы запитаў. Частыя змены запітоў рэдка калі вядуць да павышэння якосці пошуку. Калі працуеце над 3-м стадзіям сховвання вектараў, спачатку запішыце умовы вярбунка: неабходныя данні, сигнал пра успех і тое, што выходзіць пад частковым нявыпаннем. Такі список дапамагае заліцвачыць пазнейшыя змены ў кодзе. Валіце маленькія, тэставаныя елементы замест большых скрыптаў. Калі якісьць крока падвяраецца, прычына нявыпання должна вказываць на адную адпаведальнасць, а не на заплутаную лінію обробкі дадзеных.

4. Пошук вектараў (косінусавая сэмплярнасць)

Этап 4 «Пошук вектораў за допамогай косінуса» працуе наякша, калі яго розглядаць як мерыемую паверхню. Зафіксавайце адны ідеальны прыклад, адну ситуацыю неудачы і прыметкі па поверненню да пачатковага стану пры расшырэнні масштаба. Разглядзайце гэты этап як кантракт межа вхіднымі даннымі і перакананымі выходнымі рэзультатамі. Дайце назвы артыфактам, задаце критэрыя успеху і не падзеўляйцеся частым, некомплектным выкананнем задачы. Раздзеліце правілы часткавага абрабатвання данных і правілы ўзяць інформацыю. Змена адных не павінна вымагаць перапісву іншых, калі зменяюцыся паказнікі якосці.

5. Расшырэнне запиту

Этап 5 «Падчынення запросаў» працюе наякша, калі яго розглядаць як вимерную плошчу. Запісаўце адна ідеальная транскрыпцыя, адзін прыклад неудачы і прыметку па абратанні попярэдней версіі пры перадзеўранні масштаба. Запісвайце часы выканання і кост токенав або запытаў па боку функцыйнаых рэзультатаў. Відразлівасць костаў з самага пачатку запобегае неспакойным рахункам, калі працэс пераходзіць з дэмавайнтару ў спяльныя сераўысы. Задазвайце бюджет токенав на кожны раунд і на кожную сесію. Інструменты-агенты агрэсывна расширваюць контекст; строгі ліміты не дазволяюць дэмавайнтарам ператварыцца на неспакойныя рахункі.

Практычная рэалізацыя ў Node.js

Практычная рэалізацыя на стадіўцы Node працуе найкраща, калі яе спрыявае можласць вимеры. Зберагучы адна ідеальная версія даных, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану, можна запобець расшырэнню масштаба. Канфігурацыю трэба залічваць пазначкай занята ўнутры коду прыемліка. Файлы сэраўнавання сераў, хранілішчы секрэтных дадзеных і флагі функцый должны знаходзіцца ў аднам месцы, куды аператары можаць адбавіць аудыт без неабяжнага чытання всіх дадзеных. Палітыку разбівання на часткі трэба аддзеліць ад палітыкі выявлення. Змена ў одной не должна прымусваць перапісванне другой, калі зменяюцыся паказнікі якосці. Практычная рэалізацыя на стадіўцы Node працуе найкраща, калі яе спрыявае можласць вимеры. Зберагучы адна ідеальная версія даных, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану, можна запобець расшырэнню масштаба. Валічыце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшаў, неудача должна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцоўкі дзеянняў.

Крок 1: Прыем і вектарызацыя дакументаў

Для першага – практыкавання і адміністрування – пярэд зменой коду неабходна ўзначыць вхідныя даны, адпаведальнага за гэты крок і критэрыя завершэння. Аператары должны магчымае запускаваць гэты крок з вядомага пункта контролю, не спрабоўваючы здогадвацца пра схованы стан. Спрыяйце гэтаму кроку як даговору межа вхіднымі данымі і перакананымі выходнымі рэзультатамі. Даўце назвы артыфактам, узначыць перакананні пра успех і адмовіцеся ад беззвучнага частковага завершэння. Цітуйце тыя часткі, якія фактычна лежалі в основе адпаведнай адказы. Без цітатаў аператары не зможаць розразліць галюцинацыю ад працягу індэксавання.

// ingest.js
import { OpenAI } from "openai";
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
// In a real application, you would load these from Markdown files or a CMS
const documents = [
  {
    id: "doc_1",
    text: "Enterprise customers can request a full refund within 30 days of contract signing. Contact enterprise-support@example.com."
  },
  {
    id: "doc_2",
    text: "Monthly self-serve subscriptions are non-refundable once the billing cycle begins. Users can cancel anytime to avoid future charges."
  },
  {
    id: "doc_3",
    text: "Custom engineering work and onboarding packages are strictly non-refundable once the kickoff meeting has taken place."
  }
];
async function createEmbedding(text) {
  const response = await openai.embeddings.create({
    model: "text-embedding-3-small",
    input: text,
  });
  return response.data[0].embedding;
}
export async function buildKnowledgeBase() {
  const embeddedDocs = [];
  for (const doc of documents) {
    const vector = await createEmbedding(doc.text);
    embeddedDocs.push({ ...doc, vector });
  }
  return embeddedDocs;
}

Крок 2: Пошук рэлевантнага контексту

У стадії «2. Пошук релевантных данных» неабяцо практычна вказаць інпуты, адміністратара крока та крэтыры завершэння пры перадзеіснаванні коду. Аператары должны магчымаць перзапуск крока з вядомай точкі контролю, не спрабоўваючы з’ясаваць схованы стан. Запісваюцца часы выконання та косты токенаў або запытак праза функцыйнае рэзультат. Відкрытая інформацыя пра косты запобегае неспакоўным рахункам, калі процес пераходзіць з дэмовай среды ў спяльную. Наводзіцца тые часткі тексту, якія фактычна ляглі в основу адпаведзі. Без цых цитатаў аператары не можуць разлічыць галюцинацію ад прасоўкі ў індэксаванні.

// search.js
function cosineSimilarity(vecA, vecB) {
  let dotProduct = 0;
  let normA = 0;
  let normB = 0;
  for (let i = 0; i < vecA.length; i++) {
    dotProduct += vecA[i] * vecB[i];
    normA += vecA[i] * vecA[i];
    normB += vecB[i] * vecB[i];
  }
  return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
}
export function findTopMatches(queryVector, knowledgeBase, topK = 2) {
  return knowledgeBase
    .map(doc => ({
      ...doc,
      score: cosineSimilarity(queryVector, doc.vector)
    }))
    .sort((a, b) => b.score - a.score)
    .slice(0, topK);
}

Крок 3: Дапамога прапану і стварэнне адпаведзі

Для крока 3 «Расшырэнне стадіі» неабяжна практычна визначыць інпуты, адміністратара крока та крэтыяры завершэння пры зміне коду. Аператары должны магчымаць перзапуск крока з вядомай точкі контролю, не спрабоўваючы здагадвацца пра схованы стан. Конфігурацыю трэба залічыць праза код аплікацыі. Файлы сераўнавання, хранальнікі секрэтных дадзеных і флагі функцый належыць у аднам месца, якое аператары можаць пераглядаць без неабяжнай чытанняў усіх элементаў. Калі наступны крок — це код або вызов інструмента, лепш выкарыстоўваць структураваныя выходныя данні з перакананням ў схеме, чым вольныя тэкстовыя апісанні. Для крока 3 «Расшырэнне стадіі» неабяжна практычна визначыць інпуты, адміністратара крока та крэтыяры завершэння пры зміне коду. Аператары должны магчымаць перзапуск крока з вядомай точкі контролю, не спрабоўваючы здагадвацца пра схованы стан. Лепш выкарыстоўваць маленькія, тэставаныя елементы, чым вялікія скрыпты. Калі крок не выйшаў, прычына неудачы должна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны процес.

// answer.js
import { OpenAI } from "openai";
import { createEmbedding, buildKnowledgeBase } from "./ingest.js";
import { findTopMatches } from "./search.js";
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
async function askKnowledgeBase(userQuestion, knowledgeBase) {
  // 1. Convert user question into an embedding
  const questionVector = await createEmbedding(userQuestion);
  // 2. Retrieve top matching chunks
  const matches = findTopMatches(questionVector, knowledgeBase, 1);
  const contextText = matches.map(m => m.text).join("\n---\n");
  // 3. Augment prompt with retrieved context
  const systemPrompt = `
You are a helpful customer service assistant.
Answer the user's question using ONLY the context provided below.
If the context does not contain the answer, say "I do not have enough information to answer that."
Context:
${contextText}
`;
  // 4. Generate answer
  const completion = await openai.chat.completions.create({
    model: "gpt-4o-mini",
    messages: [
      { role: "system", content: systemPrompt },
      { role: "user", content: userQuestion }
    ],
    temperature: 0.2, // Low temperature minimizes creative liberties
  });
  return completion.choices[0].message.content;
}
// Example usage:
const knowledgeBase = await buildKnowledgeBase();
const answer = await askKnowledgeBase("I signed an enterprise deal 2 weeks ago, can I get my money back?", knowledgeBase);
console.log(answer);
// Output: Yes, enterprise customers can request a full refund within 30 days of contract signing. You can email enterprise-support@example.com to initiate the process.

Пашчэтныя памылкі, якія рабяць разрабатчыкі з RAG

Калі працуеце над этапам «Пашчэтныя памылкі, якія рабяць разрабатчыкі», спачатку запісайте угоду: неабяжлівыя даннэ, сігнал успеху і тое, што выходзіць у случае частковага няўспэху. Такі список контроля дапамагае заставіць пазнейшыя змены коду быць чыстымі. Спрыятлівае ставленне да гэтага этапу як да угоды межа даннемі і перакананымі выходамі. Дайце назву артыфактам, задаць критэрыя успеху і адмовіцеся ад тыхоўскага частковага завершэння. Замерьце рівень адтворэння на фіксаванай сэтке запытаў прычым регулюванні прапаза. Частая змена прапаза рэдка калі вярнуе слабую базу адтворэння.

1. Няўпрыкметнае чанкуванне

Калі працюеце над першым этапам «Naive Chunking», спачатку запісайце умовы: неабяжлівыя даны, сигнал успеху і тое, што выходзіць у разе частковага невыпання. Такі список контроля дапамагае заліцьварыцца пад змяны коду пазнейша. Запісвайце час выканання і кост токеноў або запытаў праза функцыйнае рэзультат. Відразлівасць костаў з самага пачатку запобегае неспакойным рахункам, калі працэс пераходзіць з дэмавайнага режыма ў спяльныя сераўры. Замерьце ступень воспамінання на фіксаванай сэтке запытаў прычым регулюванні патронав. Частае змена патронаў рэдка калі вялікі эфект дае на слабую систему адзыскання інформаціі.

2. Абсалютная завіснасць ад вектарнага пошуку

Калі працуеце на стадыі «2 Relying Solely on», спачатку запісайце умовы вярбунка: неабходныя даны, сігнал успеху і тое, што выходзіць пад частковыя аберанціі. Такі список дапамагае залічваць пазнейшыя змены ў кодзе чыстаюча.

Зберагайце настройкі за межамі коду прыемліка. Файлы сераўнавання, хранільнікі секрэтных дадзеных і флагі функцыйяў должны знаходзіцца ў аднам месцы, куды аператары можаюць адбавіць аудыт без неабходнасці чытання всей структуры.

Перад налагоджэнням запрошэнняў замерайце рэкалі на фіксаваным наборе запитаў. Частыя змены запрошэнняў рэдка калі выправляюць слабую систему адналёгчэння дадзеных.

Калі працуеце на стадыі «2 Relying Solely on», спачатку запісайце умовы вярбунка: неабходныя даны, сігнал успеху і тое, што выходзіць пад частковыя аберанціі. Такі список дапамагае залічваць пазнейшыя змены ў кодзе чыстаюча.

Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок збягае, аберанцыя должна паказваць на адну адпаведальнасць, а не на заплутаны ланцоўкі працы.

3. Занадто большая колька контексту (Проблема загубленага ў сярэдзіне)

Этап «Занадто большая колька» працуе наякша, калі яго спрыяваць як меравальную плошчу. Зафіксавайце адна ідеальная транскрыпцыя, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перш чым расширваць масштаб. Спрыяйце гэтам этапу як кантракту межа вхіднымі дадзеннямі і перакананымі выходнымі рэзультатамі. Дайце назвы артыфактам, задаце критэрыі успеху і адмовіцеся ад тыхоў, частковага завершэння. Раздзеліце політыку часткавага апрантавання дадзенняў ад політыкі ўзяць іх з памяці. Змена адной з іх не должна прымусваць перапісванне другой, калі зменяюцыся паказнікі якосці.

Калі трэба вжываць RAG у працу проты Файн-тюнінгу?

Этап «Калі трэба выкарыстоўваць» работае наякша, калі яго спрыяваць як вимерную плошчу. Запісайте адны ідеальны прыклад роботы, адзін прыклад неудачы і прыметку па адвярненню змян перш чым расширваць масштабы. Запісвайте час выканання і вартасць токеноў або запытаў разам з функцыйнальнымі рэзультатамі. Візуабельнасць вартасцей з самага пачатку запобегае неспакою з боку расчыткаў, калі процес пераходзіць з дэмаверсіі ў спяльныя сераўы. Раздзеляйце правілы часткавага обробкі дадзеных і правілы ўтрымання іх. Змена аднаго з яных не должна прымусіваць перапісвання другога, калі змянююцыся показнікі якосці.

Вывык

Этап Заключэння працюе найкраща, калі яго спрыяваць як до меры ўразумелы элемент. Зберагачыце адну ідеальную версію даных, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перш чым расширваць масштабы. Храніце настройкі парадульна коду прыемлена. Файлы сяродавішняе сераўісу, базы секрэтных даных і пазнакі функцый калічуцца ў адным месцы, якое аператары можаць пераглядаць без неабяжнага чытання всіх дадзеных. Раздзеляйце правілы часткавання дадзеных і правілы ўтрымання іх. Змена адных не павінна вымагаць перапісву іншых, калі зменяюцца паказатэлі якосці. Этап Заключэння працюе найкраща, калі яго спрыяваць як до меры ўразумелы элемент. Зберагачыце адну ідеальную версію даных, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перш чым расширваць масштабы. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшае, прычына неудачы павінна быць асоўваная з адной конкрэтнаяя відпаведальнасцю, а не з заплутаным ланцоўкам задач.

Чэрніца аператыўных дзеянняў

Калі працюеце над стадзіяй аператыўнага чэк-лісту, спачатку запісайце контракт: неабходныя даны, сігнал успеху і тое, што выходзіць пад час частковага абякання. Такі чэк-ліст дапамагае заставаць пазнейшыя змены коду чыстымі.

Документавайце як шлях успеху, так і шлях вярнення. Перапрыбуткі, людзкія контралі і обработка некоректных паведамленняў ёсць частью продукту, а не пазнейшым дапрацоўкам.

Змяроўвайце рэткість адзыскання інфармацыі на фіксаванай сэтке запытаў прычым регулюванні прапаноў. Частае змены прапаноў рэдка калі вярнуе слабую систему адзыскання дакументаў.

Забезпечыце фіксаваныя версіі залежнасцей і запісайце хеш-значэнне зображэння, якое было выкарыстоўвана для дэманстрацыі. Возможнасць перадарабаткі прыважней за камунітэтныя знаёмства.

Вядзьмі прыоритет над малымі, тэставанымі елементамі працэсу над вялікімі скрыптамі. Калі якісь крок абякае, абяканне должна паказваць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцюг задач.

Змяроўвайце рэткість адзыскання інфармацыі на фіксаванай сэтке запытаў прычым регулюванні прапаноў. Частае змены прапаноў рэдка калі вярнуе слабую систему адзыскання дакументаў.

Перш чым запускать стак, заморозьце версіі, зафіксавце «золаты» транскрыпты для критычнага шляху і паказайце способы абяроны. У спільных сэрвісах неабходны ліміты частоты запытоў, пераканання ў належнасці тэнанту і чысткі власнік для змены секрэтных даных. Лепш выбіраць простую надзею на надзейнасць, чым хітрыя експерыментальныя дэманстрацыі.

Прыметкі для 2c8785c21af6: не кладзіце ключы прадастальніка ў репазітарый, задаце верхнюю межу токену на кожную сесію і зберагачыце транскрыпты празаўсёды з фікстурамі eval, каб пазнейшыя замены модэляў заставаліся пораўнанымі.