Strona główna / Artykuły / Uwagi praktyczne: OKF + RAG: Ostateczny agent AI

Uwagi praktyczne: OKF + RAG: Ostateczny agent AI

Praktyczne wskazówki: OKF + RAG: Ostateczny agent AI – umowy, sprawdzenia oraz gotowe miejsca na kod dla zespołów wdrażających ten wzorzec.

1359 słów

To przewodnik pokazuje, jak odtworzyć proces od surowców do gotowego systemu dla: OKF + RAG: The Ultimate AI Agent Architecture. Skupiamy się na krokach realizowalnych w praktyce, wyraźnych sprawdzeniach oraz kodzie, który można bez problemu dodać do repozytorium, nie musząc zgadywać intencji twórcy. Aby uzyskać ogólny obraz, 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 systemu. Traktuj tę fazę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nazwij poszczególne elementy, zdefiniuj kryteria sukcesu i odrzuć przypadkowe, częściowe ukończenie zadania.

Dwa systemy pamięci

Gdy pracujesz nad „The Two Memory Systems”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego awarii. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Obok wyników funkcjonalnych zapisz czas wykonywania oraz koszt tokena lub zapytania. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy ścieżka przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Zmierz zdolność przywoływania informacji na ustalonej serii pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe mechanizmy wyszukiwania.

Czym jest OKF? (Open Knowledge Format)

Gdy pracujesz nad tematem „Co to jest OKF? (Open Knowledge Format)”, 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 grupie pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe możliwości wyszukiwania.

---
type: metric
title: "Monthly Churn Rate"
description: "Official formula for calculating monthly customer churn."
owner: "data-engineering"
tags: [revenue, kpi, board-report]
timestamp: 2026-06-20T10:00:00Z
---

# Monthly Churn Rate

The official churn rate formula used in all board reports and investor decks:

    Churn Rate = (Customers Lost During Month / Customers at Start of Month) × 100

### Rules
- **Do NOT** use trial accounts in the denominator.
- **Do NOT** count plan downgrades as churn.
- Source of truth: `analytics.monthly_churn_summary` table.

### Related
- [Monthly Active Users](mau.md)
- [Revenue Dashboard](revenue_dashboard.md)

Dlaczego to ma znaczenie

Gdy pracujesz nad rozdziałem „Dlaczego to ma znaczenie”, 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, kontrola przez ludzi oraz obsługa wiadomości nieodebranych 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 mechanizmy wyszukiwania informacji. Gdy pracujesz nad rozdziałem „Dlaczego to ma znaczenie”, 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. Nazwij poszczególne elementy, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe ukończenie zadań.

Czym jest RAG? (Retrieval-Augmented Generation)

Czym jest RAG? (Retrieval-Augmented Generation) funkcjonuje najlepiej, gdy traktuje się je jako coś mierzalnego. Zanim rozszerzysz zakres, zapisz jeden idealny przykład działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian. Zapisz czasy wykonywania zadań oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy przechodzi się z środowiska demonstracyjnego do współdzielonych środowisk. Rozdziel politykę dzielenia na fragmenty od polityki wyszukiwania informacji. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej, gdy zmieniają się metryki jakości.

Architektura hybrydowa: OKF + RAG

Architektura hybrydowa: OKF + RAG działają najlepiej, gdy traktuje się je jako mierzalną powierzchnię. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. Przechowuj konfigurację poza kodem aplikacji. Pliki środowiskowe, składysek tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury. Oddziel zasadę dzielenia na fragmenty od zasady wyszukiwania. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej, gdy zmieniają się metryki jakości.

Jak decyduje router

Sposób, w jaki router podejmuje decyzje, najlepiej analizować jako mierzalną zmienną. Zapisz jeden idealny przypadek działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres badania. Zdokumentuj zarówno prawidłowy przebieg operacji, jak i ścieżkę przywracania do normalnego stanu. Próby ponownych działań, kontrola przez ludzi oraz obsługa wiadomości nieodebranych stanowią część produktu, a nie elementy dodawane później. Rozdziel politykę dzielenia na fragmenty od polityki pobierania danych. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej w momencie zmian wskaźników jakości.

Przykład implementacji

Przykład implementacji działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię. Zapisz jeden idealny przepis realizacji, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok się nie powiedzie, 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.

from openai import OpenAI
import os
import glob
import yaml

client = OpenAI()

# 1. Load the OKF knowledge bundle from the local directory
def load_okf_bundle(bundle_path: str) -> dict:
    """Reads all Markdown files in the OKF directory into a searchable dict."""
    knowledge = {}
    for filepath in glob.glob(f"{bundle_path}/**/*.md", recursive=True):
        with open(filepath) as f:
            content = f.read()
            # Extract the title from YAML frontmatter
            if content.startswith("---"):
                _, frontmatter, body = content.split("---", 2)
                meta = yaml.safe_load(frontmatter)
                title = meta.get("title", os.path.basename(filepath))
                knowledge[title.lower()] = body.strip()
    return knowledge

# 2. Search OKF (deterministic, keyword-based)
def search_okf(query: str, okf_knowledge: dict) -> str | None:
    """Simple keyword match against OKF titles."""
    for title, content in okf_knowledge.items():
        if title in query.lower():
            return content
    return None

# 3. Search RAG (probabilistic, vector-based)
def search_rag(query: str) -> str:
    """Placeholder for your vector DB search (Pinecone, Weaviate, etc.)."""
    # results = vector_db.similarity_search(query, top_k=5)
    return "RAG context: [retrieved chunks would appear here]"

# 4. The Intelligent Router
def answer_query(query: str, okf_bundle_path: str) -> str:
    okf_knowledge = load_okf_bundle(okf_bundle_path)

    # Try OKF first (deterministic path)
    okf_result = search_okf(query, okf_knowledge)

    if okf_result:
        context = f"[SOURCE: Official Knowledge Base (OKF)]\n{okf_result}"
    else:
        # Fall back to RAG (probabilistic path)
        context = f"[SOURCE: Document Search (RAG)]\n{search_rag(query)}"

    # Send to LLM with the retrieved context
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": "Answer using ONLY the provided context."},
            {"role": "user", "content": f"Context:\n{context}\n\nQuestion: {query}"}
        ]
    )
    return response.choices[0].message.content

Wniosek

Wniosek daje najlepsze rezultaty, gdy traktuje się go jako coś mierzalnego. Zapisz jeden idealny przepis, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres pracy. Traktuj tę fazę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe ukończenie zadań. Rozdziel politykę dzielenia na fragmenty od polityki pobierania danych. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej, gdy zmieniają się metryki jakości.

Lista kontrolna operacyjna

Lista kontrolna operacyjna działa najlepiej, gdy traktuje się ją jako coś mierzalnego. Zapisz jeden idealny przepis, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres pracy.

Niech preferowane będą małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok się nie powiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji.

Rozdziel politykę dzielenia na fragmenty od polityki pobierania danych. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej w momencie zmian wskaźników jakości.

Zastosuj ludzką aprobatę w przypadku operacji, które wiążą się z wydatkami lub zmianami w danych produkcyjnych. Połączenia skompilowane w czasie kompilacji nie gwarantują pełnej kompletności biznesowej.

Napisz krótki przewodnik: jak rotować klucze, jak opróżniać kolejkę z zadań, jak cofnąć ostatni proces pobierania danych.

Zachowaj 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 przeglądania całej struktury.

Zanim wdrożysz nową architekturę, zamroź wersje oprogramowania, utwórz „złoty zapis” dla kluczowych ścieżek przetwarzania i potwierdź kroki cofnięcia. Środowiska współdzielone wymagają ograniczeń szybkości, weryfikacji przynależności użytkowników oraz jasno określonego odpowiedzialnego za rotację tajnych danych. Wolij nudną niezawodność od pomysłowych, jednorazowych demonstracji.

Uwagi dotyczące partii 26b9ceed44f1: unikaj przechowywania kluczy dostawcy 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.