Strona główna / Artykuły / Uwagi praktyczne: Przetestowałem RAG-Anything na 65 książkach o winie. Oto co...

Uwagi praktyczne: Przetestowałem RAG-Anything na 65 książkach o winie. Oto co...

Krok po kroku instrukcja obsługi „Praktyczne uwagi”: Przetestowałem RAG-Anything na 65 książkach o Wine. Oto co obejmuje: umowy, sprawdzenia oraz miejsca na kod do wstawienia dla zespołów wdrażających ten wzorzec.

3229 słów

To przewodnictwo pokazuje, jak przejść od surowców do działającego systemu w następujących przypadkach: Przetestowałem RAG-Anything na 65 książkach o winie. Oto co dobrze robi graf wiedzy — i co pomija… Skupiamy się na krokach operacyjnych, wyraźnych sprawdzeniach oraz kodzie, który można bez żadnych domysłów wkleić do repozytorium. Na etapie przeglądu należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Zapisujmy czas wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy proces przechodzi z środowiska demonstracyjnego do współdzielonych środowisk.

Dlaczego podałeś 65 książek o winie do grafu wiedzy

Gdy przechodzisz przez etap „Dlaczego podałeś 65”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Trzymaj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury. Zmierz stopę odzyskiwania informacji na ustalonej serii pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe mechanizmy wyszukiwania.

Jak działa RAG-Anything (wersja 60 sekund)

Gdy pracujesz nad etapem „Jak działa RAG-Anything”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zdokumentuj zarówno prawidłowy przebieg działania, jak i ścieżkę naprawczą. Próby ponowne, kontrola przez ludzi oraz obsługa wiadomości błędowych są częścią produktu, a nie elementem późniejszej dopracowywania. Zmierz stopień odzyskiwania informacji na ustalonej serii pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe mechanizmy wyszukiwania.

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,
)

Przetwarzanie 65 książek o winie: parserzy, błędy i czasy wykonywania

Gdy przechodzisz przez etap przetwarzania 65 książek o winie, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Zmierz stopień odzyskiwania informacji na ustalonej grupie pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe możliwości wyszukiwania.

Zbiór danych

Gdy przechodzisz przez etap The Dataset, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzuć przypadkowe, częściowe ukończenie zadania. Zmierz stopień przywoływalności na ustalonej serii pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe możliwości wyszukiwania.

Pojedynek parserów: MinerU kontra Docling

Gdy pracujesz nad etapem Parser Showdown MinerU, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Obok wyników funkcjonalnych zapisz czas wykonywania oraz koszt tokenów lub zapytań. Jasna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy przechodzi się z środowiska demonstracyjnego do współdzielonych środowisk. Zmierz stopień odzyskiwania informacji na ustalonej grupie pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko poprawiają słabe możliwości wyszukiwania.

Przewodnik przetwarzania danych

Gdy przechodzisz przez etap The Ingestion Pipeline, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Trzymaj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury. Zmierz stopę odzyskiwania informacji na ustalonej grupie pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe możliwości wyszukiwania.

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()

Czas realizacji

Gdy przechodzisz przez etap wyników czasowych, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zdokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponowne, kontrolne punkty ludzkie oraz obsługa wiadomości nieodebranych stanowią część produktu, a nie elementy dodawane później w celu udoskonalenia. Zmierz stopień odzyskiwania informacji na ustalonej grupie pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe mechanizmy wyszukiwania.

Jak wygląda wykres

Gdy przechodzisz przez etap „Jak wygląda graf”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Zmierz stopień przywoływania informacji na ustalonej serii pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe możliwości wyszukiwania. Gdy przechodzisz przez etap „Jak wygląda graf”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Obok wyników funkcjonalnych zapisz czas wykonywania oraz koszt tokenów lub zapytań. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy przechodzi się z środowiska demonstracyjnego do wspólnych środowisk.

+----------------------------+------------------------------+
| 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                  |
+----------------------------+------------------------------+

Graf vs. Wektor: 6 zapytań, 2 tryby, uczciwe wyniki

Etap Graph vs Vector 6 działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię. Zapisz jeden idealny przykład działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. Utrzymuj konfigurację poza kodem aplikacji. Pliki środowiskowe, skrytki z danymi poufnymi oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całego grafu. Oddziel zasadę dzielenia na fragmenty od zasady wyszukiwania. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej, gdy zmieniają się metryki jakości.

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")

Wyniki

Faza „The Results” funkcjonuje najlepiej, gdy traktowana jest jako mierzalna powierzchnia. Zapisz jeden idealny przypadek, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres pracy. Zdokumentuj zarówno pomyślny, jak i awaryjny scenariusz działania. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości nieodebranych stanowią część produktu, a nie elementy dodawane później w celu udoskonalenia. Oddziel zasadę dzielenia na fragmenty od zasady wyszukiwania. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej, gdy zmieniają się metryki jakości.

+---------------------------------------------------+----------------------+---------------------+-------------------------------+
| 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)          |
+---------------------------------------------------+----------------------+---------------------+-------------------------------+

Gdzie tryb grafowy ma przewagę

Faza „Where Graph Mode Wins” funkcjonuje najlepiej, gdy jest traktowana jako mierzalna powierzchnia. Zapisz jeden idealny przykład działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Oddziel zasadę dzielenia na fragmenty od zasady pobierania danych. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej, gdy zmieniają się metryki jakości. Faza „Where Graph Mode Wins” funkcjonuje najlepiej, gdy jest traktowana jako mierzalna powierzchnia. Zapisz jeden idealny przykład działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. Zapisuj czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy proces przechodzi z środowiska demonstracyjnego do współdzielonych środowisk.

Gdzie są równe

W etapie „Gdzie są równe” należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić ten krok od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Konfigurację należy przechowywać poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić, nie musząc czytać całej struktury. Należy podawać konkretne fragmenty tekstu, na których opiera się odpowiedź. Bez tych odniesień operatorzy nie będą w stanie odróżnić halucynacji od luki w indeksowaniu.

Porażka: Sparkling Wine

Dla etapu The Failure Sparkling Wine należy zdefiniować dane wejściowe, osobę odpowiedzialną za ten krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy udokumentować zarówno prawidłowy przebieg działania, jak i ścieżkę naprawczą. Próby ponownych działań, kontrola przez ludzi oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dodawane później. Należy podać fragmenty tekstu, które faktycznie stanowią podstawę odpowiedzi. Bez tych odniesień operatorzy nie będą w stanie odróżnić halucynacji od luki w indeksowaniu.

Analiza czasowa

W fazie analizy czasu należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy preferować małe, łatwe do przetestowania jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok zawiedzie, powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowaną strukturę procesów. Należy podawać konkretne fragmenty tekstu, które stanowią podstawę odpowiedzi. Bez tych odniesień operatorzy nie będą w stanie odróżnić fałszywych informacji od braków w indeksowaniu. W fazie analizy czasu należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy rejestrować czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega nieoczekiwanym rachunkom, gdy proces przechodzi z środowiska demonstracyjnego do współdzielonych środowisk.

Jak wyglądają 3 713 entytetów winnych

Gdy pracujesz nad etapem What 3 713 Wine, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Przechowuj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury. Zmierz stopę odzyskiwania informacji na ustalonej serii pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe mechanizmy wyszukiwania.

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 |
+--------------------+-------------+-----------+

Umieszczenie tego w interfejsie webowym

Gdy przechodzisz przez etap implementacji, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zdokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości nieodebranych stanowią część produktu, a nie elementy dodawane później w celu udoskonalenia. Zmierz stopień odzyskiwania informacji na ustalonej grupie pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe mechanizmy wyszukiwania.

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])

Co powinieneś wiedzieć przed przyjęciem RAG-Anything

Gdy przechodzisz przez etap „Co powiesz”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Wolij małe, testowalne jednostki od rozbudowanych skryptów. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na jedną konkretne odpowiedzialność, a nie na skomplikowany łańcuch operacji. Zmierz stopień przywoływania informacji na ustalonej serii pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe mechanizmy wyszukiwania informacji.

Kiedy Graph RAG wnosi rzeczywistą wartość

Gdy przechodzisz przez etap When Graph RAG Adds, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzuć ciche, częściowe ukończenie zadania. Zmierz stopień przywoływania informacji na ustalonej serii pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe możliwości wyszukiwania informacji.

Gdy to nie pomaga (lub szkodzi)

Gdy przechodzisz przez etap „When It Doesn’t”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zapisz czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy ścieżka przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Zmierz dokładność odzyskiwania informacji na ustalonej grupie pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe możliwości wyszukiwania.

Zalecenia praktyczne

Gdy przechodzisz przez etap Praktycznych Zaleceń, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Trzymaj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury. Zmierz stopę odzyskiwania informacji na ustalonej grupie pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe mechanizmy wyszukiwania.

+----------------------------+----------------+---------------+-------------------+
| 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              |
+----------------------------+----------------+---------------+-------------------+

Podsumowanie

Gdy przechodzisz przez etap The Bottom Line, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zdokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponownych działań, kontrola przez ludzi oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodawane później. Zmierz stopień odzyskiwania informacji na ustalonej grupie pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe możliwości wyszukiwania.

Lista kontrolna operacyjna

Etap Lista kontrolna operacyjna działa najlepiej, gdy jest traktowany jako mierzalna struktura. Zapisz jeden idealny zapis rozmowy, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy.

Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nazwij poszczególne elementy, zdefiniuj kryteria sukcesu i odrzuć ciche, częściowe ukończenie zadań.

Rozdziel politykę dzielenia na fragmenty od polityki pobierania danych. Zmiana jednej z nich nie powinna zmuszać do przepisania drugiej, gdy zmieniają się metryki jakości.

Dodaj test sprawdzający, który symuluje kluczową ścieżkę w procesie CI przy użyciu narzędzi testowych, a nie rzeczywistych płatnych API, o ile pozwala budżet.

Zapisuj czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy ścieżka przechodzi z wersji demonstracyjnej do środowisk współdzielonych.

Rozdziel politykę dzielenia na fragmenty od polityki pobierania danych. Zmiana jednej z nich nie powinna zmuszać do przepisania drugiej, gdy zmieniają się metryki jakości.

Zanim wdrożysz cały zestaw narzędzi, zamroź wersje, utwórz idealny zapis dla kluczowej ścieżki i potwierdź kroki odwracające zmiany. Środowiska współdzielone wymagają ograniczeń szybkości, weryfikacji uprawnień oraz jasno określonego właściciela odpowiedzialnego za rotację haseł. Wolisz nudną niezawodność od pomysłowych, jednorazowych demonstracji.

Uwagi dotyczące partii 02b0708cdf33: unikaj przechowywania kluczy dostawców w repozytorium, ustaw ograniczenie liczby tokenów na sesję oraz przechowuj transkrypcje obok plików testowych, aby późniejsze zmiany modeli pozostały porównywalne.

Literatura pokrewna

  • Notatki praktyczne: Obserwowalność dla agentów AI korporacyjnych: rozwiązanie open-source — Szczegółowy przewodnik po Notatkach praktycznych: Obserwowalność dla agentów AI korporacyjnych: rozwiązanie open-source: kontrakty, sprawdzenia oraz gotowe fragmenty kodu dla zespołów wdrażających ten model.
  • Notatki praktyczne: Stworzyłem hybrydowy pipeline RAG na podstawie dokumentów SEC — oto szczegóły — Szczegółowy przewodnik po Notatkach praktycznych: Stworzyłem hybrydowy pipeline RAG na podstawie dokumentów SEC — oto szczegóły: kontrakty, sprawdzenia oraz gotowe fragmenty kodu dla zespołów wdrażających ten model.
  • Notatki praktyczne: Co sprawia, że istniejąca API jest gotowa na agenty AI? — Krok po kroku omówienie Notatek praktycznych: Co sprawia, że istniejąca API jest gotowa na agenty AI?: kontrakty, sprawdzenia oraz miejsca na kod do wstawienia dla zespołów wdrażających ten wzorzec.
  • Notatki praktyczne: Pani serwer MCP pracuje na zastarzałej specyfikacji. Oto rozwiązanie — Krok po kroku omówienie Notatek praktycznych: Pani serwer MCP pracuje na zastarzałej specyfikacji. Oto rozwiązanie: kontrakty, sprawdzenia oraz miejsca na kod do wstawienia dla zespołów wdrażających ten wzorzec.