Галоўная / Артыкулы

Набор інструментаў пошуку для RAG: BM25, шчыльныя вектары, HyDE, RRF, MMR і пераранжаванне

Набор інструментаў пошуку для RAG: BM25, шчыльныя вектары, HyDE, RRF, MMR і пераранжаванне — калі што ўжываць, прыблізная затрымка кожнага этапу і як іх аб’ядноўвае гібрыдны канвеер.

Выдавец: REACTAPP.TOP8 хв чытання1736 слоў

Крыніцы: The Retrieval Toolkit That’s Quietly Deciding Whether Your RAG Pipeline Works.

Пасля выкарыстоўвання калькольных практык тыпу RAG часта сталківаешся з тым самым працоўным прыемлівам. Эмбедынгі ў якісным стане, запіты — чыстыя, але адпаведзі все равно неякісныя. Часта прычына не ў самай модэлі, а ў тым, што яй даўалі. Асновным бутылчыным горлам ёсць працэс выкарыстоўвання інформацыі, а большасць неудач вынікае з-за недастатку або няправільнага выкарыстоўвання канкрэтных тэхнік.

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

1. BM25: метод ацэнкі ключоўых слоў, які не знікне

BM25 (Best Matching 25) — гэта рэдкая, лексычная функцыя ранжыравання, якая ўдосконалівае метод TF-IDF. Яна ранжыруе дакументы за колькасцю спільных тэрмінаў запіту, пасля чаго ўрахоўвае частоту тэрмінаў і дужыну дакумента.

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

from rank_bm25 import BM25Okapi
corpus = [doc.split() for doc in documents]  # tokenized docs
bm25 = BM25Okapi(corpus)
query = "vector database indexing".split()
scores = bm25.get_scores(query)
top_k = sorted(range(len(scores)), key=lambda i: -scores[i])[:5]

BM25 уважае сам токен, а не яго значэнне, што робіць яго эфектывным для:

  • Кодаў продуктам, SKU, кодаў абэктаў і ID
  • Іменаваных аб’ектаў, такіх як людзі, компаніі і назвы лекаў
  • Рэдкіх або тэхнічных тэрмінаў, якія часта зліваюцца ў эмбедынгах

Ўжывайце яго там, дзе точнасць у спецыфічных тэрмінах мае перавагу над можлівасцю парафразавання: юрыдычныя, медычныя, пошук кодаў і лог-файлаў. Ён дышэўскі і быстры, не трэбуе трэніравання і GPU. Яго слабасць — абсэнцыя сэмантычнага разумеўння, таму «автомабіль» і «кар» для яго выглядаюць несупаўзнанымі.

2. Інтэнсіўны пошук вектараў: падбіранне за значэннем

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

from sentence_transformers import SentenceTransformer
import numpy as np
model = SentenceTransformer("BAAI/bge-small-en-v1.5")
doc_embeddings = model.encode(documents, normalize_embeddings=True)
query_embedding = model.encode([query], normalize_embeddings=True)
scores = np.dot(doc_embeddings, query_embedding.T).flatten()
top_k = np.argsort(-scores)[:5]

Ён выявляе сэмантычную садоўнасць: фраза "звалічэнне камандзюра" знаходзіць фразу "галоўны дырэктар паставіўся на паўтарку" без спяльных слоў. Людзі часта называюць гэта сэмантычным пошукам, хоць строго кажучы, механізам являецца ўшчэльнены пошук, а сэмантычнае падабранне — яго рэзультат.

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

3. Перапісваўанне запытання і HyDE: пачатак з выправлення запытання

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

Перапісуванне запіту дазвае ШЫ розгорнуць або уточніць запіт пры падзеці пошуку, ператвараючы „як шырока“ на точны запіт пра тое, сколькі дакумента за секунду можа обрабатваць прайскупленне X у сваім максімальным рэжыме.

HyDE (Hypothetical Document Embeddings) ідзе даўжэй. Уместо таго, каб укладзіць запіт, ад ШЫ прасяць стварыць правдападобны адказ, і гэты выдуманы адказ укладваецца і выкарыстоўваецца для пошуку рэальных дакументаў. Інтуіцыя такая: выдуманы адказ часта знаходзіцца бліжэй у прасторэ укладкі да справжніх адказоў, чым сам запіт.

hypothetical_doc = llm.generate(f"Write a short passage answering: {query}")
hyde_embedding = model.encode([hypothetical_doc], normalize_embeddings=True)
scores = np.dot(doc_embeddings, hyde_embedding.T).flatten()

Кортыя чысткія або неясныя запыткі ўваходзяць у чысле найпашырэйшых прычын паслабленага выкарыстоўвання інформацыі, адколі такія запыткі проста не несу достатнькай колькасці сігналу. Гэта наяўнасць наяўнасць у інтэрфейсах у стылі чату і ў сферах, дзе слоўнік вядокаў разлічыцца з слоўнікам корпусу. Цена за гэта — ўсё больш адзін вызов LLM пры пачатку выкарыстоўвання інформацыі, з дадатковым затрымленнем і віткамі, а паслабленыя гіпотэтычныя адпаведзі можу прывесты да няправільнага выкарыстоўвання інформацыі.

4. Гібрыдны пошук: выкарыстоўванне обох методаў

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

5. Фюзыя взаімных рэйтынгаў: з’едынэнне рэйтынгаў, а не скараў

RRF абсалютна не выкарыстоўвае нормалізацію балоў, спынюючыся на пазіцыі у рангаванні і ігнаруючы чыстыя балы.

RRF_score(doc) = Σ  1 / (k + rank_r(doc))   for each ranker r

Стаянная вяласць k, якая зазвычай дорэчва 60, зменшае ўплыв, тады якой-небудзь адзін першы ранг не можа домінаваць.

def reciprocal_rank_fusion(ranked_lists, k=60):
    scores = {}
    for ranked_list in ranked_lists:
        for rank, doc_id in enumerate(ranked_list):
            scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank + 1)
    return sorted(scores.items(), key=lambda x: -x[1])
bm25_ranked = ["doc3", "doc1", "doc5"]
dense_ranked = ["doc1", "doc4", "doc3"]fused = reciprocal_rank_fusion([bm25_ranked, dense_ranked])

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

6. Максімальная маргінальная рэлевантнасць: скасаванне зайвасці

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

MMR = λ · Sim(doc, query) − (1 − λ) · max(Sim(doc, selected))

Параметр λ задае баланс. Калі λ = 1, вытвараецца звычны метод top-k, а калі λ = 0 дыверсытэт максымізуецца, незалежна ад рэлевантнасці.

import numpy as np
def mmr(query_vec, doc_vecs, doc_ids, lambda_param=0.5, top_k=5):
    selected, remaining = [], list(range(len(doc_ids)))
    sim_to_query = doc_vecs @ query_vec
    while len(selected) < top_k and remaining:
        if not selected:
            idx = remaining[np.argmax(sim_to_query[remaining])]
        else:
            mmr_scores = []
            for i in remaining:
                sim_to_selected = max(doc_vecs[i] @ doc_vecs[j] for j in selected)
                mmr_scores.append(
                    lambda_param * sim_to_query[i] - (1 - lambda_param) * sim_to_selected
                )
            idx = remaining[np.argmax(mmr_scores)]
        selected.append(idx)
        remaining.remove(idx)
    return [doc_ids[i] for i in selected]

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

7. Пераранжаванне за дапамой крос-энкодэра: ключовы фактар тачнасці

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

from sentence_transformers import CrossEncoder
reranker = CrossEncoder("cross-encoder/ms-marco-MiniLM-L-6-v2")
pairs = [(query, doc) for doc in candidate_docs]
scores = reranker.predict(pairs)
reranked = [doc for _, doc in sorted(zip(scores, candidate_docs), reverse=True)]

Крос-энкодэры адко перамагаюць бі-энкодэры па показніку сэмліярнасці ў кантролі рэлевантнасці, таму што яны адночасна аналізуюць запіт і дакумент. Іх можна выкорыстоўваць як фінальную працэю над малым наборам кандыдатаў, зазвычай тымі 20–50 найлепшымі пасля фюзыі чыяў MMR, і ніколі над усім корпусам, адтуды што кожная пара дакументаў патрэбуе свайго самастоятэльнага аналізу. Пасля самага вызову LLM гэта ўсё большая додатковая затрэйдзованасць у часе, таму ён стоіць у канцы працэсу, а не ў пачатку.

8. Час на адпаведзь: цена за ўсё гэта

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

  • Перапісаванне запіту або HyDE, калі вікорыстоўваецца: прыблізна 200 мс да 1 секунды, додатны вызов LLM перад пачаткам адзысквання.
  • Пошук у BM25: прыблізна 5 да 20 мс, за дапамою дэшавог умяшанага інверсаванага індэкса.
  • Пошук у ўпакоўаных вектарах (ANN): прыблізна 10 да 50 мс, залежна ад розмеру і тыпу індэкса — HNSW або плоскі.
  • Фюзыя RRF: 1 да 5 мс, простыя арыфметычныя вычысленні над спісамі рангаў.
  • Пераранжаванне MMR: прыблізна 20 да 100 мс, час зрастае з колькасцю кандыдатаў, таму што працэс ітэратыўны і па парах.
  • Пераранжаванне за дапамою крос-кодэра, калі вікорыстоўваецца: прыблізна 50 да 300 мс, часта гэта самы большы часавы затраты, кроме самага стварэння тэксту.
  • Стварэнне тэксту за дапамою LLM: прыблізна 500 мс да кальколькі секунд, зазвычай займае большую частку часу.

Ёжы кантролюваць гэтыя загальныя затраты:

  • Выконваеце BM25 і метод ўшчэльненага адналёгчэння паралельна. Яны не залежыць адзін ад другога.
  • Застосавайце MMR да невялікага калеку, напрыклад, да 20-30 найлепшых рэзультатаў пасля RRF, адколькі пераменная перапільная перадоўгласнасць працуе вельмі слаба.
  • Зберагаеце эмбедынгі для частых або павтараючыхся запыткаў у кэшы.
  • Дадаеце крос-кодэр толькі тады, калі падышча точнасці явна правяжа затрымку.
  • Фіксуйце час адпаведзі ў якосты аблікованага паказніка разам з якасцю адпаведзі, такой як аддакнечнасць аб recall@k. Сістэма, якая на 2 процэнты точнейшая, але на трохі медленейшая, можа не будаць годная для выкорыстання.

Як усе складаецца

У прымэтных сістэмах гібрыдныя практыкі адналёгчэння зазвычай працуюць так:

  • Перапісва запыткаў аб метод HyDE прыводзяць нечысты запытак у лепейшы стан пры адналёгчэнні, за выборам, але за цену затрымкі.
  • BM25 выловляе точныя тэрміны.
  • Метод ўшчэльненага адналёгчэння выловляе значэнне.
  • RRF спаўнае два спісы без жадных прыемаў нормалізаціі рэйтынгаў.
  • MMR скарацоўвае спаўнены спіс да разнаобразнага, без дублікаў, сэту кандыдатаў.
  • Крос-кодэр адбывае фінальную працэю з высокай тачнасцю над гэтым меньшым сэтом.
  • Час адпаведзі ёсць показнік, які паказвае, чы можна усё гэта выкорыстаць.

Короткія практычныя рэкамендаціі

  • Короткія, нечысткія або не з відпаведнага слоўніка запіты? Перапішыце іх або спробуйце HyDE.
  • Тачная адпаведнасць для кодаў, ID-аў і рэдкіх тэрмінаў? BM25.
  • Дапускаецеся парафразаванне? Аднаўленне рэзультатаў за дапамогою методу Dense retrieval.
  • Хочаце і тое, і іншае? Адзінавайце методы за дапамогою RRF.
  • У кантэксце ёсць дублікаты частак? Iспользуйце MMR.
  • Найвышшая рэлевантнасць у маленькім фінальным сэце? Пераранжаванне за дапамогою крос-кодэра.
  • Точны, але медленны? Замеры кожнага этапу перш чым прымусова оптымізаваць.

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

Супаўзвязаныя матэрыялы

  • Beyond Cosine Similarity: Five RAG Retrieval Techniques Compared — Інтарпрэтацыя косай сэмабліднасці, BM25, гібрыднага RRF, методу перэранкі з вікорыстаннем крос-энкодэра і MMR прыкладамі коду, перадоўгамі і падходам, як спачатку выбраць тэхніку адзыскання даных, якая патрэбна для вашага RAG.
  • Практычная архітэктура RAG на Firebase і Vertex AI з вектарамі Firestore — Створэнне RAG за дапамою эмбедынгаў Vertex AI і вектарнага пошуку Firestore: групаванне, фільтры метадаў, ізоляцыя тэнантаў, чыстыя запросы, кэшаванне і метрыкі.