Практычныя прытамулкі: Я перастаў выкарыстоваць базы дадзэння Vector для RAG : PageIndex
Практычныя прытамулкі: Я перестаў вжываць базы дадзеных Vector для RAG : PageIndex: кантракты, перакрыцчы і слоты для коду для команд, якія выкарыстоўваюць гэты патэрн.
Наступныя прыміткі паказваюць практычны шлях развіцця ў напрамку “I Stopped Using Vector Databases for RAG : PageIndex Vectorless RAG”. Акцэнт ставіцца на контракты, перакрычанняя і мескі для коду, які можна проста заместіць, а не на мотывацыйныя аспекты. Калі працуеце на стадіўцы агляду, спачатку запісайте контракт: неабходныя даны, сігнал успеху і тое, што вядзецца пад частым нявыпаннем задачы. Такі список дапамагае заліцватися з пазнейшымі змянамі ў кодзе. Документавайце як шлях успеху, так і шлях вярнення да нормальнага стану. Перапрыбуткі, людзкія перакрычанняя і обробка некоректных паведамленняў є частью продукту, а не пазнейшым дапрацоўкам.
Што такое PageIndex?
Этап What Even Is PageIndex працюе найкраща, калі яго розглядаць як параметр, які можна змерыць. Запісаўце адну ідеальную версію, адзін прыклад неудачы і прыметку па поверненню да попярэдня стану, прычаму расшыроўваць масштабы не трэба. Валіце маленькія, теставаныя елементы замест большых скрыптов. Калі якісьць крок не выйшла, прычына неудачы павінна вказываць на адную адпаведальнасць, а не на заплутаны ланцужок дзеянняў. Раздзеляйце правілы часткавання інфармацыі ад правіл яе выявлення. Змена ў одных не павінна прымусваць перапісванне іншых, калі змянююцца паказнікі якосці.
Проблема з Vector RAG (пра якую ніхто не гаворыць дастатнька)
Проблема з этапам Vector выконваецца наяўней, калі яго спрыятарабатваць як вимерную паверхню. Зафіксавайце адны ідеальны прыклад, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перш чым расширваць масштабы. Спрыятарабатвайце гэты этап як кантракт межа вхіднымі даннымі і перакананымі выходнымі рэзультатамі. Дайце назвы артыфактам, задаце критэрыя успеху і не падзеўляйцеся частым, непূরным выкананнем задачы. Раздзеліце правілы частковай обробкі дадзеных ад правілаў ўзяць іх. Змена адных не павінна прымусваць перапісванне іншых, калі змянююцца показнікі якосці.
Увайсце PageIndex – Адзысканне на адной парадогамі
Метод Enter PageIndex- Retrieval by stage дае найлепыя результаты, калі яго рассматрываць як параметр, які можна вымерыць. Перш чым расширваць масштабы, зафіксавайце адны ідеальны прыклад работы, адну ситуацыю неудачы і прыметкі па поверненню да пачатковага стану. Запісвайце час выконання аперацый, а таксу карточакоў чы запитаў разам з функцыйнальнымі рэзултатамі. Відразы цены з самага пачатку запобегае неспакою, калі процес пераходзіць з дэмовай среды ў спакульную. Задаць ліміт карточакоў на адну партыю і на адну сесію. Інструменты-агенты актыўна расширваюць контекст; строгі ліміты не дазволяюць дэмам ператварыцца на неспакоўныя рахункі. Метод Enter PageIndex- Retrieval by stage дае найлепыя результаты, калі яго рассматрываць як параметр, які можна вымерыць. Перш чым расширваць масштабы, зафіксавайце адны ідеальны прыклад работы, адну ситуацыю неудачы і прыметкі па поверненню да пачатковага стану. Адначасова задокументавайце шлях успеху і шлях вярнення да нормальнага стану. Перапрыбуткі, людзкі контроль і обработка некоректных паведамленняў є часткай продукту, а не элементамі пазнейшага доўнешчэння.
Як гэта на самай працы
Для этапа «Як це насправды працюе» неабяжна прадзефінаваць вхідныя даны, адпраўніка крока і критэрыя завершэння перад змінайом коду. Аперацыяныя працавнікі павінны магчыма было перзапусціць крок з вядомай точкі контролю, не падозрываючы прыхованы стан. Лепш выбіраць маленькія, тэставаныя елементы замест большых скрыптов. Калі крок не выйшоў, прычына неудачы павінна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцюг задач. Наводзіце тыя часткі тексту, якія фактычна лежаць у падставе адпаведнай адказы. Без ціх цитатаў аперацыяныя працавнікі не зможуць адразніць галюцинацыю ад працявання з непаштоўнымі даннымі.
Annual Report 2023
├── Business Overview
│ ├── Products and Services
│ └── Market Position
├── Risk Factors
│ ├── Financial Risks
│ └── Operational Risks
├── Financial Statements
│ ├── Balance Sheet
│ │ ├── Assets
│ │ └── Liabilities
│ └── Income Statement
└── Notes to Financial Statements
├── Note 1: Accounting Policies
└── Note 12: Long-term Debt
Архітэктура PageIndex
Для стадіі архітектуры PageIndex неабяжна прадзефінаваць вхідныя даны, адпраўніка крока і крэтыяры завершэння пры перадзеўці коду. Аперацыйныя працавнікі павінны магчыма было перзапусціць крок з вядомага пункту контролю, не спрабоўваючы здагадвацца пра схованы стан. Спрацавляйце з гэтай стадіяй як з кантрактом межа вхіднымі данымі і падтвердзенымі выходнымі рэзультатамі. Даўце назвы артыфактам, прадзефінаваць перагляды успеху і адмовіцеся ад бяспрэчнага частковага завершэння. Цітавайце тыя часткі, якія фактычна лежалі в основе адпаведнай адказы. Без цітатаў аперацыйныя працавнікі не зможуць адразніць галюцинацыю ад прасоўкі ў індэксаванні.
Дзеямо з кодам
Для стадіі «Let’s Code» неабяжна ўзначыць вхідныя даны, адпаведальнага за крок і крэтыяры завершэння пры зміне коду. Аперацыйныя працавнікі должны магчыма ўвайсці крок з вядомага пункта контролю, не спрабоўваючы здагадвацца пра схованы стан. Запісвайце час выконання і кост токенаў або запытаў па боку функцыйнаых рэзультатаў. Відразлівая видавальнасць костаў з самага пачатку запобегае неспакойным рахункам, калі парадок пераходзіць з дэмавайнага сераўера ў спяльныя сераўеры. Указвайце тыя часткі тексту, якія фактычна ляглі в основу адпаведнай адказаў. Без ціх цытатаў аперацыйныя працавнікі не можуць разлічыць галюцинацію ад прасоўкі ў індэксаванні.
Крок 1: Аналіз дакумента
Для першага — адміністрування етапу — неабяжна практыка: перш чым зменаваць код, неабяжна задаць вхідныя даны, адпаведнага адпаведальнага за этап і крэтыяры завершэння. Аперацыяныя працавнікі павінны магчымае перазапускаць этап з вядомай точкі контролю, не падозрываючы прыхованы стан. Конфігурацыю трэба знаходзіць за межамі коду прыемленае. Файлы сераўіснага сэрвісу, хранення секретных дадзенаў і флагі функцый павінны быць у адном месца, якое працавнікі можуць пераглядаць, не чытаючы весь граф. Неабяжна цітаваць тые часткі, якія фактычна лежалі в основе адпаведнай адказы. Без цітатаў працавнікі не можуць адразліваць галюцинацыю ад прасоўкі ў індэксаванні.
import fitz # pip install pymupdf
def parse_pdf(pdf_path: str) -> list[dict]:
doc = fitz.open(pdf_path)
pages = []
for i, page in enumerate(doc):
text = page.get_text().strip()
if text:
pages.append({"page_num": i + 1, "text": text})
doc.close()
return pages
def group_pages_into_sections(pages, per_section=3):
sections = []
for i in range(0, len(pages), per_section):
batch = pages[i : i + per_section]
section_id = f"S{str(i // per_section + 1).zfill(3)}"
combined_text = "\n\n".join(p["text"] for p in batch)
sections.append({
"section_id": section_id,
"start_page": batch[0]["page_num"],
"end_page": batch[-1]["page_num"],
"text": combined_text,
})
return sections
Этап 2: Стварэнне індекса дрэва (з апытам LLM)
Для другога крока – стварэння етапу – пярэд змены коду неабходна ясная ваказка пра вхідныя даны, адміністратара крока і крэтэрыяў завершэння. Аператары должны магчымае перзапускать крок з вядомай точкі контролю, не падозрываючы прыхованы стан. Неабходна адначасова документавацыя шляху успеху і шляху вярнення. Перапрыбуткі, людзкія перакрыцці і обробка некоректных паведамленняў є часткай продукту, а не яго пазнейшай дапрацоўкі. Калі наступны крок – це код або вызов інструмента, лепш выкарыстоўваць структураваныя выходныя даны з перакананнем ў схэме, чым вольныя тэкстовыя апісанні.
from google import genai
from google.genai import types
client = genai.Client(api_key="YOUR_GEMINI_API_KEY")
def index_section(section: dict) -> dict:
preview = section["text"][:1500]
prompt = f"""Read this section from a document and summarize it.
Section pages: {section['start_page']} to {section['end_page']}
Text:
{preview}
Respond with ONLY valid JSON:
{{
"title": "short descriptive title (5-8 words)",
"summary": "2-3 sentence summary of what this section covers",
"key_topics": ["topic1", "topic2", "topic3"]
}}"""
response = client.models.generate_content(
model="gemini-2.0-flash",
contents=prompt,
config=types.GenerateContentConfig(temperature=0.0),
)
parsed = json.loads(response.text.strip())
return {
"node_id": section["section_id"],
"title": parsed["title"],
"pages": f"{section['start_page']}-{section['end_page']}",
"summary": parsed["summary"],
"key_topics": parsed["key_topics"],
}
def build_tree_index(sections):
nodes = [index_section(s) for s in sections]
return {
"title": "Your Document Title",
"total_sections": len(nodes),
"nodes": nodes,
}
# Save for reuse
with open("tree.json", "w") as f:
json.dump(tree, f, indent=2)
Крок 3: Пошук у дрэве (рацыянары, а не сэмлівасць)
Для стадіі пошуку ў дрэве на 3-й спрынце неабходна пазначыць вхідныя даны, адпаведальнага за спрынц і крэтыяя для завершэння працы перад зменым коду. Аперарабы должны магчымаць перзапуск спрынца з вядомай точкі контролю, не падозрываючы схованы стан. Лепш выбіраць маленькія, тэставаныя елементы замест большых скрыптов. Калі спрынц не выконваецца, прычына неудачы должна вказываць на адзін конкрэтны аспект, а не на заплутаны ланцюг задач. Калі наступны спрынц — це код або вызов інструмента, лепш выкарыстоўваць структураваныя выходны даны з пераканальваннем схэмы, а не вольнае пісьменне выражэння.
def retrieve_sections(tree: dict, query: str) -> dict:
# Build a compact text representation of the tree
tree_text = f"Document: {tree['title']}\n\n"
for node in tree["nodes"]:
tree_text += f"[{node['node_id']}] Pages {node['pages']} | {node['title']}\n"
tree_text += f" Summary: {node['summary']}\n"
tree_text += f" Topics: {', '.join(node['key_topics'])}\n\n"
prompt = f"""You are a document retrieval expert.
Given this document tree, identify which sections most likely answer the question.
Think step by step about where a human expert would look.
{tree_text}
QUESTION: {query}
Respond with ONLY valid JSON:
{{
"reasoning": "your step-by-step reasoning about where to look",
"selected_ids": ["S001", "S004"],
"confidence": "high/medium/low"
}}"""
response = client.models.generate_content(
model="gemini-2.0-flash",
contents=prompt,
config=types.GenerateContentConfig(temperature=0.0),
)
return json.loads(response.text.strip())
Спрынц 4: Адзысканне кантэнту
Для стадіі 4 «Адзыяць кантэнту» неабходна прадзеявленне вхідных дадзеных, адпаведнага адпаведальніка за гэтую стадію і крэатарыяў выходу пры перамены коду. Аператары должны магчыма было перзапускаць гэтую стадію з вядомага пункту контролю, не спрабоўваючы з’ясаваць захаваны стан. Спрыятлівайце гэтую стадію як кантракт межа вхіднымі дадзенымі і перакананымі выходнымі рэзультатамі. Даўце назвы артыфактам, прадзеявліце крэатарыяў успеху і адмовіцеся ад бяспрэчнага частковага завершэння. Цітуйце тыя часткі, якія фактычна лежалі в основе адпаведзення. Без цітаў аператары не зможуць разлічыць галюцинацію ад прасоўкі ў індэксаванні.
def retrieve_content(selected_ids: list, sections: list) -> str:
section_map = {s["section_id"]: s for s in sections}
context_parts = []
for sid in selected_ids:
if sid in section_map:
sec = section_map[sid]
context_parts.append(
f"--- Pages {sec['start_page']}-{sec['end_page']} ---\n"
+ sec["text"][:3000]
)
return "\n\n".join(context_parts)
Шаг 5: Стварэнне адпаведзення
Для стадіі генеравання адказаў у Кроку 5 неабходна ўжо падчас змены коду адзначыць вхідныя даны, адпаведальнага за крок і крэтыяры завершэння. Аператары должны магчымае запускіць крок з вядомай точкі контролю, не падозрываючы прыхованы стан. Запісваць час выконання і кост токенаў або запытаў разам з функцыйнаімі рэзультатамі. Відразлівае паказанне костаў запобегае неспадзяваным рахункам, калі процес пераходзіць з дэмовай среды ў спадзеленую. Указваць тыя часткі тексту, якія фактычна ляглі ва основу адказа. Без цых цытатаў аператары не можуць разлічыць галюцинацію ад прасоў у індэксаванні. Для стадіі генеравання адказаў у Кроку 5 неабходна ўжо падчас змены коду адзначыць вхідныя даны, адпаведальнага за крок і крэтыяры завершэння. Аператары должны магчымае запускіць крок з вядомай точкі контролю, не падозрываючы прыхованы стан. Аддзялваць дакументацыю пра успішны і варыянт вяснавання проблем. Перапрыбуткі, людзкія перакрыцця і обработка нераспрацаваных паведамленняў є часткай продукту, а не чымсь, што дадаецца пазней.
def generate_answer(query: str, context: str) -> str:
prompt = f"""Answer the question using only the provided context.
Be specific. Include exact numbers, technical terms, and cite page numbers.CONTEXT:
{context}
QUESTION: {query}
ANSWER:"""
response = client.models.generate_content(
model="gemini-2.0-flash",
contents=prompt,
config=types.GenerateContentConfig(temperature=0.1),
)
return response.text.strip()
PageIndex протык Традыцыйнага вектарнага RAG
Калі працуеце над этапам PageIndex протык Традыцыйнага вектарнага RAG, спачатку запісайце умовы викорыстоўвання: неабходныя данні, сігнал успеху і тое, што выканаецца у разы частковага нявыпання. Такі список контроля дапамагае заліцьваты змяны ў кодзе. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшае, прычына нявыпання павінна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцужок задач. Перад налаштаваннем запитоў пераканайцеся, як функцыонуе алгорытм выкарыстоўвання інформацыі на фіксаванай сэтке запитаў. Частыя змены запитоў рэдка калі вядуць да павышэння якасці выкарыстоўвання інформацыі.
Калі трэба викорыстоўваць PageIndex?
Калі працюеце над этапам «Калі трэба выкарыстоўваць», спачатку запісайце угоду: неабходныя даны, сігнал успеху і тое, што выходзіць у разе частковай нявыплненасці. Такі список контроля дапамагае залічыць пазнейшыя змены ў кодзе. Спрэцьвачайце гэты этап як угоду межа данымі і перакананымі выходамі. Дайце назвы элементам, задаць критэрыя успеху і не падтрымайце тыхі частковыя завершэння. Замерайце рэкалі на фіксаваным наборе запитаў прычым налаштаванні прапаза. Частая змена прапаза рэдка калі вярнайша слабую систему пошуку.
Заключныя меркі
Калі працюеце над стадзіяй «Фінальная думка», спачатку запісайце умовы працы: неабяжлівыя данні, сигнал успеху і тое, што выходзіць у разе частковага невыпання. Такі список контролю дапамагае заліцварыць пазнейшыя змены ў кодзе. Запісвайце час выканання і кост токеноў або запытаў праза функцыйнае рэзультат. Відразлівасць костаў з самага пачатку запобегае неспакойным рахункам, калі працэс пераходзіць з дэмаверсіі ў спяльныя среды. Замерьце рэткість адказаў на фіксаваны набор запытаў прычым рэгулюванні прапазаў. Частыя змены прапазаў рэдка калі-небудзь выправляюць слабыя аспекты адналічэння інформацыі. Калі працюеце над стадзіяй «Фінальная думка», спачатку запісайце умовы працы: неабяжлівыя данні, сигнал успеху і тое, што выходзіць у разе частковага невыпання. Такі список контролю дапамагае заліцварыць пазнейшыя змены ў кодзе. Аддзекументавайце як «шчаслівы» шлях, так і шлях вяснавання. Перапрыбуткі, людзкія контрольныя пункты і обработка некоректных адказаў ёсць часткай продукту, а не пазнейшым дапрацоўкам.
Пачатак работы
Этап «Пачатак работы» найбэе функцыонуе, калі яго спрыявае можлівасць аналізу ў вачоўку памерных показнікаў. Зберагуце адна ідеальная версія транскрыпцыі, адзін прыклад неудачы і запіс пра вярнэнне да поперадней становішчы, прычаму расширяючы масштабы. Валідзіце лепш маленькія, тэставаныя елементы, чым велікія скрыпты. Калі якісь крок не выйшае, прычына неудачы павінна вказываць на адную конкрэтную адпаведальнасць, а не на заплутаны ланцюг задач. Раздзеляйце правілы часткавага апрантавання і правілы выкарыстоўвання дадзеных. Змена адных не павінна вымагаць перапісву іншых, калі зменяюцыся показнікі якосці.
Чэрніця кантролю
Для этапу «Чэрніця кантролю» практычна ўзначыць вхідныя даны, адпаведальнага за крок і критэрыя завершэння пры змены коду. Аперацыйныя працавнікі павінны магчымае перазапускаць крок з вядомай точкі контролю, не прабуючы здогадвацца пра схованы стан. Зберагуйце настройкі парадульна ад коду прыемленае. Файлы сераўіса, хранільнікі секрэтных дадзеных і флагі функцый павінны знаходзіцца ў адном месцы, якое працавнікі можуць пераглядаць, не чытаючы весь структураны код.
Указаць тыя часткі тексту, які фактычна ляглі в основу адказу. Без цых цытатаў аператары не можаюць разлічыць галюцинацію ад прасоўкі ў індэксаванні.
Напісаць кароткі практычны паказ: як роціраваць канты, як апустошыць чергу, як вярнуць стан да пярэдніх настройкаў.
Дакументаваць як шлях успеху, так і шлях вяснавання. Перапрыбуткі, людзкія перакрыцчы і обработка некоректных паведамленняў є частью продукту, а не чымсь, што дадаецца пазней.
Указаць тыя часткі тексту, які фактычна ляглі в основу адказу. Без цых цытатаў аператары не можаюць разлічыць галюцинацію ад прасоўкі ў індэксаванні.
Перш чым падняць стэк на вышэйшы ранг, заморозіць версіі, зафіксаваць ідеальны транскрыпт для критычнага шляху і падтвердзіць крокі вярнення да пярэдніх настройкаў. У спакульнаваных средах патрэбны ліміты частоты запытоў, перакрыцчы на адпаведнасць тэнантам і чысткі власнік для роціравання секрэтных даных. Лепш выбраць простую надзеямаснасць, чым крэатывныя, але еднакратныя дамыслы.
Запіскі для пакета e54dedbe364e: не класты ключі прадаўцоў у репозітарыю, задаць максымальны ліміт токена на сесію, а таксама зберагчы транскрыпціі праза фіксатуры для ацэнкі, каб пазнейшыя замены моделяў заставаліся порównаннэй.