Powrót

Architektura referencyjna: Wdrożenie Langfuse w OVHcloud MKS na potrzeby obserwowalności LLM i monitorowania kosztów AI

Eléa Petton23.07.202614 min. czytania

Architektura referencyjna: Wdrożenie Langfuse w OVHcloud MKS na potrzeby obserwowalności LLM i monitorowania kosztów AI

Kontekst

OVHcloud AI Endpoints udostępnia interfejs API zgodny z OpenAI, który zapewnia aplikacjom dostęp do szerokiego katalogu modeli o otwartych wagach, w tym modeli Qwen, Llama, Mistral i gpt-oss oraz modeli embeddingowych, guard i speech, bez konieczności zarządzania przez zespoły infrastrukturą do inferencji. Jest to warstwa inferencji rozliczana według zużycia, monitorowana w ramach tej architektury.

OVHcloud Managed Kubernetes Service (MKS) eliminuje obciążenia operacyjne związane z obsługą warstwy control plane narzędzia Kubernetes: OVHcloud zajmuje się pulami węzłów, aktualizacjami i wysoką dostępnością, a Ty zachowujesz pełną kontrolę nad tym, co działa na węzłach roboczych. Jest to naturalne środowisko do uruchamiania aplikacji bezstanowej, takiej jak procesy webowe i procesy worker Langfuse, podczas gdy komponenty stanowe (bazy danych, Object Storage) działają w sąsiadujących z nią usługach zarządzanych OVHcloud.

Langfuse zapewnia warstwę obserwowalności dla aplikacji korzystających z AI Endpoints. Ponieważ integracja Langfuse z OpenAI SDK działa jako bezpośredni zamiennik (from langfuse.openai import openai zamiast import openai), przekierowanie istniejącej bazy kodu zgodnej z OpenAI do AI Endpoints i uzyskanie pełnego śledzenia wymaga zmiany zaledwie dwóch wierszy kodu, a nie jego przepisywania.

Razem te trzy elementy tworzą samodzielnie hostowany stos obserwowalności z przypisywaniem kosztów dla dowolnej aplikacji wywołującej AI Endpoints, bez przesyłania ani jednego tokena danych promptów ani odpowiedzi poza kontrolowaną przez Ciebie infrastrukturę.

Architektura Langfuse

Langfuse w OVHcloud MKS na potrzeby obserwowalności LLM i monitorowania zużycia tokenów

Prezentacja architektury

Aplikacje webowa i worker Langfuse są wdrażane w klastrze MKS. Ingress i zarządzanie certyfikatami działają obok nich jako oddzielne dodatki do klastra, które można wykorzystywać wielokrotnie. Każda zależność stanowa – PostgreSQL, Valkey, ClickHouse i Object Storage – działa jako usługa zarządzana OVHcloud poza klastrem, z którą połączenie jest nawiązywane przez TLS.

1. Przepływ danych

Po złożeniu wszystkich elementów w całość pojedyncze śledzone żądanie przebiega następująco:

przepływ danych

Przepływ danych

1. Aplikacja wywołuje AI Endpoints bezpośrednio

Klient openai.OpenAI() używany jako bezpośredni zamiennik wysyła żądanie bezpośrednio do API inferencji – Langfuse pozostaje całkowicie poza tym wywołaniem, dzięki czemu awaria Langfuse nie wpływa na możliwość uzyskania odpowiedzi przez aplikację.

2. AI Endpoints przesyła strumieniowo odpowiedź z powrotem

Końcowy fragment zawiera dane dotyczące wykorzystania tokenów.

3. SDK eksportuje zarejestrowane przed chwilą dane jako partię spanów OpenTelemetry

Odbywa się to asynchronicznie, za pośrednictwem protokołu HTTPS, do punktu końcowego /api/public/otel/v1/traces w instancji Langfuse.

Proces ten działa w tle i nie zwiększa opóźnienia odpowiedzi, którą aplikacja otrzymała już w kroku 2.

4. Komponent webowy Langfuse odbiera partię spanów

Sprawdza klucz API żądania względem projektu w Postgres (wyszukiwanie jest buforowane w Valkey, więc nie jest wykonywane jako nowe zapytanie przy każdym wywołaniu), zapisuje nieprzetworzoną partię danych w niezmienionej postaci w Object Storage i umieszcza w kolejce Valkey jedynie odwołanie do niej.

5. Worker opróżnia tę kolejkę zgodnie z własnym harmonogramem, niezależnie od konkretnego żądania

Pobiera odwołanie z Valkey, pobiera pełną partię danych z Object Storage, za pośrednictwem Postgres identyfikuje powiązany z nią wpis Prompt Management (jeśli istnieje), a następnie zapisuje rekordy śledzenia i generowania w ClickHouse (model, liczba tokenów, opóźnienie, ceny).

6. Worker obsługuje również wszystkie zadania zaplanowane lub wykonywane zbiorczo

Eksporty wsadowe i przesyłane pliki multimedialne trafiają do S3 niezależnie od tego, kiedy nastąpiło pierwotne żądanie.

⚠️ Uwaga: Od kroku 3 żaden z tych procesów nie może zwiększyć opóźnienia żądania aplikacji z kroków 1-2. To właśnie asynchroniczne przekazanie danych oraz fakt, że komponent webowy nie czeka na odpowiedź Postgres ani ClickHouse przed potwierdzeniem przyjęcia partii danych, sprawiają, że śledzenie nie powoduje żadnego dodatkowego narzutu na ścieżce krytycznej.

2. Interfejsy API AI Endpoints

Wszystkie poniższe elementy wywołują jeden z dwóch odrębnych interfejsów API OVHcloud AI Endpoints:

Jest to interfejs API, z którym faktycznie komunikuje się Twoja aplikacja. Implementuje interfejs zgodny z API OpenAI, dzięki czemu można z niego korzystać za pomocą dowolnego SDK zgodnego z OpenAI, zmieniając jedynie base_url i klucz API:
 

bash
import openai 
client = openai.OpenAI(
     api_key="<your-ai-endpoints-token>",
     base_url="https://oai.endpoints.kepler.ai.cloud.ovh.net/v1",
 )
 
 response = client.chat.completions.create(
     model="Qwen3.5-397B-A17B",
     messages=[{"role": "user", "content": "hello"}],
 )

Jeśli pobierzesz schemat OpenAPI bezpośrednio z bramy (GET /openapi.json), zobaczysz, że dostępny interfejs wykracza daleko poza generowanie odpowiedzi na czacie.
 Warto przynajmniej raz wywołać bezpośrednio interfejs GET /v1/models: zwraca on listę wszystkich modeli, do których Twój token zapewnia dostęp.

Poniższa sekcja koncentruje się na interfejsie API katalogu, który umożliwia uzyskanie dodatkowych informacji o modelach, w tym danych dotyczących cen, niezbędnych do monitorowania kosztów.

Jest to interfejs API wykorzystywany przez stronę internetowego katalogu „AI Endpoints”. Jest to proste żądanie GET, które nie wymaga uwierzytelniania i zwraca pełną listę modeli wraz z metadanymi wyświetlanymi w interfejsie użytkownika katalogu: opisem, wynikami benchmarków, wydawcą, licencją, rozmiarem kontekstu, linkami do playgroundu i dokumentacji, a także blokiem usage_information.pricing:

bash
curl -s https://catalog.endpoints.ai.ovh.net/rest/v1/models_v2 | jq '.[0]'

Zwraca:

bash
{
   "id": "qwen-3-5-397b",
   "name": "Qwen3.5-397B-A17B",
   "category": "Visual LLM",
   "metadata": {
     "aliases": ["Qwen/Qwen3.5-397B-A17B", "qwen3.5-397b-a17b"],
     "context": "262k",
     "usage_information": {
       "pricing": [
         {"price": 0.6, "price_unit": "million_input_tokens"},
         {"price": 3.6, "price_unit": "million_output_tokens"}
       ]
     }
   }
 }

Te dwa interfejsy API wzajemnie się uzupełniają:

  • interfejs API katalogu  jest pobierany jednorazowo lub okresowo w celu tworzenia lokalnych tabel cen i metadanych
  • interfejs API inferencji jest wywoływany przez działającą aplikację przy każdym żądaniu

Te dwa interfejsy API wzajemnie się uzupełniają:

  • interfejs API katalogu  jest pobierany jednorazowo lub okresowo w celu tworzenia lokalnych tabel cen i metadanych
  • interfejs API inferencji jest wywoływany przez działającą aplikację przy każdym żądaniu
Interfejsy API inferencji i katalogu AI Endpoints

Interfejsy API inferencji i katalogu AI Endpoints

⚠️ Uwaga: Pamiętaj, że ceny AI Endpoints są podawane w euro.

Wymagania

Przed rozpoczęciem upewnij się, że masz:

  • Konto OVHcloud Public Cloud
  • Użytkownika OpenStack z rolą Administrator
  • Klucz API AI Endpoints
  • Nazwę domeny, którą możesz skierować do modułu Load Balancer
  • Zainstalowane narzędzia kubectl oraz helm

(co najmniej w wersji 3.x)

Teraz, gdy masz już wszystkie potrzebne elementy, czas wdrożyć Langfuse przy użyciu OVHcloud MKS i innych usług zarządzanych!

Przewodnik po architekturze: Wdrożenie Langfuse w usługach zarządzanych OVHcloud Public Cloud

Krok 1 – Tworzenie klastra Kubernetes i usług zarządzanych OVHcloudProcesy web i worker

Langfuse są same w sobie lekkie. Dlatego wybór zasobów zależy niemal całkowicie od otaczających je usług zarządzanych. Poniżej opisano praktyczne kroki wymagane do skonfigurowania każdej z tych usług.

Wszystkie poniższe zasoby są tworzone w Panelu klienta OVHcloud, w sekcji Public Cloud danego projektu.

1. Utwórz klaster MKS i pule węzłów

1.1. Skonfiguruj klasterW Panelu klienta OVHcloud, utwórz klaster Kubernetes przy użyciu usługi MKS

  • :Nazwa:
  • langfuse-clusterLokalizacja: Region 1-AZ – Gravelines (GRA11
  • )Plan:
  •  Free (lub Standard)Sieć: podłącz sieć prywatną (np. 0000 - AI Private Network
  • )Wersja: Najnowsza stabilna (np. 1.35
)

1.2. Utwórz pule węzłów

Podczas tworzenia klastra skonfiguruj 2 pule węzłów.Pierwsza z nich to np-system

  • . Uruchamiane są w niej komponenty na poziomie klastra, w tym Traefik (Ingress) i cert-manager (certyfikaty TLS), a także domyślne systemowe zestawy DaemonSet Kubernetes.Nazwa puli węzłów:
  • np-systemTyp instancji:
  •  B3-8Liczba węzłów:
  •  3Autoskalowanie:

 Wyłączone (OFF)Druga z nich to np-workload

  • , przeznaczona dla podów aplikacji Langfuse (web + worker).Nazwa puli węzłów:
  •  np-workloadTyp instancji:
  •  B3-16Liczba węzłów:
  •  1Autoskalowanie:
 Wyłączone (OFF)

1.3. Skonfiguruj dostęp do KubernetesPo utworzeniu węzłów możesz pobrać plik Kubeconfig

bash
# configure kubectl with your MKS cluster
 export KUBECONFIG=/path/to/your/kubeconfig-xxxxxx.yml
 
 # verify cluster connectivity
 kubectl cluster-info
 kubectl get nodes
Returns:
NAME STATUS ROLES AGE VERSION
 np-system-node-388e55 Ready <none> 12d v1.35.2
 np-system-node-4c5326 Ready <none> 12d v1.35.2
 np-system-node-93bc1c Ready <none> 12d v1.35.2
 np-workload-node-3a76f7 Ready <none> 12d v1.35.2

2. Skonfiguruj bazy danych

2.1. Baza danych Postgre dla danych transakcyjnych Langfuse

W sekcji Databases usługi OVHcloud Public Cloud kliknij Create a service i skonfiguruj ją w następujący sposób:

  • Silnik: PostgreSQL
  • Wersja: 17
  • Lokalizacja: GRA
  • Plan usługi: Business
  • Instancja: Db1-4
  • Przestrzeń dyskowa: 80 GB (domyślnie)
  • Sieć: Sieć publiczna (internet)

Przed przejściem do kolejnego kroku zachowaj poniższe informacje w bezpiecznym miejscu:
 - host
 - port
 - nazwa bazy danych
 - nazwa użytkownika
 - hasło
 - URI

2.2. Baza danych Valkey do buforowania zadań i obsługi kolejek

W sekcji Databases usługi OVHcloud Public Cloud kliknij Create a service i skonfiguruj ją w następujący sposób:

  • Silnik: Valkey
  • Wersja: 8.1
  • Lokalizacja: GRA
  • Plan usługi: Business
  • Instancja: Db1-4
  • Przestrzeń dyskowa: 80 GB (domyślnie)
  • Sieć: Sieć publiczna (internet)

Przed przejściem do kolejnego kroku zachowaj poniższe informacje w bezpiecznym miejscu:
 - host
 - port
 - nazwa bazy danych
 - nazwa użytkownika
 - hasło
 - URI

2.3. ClickHouse, serce systemu obserwowalności

W sekcji Analytics usługi OVHcloud Public Cloud kliknij Create a service i skonfiguruj ją w następujący sposób:

  • Silnik: ClickHouse
  • Wersja: 25.8
  • Lokalizacja: EU-WEST-PAR
  • Plan usługi: Production
  • Instancja: B3-16
  • Przestrzeń dyskowa: 100 GB (domyślnie)
  • Sieć: Sieć publiczna (internet)

Przed przejściem do kolejnego kroku zachowaj poniższe informacje w bezpiecznym miejscu:
 - host
 - port
 - nazwa bazy danych
 - nazwa użytkownika
 - hasło
 - URI

Uwaga: Zarządzane bazy danych OVHcloud (Postgres, Valkey i ClickHouse) domyślnie odrzucają wszystkie połączenia, dopóki na stronie „Ograniczenia IP” każdej instancji w Panelu klienta OVHcloud nie dodasz dozwolonych źródłowych adresów IP. Pamiętaj, że przed wdrożeniem Langfuse musisz dodać publiczne adresy IP pul węzłów MKS do listy dozwolonych adresów IP we wszystkich trzech bazach danych. W przeciwnym razie każda próba połączenia z klastra zakończy się przekroczeniem limitu czasu.

Na karcie Configuration każdej bazy danych skonfiguruj listę dozwolonych adresów IP, jak pokazano w poniższym przykładzie:

Dodawanie publicznych adresów IP puli węzłów MKS do listy dozwolonych adresów IP

Dodawanie publicznych adresów IP puli węzłów MKS do listy dozwolonych adresów IP

3. Utwórz bucket zgodny z S3 jako zaplecze pamięci masowej

W sekcji Object Storage usługi OVHcloud Public Cloud utwórz kontener obiektów:

  • Typ kontenera: API kompatybilne z S3
  • Lokalizacja: GRA

Przed przejściem do kolejnego kroku zachowaj poniższe informacje w bezpiecznym miejscu:
 - nazwa bucketu
 - punkt końcowy
 - klucz dostępu
 - klucz tajny

Krok 2 – Tworzenie przestrzeni nazw i konfigurowanie limitów zasobów

Utwórz dedykowane przestrzenie nazw dla kontrolera Ingress, menedżera certyfikatów i samego Langfuse oraz ogranicz zasoby, z których może korzystać przestrzeń nazw Langfuse, aby niekontrolowane obciążenie nie mogło zakłócić działania pozostałej części klastra.

Najpierw utwórz:

Następnie uruchom wdrożenie.

bash
kubectl apply -f deploy/bootstrap/namespaces.yaml
kubectl apply -f deploy/bootstrap/resourcequota.yaml

Krok 3 – Instalowanie kontrolera Ingress i menedżera certyfikatów

W tej architekturze zastosowano Traefik zamiast ingress-nginx.Pełne polecenia instalacyjne znajdują się w pliku

deploy/ingress/install.sh. Możesz uruchomić:. You can run:

bash
 bash deploy/ingress/install.sh

helm upgrade --install automatycznie tworzy nowy OVHcloud Load Balancer z publicznym adresem IP. Poczekaj na jego przypisanie przed przejściem dalej:

bash
kubectl -n traefik get svc traefik -w

cert-manager obsługuje wydawanie i odnawianie certyfikatów. Zainstaluj go z rejestru OCI, który jest obecnie zalecany przez cert-manager jako preferowana metoda dla najnowszych wersji zamiast starszego repozytorium Helm.

Pobierz skrypt  cert-manager/install.sh i uruchom:

bash
bash cert-manager/install.sh

Następnie utwórz ClusterIssuer dla Let's Encrypt, używając Traefik jako „mechanizmu weryfikacji” HTTP-01.

Najpierw podaj swój adres e-mail w pliku cert-manager/cluster-issuer.yaml.

⚠️ Uwaga: Let’s Encrypt używa tego adresu do wysyłania powiadomień o wygaśnięciu certyfikatu, a cert-manager zaakceptuje domyślną wartość bez ostrzeżenia, jeśli zapomnisz podać własną. Ten krok należy wykonać dopiero po uruchomieniu cert-manager i skonfigurowaniu klasy Ingress Traefik, aby mechanizm weryfikacji mógł się do niej odwołać. Dlatego uruchom go po zakończeniu obu opisanych powyżej instalacji:

bash
kubectl apply -f cert-manager/cluster-issuer.yaml

⚠️ Uwaga: Musisz jawnie określić wersję chartu za pomocą opcji (--version). W przeciwnym razie oba powyższe polecenia będą domyślnie używać najnowszej wersji dostępnej w momencie instalacji, co oznacza, że z czasem nie będzie można dokładnie odtworzyć wdrożenia.

Krok 4 – Konfigurowanie DNS w celu skierowania ruchu do Load Balancera

Gdy usługa Traefik otrzyma zewnętrzny adres IP, utwórz rekord A dla nazwy hosta, pod którą będzie dostępny Langfuse:

bash
kubectl -n traefik get svc traefik -o jsonpath='{.status.loadBalancer.ingress[0].ip}'

Utwórz w swojej strefie DNS rekord langfuse.<your-domain> wskazujący na ten adres IP i przed przejściem dalej upewnij się, że nazwa jest prawidłowo rozwiązywana – w przeciwnym razie weryfikacja HTTP-01 cert-manager zakończy się niepowodzeniem bez wyświetlenia błędu i będzie ponawiana bez końca.

Krok 5 – Zapisywanie danych uwierzytelniających w sekrecie Kubernetes i konfigurowanie wartości Helm

Chart Helm Langfuse odczytuje wszystkie dane uwierzytelniające z sekretu, a nie ze zwykłych wartości, dzięki czemu żadne dane wrażliwe nie muszą być przechowywane w pliku wartości.

bash
kubectl -n langfuse create secret generic langfuse-secrets \
   --from-literal=LANGFUSE_SALT="$(openssl rand -base64 32)" \
   --from-literal=LANGFUSE_SECRET_KEY="$(openssl rand -hex 32)" \
   --from-literal=NEXTAUTH_SECRET="$(openssl rand -base64 32)" \
   --from-literal=POSTGRES_PASSWORD="<your-postgres-password>" \
   --from-literal=VALKEY_PASSWORD="<your-valkey-password>" \
   --from-literal=CLICKHOUSE_PASSWORD="<your-clickhouse-password>" \
   --from-literal=S3_ACCESS_KEY="<your-s3-access-key>" \
   --from-literal=S3_SECRET_KEY="<your-s3-secret-key>"

Używany jest oficjalny chart langfuse/langfuse-k8s. Pełny plik znajdziesz w repozytorium GitHub OVHcloud public-cloud-examples: deploy/langfuse/values.yaml

⚠️ Uwaga: Każde ustawienie deploy: false informuje chart Helm, aby nie instalował własnych subchartów Postgres/Valkey/ClickHouse/MinIO, lecz zamiast tego łączył się z zarządzanymi instancjami OVHcloud. To właśnie sprawia, że jest to wdrożenie oparte na usługach zarządzanych, a nie wdrożenie zarządzane samodzielnie.

Krok 6 – Instalacja Langfuse

Pobierz z repozytorium plik deploy/langfuse/values.yaml i wprowadź niezbędne zmiany:

  • <your-domain>
  • <your-postgresql-host>
  • <your-valkey-host>
  • <your-clickhouse-host>
  • <your-bucket>

Następnie zapisz zaktualizowany plik values.yaml i na koniec uruchom deploy/langfuse/install.sh:

bash
bash deploy/langfuse/install.sh

To ostatni etap instalacji: wymaga on przestrzeni nazw i sekretu utworzonych w krokach 2 i 5, prawidłowego rozwiązywania DNS skonfigurowanego w kroku 4 (w przeciwnym razie nie będzie można wydać certyfikatu TLS) oraz istniejącego już ClusterIssuer utworzonego w kroku 3.

Następnie sprawdź, czy cały proces wdrożenia przebiegł prawidłowo:

bash
kubectl -n langfuse get pods
curl -s https://langfuse.<your-domain>/api/public/health

{"status":"OK","version":"<chart appVersion>"} z endpointu kontroli stanu oraz oba pody w stanie Running bez restartów oznaczają, że cały stos działa prawidłowo: ingress, TLS, Postgres, Valkey, ClickHouse i S3 są dostępne.

Krok 7 – Instrumentowanie aplikacji

1. Skonfiguruj SDK w swojej aplikacji

Gdy Langfuse będzie już dostępny, wystarczy podmienić SDK w aplikacji, nie trzeba przepisywać kodu. W przypadku aplikacji, która korzysta już z Python SDK openai do komunikacji z AI Endpoints:

bash
from dotenv import load_dotenv
 
 load_dotenv()  # OPENAI_API_KEY, OPENAI_BASE_URL, LANGFUSE_* must be loaded first
 
 from langfuse.openai import openai  # drop-in replacement for `import openai`
 
 client = openai.OpenAI()  # reads OPENAI_API_KEY / OPENAI_BASE_URL
 
 response = client.chat.completions.create(
     model="Qwen3.5-397B-A17B",
     messages=[{"role": "user", "content": "hello"}],
     stream=True,
     stream_options={"include_usage": True},
     name="chat-response",
     metadata={
         "langfuse_session_id": "session-123",
         "langfuse_user_id": "user-456",
         "langfuse_tags": ["feature:chat"],
     },
 )

⚠️ Uwaga: Użyj pliku examples/.env.example , a następnie zmodyfikuj ten plik .env wpisując własne zmienne środowiskowe. Następnie załaduj zmienne środowiskowe i skonfiguruj klienta Langfuse przed zaimportowaniem langfuse.openai.

Pełne, przetestowane implementacje referencyjne tego wzorca – obejmujące rozmowy wieloturowe, tagowanie sesji i użytkowników oraz Prompt Management w czterech różnych scenariuszach użycia (generowanie kodu, FAQ, podsumowywanie dokumentów i generowanie dłuższych treści) można znaleźć tutaj:

⚠️ Ostrzeżenie: Jeśli korzystasz z odpowiedzi strumieniowej, nie przerywaj iteracji natychmiast po wystąpieniu finish_reason == "stop". Niektórzy dostawcy zgodni z OpenAI, w tym AI Endpoints, wysyłają chunk zawierający dane o wykorzystaniu tokenów dopiero później. Zbyt wczesne przerwanie iteracji sprawia, że Langfuse nie otrzymuje tych danych, a koszt śladu jest wyświetlany jako zero, mimo że tokeny zostały faktycznie wykorzystane.

Kilka dodatkowych elementów sprawia, że działająca integracja staje się naprawdę użyteczna:

Tabela funkcji

2. Monitorowanie kosztów korzystania z AI Endpoints

Langfuse oblicza koszt każdego śladu na podstawie tabeli cen modeli, ale domyślnie nie zawiera ona wpisów dla modeli hostowanych przez OVHcloud – dopóki nie podasz kosztu każdego modelu, wszystkie ślady będą miały koszt równy 0 USD. Do tego właśnie służy wspomniany wcześniej interfejs API katalogu (“https://catalog.endpoints.ai.ovh.net/rest/v1/models_v2“): pobierz z niego dane jednorazowo, zarejestruj cenę każdego modelu za pomocą interfejsu Models API Langfuse, a koszty wszystkich kolejnych wywołań będą obliczane automatycznie.

bash
import os
 import requests
 
 LANGFUSE_BASE_URL = os.environ["LANGFUSE_BASE_URL"]
 LANGFUSE_PUBLIC_KEY = os.environ["LANGFUSE_PUBLIC_KEY"]
 LANGFUSE_SECRET_KEY = os.environ["LANGFUSE_SECRET_KEY"]
 
 catalog = requests.get(
     "https://catalog.endpoints.ai.ovh.net/rest/v1/models_v2"
 ).json()
 
 for model in catalog:
     pricing = model.get("metadata", {}).get("usage_information", {}).get("pricing")
     if not pricing:
         continue
     prices = {
         {"million_input_tokens": "inputPrice", "million_output_tokens": "outputPrice"}[p["price_unit"]]: p["price"] / 1_000_000
         for p in pricing
         if p["price_unit"] in ("million_input_tokens", "million_output_tokens")
     }
     if not prices:
         continue
     requests.post(
         f"{LANGFUSE_BASE_URL}/api/public/models",
         auth=(LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY),
         json={
             "modelName": f"ovh-ai-endpoints/{model['id']}",
             "matchPattern": f"(?i)^({model['name']})$",
             "unit": "TOKENS",
             **prices,
         },
     )

Jest to jednorazowe wywołanie interfejsu API, a nie skrypt przechowywany w tym repozytorium: po zarejestrowaniu ceny modelu jest ona zapisywana w samym Langfuse i może ją tam znaleźć każdy klient. Pełne uzasadnienie, w tym wyjaśnienie, dlaczego ceny są podawane w euro pomimo wyświetlania w Langfuse symbolu $, można znaleźć w pliku /README.md.

Gdy istnieje pasująca definicja ceny, koszt jest od razu wyświetlany dla nowych śladów.

W przypadku rzeczywistego wywołania modelu Qwen3.5-397B-A17B: 

  • 28 tokenów wejściowych (0,60 € za milion tokenów)
  • 1430 tokenów wyjściowych (3,60 € za milion tokenów)

Wartość calculatedTotalCost obliczona przez Langfuse wyniosła dokładnie: 28 * 0,0000006 + 1430 * 0,0000036 = 0,0051648 €

Dashboard kosztów Langfuse

Dashboard kosztów Langfuse

⚠️ Uwaga: Langfuse zawsze wyświetla koszt z symbolem $ przed wartością; nie ma ustawienia waluty dla poszczególnych projektów. Jeśli importowana tabela cen jest podana w euro, tak jak cennik OVHcloud AI Endpoints, każda kwota w interfejsie Langfuse jest wartością w euro wyświetlaną ze znakiem dolara.

Możesz także sprawdzić różne metryki opóźnienia modelu:

Dashboard opóźnień Langfuse

Dashboard opóźnień Langfuse

Przejdź jeszcze dalej i analizuj ślady reprezentujące żądania lub operacje.

Przykład śledzenia w Langfuse

Przykład śledzenia w Langfuse

Gratulacje! Masz teraz dostęp do wszystkich funkcji Langfuse w kontrolowanym środowisku.

Więcej informacji

  • Wysoka dostępność: w tej architekturze działa jedna replika komponentu webowego i jedna replika workera. Wystarcza to do zweryfikowania konfiguracji, ale nie zapewnia możliwości usunięcia poda bez przestoju. Zwiększ liczbę replik komponentu webowego do co najmniej 2 w przypadku wdrożenia publicznie dostępnego i dodaj odpowiednio skonfigurowany PodDisruptionBudget – skonfigurowanie go dla jednej repliki nie zapewnia żadnej ochrony.
  • Autoscaling: domyślnie nie jest włączony ani HPA, ani KEDA. Włącz jedno z tych rozwiązań, jeśli liczba żądań jest trudna do przewidzenia.
  • Alerty dotyczące kosztów: ten sam interfejs Models API, który służy do wprowadzania cen, może być następnie odpytywany za pośrednictwem Metrics API Langfuse w celu tworzenia automatycznych alertów kosztowych dla poszczególnych zespołów lub funkcji, zamiast ręcznego sprawdzania dashboardów.
  • Polityki sieciowe: w tej konfiguracji nie zdefiniowano żadnych polityk; rozważ ograniczenie ruchu wychodzącego z przestrzeni nazw Langfuse wyłącznie do punktów końcowych zarządzanych usług, których Langfuse potrzebuje.

Podsumowanie

Ta architektura zapewnia wdrożenie Langfuse, które:

  • Działa w OVHcloud MKS bez samodzielnie zarządzanych baz danych – Postgres, Valkey, ClickHouse i Object Storage są usługami zarządzanymi przez OVHcloud
  • Automatycznie obsługuje zakończenie TLS za pomocą Traefik i cert-manager, odnawiając certyfikaty bez konieczności ręcznej interwencji
  • Rejestruje pełne ślady, w tym wykorzystanie tokenów i opóźnienia, z dowolnej aplikacji wywołującej OVHcloud AI Endpoints, dzięki zmianie zaledwie dwóch wierszy kodu SDK
  • Przypisuje koszty do poszczególnych modeli, użytkowników i sesji na podstawie cen z katalogu AI Endpoints, zamiast opierać się na szacunkach
  • Przechowuje każdy prompt, każdą odpowiedź i wszystkie dane dotyczące kosztów w infrastrukturze, nad którą masz pełną kontrolę

Udostępnij na: