34-წუთიანი სამუშაო სესია retrieval-augmented generation-ზე — როგორ ვაპასუხებინოთ ენის მოდელს თქვენი დოკუმენტებიდან, ხელახლა წვრთნის გარეშე. ემბედინგები, ჩანკინგი, მსგავსების ძებნა, რერანკინგი და ვექტორული ბაზები, რომლებიც ამ ყველაფერს ერთად კრავს.
LLM-მა საჯარო ინტერნეტი ისწავლა ფიქსირებულ წვრთნის ზღვრამდე. მას არასდროს უნახავს თქვენი კომპანიის wiki, გუშინდელი მხარდაჭერის ტიკეტები ან PDF, რომელიც მომხმარებელმა ახლახან ატვირთა. ჰკითხეთ ამაზე და ან იტყვის „არ ვიცი“, ან, უარესი, რაღაცას მოიგონებს. RAG ამას ასწორებს: მოდელს კითხვის მომენტში სწორ ფაქტებს აწვდის.
კითხვა ამოიღებს ნაწყვეტებს თქვენი ცოდნის ბაზიდან; ეს ნაწყვეტები პრომპტში მიჰყვება, რომ მოდელმა მათგან უპასუხოს.
ანალოგია როგორც განსხვავება იმას შორის, გამოცდისთვის სახელმძღვანელოს ზეპირად სწავლობთ (ფაინთიუნინგი) თუ წიგნის შეტანისა და გადამოწმების უფლება გაქვთ (RAG). ფაინთიუნინგი სტილსა და უნარებს ასწავლის; RAG ფაქტებს აწვდის. გუნდების უმეტესობა ჯერ RAG-ს მიმართავს.
კომპიუტერი წინადადებებს ისე ვერ ადარებს, როგორც ჩვენ. ხრიკი ისაა, რომ ტექსტის თითოეული ნაწილი რიცხვების გრძელ სიად — ვექტორად — გადაიქცეს და ისე განლაგდეს, რომ მსგავსი აზრის ტექსტები ერთმანეთთან ახლოს მოხვდნენ. ამ გარდაქმნას ემბედინგი ჰქვია და სწორედ ის ამუშავებს მთელ ვექტორულ ძებნას.
import { embed } from "ai" import { openai } from "@ai-sdk/openai" const { embedding } = await embed({ model: openai.embedding("text-embedding-3-small"), value: "How do I get my money back?", }) // embedding → [0.021, -0.044, 0.087, … ] (1536 numbers)
თითოეული ტექსტი წერტილად იქცევა. „თანხის დაბრუნება“ და „ფულის უკან დაბრუნება“ ერთად დგას; „ამინდი“ — შორს.
refund ეძებდა. ემბედინგები იდეას უსადაგებს, ასე რომ სულ სხვაგვარად ჩამოყალიბებული კითხვაც სწორ დოკუმენტს პოულობს.text-embedding-3) — ძლიერი ნაგულისხმევი არჩევანი, მარტივი API, გადახდა ტოკენებზე.embed v3/v4) — შესანიშნავი მრავალენოვანი ხარისხი; ასევე მისია ის რერანკერი, რომელსაც მე-5 ნაწილში შევხვდებით.BGE, E5, nomic) — თავად უშვებთ, გამოძახებაზე გადასახდელი არ არის, მონაცემები სრულად თქვენს კონტროლშია.ერთი წესი: დოკუმენტებსა და შეკითხვებს ემბედინგი ერთი და იმავე მოდელით გაუკეთეთ. ორი სხვადასხვა მოდელის ვექტორები ერთსა და იმავე სივრცეში არ ცხოვრობს და მათი შედარება შეუძლებელია.
50-გვერდიან სახელმძღვანელოს ერთ ვექტორად არავინ აქცევს — ეს ერთი წერტილი მასში არსებული ყველაფრის ბუნდოვანი საშუალო იქნებოდა და მოდელისთვისაც მთელი დოკუმენტი უნდა მიგეწოდებინათ. სამაგიეროდ, დოკუმენტებს პატარა, ფოკუსირებულ ნაწილებად — ჩანკებად — ჭრით და თითოეულს ცალკე ემბედინგს უკეთებთ.
// split a long document into overlapping windows const chunks = splitText(doc, { size: 800, // ~chars (or tokens) per chunk overlap: 100, // repeat across the seam }) // → each chunk gets embedded + stored on its own for (const c of chunks) await store(await embed(c), c)
დოკუმენტი იჭრება ჩანკებად, რომლებიც ოდნავ ფარავს ერთმანეთს — ასე ნაკერზე გაყოფილი წინადადება ერთ-ერთ მათგანში მაინც სრულად ჩანს.
რამდენიმე ასეული სიტყვა ჩვეულებრივ ოქროს შუალედია — საკმარისად დიდი, რომ ერთი სრული აზრი დაიტიოს, და საკმარისად პატარა, რომ ვექტორი მკვეთრი დარჩეს.
მეზობლებს შორის გაიმეორეთ ტექსტის ~10–20%, რომ საზღვარზე გადამჯდარი აზრი არ დაიკარგოს — პასუხი სწორედ გაჭრის ადგილას შეიძლება იჯდეს.
დაყავით სათაურებზე, აბზაცებზე ან წინადადებებზე — და არა სიტყვის შუაში. სტრუქტურის დაცვა თითოეულ ჩანკს იკითხებადს და თემატურს ტოვებს.
ანალოგია კულინარიული წიგნის ინდექსი რეცეპტების და არა თავების მიხედვით — გინდათ ზუსტად იმ კერძის გვერდი და არა მთელი „დესერტების“ სექცია.
ახლა თითოეული ჩანკი წერტილია. კითხვაზე პასუხისთვის კითხვასაც წერტილად აქცევთ და შემდეგ პოულობთ იმ რამდენიმე შენახულ წერტილს, რომელიც მას ყველაზე ახლოს დგას. სწორედ ესენია ყველაზე რელევანტური ჩანკები. ეს არის ვექტორული ძებნა — RAG-ის „მოძიების“ ნაწილი.
k 3-დან 10-მდეა.შეკითხვა (ქარვისფერი) ჩანკებს შორის ლაგდება; სამი უახლოესი (ზურმუხტისფერი) არის top-k შედეგი. შორეული წერტილები იგნორირდება.
თითოეული შედეგი მსგავსების ქულით ბრუნდება; ინახავთ top-k-ს და შეგიძლიათ ზღვარს ქვემოთ ყველაფერი გადააგდოთ.
შეკითხვის შედარება ყველა შენახულ ვექტორთან სათითაოდ ზუსტია, მაგრამ ნელი, როცა მილიონობით ჩანკი გაქვთ. ამიტომ ვექტორული ბაზები აგებენ ჭკვიან ინდექსს (პოპულარულს HNSW ჰქვია), რომელიც უახლოეს მეზობლებს მიახლოებით პოულობს — თითქმის ისეთივე ზუსტად, მაგრამ მკვეთრად უფრო სწრაფად. ამ ოჯახის მეთოდებს ANN, approximate nearest neighbor ძებნა ჰქვია. ცოტაოდენ recall-ს დიდ სისწრაფეში ცვლით — თითქმის ყოველთვის სწორი გადაწყვეტილება.
სუფთა მსგავსების ძებნას ბრმა წერტილები აქვს. მას შეიძლება გამორჩეს ზუსტი ტერმინი — შეცდომის კოდი ან პროდუქტის SKU — და მისი პირველი შედეგი ყოველთვის საუკეთესო არაა. ორი იაფი გაუმჯობესება ამის უმეტესობას ასწორებს: ჰიბრიდული ძებნა და რერანკინგი.
ERR-503-ს, უტყუარად პოულობს; სემანტიკური ძებნა პერიფრაზებს იჭერს. ერთად ისინი ერთმანეთის ხარვეზებს ფარავენ.საკვანძო სიტყვის ძებნა სიტყვებზე ზუსტია; ვექტორული ძებნა აზრში ერკვევა. გაუშვით ორივე და შემდეგ ორი რანგირებული სია ერთში შეადუღეთ. გავრცელებული და მდგრადი გზაა RRF (reciprocal rank fusion) — ის უბრალოდ აჯილდოებს ჩანკებს, რომლებიც რომელიმე სიაში მაღლა დგანან, და ქულების მორგება არ სჭირდება.
ორი დამოუკიდებელი ძებნა, ერთი შერწყმული შედეგების სია.
სწრაფი ვექტორული ძებნა უხეშ მოკლე სიას გაძლევთ — ვთქვათ, საუკეთესო 50-ს. რერანკერი უფრო მძიმე და უფრო ზუსტი მოდელია, რომელიც შეკითხვასა და თითოეულ კანდიდატს ერთად კითხულობს, ნამდვილ რელევანტურობას აქულებს და შემდეგ თავიდან ალაგებს. რერანკინგის მერე მხოლოდ საუკეთესო 5-ს ტოვებთ. ერთეულზე ის უფრო ნელია და სწორედ ამიტომ უშვებთ 50-ზე და არა 5 მილიონზე.
// Cohere Rerank — reorder by true relevance const ranked = await cohere.rerank({ model: "rerank-v3.5", query, documents: candidates, // top-50 from search topN: 5, // keep the best 5 })
მოიძიეთ ფართოდ და იაფად, გადაარანჟირეთ ვიწროდ და მკვეთრად.
ვექტორული ბაზა ინახავს თქვენი ჩანკების ვექტორებს, აგებს ANN-ინდექსს და მსგავსების შეკითხვებს სწრაფად პასუხობს — უმეტესობა ასევე აკეთებს იმ მეტამონაცემებით ფილტრაციასა და ჰიბრიდულ ძებნას, რომელიც ახლახან ნახეთ. აი, წამყვანი ვარიანტები, რაში არის თითოეული საუკეთესო და როგორ ავირჩიოთ.
გაფართოება, რომელიც ჩვეულებრივ Postgres-ს ვექტორულ სვეტსა და ANN-ინდექსს ამატებს.
ჰოსტინგზე მდგარი, სერვერლეს ვექტორული სერვისი — ინფრასტრუქტურის მართვა არ გჭირდებათ.
გამოყოფილი ვექტორული ძრავი ძლიერი ფილტრაციით; თვითჰოსტი ან მათი ღრუბელი.
ღია კოდის ბაზა ჩაშენებული ჰიბრიდული ძებნითა და ჩასართავი ემბედინგის მოდულებით.
მსუბუქი, ღია კოდის საცავი, რომელიც ლოკალურად თითქმის უპარამეტროდ ეშვება.
ღია კოდის, განაწილებული ვექტორული ბაზა ძალიან დიდი დანერგვებისთვის.
ორი ფაზა. ინჯესტი ერთხელ ხდება (და ყოველთვის, როცა მონაცემები იცვლება); შეკითხვა — ყოველ კითხვაზე. ამ დეკის ყველაფერი ერთ-ერთ მათგანში ჯდება.
ინჯესტის ფაზა — ეშვება ერთხელ და დოკუმენტის ყოველი ცვლილებისას. ავსებს ვექტორულ საცავს.
შეკითხვის ფაზა — ეშვება ყოველ კითხვაზე. ინჯესტისას აგებული ვექტორული ბაზა ორივე ფაზის საერთო ანჯამაა.
// the query phase, in five lines const qv = await embed(question) // 1 · embed query const hits = await db.search(qv, { topK: 50 }) // 2 · vector search const top = await rerank(question, hits, 5) // 3 · rerank const { text } = await generateText({ // 4 · augment + generate model: anthropic("claude-opus-4-8"), prompt: `Context:\n${top}\n\nQuestion: ${question}`, })
ხუთი სწრაფი შეკითხვა RAG-ზე, ემბედინგებზე, ჩანკინგზე, მოძიებასა და ინსტრუმენტებზე — მყისიერი უკუკავშირი, ავტორიზაციის გარეშე.
ნავიგაცია ← → ღილაკებით ან სქროლით · უკან ბიბლიოთეკაში