Галоўная / Артыкулы / Практычныя прытамулкі: Стратэгіі адзыскання ў RAG: За межамі базовага пошуку падобнасці

Практычныя прытамулкі: Стратэгіі адзыскання ў RAG: За межамі базовага пошуку падобнасці

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

2161 слоў

У гэтым карыце парадоксальнае шлях ад сыр'ёў да рабочай системы для: Стратэгіяў выкарыстоўвання дадзеных у RAG: За межамі базовага пошуку падобнасці. Акцэнт ставяцца на практычныя крокі, чыстае перакананне ў правильнасці дзействаў і код, які можна проста падключыць у репазітарый, не спрабоўваючы здогадвацца пра намеры. У стадії агульнага відгледу неабходна з'явіць вхідныя даны, адпаведальнага за крок і критэрыя завершэння пры перадзеі коду. Аперацыйныя працавнікі должны магчымае перадзеі крок з вядомай точкі контролю, не спрабоўваючы здагадвацца пра схованы стан. Запісвайце час выконання і кост токенавання або запыту разам з функцыйнальнымі рэзультатамі. Відразлівае паказанне костаў з'являецца запобежнення неспакою, калі шлях пераходзіць з дэмаверсіі ў спакульнаныя сераўы.

Введэнне

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

Змест

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

1. Як працюе базавы пошук сэроднечнасі → Короткае падсумаванне

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

# Basic similarity search — what most RAG systems do
results = vector_store.similarity_search(query, k=3)

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

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

3. BM25 → Пошук на аднойчыну з ключавымі словамі

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

from langchain_community.retrievers import BM25Retriever
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
# Load and split documents
loader = TextLoader("knowledge_base.txt")
documents = loader.load()
splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
chunks = splitter.split_documents(documents)
# Create BM25 retriever
bm25_retriever = BM25Retriever.from_documents(chunks)
bm25_retriever.k = 3
# Search
results = bm25_retriever.invoke("FAISS vector index")
for doc in results:
    print(doc.page_content[:200])

4. Гібрыдны пошук → Адыянал гэтага і таго

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

from langchain_community.retrievers import BM25Retriever
from langchain_google_genai import GoogleGenerativeAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain.retrievers import EnsembleRetriever
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import TextLoader
#Load and split
loader = TextLoader("knowledge_base.txt")
documents = loader.load()
splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
chunks = splitter.split_documents(documents)
#Retriever 1 — Semantic (FAISS)
embeddings = GoogleGenerativeAIEmbeddings(
    model="models/embedding-001",
    google_api_key="YOUR_KEY"
)
vector_store = FAISS.from_documents(chunks, embeddings)
semantic_retriever = vector_store.as_retriever(search_kwargs={"k": 5})
#Retriever 2 — Keyword (BM25)
bm25_retriever = BM25Retriever.from_documents(chunks)
bm25_retriever.k = 5
#Combine both — Hybrid Search
hybrid_retriever = EnsembleRetriever(
    retrievers=[semantic_retriever, bm25_retriever],
    weights=[0.6, 0.4]  # 60% semantic, 40% keyword
)
#Search
results = hybrid_retriever.invoke("What is FAISS and how does it store vectors?")
print(f"Retrieved {len(results)} chunks")
for i, doc in enumerate(results):
    print(f"\nChunk {i+1}: {doc.page_content[:150]}")

5. Переранкінг → Выбіранне найлепшага з найлепшых

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

from langchain_community.cross_encoders import HuggingFaceCrossEncoder
from langchain.retrievers.document_compressors import CrossEncoderReranker
from langchain.retrievers import ContextualCompressionRetriever
#Base retriever — fetch top 20 candidates
base_retriever = vector_store.as_retriever(search_kwargs={"k": 20})
#Reranker model
reranker_model = HuggingFaceCrossEncoder(
    model_name="BAAI/bge-reranker-base"
)
#Reranker compressor — keeps only top 3 after reranking
reranker = CrossEncoderReranker(model=reranker_model, top_n=3)
#Combine base retriever + reranker
reranking_retriever = ContextualCompressionRetriever(
    base_compressor=reranker,
    base_retriever=base_retriever
)
#Search — fetches 20, reranks, returns top 3
results = reranking_retriever.invoke("How does FAISS perform similarity search?")
print(f"Final chunks after reranking: {len(results)}")
for i, doc in enumerate(results):
    print(f"\nTop {i+1}: {doc.page_content[:200]}")

6. Максымальная маргінальная рэлевантнасць → Адвядзенне ад зайвых рэзультатаў

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

# Standard similarity search — might return redundant chunks
standard_results = vector_store.similarity_search(query, k=3)
# MMR search — returns relevant AND diverse chunks
mmr_results = vector_store.max_marginal_relevance_search(
    query,
    k=3,           # final number of chunks to return
    fetch_k=20,    # candidates to consider before selecting diverse ones
    lambda_mult=0.5  # 0 = max diversity, 1 = max relevance
)

7. Полны прыглыблены пайплайн адзысквання інфармацыі

Для стадіі 7 A Complete Advanced неабяжна ўзначыць вхідныя даны, адпаведальнага за крок і крэтыры завершэння пры змяне коду. Аперацыйныя працавнікі должны магчымае перадзеяць крок з вядомай точкі контролю, не спрабоўваючы здагадвацца пра схованы стан. Лепш выбіраць маленькія, тэставаныя елементы замест большых скрыптов. Калі крок не выйшаў, прычына неудачы должна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцужок задач. Прытамульвайце тыя часткі тексту, якія фактычна лежаць у падставе адпаведнай адказы. Без цітатаў аперацыйныя працавнікі не зможуць адразліць галюцинацыю ад працяжкі ў індэксаванні. Для стадіі 7 A Complete Advanced неабяжна ўзначыць вхідныя даны, адпаведальнага за крок і крэтыры завершэння пры змяне коду. Аперацыйныя працавнікі должны магчымае перадзеяць крок з вядомай точкі контролю, не спрабоўваючы здагадвацца пра схованы стан. Запісвайце час выконання і кост токеноў або запытаў разам з функцыйнальнымі рэзультатамі. Відразлівасць костаў з самага пачатку запобегае неспакойным рахункам, калі процес пераходзіць з дэмовай среды ў спаканую.

/p>
from langchain_google_genai import ChatGoogleGenerativeAI, GoogleGenerativeAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_community.retrievers import BM25Retriever
from langchain_community.cross_encoders import HuggingFaceCrossEncoder
from langchain.retrievers import EnsembleRetriever, ContextualCompressionRetriever
from langchain.retrievers.document_compressors import CrossEncoderReranker
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import TextLoader
# Setup
llm = ChatGoogleGenerativeAI(model="gemini-1.5-flash", google_api_key="YOUR_KEY")
embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001", google_api_key="YOUR_KEY")
# Load and split documents
loader = TextLoader("your_knowledge_base.txt")
documents = loader.load()
splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
chunks = splitter.split_documents(documents)
# Build retrievers
vector_store = FAISS.from_documents(chunks, embeddings)
semantic_retriever = vector_store.as_retriever(search_kwargs={"k": 10})
bm25_retriever = BM25Retriever.from_documents(chunks)
bm25_retriever.k = 10
# Hybrid retriever
hybrid_retriever = EnsembleRetriever(
    retrievers=[semantic_retriever, bm25_retriever],
    weights=[0.6, 0.4]
)
# Add reranking on top
reranker = CrossEncoderReranker(
    model=HuggingFaceCrossEncoder(model_name="BAAI/bge-reranker-base"),
    top_n=3
)
final_retriever = ContextualCompressionRetriever(
    base_compressor=reranker,
    base_retriever=hybrid_retriever
)
# RAG prompt
prompt = ChatPromptTemplate.from_messages([
    ("system", """Answer the question using only the context below.
    If the answer is not in the context, say "I don't have that information."

    Context: {context}"""),
    ("human", "{question}")
])
def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)
# Complete chain
rag_chain = (
    {"context": final_retriever | format_docs, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)
# Use it
answer = rag_chain.invoke("Your question here")
print(answer)

8. Какую стратэгію трэба выкарыстоўваць?

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

Just starting out / simple use case?
    → Basic similarity search is fine
Documents have specific technical terms or product names?
    → Add BM25 → use Hybrid Search
Answer quality is critical, wrong answers are costly?
    → Add Reranking on top of any retriever
Documents have lots of repeated content?
    → Use MMR instead of standard similarity search
Production system with high quality requirements?
    → Hybrid Search + Reranking together

Галоўныя выводы

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

Што далей? Апература блога №32

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

Чэк-ліст для эксплуатацыі

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

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

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

Оценяйце адпаведным чынам адказы пасля адной перадачы і траекторіі пасля калькольках перадач. Агрэгаванне балоў чату маскіруе неудачы ў працэсе взаємадзейства з інструментамі.

Напісце кароткі посібнік: як зменяць канфігурацыйныя параметры, як спрабаваць дадзеныя з очакванай лініі, як атрыбуцыя назад пасля последней перадачы.

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

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

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