Strona główna / Artykuły / Wskazówki praktyczne: Nigdy nie łączyć dwóch bilansów.

Wskazówki praktyczne: Nigdy nie łączyć dwóch bilansów.

Praktyczne wskazówki: Nigdy nie łącz dwóch bilansów – umowy, czeki oraz miejsca na kod dostępne dla zespołów wdrażających ten wzorzec.

1705 słów

Niech to służy jako wersja przeznaczona dla operatorów, zawierająca zasady przedstawione w „Never Average Two Balance Sheets”: wyraźne etapy, uporządkowane sekcje kodu oraz notatki dotyczące przywracania stanu po przeniesieniu obowiązków. Etap Przeglądu sprawdza się najlepiej, gdy traktowany jest jako mierzalna powierzchnia do analizy. Zapisz jeden idealny przykład działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Zapisuj czasy wykonywania zadań oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega nieoczekiwanym rachunkom, gdy przechodzi się od środowiska demonstracyjnego do wspólnych środowisk.

Rysowanie granic

W etapie rysowania linii należy zdefiniować dane wejściowe, osobę odpowiedzialną za ten 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ć bez konieczności przeglądania 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.

Jedna prośba, od początku do końca

Aby proces One request end to stage mógł przejść dalej, należy zdefiniować dane wejściowe, osobę odpowiedzialną za daną fazę oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić tę fazę na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy udokumentować zarówno prawidłowy przebieg procesu, jak i ścieżkę naprawczą. Próby ponownych działań, kontrolne punkty ludzkie 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 braku danych w indeksie.

@app.get("/api/analyze")
def analyze(q: str, market: str = "US", refresh: bool = False):
    snap = _up("marketdata", "/snapshot",
               params={"q": q, "market": market, "refresh": refresh})
    rates = _up("marketdata", f"/rates/{market}")
    result = _up("valuation", "/analyze", method="POST", json={
        "symbol": snap["symbol"], "market": market,
        "snapshot": snap["data"], "rates": rates, "persist": True,
    })
    # Provenance travels with the numbers, so the UI can show who said what.
    result["sources"] = snap.get("sources", [])
    result["disagreements"] = snap.get("disagreements", [])
    return result

Trzy źródła oraz zasada, że nic nie jest średnione

Dla Trzech źródeł i etapu należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy dany krok zawiedzie, powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany proces. Należy podawać fragmenty tekstu, które faktycznie stanowią podstawę odpowiedzi. Bez tych odniesień operatorzy nie będą w stanie odróżnić halucynacji od braku danych w indeksie. Dla Trzech źródeł i etapu należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić dany 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 niespodziewanym rachunkom, gdy proces przechodzi z środowiska demonstracyjnego do wspólnych środowisk.

/p>
# SEC is as-filed, so it outranks everything in the US.
PRIORITY_US    = ("sec", "fmp", "yahoo")
PRIORITY_OTHER = ("fmp", "yahoo")
def _dispersion(values: list[float]) -> float | None:
    """Relative spread across sources. 0.0 means they agree exactly."""
    clean = [v for v in values if v is not None]
    if len(clean) < 2:
        return None
    scale = abs(statistics.median(clean))
    if scale < 1e-9:
        return None if max(map(abs, clean)) < 1e-9 else 1.0
    return (max(clean) - min(clean)) / scale

Brama walutowa

Podczas przechodzenia przez etap Bramy walutowej 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 mechanizmy wyszukiwania.

for name, data in sources.items():
    rc = (data.get("reporting_currency")
          or data.get("currency") or base_currency or "").upper()
    allowed_statements[name] = (not base_currency) or rc == base_currency.upper()

Zrezygnuj z ręcznego wpisywania stopy wolnej od ryzyka

Gdy przechodzisz przez etap zaprzestania hardkodowania, 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 błędnych 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.

"US": {"rf": 0.042, "erp": 0.045, "tax": 0.21},
def risk_free(market: str, fallback: float) -> dict:
    """{rate, source, observed_on, series}. Never raises."""
    series_id = SERIES.get(market)
    static = {"rate": fallback, "source": "static",
              "observed_on": None, "series": None}
    if not series_id or not enabled():
        return static
    ...

Dane są obliczane, nigdy nie przechowywane

Gdy pracujesz nad etapami wytwarzania Holdings, 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 nad rozbudowane skrypty. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany proces. Zmierz stopień przywoływania informacji na ustalonej grupie pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe możliwości wyszukiwania. Gdy pracujesz nad etapami wytwarzania Holdings, 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 przechodzi się z środowiska demonstracyjnego do wspólnych środowisk.

Analityk, który nie może odrzucić wyników analizy

Analityk, który nie może przeprowadzać etapów pracy, funkcjonuje najlepiej, gdy traktowany jest jako mierzalna powierzchnia. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę o cofnięciu zmian przed rozszerzeniem zakresu. 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. Oddziel zasadę dzielenia na fragmenty od zasady pobierania danych. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej w momencie zmian wskaźników jakości.

VALUATION
  blended fair value: 1402.11 INR (confidence medium, model spread 0.43)
  per model: dcf=1610.22, epv=1104.50, graham=1288.31, gordon=1377.90
  margin of safety: -8.4% - Trading above fair value
  growth assumed: 11.0% (basis: revenue YoY 11.0%)   discount rate: 11.2%
SOURCE DISAGREEMENTS (treat these figures as uncertain):
  net_income: fmp=261.0B, yahoo=248.5B (spread 4.9%, using fmp)
def _clamp_to_engine(model_verdict, engine_verdict):
    gap = SCALE.index(model_verdict) - SCALE.index(engine_verdict)
    if abs(gap) <= 1:
        return model_verdict, None
    capped = SCALE[SCALE.index(engine_verdict) + (1 if gap > 0 else -1)]
    return capped, (f"model said '{model_verdict}', more than one rung from "
                    f"the engine's '{engine_verdict}' - capped at '{capped}'")

Co faktycznie kodują manifesty

Struktura manifestów funkcjonuje najlepiej, gdy traktowana jest jako mierzalna powierzchnia do analizy. Zapisz jeden idealny przypadek działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Zdokumentuj zarówno prawidłowy przebieg operacji, jak i ścieżkę przywracania do stanu poprzedniego. Próby ponownych działań, kontrola przez ludzi oraz obsługa wiadomości nieodebranych stanowią część produktu, a nie elementy dodawane później w celu udoskonalenia. Oddziel zasady dzielenia na fragmenty od zasad pobierania danych. Zmiana jednych nie powinna zmuszać do przepisywania drugich, gdy zmieniają się metryki jakości.

startupProbe:    { httpGet: { path: /health/live,  port: http },
                   failureThreshold: 30, periodSeconds: 5 }
readinessProbe:  { httpGet: { path: /health/ready, port: http }, periodSeconds: 15 }
livenessProbe:   { httpGet: { path: /health/live,  port: http }, periodSeconds: 30 }

Cztery rzeczy, które się zepsuły

Cztery elementy, które doprowadziły do awarii na etapie realizacji, najlepiej traktować jako mierzalną powierzchnię do analizy. Zapisz jeden idealny zapis działania, 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 zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Rozdziel politykę dzielenia na części od polityki pobierania danych. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej, gdy zmieniają się metryki jakości. Cztery elementy, które doprowadziły do awarii na etapie realizacji, najlepiej traktować jako mierzalną powierzchnię do analizy. Zapisz jeden idealny zapis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Zapisuj czasy wykonywania operacji oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy przechodzi się od wersji demonstracyjnej do środowisk współdzielonych.

Co zmieniłbyś

W fazie „Co zmienisz” 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 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ć bez konieczności czytania 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 braku danych w indeksie.

Lista kontrolna operacyjna

Podczas pracy nad fazą Listy kontrolnej operacyjnej najpierw należy spisać warunki realizacji zadania: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista zapewnia uczciwość późniejszych zmian w kodzie.

Rozpatruj tę fazę 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ływalności na ustalonej serii pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe mechanizmy wyszukiwania informacji.

Zapisz wersje zależności oraz digest obrazu użytego podczas demonstracji. Reprodukowalność jest lepsza od lokalnej wiedzy zespołu.

Zapisz czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Jasna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy przechodzi się od demonstracji do wspólnych środowisk.

Zmierz stopień przywoływalności na ustalonej serii pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe mechanizmy wyszukiwania informacji.

Zanim wdrożysz tę architekturę, zamroź wersje, utwórz dokładny zapis dla kluczowych etapów realizacji oraz potwierdź kroki odwracania zmian. Środowiska współdzielone wymagają ograniczeń szybkości, weryfikacji przynależności użytkowników oraz wyraźnego właściciela odpowiedzialnego za rotację haseł. Wolimy nudną niezawodność od pomysłowych, jednorazowych demonstracji.

Uwaga dotycząca wersji 6fc55994b561: unikaj przechowywania kluczy dostawcy w repozytorium, ustaw ograniczenie liczby tokenów na sesję oraz przechowuj zapisy obok plików testowych, aby późniejsze zmiany modeli pozostawały porównywalne.