Головна / Статті / Практичні зауваження: розділення на частини — це приховане дизайнерське рішення в RAG

Практичні зауваження: розділення на частини — це приховане дизайнерське рішення в RAG

Покроковий огляд практичних порад: чанкінг – це приховане дизайнерське рішення в RAG: контракти, перевірки та слоти для коду для команд, які використовують цю схему.

1980 слів

У цьому посібнику детально описано шлях від сировини до функціональної системи для: чанкінг є прихованим дизайнерським рішенням у RAG. Основна увага приділяється крокам, які можна виконувати, чітким перевіркам та коду, який можна додати до репозиторію без необхідності здогадуватися про мету. На етапі огляду необхідно визначити вхідні дані, відповідальну особу за крок та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не здогадуючись про прихований стан. Необхідно документувати як успішний, так і відновлювальний шлях виконання. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої оптимізації.

Потік RAG

Під час роботи над етапом The RAG flow спочатку запишіть умови використання: необхідні дані вхіду, сигнал про успіх та те, що відбувається у разі часткової невдачі. Такий перелік допомагає зберігати чесність пізніших змін у коді. Віддавайте перевагу невеликим, тестованим одиницям коду перед об’ємними скриптами. Якщо якийсь крок зазнає невдачі, причина має вказувати на конкретну відповідальність, а не на заплутану структуру обробки даних. Перед налаштуванням запитів вимірюйте рівень відтворення інформації на фіксованому наборі запитань. Часта зміна формулювань запитів рідко допомагає покращити якість пошуку інформації.

Під час виконання етапу «Від тексту до векторів» спочатку складіть контракт: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Цей перелік допомагає зберігати чесність пізніших змін у коді. Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Дайте назви кожним елементам, визначте критерії успіху та не допускайте безповідомного часткового виконання завдань. Вимірюйте рівень відтворення інформації на фіксованому наборі запитань перед налаштуванням підказок. Часта зміна підказок рідко виправляє проблеми з низькою ефективністю пошуку.

Розмір та перекриття частин

Під час роботи над етапом розміру та перекриття частин даних спочатку запишіть умови використання: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Цей перелік допомагає зберігати чесність у подальших змінах коду. Запишіть час виконання та витрати на токени або запити поруч із функціональними результатами. Чітке бачення витрат заздалегідь запобігає несподіваним рахункам, коли процес переходить від демо-версії до спільних середовищ. Вимірюйте рівень точності відповідей на фіксований набір запитань перед налаштуванням формулювань запитів. Часта зміна формулювань рідко допомагає покращити якість пошуку. Під час роботи над етапом розміру та перекриття частин даних спочатку запишіть умови використання: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Цей перелік допомагає зберігати чесність у подальших змінах коду. Одночасно задокументуйте оптимальний та альтернативний сценарії роботи. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої оптимізації.

DEFAULT_CHUNK_SIZE = 800      # characters
DEFAULT_CHUNK_OVERLAP = 150   # characters
stride = chunk_size − chunk_overlap
       = 800 − 150
       = 650 characters
"…but left school at the age of ten."

Що містить запис у сховищі векторів

Етап «Що містить запис у сховищі векторів» працює найкраще, якщо його розглядати як вимірювану поверхню. Збережіть один ідеальний зразок, один випадок збою та примітку про скасування дій перед розширенням обсягу роботи. Віддавайте перевагу невеликим, тестованим одиницям перед складними скриптами. Коли якась дія зазнає невдачі, причина має вказувати на конкретну відповідальність, а не на заплутану послідовність операцій. Розділяйте політику часткової обробки даних та політику їх пошуку. Зміна однієї з них не повинна змушувати переписувати іншу при зміні показників якості.

id
document
embedding
metadata
id         7c2a1e90-4b11-4d3e-9f08-12a6c0e84b21

document   "His boyhood in Boston was a stern beginning of the habit
            of hard work and rigid economy which marked the man. For
            a year he went to the Latin Grammar School on School
            Street, but left off at the age of ten to help his father
            in making soap and candles."

embedding  384 floats — [-0.0412, 0.0187, 0.0621, -0.0094, 0.0330, …]
           norm = 1.0

metadata   {
             book: "Franklin's Autobiography",
             source: "https://www.gutenberg.org/cache/epub/36151/pg36151-images.html",
             gutenberg_id: 36151,
             page_label: "5",
             chunk_index: 2
           }

Чому важлива нормалізація

Етап «Чому нормалізація має значення» функціонує найкраще, якщо його розглядати як вимірювану поверхню. Запишіть один ідеальний зразок результату, один випадок невдачі та примітки щодо скасування змін перед розширенням обсягу роботи. Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте мовчазного часткового виконання завдань. Розділіть політику часткової обробки даних від політики їх отримання. Зміна однієї з них не повинна змушувати переписувати іншу при зміні показників якості.

‖v‖ = √(v₁² + v₂² + … + vₙ²)
cos θ = (a · b) / (‖a‖ ‖b‖)
If ‖a‖ = ‖b‖ = 1:
cos θ = a · b

Ліміт токенів, якого ви не бачите

Ліміт токенів, який ви використовуєте на етапі тестування, найкраще функціонує, якщо його розглядати як показник для вимірювання. Збережіть один ідеальний запис виконання, один випадок збою та примітку щодо скасування змін перед розширенням обсягу роботи. Записуйте час виконання та витрати на токени або запити поруч із функціональними результатами. Візуальний контроль витрат заздалегідь запобігає несподіваним рахункам, коли процес переходить від демо-версії до спільних середовищ. Визначте бюджет токенів на кожну спробу та на кожну сесію. Інструменти типу агентів активно розширюють контекст; жорсткі ліміти запобігають тому, що демо-версії перетворюються на несподівані рахунки. Ліміт токенів, який ви використовуєте на етапі тестування, найкраще функціонує, якщо його розглядати як показник для вимірювання. Збережіть один ідеальний запис виконання, один випадок збою та примітку щодо скасування змін перед розширенням обсягу роботи. Документуйте як успішний, так і відновлювальний сценарії роботи. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої оптимізації.

maximum safe chunk size in characters
≈ model token limit × 4

Фрагменти коду

На етапі фрагментів коду необхідно визначити вхідні дані, виконавця кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись вгадати прихований стан. Краще використовувати невеликі, перевірювані одиниці коду замість об’ємних скриптів. Коли крок зазнає невдачі, причина має вказувати на конкретну відповідальність, а не на заплутану структуру обробки даних. Наводьте ті уривки, які фактично лежать в основі відповіді. Без посилань оператори не зможуть відрізнити галюцинацію від проблем із індексуванням.

from rag_qa.gutenberg import load_pages
from rag_qa.chunk import chunk_documents
from rag_qa.config import load_settings

s = load_settings()
print(s.summary())
# {
#   'chunk_size_chars': 800,
#   'chunk_overlap_chars': 150,
#   'stride_chars': 650,            # size − overlap; this sets chunk count
#   'model': 'all-MiniLM-L6-v2',
#   'model_max_tokens': 256,        # hard cap; overflow is silent
#   'embedding_dims': 384,
#   'max_safe_chunk_chars': 1024,   # 256 × 4
#   'book': "Franklin's Autobiography",
#   'gutenberg_id': 36151,
# }
pages = load_pages()
chunks = chunk_documents(pages, s.chunk_size, s.chunk_overlap)
print(len(pages), len(chunks), s.stride)
from sentence_transformers import SentenceTransformer
from rag_qa.tokens import check_chunk

m = SentenceTransformer("all-MiniLM-L6-v2")
print(m.max_seq_length)                    # 256
for c in chunks:
    r = check_chunk(c)
    if r.truncated:
        print("silent truncate:", r.n_chars, "chars /", r.n_tokens, "tokens")
256
256
silent truncate: 1820 chars / 412 tokens
silent truncate: 960 chars / 301 tokens
from rag_qa.store import ingest, open_store

store = open_store()
ingest(chunks, store)
row = store.get(limit=1)
print(row["ids"][0])
print(row["documents"][0][:200])
print(len(row["embeddings"][0]), row["metadatas"][0])
# 384 floats, norm 1.0, metadata.page_label == printed [Pg N]
doc-12-p3-c0
She left school at the age of ten. The next sentence continues on the same page…
384 {'page_label': '3', 'source': 'notes.pdf'}
from rag_qa.retrieve import search, search_mmr

q = "why did Franklin want Britain to keep Canada"

for hit in search(q, k=5):
    print(f"{hit['score']:.3f}  p.{hit['metadata']['page_label']}  {hit['document'][:120]}")
# overlap makes near-duplicate hits; MMR trades a little score for diversity

for hit in search_mmr(q, k=5):
    print(hit["metadata"]["page_label"], hit["score"])
0.812  p.7  I have long been of opinion that the foundations of the future grandeur and stability of the British empire lie in America
0.781  p.7  they are, nevertheless, broad and strong enough to support the greatest political structure that human wisdom ever yet
0.744  p.7  I am, therefore, by no means for restoring Canada. If we keep it all the country from the St. Lawrence to the Mississippi
0.691  p.8  I left England about the end of August, 1762, in company with ten sail of merchant ships
0.640  p.6  In this Autobiography Franklin tells of his own life to the year 1757, when he went to England

Додаток

На етапі Додатку необхідно визначити вхідні дані, відповідальну особу за крок та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись вгадати прихований стан. Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте мовчазного часткового завершення. Наводьте конкретні уривки, які лежать в основі відповіді. Без посилань оператори не зможуть відрізнити галюцинацію від проблем із індексуванням.

A. Той самий уривок, періодичне збігання

На етапі перекриття однакових уривків тексту необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість знову виконати крок з відомої точки контролю, не намагаючись вгадати прихований стан. Записуйте час виконання та витрати на токени чи запити поруч із функціональними результатами. Чітке відображення витрат заздалегідь запобігає несподіваним рахункам під час переходу з демо-середовища у спільні середовища. Наводьте конкретні уривки тексту, які лягли в основу відповіді. Без посилань оператори не зможуть відрізнити галюцинації від проблем з індексуванням. На етапі перекриття однакових уривків тексту необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість знову виконати крок з відомої точки контролю, не намагаючись вгадати прихований стан. Документуйте як успішний, так і відновлювальний сценарії роботи. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої оптимізації.

[0] 59  His boyhood in Boston was a stern beginning of the habit of
[1] 55  hard work and rigid economy which marked the man. For a
[2] 58  year he went to the Latin Grammar School on School Street,
[3] 31  but left off at the age of ten.
[0] 59  His boyhood in Boston was a stern beginning of the habit of
[1] 57  ⟦the habit of⟧ hard work and rigid economy which marked the
[2] 55  ⟦marked the⟧ man. For a year he went to the Latin Grammar
[3] 58  ⟦Latin Grammar⟧ School on School Street, but left off at the
[4] 22  ⟦off at the⟧ age of ten.
⟦…⟧ = text repeated from the previous chunk

B. Бібліотеки для створення RAG та куди потрапляють вектори

Під час роботи над етапом використання бібліотек для створення RAG спочатку складіть контракт: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Такий перелік допомагає зберігати чесність пізніших змін у коді. Віддавайте перевагу невеликим, тестованим одиницям коду перед об’ємними скриптами. Коли якийсь крок зазнає невдачі, причина має вказувати на конкретну відповідальність, а не на заплутану послідовність операцій. Перед налаштуванням запитів вимірюйте рівень відтворення інформації на фіксованому наборі запитань. Часта зміна формулювань запитів рідко допомагає покращити ефективність пошуку інформації.

Перелік операційних кроків

Етап переліку операційних кроків працює найкраще, якщо його розглядати як вимірюваний показник. Збережіть один ідеальний зразок виконання, один випадок невдачі та примітки щодо скасування змін перед розширенням обсягу роботи.

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

Розділіть політику часткової обробки даних від політики їх отримання. Зміна однієї з них не повинна змушувати переписувати іншу при зміні показників якості.

Коли це дозволяють бюджетні обмеження, додайте тест на базову функціональність, який перевіряє критичний шлях у процесі CI за допомогою фікстур, а не реальних платних API.

Одночасно задокументуйте шлях успішної роботи та шлях відновлення. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої оптимізації.

Розділіть політику часткової обробки даних від політики їх отримання. Зміна однієї з них не повинна змушувати переписувати іншу при зміні показників якості.

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

Примітка до запису 62ec22cbf28d: не зберігайте ключі постачальника у репозиторії, встановіть ліміт токенів на сеанс та зберігайте записи поруч із фікстурами для оцінки, щоб подальша заміна моделей залишалася порівнянною.