Галоўная > Як навучыць штучны інтэлект чытаць вашыя дакументы і адказваць на пытанні па іх

Як навучыць штучны інтэлект чытаць вашыя дакументы і адказваць на пытанні па іх

бд
ШІ
Vector
Search

RAG intro

Вітанкі спадарства.

Працягваем наш трып у свет штучнага інтэлекту. І сёння — рэальна цікавая тэма: разбіраемся, што такое RAG (Retrieval-Augmented Generation), чаму ўсе пра яго гавораць і як зрабіць яго на ўласным камп’ютары, нават без воблачных сэрвісаў.

Так-так, без OpenAI, API-ключоў і без платных падпісак. Усё будзе працаваць лакальна — з дапамогай phi-4 ад Microsoft, gemma3 ад Google, трохі LangChain (не пужайцеся, дакранемся толькі павярхоўна) і вектарнай базы Qdrant.

Навошта нам гэты RAG?

Вялікія моўныя мадэлі (LLM) — гэта класна. Яны могуць напісаць казку, сфармуляваць адказ, нават “паразмаўляць”. Але толькі на тым, што ўжо ведаюць.

А калі табе трэба, каб AI адказваў на пытанні па тваёй уласнай дакументацыі? Ці рабіў высновы на падставе ўнутраных файлаў? У такім выпадку стандартная LLM — як бы “разумная, але нічога не ведае”.

І вось тут на арэну выходзіць RAG. Ён нібы дае мадэлі “шпаргалку” — падсоўвае патрэбныя дакументы прама перад генерацыяй адказу. Гэта як бы сказаць: “Вось, пачытай спачатку, а потым адказвай”.

RAG пад капотам (але проста)

Каб зразумець, як усё працуе, трэба тры рэчы:

  1. Эмбэдынгі — гэта калі тэкст пераўтвараецца ў вектар. Лічбы, што адлюстроўваюць сэнс сказанага.
  2. Вектарная база (Qdrant) — туды мы і “захоўваем сэнс”.
  3. LangChain — звязвае ўсё разам. Ён чытае тэксты, пераўтварае іх у эмбэдынгі, адпраўляе ў базу, а потым знаходзіць патрэбнае (звяртаецца да базы) і “падае” гэта мадэлі.

Крыху дэталяў

🔹Дык што такое эмбэдынгі?

Эмбэдынг — гэта лічбавае прадстаўленне тэксту. Калі сказаць больш тэхнічна, гэта вектар (спіс лічбаў), які адлюстроўвае сэнс тэксту. Два падобныя тэксты будуць мець блізкія эмбэдынгі, а розныя — далёкія.

🔹 Навошта яны?

Каб шукаць “па сэнсе”, а не па дакладных словах. Звычайны пошук тыпу ctrl + F не ведае, што “гусь” і “гусак” — гэта амаль адно і тое ж. Вектарны пошук — ведае.

🔹 Дзе мы іх захоўваем?

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

🔹 А што робіць LangChain?

LangChain — гэта мост (агульна - фрэймворк) паміж мадэллю, базай і вашымі дакументамі. Ён разбівае тэксты, стварае эмбэдынгі, адпраўляе іх у Qdrant, а потым, калі вы задаеце пытанне, шукае адпаведныя фрагменты і падстаўляе іх у мадэль перад генерацыяй адказу. У нашым выпадку мы будзем выкарыстоўваць толькі некаторыя яго магчымасці.

Практыка: ствараем RAG-сістэму

А цяпер — да справы! Мы створым лакальную сістэму, якая:

  1. Чытае PDF-файл,
  2. Разбівае яго на тэкставыя кавалкі,
  3. Стварае эмбэдынгі праз phi-4,
  4. Загружае іх у Qdrant,
  5. Рэалізуе пошук па дакументах,
  6. І нарэшце — дазваляе мадэлі адказваць на вашы пытанні на падставе гэтых дакументаў.

Што выкарыстоўваем:

  • phi-4 ад Microsoft (праз Ollama) для эмбэдынгу ,
  • gemma3 ад Google у якасці моўнай мадэлі,
  • LangChain — для ланцужкоў,
  • Qdrant — як вектарную базу,
  • PDF — у якасці нашай крыніцы інфармацыі.

⚠️ Калі ў цябе камп’ютар не NASA-рэйтынгу, усё яшчэ нармальна. У мяне 32 ГБ аператыўкі — і ўсё працуе. Але калі менш — бяры мадэлі лягчэйшыя. І не саромейся пісаць у каментарах, калі нешта не заводзіцца.

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

Як гэта выглядае агулам:

  • Загружаем PDF → атрымліваем тэкст
  • Разбіваем тэкст на кавалкі
  • Для кожнага кавалка ствараем эмбэдынг (phi-4)
  • Захоўваем эмбэдынгі ў Qdrant
  • На запыт карыстальніка — шукаем блізкія кавалкі тэксту
  • Падаём іх у мадэль разам з пытаннем
  • Атрымліваем разумны адказ

🚀 Усталеўваем ollama

Першы крок — ставім Ollama. Гэта простая праграма, праз якую запускаюцца мадэлі лакальна. Ідзем на сайтhttps://ollama.com/ — і націскаем “Download”. Усталёўка — хвілінная справа.

Пасля усталявання запампуем патрэбныя нам мадэлі - гэта будзе gemma3:12b (Можна і gemma3:27b, але толькі калі ў цябе шмат памяці — яна жадная.) і phi4. Можна ўсталяваць толькі апошнюю але з беларускай мовай у яе слабавата.

Устаноўка мадэляў ажыццяўляецца камандамі

ollama run gemma3:12b

Пасля таго як мадэль спампуецца адчыніцца поле ўводу, праз якое мы можам пакамунікаваць з устаноўлена мадэллю. Гемма сярод лакальных мадэляў мне падаецца зараз адна з самых моцных, і крыху нават піша па-беларуску. Яе мы будзем выкарыстоўваць для напісання адказаў.

** 🧠 Усталюем phi4**

ollama run  phi4

Гэта мадэль будзе выкарыстоўвацца для эмбэдынгу. Phi-4 трохі лепш разумее беларускую, чым многія іншыя лакальныя мадэлі, але ўсё роўна — з беларускай мовай бывае вельмі цяжкавата. Часам вынікі будуць “так сабе, ці увогуле ніяк” — таму не чакай цудаў, але ў агульным — працуе. Тут галоўнае паказаць прынцып

⚙️ Усталеўваем BUN

Цяпер нам патрэбна рэч пад назвай Bun. Гэта такое хуткае асяроддзе, у якім можна запускаць TypeScript-код без лішніх танцаў з бубнам.

Усё проста:

  1. Ідзем на сайт: https://bun.sh/
  2. Ставім — як звычайную праграму
  3. Гатова!

Bun дазваляе запускаць .ts файлы наўпрост, без папярэдняй кампiляцыi ў JS. Значыць — менш крокаў, менш галаўнога болю.

🐳 Docker

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

Калі Docker яшчэ не ўсталяваны — ляцім сюды: 👉 Docker desktop.

Выбіраем “спампаваць” (не трэба нічога аплачваць!) — і ставім. (мы ж бясплатна ўсе робім).

🚦 Запускаем вектарную базу

Пасля ўсталёўкі Docker час зрабіць крок да запуску Qdrant. Для гэтага нам трэба код з гітхабу (Наш рэпазіторый). Бяром так:

https://github.com/bel-frontend/RAG (Спадзяюся што тут падрабязна распавядаць не трэба)

або проста ў тэрмінале камандай:

git clone  https://github.com/bel-frontend/RAG

Пераходзім у тэчку з базай :

cd lesson1_phi4/qdrant

(Важна: усе дзеянні будуць выконвацца у тэчцы ўрока №1: lesson1_phi4)

Запускаем Docker:

docker compose up -d

Гатова. Можна праверыць, ці ўсё працуе:

docker ps

Убачыш нешта накшталт гэтага:

CONTAINER ID   IMAGE                  COMMAND                  CREATED        STATUS                PORTS                              NAMES
f57677d89200   qdrant/qdrant:latest   "./entrypoint.sh"        14 hours ago   Up 14 hours           0.0.0.0:6333-6334->6333-6334/tcp   qdrant

І самае кайфавае — можаш зайсці ў браўзеры на http://localhost:6333/dashboard Там — прыгожы інтэрфейс, дзе ўсё відаць: дакументы, вектары, запыты.

📥 Дадаем дадзеныя

Цяпер база працуе, але яна пустая. Час яе “пакарміць”.

У спампаваным праекце ёсць тэчка pdf_documents — туды можна скідаць PDF-кі, з якіх ты хочаш атрымліваць адказы.

Дэталева код які мы выканаем можна паглядзець у спампаваным праекце ці на старонцы гітхабу

🧩 Ствараем калекцыю

Запускаем першы скрыпт (у тэчцы lesson1_phi4):

bun run create_collection.ts

На дашбордзе з’явіцца новая калекцыя test_collection. Гэта як асобная “скрыня” для нашых вектараў.

🔄 Эмбэдзім PDF-файлы

А цяпер — самае смачнае:

bun run embeddings.ts

Гэты скрыпт:

  • прачытае ўсе PDF,
  • разбівае тэкст на часткі,
  • для кожнай часткі зробіць эмбэдынг,
  • адправіць усё ў Qdrant.

⏳ Час выканання залежыць ад колькасці файлаў і хуткасці машыны. Можна якраз зрабіць сабе чай/каву ☕.

У кансолі будзе нешта накшталт:

Embedding document 10 of 10
Inserted points: {
  result: {
    operation_id: 3,
    status: "acknowledged",
  },
  status: "ok",
  time: 0.002781666,
}

Цяпер у цябе ёсць “разумная база дадзеных”, якая разумее сэнс тэксту, а не толькі словы. (Можна пабачыць у дашбордзе)

🤖 Падключаем LLM і глядзім на вынік

База працуе. Дадзеныя ўнутры. Што далей?

Цяпер мы падключаем моўную мадэль (у нашым выпадку — gemma3) і глядзім, як яна адказвае на пытанні з улікам кантэксту. Гэта як калі б ты перад экзаменам даў ШІ канспект — і папрасіў адказаць згодна з ім.

🔍 Код, які ўсё робіць

Усё адбываецца праз файл index.ts. Ён:

  • Дасылае запыт у Qdrant,
  • Атрымлівае фрагменты тэксту, звязаныя з запытам,
  • Перадае гэтыя фрагменты ў LLM разам з тваім пытаннем,
  • І мадэль адказвае, ужо ведаючы кантэкст.

Вось кавалак, які гэта робіць:

const promptQuery = "напішы мне прыклады якія ты ведаеш";

const res = await searchString(promptQuery); // пошук у базе
...
const response = await ollama.chat({
  model: "gemma3:27b", // мадэль
  messages: [
    {
      role: "system",
      content: "Ты — эксперт. Адказвай па-беларуску і толькі на падставе прадстаўленых дадзеных."
    },
    ...res.map((item) => ({
      role: "system",
      content: item.text
    })),
    {
      role: "user",
      content: `Запыт карыстальніка: ${promptQuery}`
    }
  ]
});

Можна думаць пра гэта так:

📄 Твой запыт ідзе ў базу → 🧠 база вяртае кантэкст → 🤖 мадэль чытае, аналізуе і адказвае.

Функцыя searchString(promptQuery) шукае найбольш рэлевантныя фрагменты тэксту на падставе эмбедынгаў. Знойдзеныя дакументы (у выглядзе масіва аб’ектаў з полем text) выкарыстоўваюцца як кантэкст для LLM.

Мадэлі перадаецца спіс паведамленняў:

  • два паведамленні з роляй system вызначаюць паводзіны мадэлі: адказваць па-беларуску, як эксперт, і толькі на падставе прадстаўленых дадзеных;
  • затым перадаюцца знойдзеныя фрагменты (з пошуку);
  • у канцы — зыходны запыт карыстальніка.

Мадэль gemma3:12b, запушчаная праз ollama, адказвае з улікам усяго кантэксту. У кансолі выводзіцца сфармаваны адказ, які можна далей выкарыстоўваць або аналізаваць.

🧪 Параўнаем: з кантэкстам vs. без

З кантэкстам

Response: Згодна з прадстаўленым тэкстам, вось прыклады, якія там згадваюцца:

**1. Вызначэнне сэнтыменту твіту (Zero-shot, One-shot, Few-shot):**
(І далей — спіс добрых prompt-практык, як ты і чакаў.)

Тут мадэль дакладна адказвае, бо атрымала “шпаргалку” — часткі тэксту, якія знайшла база.

Без кантэксту:

Каб прааналізаваць розніцу, проста закоментуй перадачу фрагментаў у messages:

    ...res.map((item) => ({
      role: "system",
      content: item.text,
    })),

І тады адказ будзе прыкладна такі:

Response: Прабачце, але вы не далі мне ніякіх дадзеных. Я не магу напісаць прыклады, таму што не ведаю, якія прыклады вас цікавяць і на аснове чаго іх ствараць. 

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

Што, у прынцыпе, справядліва. Мадэль — не чараўнік. Яна працуе з тым, што мае.

🎯 Вынік?

Зараз ты бачыў усё на свае вочы: з кантэкстам — мадэль разумная, без — як “дурачок у белым пальто”.

RAG сапраўды кардынальна паляпшае вынікі, калі трэба працаваць з канкрэтнымі дакументамі ці ўласнымі дадзенымі.

Ну што, зрабілі мы немалае. І, галоўнае — усё лакальна, сваімі рукамі. Без OpenAI, без ключоў, без “платных чароў”.

🔚 Што ў глабальным выніку?

✅ Сабралі працоўную RAG-сістэму:   — phi-4 для эмбэдынгаў,   — gemma3 для генерацыі адказаў,   — Qdrant — вектарная база,   — LangChain — каб усё злучыць.

✅ Пераканаліся, што з кантэкстам мадэль сапраўды разумная, а без — проста генератар выпадковых адказаў.

✅ І самае галоўнае — пачалі разумець, як уся гэта магія працуе знутры.

🚀 Што далей?

А далей — яшчэ цікавей. У наступных артыкулах:

📌 Паглядзім, як пісаць добрыя prompt-ы, 📌 Патэсцім іншыя лакальныя мадэлі, 📌 Зробім інтэграцыю з UI або Telegram-ботам, 📌 І — магчыма — навучымся рабіць свае эмбэдынгі на аснове іншых мадэляў.

🙌 PS:

Дзякуй, што дачытаў(-ла) да канца! Калі матэрыял быў карысны — будзем вельмі рады, калі:

  • 💬 Напішаш каментар ці пытанне,
  • 📨 Падкінеш ідэю для наступнага артыкула,
  • 🚀 Або проста падзелішся з сябрамі!

Тэхналогіі становяцца бліжэй, калі іх разумець. І ты ўжо зрабіў(ла) першы важны крок 💪

Да сустрэчы ў наступным артыкуле! Дзякуй вам за падтрымку!

Admin, 2025-04-22
Каментары

    (Каб даслаць каментар залагуйцеся ў свой уліковы запіс)

    ;