Практычныя прытамулкі: Я перапрацаваў RAG-Anything на 65 кнігах пра вайн. Ось што...
Практычныя прытамулкі: Я перабраў RAG-Anything на 65 кнігах пра вайн. Чым можна скорасты роботу: контракты, перакананні та спецыяльныя месца для коду для команд, якія викорыстоўваюць гэты патэрн.
У гэтым карыце парадоксальная дорага ад сыр'ёў да рабочай системы для: «Я працаваў з RAG-Anything на 65 кнігах Wine. Чаго досягае граф знаёмых — і чаго не можа...». Акцэнт ставіцца на практычныя крокі, чыстае перакананне і код, які можна проста дадаць у репазітарый без неабяснення меты. У стадзіі агульнага відгледу неабходна прадзефінаваць вхідныя даны, адпаведальную особу за крок і критэрыя завершэння пры перамены коду. Аперацыйныя працавнікі должны магчымае перадзеўжваць крок з вядомай точкі перапытку без неабяснення схованага стану. Запісваюцься часы выконання і вартасць токенаў або запытак паляглі ўжо разам з функцыйнальнымі рэзултатамі. Відразувыя даны пра вартасці запобегаюць неспадзяваным рахункам, калі дорага пераходзіць з дэмаверсіі ў спяльныя среды.
Чаму вы падалі 65 кнігах Wine у граф знаёмых
Калі працюеце над этапам «Чырвоныя прычыны 65», спачатку запісайце умовы кантракту: неабяжлівыя данні, сігнал успеху і тое, што выходзіць пад частыя неудачы. Такі список дапамагае заліцварваць будучыя змены ў кодзе. Зберагаюце настройкі паза кодам прыемліка. Файлы сераўіса, хранільнікі секрэтных данных і флагі функцыйяў должны знаходзіцца ў аднам месцы, куды аператары можаць адбавіць аудыт без неабяжлівага чытання всей структуры. Перад налаштаваннем запитоў пераканайцеся, што система правільна адзначае важлівыя данні, выкарыстоўваючы фіксаваны набор запитанняў. Частае змены запітоў рэдка калі выправляюць слабыя аспекты пошуку.
Як працюе RAG-Anything (версія за 60 секунд)
Калі працуеце над этапам «Як працюе RAG-Anything», спачатку запісайте умовы виконання: неабяцковыя даны, сігнал успеху і тое, што вядзецца праз частковыя неудачы. Такі список дапамагае заліцварваць можлівыя змены ў коде. Документавайце як правільны, так і альтернатыўны шляхі виконання. Практыка перапрыбуткавань, людзкі контроль і обработка некоректных паведамленняў є частью самага продукту, а не дадатковыми элементамі для його удосконалення. Перад налаштаваньмю запрошэнняяў (prompts) пераканайцеся ў рівні воспамінання на фіксаванай сэтцы запитаў. Частая зміна запрошэнняяў рэдка калі вядзець да павышэння якасці адналёгчэння інформацыі.
PDF Document
|
v
[Document Parser] ─── MinerU (VLM-based) or Docling (lighter/cheaper)
|
v
[Content Extraction] ─── text, tables, images, equations
|
v
[Text Chunking] ─── split into manageable pieces
|
v
[LLM Entity/Relation Extraction] ─── LLM extracts entities + relationships
|
├──> [Knowledge Graph] ─── entities as nodes, relations as edges (GraphML)
└──> [Vector Embeddings] ─── chunks embedded for similarity search (JSON)
+--------+------------------------------+-------------------------------+---------------------------------+
| Mode | What It Searches | Best For | Weakness |
+--------+------------------------------+-------------------------------+---------------------------------+
| naive | Vector similarity only | Factoid questions, robustness | Misses relational structure |
| local | Graph neighborhood traversal | Entity-specific deep dives | Blind to entities not extracted |
| global | Community-level summaries | Broad thematic questions | Less specific, slower |
| hybrid | local + global | Balanced depth and breadth | No vector fallback |
| mix | Graph + vector together | General-purpose (recommended) | Slowest mode |
+--------+------------------------------+-------------------------------+---------------------------------+
from openai import AsyncOpenAI
from lightrag.utils import EmbeddingFunc
from raganything import RAGAnythingConfig
aclient = AsyncOpenAI(api_key=os.getenv("OPENAI_API_KEY"))
# Text LLM - handles entity extraction and answer synthesis
async def llm_model_func(prompt, system_prompt=None, history_messages=None, **kwargs):
messages = []
if system_prompt:
messages.append({"role": "system", "content": system_prompt})
if history_messages:
messages.extend(history_messages)
messages.append({"role": "user", "content": prompt})
response = await aclient.chat.completions.create(
model="gpt-4o-mini", messages=messages, temperature=0.0,
)
return response.choices[0].message.content
# Embeddings - 1,536 dimensions, 8K token window
async def _embed_texts(texts, **kwargs):
response = await aclient.embeddings.create(model="text-embedding-3-small", input=texts)
return np.array([item.embedding for item in response.data])
embedding_func = EmbeddingFunc(embedding_dim=1536, max_token_size=8192, func=_embed_texts)
# Configuration - Docling parser, tables enabled, images disabled for cost
rag_config = RAGAnythingConfig(
working_dir="./rag_storage",
parser="docling",
enable_image_processing=False, # skipping images - valid for my use-case
enable_table_processing=True,
enable_equation_processing=True,
)
Працэс абрабоцкі 65 кніг пра вайну: парсеры, неудачы і часавыя практыкі
Калі вы працюеце над этапам «Прыем 65 кнігаў пра вайну», спачатку запісуйце угоду: неабходныя даны, сигнал успеху і тое, што выканаецца у разы частковага невясковасці. Такі список контроля дапамагае залічыць пазнейшыя змены ў кодзе. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшоў, невясковасць павінна вказваць на адную адпаведальнасць, а не на заплутаны ланцюг задач. Перад налаштаваннем запитоў пераканайцеся, наскількі эфектыва система адпаведзае на фіксаваны набор запитанняў. Частае зміненне запитоў рэдка калі-небудзь выправляе слабкую эфектывнасць адзыскання інформаціі.
Набор дадзеных
Калі працюеце над стадзіяй «Набор данных», спачатку запісайце угоду: неабяжлівыя вхідныя даны, сігнал успеху і тое, што выходзіць у разе частковага невыпання. Такі список пераконтроўвае чыстасць пазнейшых змян у кодзе. Спрыятлівае ставленне да гэтай стадзіі як да угоды межа вхіднымі данымі і перакананымі выходнымі рэзультатамі. Дайце назвы артыфактам, задаце критэрыя успеху і не падзволяйце частковым завершэнням без паведамлення. Змяркуйце рівень запам’ятовання на фіксаваным наборы пытанняў прычым перэналаштаваць запрошэння. Частыя змены запрошэння рэдка калі вядуць да павышэння якасці адзысквання інформацыі.
Супербатл парсераў: MinerU проты Docling
Калі працуеце над Parser Showdown MinerU vs stage, спачатку запісайте умовы працы: неабяжлівыя данні, сигнал успеху і тое, што выходзіць у разе частковага невыпання. Такі список дапамагае заліцварыць будучыя змены ў кодзе. Запісвайце час выканання і кост токеноў або запытаў праза функцыйнае рэзультат. Відразлівасць костаў з самага пачатку запобегае неспакойным рахункам, калі праця пераходзіць з дэмавайнтару ў спяльныя среды. Замерьце рэкалі на фіксаванай сэтке запытаў прычым регулюванні прапаза. Частыя змены прапаза рэдка калі-небудзь выправляюць слабую эфектыўнасць адзысквання інформаціі.
Працэс прыемкі даных
Калі працюеце над стадзіяй «The Ingestion Pipeline», спачатку запісайце умовы працы: неабяжлівыя даннэ, сігнал успеху і тое, што выходзіць пад частыя неудачы. Такі список контроля дапамагае заліцьварыць пазнейшыя змены ў кодзе. Храніце настройкі парадульна ад коду прыемліка. Файлы сераўіснага сэрвісу, хранальнікі секретных данных і флагі функцыйяў должны знаходзіцца ў аднам месцы, куды аператары можаюць адбавіць аудыт без неабяжлівага чытання всей структуры. Перад налаштаваннем запитоў пераканайцеся ў рэверсі на аднам фіксаваным наборе запитаў. Частыя змены запітоў рэдка калі вядуць да павышэння якасці выкарыстоўвання данных.
from raganything import RAGAnything
rag = RAGAnything(
config=rag_config,
llm_model_func=llm_model_func,
embedding_func=embedding_func,
)
for pdf_path in sorted(Path("./data").glob("*.pdf")):
file_start = time.time()
await rag.process_document_complete(
file_path=str(pdf_path),
output_dir="./output",
)
print(f"Completed {pdf_path.name} in {time.time() - file_start:.1f}s")
await rag.finalize_storages()
Рэзультаты за час
Калі працюеце над стадзіяй «Рэзультаты часавання», спачатку запісайце умовы кантракту: неабяжлівыя даны, сігнал успеху і тое, што выканаецца у разе частковага нявыполнення. Такі список контроля дапамагае заліцварыць будучыя змены коду.
Як выглядае граф
Калі працуеце над стадзіяй «Як выглядае граф», спачатку запісайце умовы вярбунка: неабяжлівыя данні, сігнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі список дапамагае заліцьваты пазнейшыя змены коду. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшае, прычына нявыпання павінна вказываць на адзін конкрэтны аспект, а не на заплутаны ланцюг задач. Перад налаштаваннем запитоў пераканайцеся, наскількі эфектыва система адпаведае на фіксаваны набор запитанняў. Частыя змены запитоў рэдка калі вядуць да павышэння якосці адзысквання інформацыі. Калі працуеце над стадзіяй «Як выглядае граф», спачатку запісайце умовы вярбунка: неабяжлівыя данні, сігнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі список дапамагае заліцьваты пазнейшыя змены коду. Рэгіструйце час выканання і кост токеноў або запытаў разам з функцыйнальнымі рэзултатамі. Відразувыя даны пра косты запобегаюць неспакойным рахункам, калі працэс пераходзіць з дэмавайнага режыма ў спяльныя сервісы.
+----------------------------+------------------------------+
| Metric | Value |
+----------------------------+------------------------------+
| Entities (graph nodes) | 37,132 |
| Relations (graph edges) | 47,650 |
| Text chunks | 6,247 |
| Storage on disk | ~185 MB (all JSON + GraphML) |
| Indexed documents | 65 |
| Load time at query startup | ~10 seconds |
+----------------------------+------------------------------+
Граф проты вектара: 6 запитоў, 2 режымы, чыстыя рэзультаты
Этап «Граф проты вектара 6» работае наякша, калі яго спрыяваць як вимерную паверхню. Запісаўце адны ідеальны прыклад, адну справу з бягам і прыміткі па поверненню да пачатковага стану пры розшырэнні масштаба. Хавайце настройкі за межамі коду прыемліка. Файлы сяродавішча, хранільнікі секрэтных дадзеных і флагі функцыйяў должны знаходзіцца ў аднам месцы, куды аператары можаць адбавіць аудыт без неабяжнага чытання всіх дадзеных. Раздзеляйце правілы часткавання дадзеных і правілы ўзяць іх. Змена адных не павінна вымагаць перапісву іншых, калі зменяюцыся паказнікі якосці.
async def compare_modes(rag, query):
"""Compare different retrieval modes on the same query."""
for mode in ["local", "naive"]:
result = await rag.aquery(query, mode=mode)
print(f"[{mode}] {len(result)} chars, {elapsed:.1f}s")
Рэзультаты
Этап «Рэзултаты» працюе наяўней, калі яго спрыяваць як мерыемую паверхню. Запісаце адна ідеальная версія, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перш чым расширваць масштабы. Дакументаваце як успішны, так і вярнучыся шляхы. Перапрыбуткі, людзкія контралі і обработка некоректных паведамленняў ёсць часткай продукту, а не чымось, што дадаецца пазней. Раздзеліце політыку часткавай обработкі ад політыки выкарыстоўвання дакументаў. Змена адной не должна прымусіць перапісваць другую, калі зменяюцыся паказнікі якосці.
+---------------------------------------------------+----------------------+---------------------+-------------------------------+
| Query | Graph (local) | Vector (naive) | Winner |
+---------------------------------------------------+----------------------+---------------------+-------------------------------+
| How does soil type influence wine character? | 32.5s / 3,464 chars | 28.2s / 2,531 chars | Tie |
| Relationship between tannins, acidity, and aging? | 24.8s / 2,266 chars | 25.8s / 2,289 chars | Graph (structure) |
| Compare red vs. white winemaking | 32.9s / 3,119 chars | 42.0s / 3,423 chars | Graph (speed + structure). |
| What role does yeast play in fermentation? | 27.8s / 2,587 chars | 26.8s / 2,403 chars | Tie |
| How do fortified wines differ from table wines? | 28.5s / 2,635 chars | 23.1s / 2,597 chars | Tie |
| Sparkling wine production methods? | 10.7s / 48 chars | 48.4s / 2,900 chars | Vector (graph fails) |
+---------------------------------------------------+----------------------+---------------------+-------------------------------+
Дзе выграў режым графа
Этап «Where Graph Mode Wins» працюе найкраща, калі яго спрыяваць як до меры можна. Зафіксавайце адны ідеальны прыклад, адну справу з бягамі та прыметкі па поверненню да пачатковага стану пры розшырэнні масштаба. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшае, прычына бягу должна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцюг задач. Раздзеляйце правілы часткавання дадзеных і правілы ўтрымання іх. Змена адных не должна вымагаць перапісву іншых, калі зменяюцыся паказателі якосці. Этап «Where Graph Mode Wins» працюе найкраща, калі яго спрыяваць як до меры можна. Зафіксавайце адны ідеальны прыклад, адну справу з бягамі та прыметкі па поверненню да пачатковага стану пры розшырэнні масштаба. Запісвайце часы выконання та косты токенав або запитоў разам з функцыональнымі рэзультатамі. Відразлівасць костаў з самага пачатку запобегае неспакойным рахункам, калі процес пераходзіць з дэмавайнага режыма ў спяльныя сераўы.
Дзе яны равны
Для стадіі «Where They re Equal» неабяжна ўзначыць вхідныя даны, абавесць крока і крэтыры выходу пры перадзеі коду. Аператары должны магчымаць перзапуск крока з вядомай точкі контролю, не падозрываючы схованы стан. Конфігурацыю трэба захаваць пазначыльна ад коду прыкладнення. Файлы сераўнавання, хранілішчы секрэтных дадзеных і флагі функций должны знаходзіцца ў аднам месцы, якое аператары можаць пераглядаць, не чытаяўшы весь граф. Наводзіце часткі тексту, якія фактычна сталі падставай для адпаведзення. Без ціх цитатаў аператары не можаць разлічыць галюцинацію ад прасоўкі ў індэксаванні.
Працоўнае выкліканне: Sparkling Wine
Для стадіі «The Failure Sparkling Wine» неабяжна прадзеўдзіць вхідныя даны, адпаведальнага за крок і крэтыяры завершэння пры перадзмене коду. Аперацыйныя працавнікі павінны магчыма было перзапусціць крок з вядомага пункта контролю, не спрабоўваючы з’ясаваць схованы стан. Неабяжна задокументаваць як шлях успеху, так і шлях вяснавання ситуацыі. Перапрыбуткі, людзкія перакрыцці і обробка некоректных паведамленняў є часткай продукту, а не чымсь, што дадаецца пазней. Паказваць часткі тексту, якія фактычна лежаць у падставе адпаведнай адказы. Без ціх цитатаў аперацыйныя працавнікі не зможуць адразніць галюцинацыю ад прасоў у індэксаванні.
Аналіз часу
Для стадіі аналізу часу неабяцо практычна выявіць вхідныя даны, адпаведальнага за крок і крэтырыя для завершэння пры перадзеіснаванні коду. Аператары должны магчымаць перзапуск крока з вядомай точкі контролю, не падозрываючы прыхованы стан. Лепш выбіраць маленькія, тэставаныя елементы замест большых скрыптов. Калі крок не выконваецца, прычына нехарактэрства павінна вказываць на адзін конкрэтны элемент, а не на заплутаны ланцюг задач. Указваць тыя часткі тексту, якія фактычна служылі падставай для адказу. Без цых цитатаў аператары не можаць разлічыць галюцинацію ад працягу індэксавання. Для стадіі аналізу часу неабяцо практычна выявіць вхідныя даны, адпаведальнага за крок і крэтырыя для завершэння пры перадзеіснаванні коду. Аператары должны магчымаць перзапуск крока з вядомай точкі контролю, не падозрываючы прыхованы стан. Запісваць час выконання і кост токеноў або запытаў разам з функцыйнальнымі рэзультатамі. Відразувыя даны пра косты запобегаюць неспакоўным рашчыткам, калі процес пераходзіць з дэмовай среды ў спакульнаваныя сераўы.
Як выглядаюць 3,713 аб’ектаў вайна
Калі працуеце над этапам «Што такое 3,713 аб’ектаў вайна», спачатку запішыце контракт: неабходныя даны, сигнал успеху і тое, што відбываецца у разы частковага невыпання. Такі список дапамагае заліцварыць пазнейшыя змены ў кодзе. Зберагаюце настройкі паза кодам прыемліка. Файлы сераўнавання, хранільнікі секрэтных дадзеных і флагі функцыйяў должны знаходзіцца ў аднам месцы, куды аператары можаць пераглядаць іх без неабходнасці чытання всей структуры. Перад налаштаваннем запитоў пераканайцеся, як працуе алгорытм на фіксаванай сэтке запытаў. Частае зміненне запытаў рэдка калі-небудзь выправляе слабкую эфективнасць алгорытму пошуку.
import networkx as nx
from pyvis.network import Network
G = nx.read_graphml("rag_storage/graph_chunk_entity_relation.graphml")
# Focus on the most connected nodes (hubs)
degree_dict = dict(G.degree())
top_nodes = sorted(degree_dict, key=degree_dict.get, reverse=True)[:120]
subG = G.subgraph(top_nodes).copy()
# Categorize nodes by wine domain keywords
def categorize(name):
lower = name.lower()
if any(k in lower for k in ["cabernet", "merlot", "pinot", "riesling", ...]):
return "grape" # Red nodes
if any(k in lower for k in ["bordeaux", "california", "champagne", ...]):
return "region" # Blue nodes
if any(k in lower for k in ["fermentation", "aging", "maceration", ...]):
return "process" # Green nodes
if any(k in lower for k in ["port", "sherry", "sparkling", ...]):
return "wine_type" # Orange nodes
return "general" # Purple nodes
+--------------------+-------------+-----------+
| Entity | Connections | Category |
+--------------------+-------------+-----------+
| Wine | 2,136 | General |
| Wine Production | 1,344 | General |
| Italian Wines | 768 | General |
| Bordeaux | 442 | Region |
| Cabernet Sauvignon | 420 | Grape |
| Riesling | 412 | Grape |
| Champagne | 348 | Region |
| California | 321 | Region |
| Grapes | 287 | Grape |
| Port | 243 | Wine Type |
+--------------------+-------------+-----------+
Інтеграцыя ў веб-інтерфейс
Калі працюеце над этапам разработкі, спачатку запісайце умовы контракту: неабяжлівыя даны, сігнал успеху і тое, што вядзецца пад частым нявыпаннем. Такі список пераконвае ў тым, што пазнейшыя змены коду будуць чыстымі. Документавайце як шлях успеху, так і шлях вярнення да стану нормы. Перапрыбуткі, людзкія контралі і обработка некоректных паведамленняў є частью продукту, а не пазнейшым дапрацоўкам. Перад налаштаваннем запитаў пераканайцеся ў правільнасці адзыву на фіксаваны набор запитаў. Частая зміна запитоў рэдка калі вярнайце слабкую эфектыўнасць адзыву.
import gradio as gr
def query_wine(question, mode):
t0 = time.time()
result = _run_async(_query(question, mode))
elapsed = time.time() - t0
return result, f"**Mode:** {mode} | **Time:** {elapsed:.1f}s"
with gr.Blocks(title="Wine Knowledge RAG") as demo:
question = gr.Textbox(label="Ask a wine question", lines=2)
mode = gr.Radio(
choices=["mix", "local", "global", "hybrid", "naive"],
value="mix", label="Retrieval Mode",
)
submit_btn = gr.Button("Ask", variant="primary")
stats = gr.Markdown("")
answer = gr.Markdown(label="Answer")
submit_btn.click(fn=query_wine, inputs=[question, mode], outputs=[answer, stats])
Што трэба сказаць перш чым адмацаваць RAG-Anything
Калі працюеце над этапам «Што вы скажаце», спачатку запісайце умовы контракту: неабяжлівыя даны, сігнал успеху і тое, што выканаецца у разы частковага нявыполнення. Такі список контроля дапамагае заліцварыць будучыя змены коду. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшае, прычына нявыполнення павінна вказываць на адзін конкрэтны аспект, а не на заплутаны ланцюг задач. Перад налаштаваннем запитоў пераканайцеся, што система правільна запам’ятае інформацыю, выкорыстоўваючы фіксаваны набор запитанняў. Частае змены запитоў рэдка калі вярнуюць нормальную працэздатнась системы.
Калі Graph RAG даўа рэальную цянь
Калі працюеце над стадзіяй «When Graph RAG Adds», спачатку запісайце контракт: неабяжлівыя даннэ, сігнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі список перакладзець пазнейшыя змены коду на адказнае. Спрыятліваце гэтую стадзію як контракт межа даннемі і перакананымі выходамі. Дайце назвы артыфактам, задаце правіла пераканання успеху і не падзейцеся частковым завершэнням без адказу. Замерайце рівень запам’ятовання на фіксаванай сэтцы пытанняў прычымо да налаштавання запрасаў. Частыя змены запрасаў рэдка калі выправляюць слабкую систему аднаходжэння інформацыі.
Калі гэта не дапамагае (або шкодзіць)
Калі працюеце з этапам «Калі гэта не спрацоўвае», спачатку запісайце умовы кантракту: неабходныя даны, сігнал успеху і тое, што выходзіць пад частым неудачам. Такі список контроля дапамагае залічыцца з пазнейшымі змянамі ў кодзе. Запісвайце час выканання і кост токена або запыту пад функцыйнальнымі рэзултатамі. Відразы коста з самага пачатку запобегае неспакою, калі процес пераходзіць з дэмовай среды ў спяльныя сераўеры. Замерьце рэткість аднаходжэння адпаведных даўедзенняў на фіксованыя наборы запытаў прычым рэгулювання підказак. Частае змяненне підказак рэдка калі-небудзь выправляе слабыя аспекты пошуку.
Практычныя рэкамендацыі
Калі працюеце над стадзіяй «Практычныя рэкамендацыі», спачатку запісайце угоду: неабяжлівыя данны, сігнал успеху і тое, што выходзіць пад частыя неудачы. Такі список контроля дапамагае заліцвачыць змяны ў кодзе пазнейша. Зберагайце настройкі за межамі коду прыемліка. Файлы сераўіса, хранільнікі секрэтных данных і флагі функцыйяў должны знаходзіцца ў аднам месцы, куды аператары можаць адбавіць аудыт без неабяжлівага чытання всей структуры. Перад налаштаваннем запитоў пераканайцеся ў рэверыі на фіксаванай сэтке запитаў. Частыя змены запітоў рэдка калі выправляюць слабую эфектыўнасць адзысквання дакументаў.
+----------------------------+----------------+---------------+-------------------+
| Query Type | Vector (naive) | Graph (local) | Mix (recommended) |
+----------------------------+----------------+---------------+-------------------+
| Factoid lookup | Good | Good | Good |
| Relational ("X affects Y") | OK | Best | Best |
| Comparative ("A vs B") | OK | Best | Best |
| Cross-document synthesis | OK | Good | Best |
| Topic with extraction gaps | Best | Fails | Good |
+----------------------------+----------------+---------------+-------------------+
Уснагае
Калі працюеце над стадзіяй «The Bottom Line», спачатку запісайце контракт: неабяжлівыя даны, сігнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі список пераконтролю дапамагае заліцьварыць чыстасць пазнейшых змян у кодзе. Документавайце як шлях успеху, так і шлях вярнення. Перапрыбуткі, людзкіе перакрыцця і обробка некоректных паведамленняў ёсць часткай продукту, а не пазнейшым дапрацоўкам. Перад налаштаваннем запытанняў змерайце рэкалі на фіксаваным наборы запытанняў. Змена запытанняў рэдка калі вярнайце слабкую якасць адзысквання інформаціі.
Чэк-ліст для эксплуатацыі
Стадзія чэк-ліста для эксплуатацыі працюе лепей, калі яе спрыяваць як меравальную плошчу. Запісайце адна ідеальная транскрыпцыя, адзін прыклад нявыпання і прыметку па вярненню да пачатковага стану перш чым расширваць масштаб. Спрыявайце гэтай стадзіі як контракту межа данымі і перакананымі выходамі. Дайце назвы артыфактам, задаце критэрыя успеху і адмовіцеся ад мовчанкавага частковага завершэння.
Раздзеліце політыку часткавання дадзейнаў ад політыки ўзяць іх. Змена адной з яных не павінна вымагаць перапісву другой, калі зменяюцыся паказнікі якосці.
Дадзейснюйце тэсты на працэс, які перавершвае критычны шлях у системе CI з викорыстаннем фіксатываў, а не рэальных платных API, калі тое дазволяе бюджет.
Запісвайце час выканання аперацый, а таксама кост токенаў чы супылакоў, праза функцыйнае рэзультат. Відразлівае відображэнне костаў запобегае неспакойным рахункам, калі шлях пераходзіць з дэмавайнага режыма ў спадзеленыя сераўеры.
Раздзеліце політыку часткавання дадзейнаў ад політыки ўзяць іх. Змена адной з яых не павінна вымагаць перапісву другой, калі зменяюцыся паказнікі якосці.
Перш чым пераводзіць всю структуру, заморозьце версіі, зафіксавайце ідеальны варыянт дадзейнаў для критычнага шляху і паказвайце способы адворачэння змян. У спадзеленых сераўерах неабходны ліміты на колькасць запытоў, перакананні ў правах на выкарыстоўванне ресурсаў і чысткі власнік для змены секрэтных даных. Валіце простую надзейнасць працы над крэатывнымі, але разовымі дэмамі.
Запіскі для пакета 02b0708cdf33: не класты ключі прадаўцоў у репазітарыю, задаць максымальны ліміт токена на сесію, а таксама зберагчы транскрыпціі празаўсюды з фікстурамі для ацэнкі, каб пазнейшыя замены моделяў заставаліся порównаннэй.