Vai al contenuto principale

Tutorial LangFuse: piattaforma di LLM engineering per monitoraggio ed evals

Crea uno strumento di Q&A su documenti mentre scopri come LangFuse semplifica il debug, traccia i costi e organizza i prompt nelle applicazioni LLM complesse.
· 15 min leggi

Scopri con l'IA

Sviluppare applicazioni LLM diventa caotico in fretta. Inizi a indovinare i costi. Fare debug dei fallimenti è più difficile quando non puoi vedere cosa è successo. I prompt si disperdono in tutto il codice. LangFuse risolve tutto questo con una piattaforma che traccia ogni cosa, gestisce i prompt e misura la qualità.

In questo tutorial costruirai uno strumento di Q&A su documenti e vedrai come LangFuse organizza il tuo sviluppo. Imparerai a tracciare le chiamate LLM per il debug, gestire i prompt con controllo di versione ed esplorare approcci di valutazione.

Che cos'è LangFuse?

LangFuse è una piattaforma open source che aiuta i team a creare applicazioni LLM migliori. Mentre tu ti concentri sulle funzionalità, LangFuse si occupa di monitoraggio, test e debug.

La piattaforma copre tre aree principali:

  1. Osservabilità: vedi cosa succede quando gira il tuo LLM. Traccia i costi, individua gli errori e capisci come gli utenti interagiscono con la tua app. Basta indovinare perché qualcosa si è rotto o quanto ti ha addebitato OpenAI il mese scorso.
  2. Gestione dei prompt: archivia e versiona i prompt in un unico posto invece di spargerli nel codice. Il tuo team può testare versioni diverse senza toccare il codice in produzione.
  3. Valutazione: misura quanto bene performa il tuo LLM. Imposta test automatici che verificano se le risposte hanno senso, restano in tema o rispettano standard di qualità.

Quando dovresti usare LangFuse?

Vorrai LangFuse quando la tua applicazione LLM supera i semplici esperimenti. Ecco le situazioni in cui diventa prezioso:

  • Più membri del team lavorano sui prompt e ti serve il controllo di versione
  • Applicazioni in produzione in cui devi tracciare i costi e monitorare le prestazioni
  • Workflow complessi come sistemi RAG, setup multi-agent o catene conversazionali
  • Preoccupazioni sulla qualità per cui ti servono test sistematici invece di controlli spot manuali

Se stai creando un prototipo veloce o un progetto personale, probabilmente non ti serve ancora. Ma quando la tua app gestisce utenti reali o il team cresce oltre una persona, LangFuse diventa utile.

Adozione e integrazione

LangFuse funziona con il tuo stack AI esistente. Si integra con framework principali come LangChain, LlamaIndex, AutoGen e CrewAI. Puoi usarlo con qualsiasi provider di modelli — OpenAI, Anthropic, Google Gemini, Mistral o i modelli Hugging Face funzionano tutti out of the box.

La piattaforma offre SDK nativi per Python e JavaScript, più supporto OpenTelemetry per setup personalizzati. Che tu stia usando builder no-code per agent o framework multi-agent complessi, LangFuse si integra senza cambiare la tua architettura core.

Aziende come Samsara, Twilio e Khan Academy lo usano in produzione, e rispetta gli standard di sicurezza enterprise. Il progetto ha oltre 16.500 stelle su GitHub con il supporto di Y Combinator. Puoi usare la versione hosted o eseguirlo sulla tua infrastruttura.

Ora che sai cosa fa LangFuse e quando aiuta, costruiamo qualcosa con esso. Come promesso, creeremo un semplice strumento di Q&A su documenti che mostra in azione tutte e tre le funzionalità.

Prerequisiti

Ti servono un po' di esperienza con Python e LLM prima di tuffarti in LangFuse.

Indispensabili:

  • Python 3.8+ e conoscenza base delle API
  • Esperienza con l'API di OpenAI (useremo GPT-4)
  • Basi di LangChain — prompt, chain e concetti core

Utile avere:

  • Comprensione di embedding e pattern di retrieval
  • Esperienza con il prompt engineering

Setup:

  • Chiave API OpenAI
  • Gestore pacchetti Python (uv o pip)
  • Creeremo insieme un account LangFuse gratuito

Nuovo allo sviluppo AI? Inizia prima con la nostra guida completa all'apprendimento dell'AI.

Per capire dove si inserisce LangFuse nell'ecosistema più ampio, dai un'occhiata alla nostra panoramica degli strumenti LLMOps.

Ora costruiamo qualcosa. Partiremo da una semplice funzione di Q&A su documenti e vedremo come LangFuse traccia cosa succede quando la esegui. Questo esempio di base ti mostrerà le tre funzionalità principali — osservabilità, gestione dei prompt e valutazione — in un modo che scala a progetti più complessi.

Creare uno strumento di Q&A su documenti con LangFuse

Costruirai un semplice sistema di Q&A su documenti che risponde a domande a partire da un PDF. Ti dà qualcosa di reale da tracciare, gestire e valutare. Anche se teniamo l'esempio semplice, gli stessi pattern funzionano per sistemi RAG complessi e workflow multi-agent.

Configurare l'ambiente

Per prima cosa, crea una directory per il progetto e installa i pacchetti necessari:

mkdir langfuse-qa-demo
cd langfuse-qa-demo
uv add langfuse langchain langchain-openai langchain-community pypdf python-dotenv

Iscriviti a un account gratuito LangFuse Cloud su langfuse.com. Dopo l’accesso, crea una nuova organizzazione e un progetto. Vedrai una schermata con le tue chiavi API:

Dashboard di LangFuse che mostra le chiavi API per un nuovo progetto con campi Public Key e Secret Key

Copia la tua Public Key e la Secret Key. Ti servirà anche la chiave API OpenAI da platform.openai.com.

Ora crea un file .env nella directory del progetto:

OPENAI_API_KEY=your_openai_key_here
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_HOST=https://cloud.langfuse.com

Se preferisci eseguire LangFuse sulla tua infrastruttura, puoi usare Docker Compose per i test locali. La guida al self-hosting spiega come impostare PostgreSQL, ClickHouse e i servizi LangFuse. Per deploy in produzione, usa Kubernetes o template Terraform specifici per il cloud.

Costruire una chain di Q&A su documenti in LangChain

Costruirai una retrieval chain che carica un PDF, lo divide in chunk, li archivia in un database vettoriale e risponde alle domande in base al contesto recuperato.

Crea un file chiamato qa_chain.py:

from langchain_community.document_loaders import PyPDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_core.vectorstores import InMemoryVectorStore
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate
from dotenv import load_dotenv

load_dotenv()

Questo importa tutto ciò di cui hai bisogno. La chiamata load_dotenv() carica le chiavi API dal file .env.

# Load and split PDF
loader = PyPDFLoader("ai-security-landscape.pdf")
docs = loader.load()

text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
splits = text_splitter.split_documents(docs)

Qui stiamo caricando il documento ai-security-landscape.pdf, uno dei whitepaper scritti da Amazon Web Services. Per eseguire questo esempio, dovrai scaricare il file per conto tuo e aggiungerlo alla tua directory di lavoro con il nome corretto.

Il PyPDFLoader legge il PDF e RecursiveCharacterTextSplitter lo suddivide in chunk da 1000 caratteri con un overlap di 200 caratteri. L’overlap aiuta a mantenere il contesto tra i confini dei chunk.

Successivamente, crea lo store vettoriale:

# Create vector store
embeddings = OpenAIEmbeddings()
vectorstore = InMemoryVectorStore.from_documents(documents=splits, embedding=embeddings)

InMemoryVectorStore archivia gli embedding dei documenti in memoria. In produzione, useresti Pinecone, Weaviate o un altro database vettoriale.

Ora costruisci la chain di QA:

# Build QA chain
llm = ChatOpenAI(model="gpt-4")
prompt = ChatPromptTemplate.from_messages([
   ("system", "Use the given context to answer the question. If you don't know the answer, say you don't know. Keep the answer concise.\n\n{context}"),
   ("human", "{input}"),
])

question_answer_chain = create_stuff_documents_chain(llm, prompt)
qa_chain = create_retrieval_chain(vectorstore.as_retriever(), question_answer_chain)

create_stuff_documents_chain prende i documenti recuperati e li inserisce nel contesto del prompt. create_retrieval_chain combina retrieval e risposta in un'unica chain.

Con la chain pronta, colleghiamola a LangFuse per il tracing.

Tracciare la tua prima chiamata con LangFuse

Aggiungi un callback handler di LangFuse allo script:

from langfuse.langchain import CallbackHandler

langfuse_handler = CallbackHandler()

response = qa_chain.invoke(
   {"input": "What are the main security risks discussed?"},
   config={"callbacks": [langfuse_handler]}
)

print(response["answer"])
The main security risks discussed in relation to generative artificial intelligence (AI) are context window overflow, agent mismanagement, indirect prompt injections and data leaks from overprivileged agents, logging, and caching.

Trace sent to LangFuse! Check your dashboard at https://cloud.langfuse.com

Quando esegui questo, LangFuse cattura l’intera traccia di esecuzione. Vai alla tua dashboard LangFuse e la vedrai aggiornata con nuovi dettagli:

Dashboard di LangFuse che mostra la prima esecuzione tracciata della chain di Q&A con metriche di tempo e token

Nota che, anche se qui usiamo un esempio semplice, LangFuse funziona con pipeline RAG complesse che gestiscono più tipi di documenti, usano re-ranking o eseguono più strategie di retrieval in parallelo.

Con il tuo sistema di Q&A in esecuzione e il tracing di LangFuse attivo, sei pronto a capire cosa cattura LangFuse e come usare queste informazioni per migliorare la tua applicazione.

Osservabilità in LangFuse

Hai appena inviato una trace a LangFuse. Ora vediamo cosa ti offre e perché è importante.

Perché l'osservabilità LLM è importante

Il logging tradizionale non funziona bene per le app LLM. Puoi registrare che una funzione è stata eseguita, ma non puoi vedere cosa ha fatto realmente il modello con l'input dell'utente. Ha recuperato i documenti giusti? Il prompt è stato formattato correttamente? Quale passaggio ha impiegato cinque secondi?

L'osservabilità LLM traccia l'intero percorso di esecuzione. Vedi ogni input, output e passaggio intermedio. Quando un utente segnala risposte sbagliate, apri la sua trace e guardi esattamente cosa è successo. Non indovini. Sai.

Questo conta ancora di più man mano che l’app si fa complessa. Una semplice chain di Q&A ha 4–5 passaggi. I sistemi RAG in produzione hanno loader di documenti, strategie di chunking, più retriever, re-ranker e passaggi di generazione. Senza osservabilità, il debug diventa impossibile. Con essa, individui i problemi.

Capire trace e sessioni

Apri la tua dashboard LangFuse e clicca “Tracing” nella sidebar di sinistra. Vedrai la tua prima trace elencata in una tabella.

La tabella mostra quando è stata eseguita la trace, come si chiamava (retrieval_chain) e cosa è entrato e uscito. Ogni riga rappresenta un'esecuzione completa della tua chain di Q&A.

Clicca sulla trace per vedere cosa è successo all'interno. Otterrai una scomposizione dettagliata.

Il pannello di sinistra mostra il tuo albero di esecuzione. LangFuse ha tracciato ogni passaggio della tua chain. La radice retrieval_chain ha impiegato in totale 4,75 secondi. Sotto, vedi ogni operazione eseguita: recupero dei documenti (retrieve_documents), ricerca vettoriale (VectorStoreRetriever) e generazione della risposta (stuff_documents_chain). Ogni passaggio mostra il suo tempo di esecuzione.

Questa gerarchia ti dice dove la tua chain ha speso tempo. Se la tua app è lenta, saprai se è la ricerca degli embedding, la ricerca vettoriale o la chiamata all'LLM.

Il pannello di destra mostra i dati della trace. In alto, hai le metriche che contano: latenza (4,75s), costo (~$0,016) e token usati (426 input, 55 output). Sotto, vedi l'input e l'output effettivi. La sezione context mostra i quattro chunk di documento che il tuo retriever ha estratto dallo store vettoriale.

In basso, un diagramma di flusso mappa come la tua chain collega le sue operazioni. Questo aiuta quando fai debug di chain complesse con più rami.

Ora parliamo delle sessioni. Una trace cattura un ciclo domanda-risposta. Ma le app reali hanno conversazioni. Un utente potrebbe porre tre domande correlate sui rischi di sicurezza. Vuoi raggruppare quelle trace insieme.

È ciò che fanno le sessioni. Raccolgono più trace in un unico thread di conversazione. Quando un utente segnala un bug, puoi aprire l'intera sessione e vedere ogni domanda posta e ogni risposta ricevuta.

Vediamolo in azione. Crea prima un file helper chiamato build_chain.py che incapsula la logica di costruzione della chain:

from langchain_community.document_loaders import PyPDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_core.vectorstores import InMemoryVectorStore
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate
from dotenv import load_dotenv

load_dotenv()

def build_qa_chain():
   # Load and split PDF
   loader = PyPDFLoader("ai-security-landscape.pdf")
   docs = loader.load()

   text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
   splits = text_splitter.split_documents(docs)

   # Create vector store
   embeddings = OpenAIEmbeddings()
   vectorstore = InMemoryVectorStore.from_documents(documents=splits, embedding=embeddings)

   # Build QA chain
   llm = ChatOpenAI(model="gpt-4")
   prompt = ChatPromptTemplate.from_messages([
       ("system", "Use the given context to answer the question. If you don't know the answer, say you don't know. Keep the answer concise.\n\n{context}"),
       ("human", "{input}"),
   ])

   question_answer_chain = create_stuff_documents_chain(llm, prompt)
   qa_chain = create_retrieval_chain(vectorstore.as_retriever(), question_answer_chain)

   return qa_chain

Questo incapsula tutto in una funzione che puoi importare. Ora crea sessions_demo.py:

from build_chain import build_qa_chain
from langfuse.langchain import CallbackHandler

# Build the Q&A chain
qa_chain = build_qa_chain()

# Set up LangFuse handler
langfuse_handler = CallbackHandler()
This imports your chain and sets up the LangFuse handler. Now add session tracking for the first conversation:
# Session 1: User asking about security risks
response1 = qa_chain.invoke(
   {"input": "What are the main security risks discussed?"},
   config={
       "callbacks": [langfuse_handler],
       "metadata": {"langfuse_session_id": "conversation-001"}
   }
)
print(f"Q1: {response1['answer']}\n")

Il campo metadata con langfuse_session_id tagga questa trace con un ID di sessione. Esegui e vedrai:

Q1: The main security risks discussed are context window overflow, agent mismanagement, and indirect prompt injections.

Ora aggiungi una domanda di follow-up con lo stesso ID di sessione:

response2 = qa_chain.invoke(
   {"input": "How can these risks be mitigated?"},
   config={
       "callbacks": [langfuse_handler],
       "metadata": {"langfuse_session_id": "conversation-001"}
   }
)
print(f"Q2: {response2['answer']}\n")

Questa seconda domanda appartiene alla stessa conversazione, quindi usa di nuovo conversation-001. Vedrai una risposta più lunga:

Q2: Risks can be mitigated through several strategies including:
1. Input Management: Limit and sanitize inputs going into the model.
2. Real-time Monitoring: Use systems that alert when the context window is nearing capacity.
3. Principle of Least Privilege: Implement this for all agents and external integrations.
....

Ora simula un secondo utente con domande diverse. Aggiungi questo al tuo script:

# Session 2: Different user asking about AI applications
response3 = qa_chain.invoke(
   {"input": "What AI applications are mentioned in the document?"},
   config={
       "callbacks": [langfuse_handler],
       "metadata": {"langfuse_session_id": "conversation-002"}
   }
)
print(f"Q3: {response3['answer']}\n")

response4 = qa_chain.invoke(
   {"input": "What are the benefits of these applications?"},
   config={
       "callbacks": [langfuse_handler],
       "metadata": {"langfuse_session_id": "conversation-002"}
   }
)
print(f"Q4: {response4['answer']}\n")

Queste due domande usano conversation-002. Esegui lo script completo:

uv run python sessions_demo.py

Gli ultimi due output saranno:

Q3: The document does not specifically mention any AI applications. However, it discusses the concept of generative AI and its security considerations.

Q4: The context does not provide specific benefits of these applications.

Ora vai alla tua dashboard LangFuse e clicca “Sessions” nella sidebar di sinistra. Vedrai entrambe le conversazioni elencate:

Compaiono due sessioni: conversation-002 (~4 secondi di durata) e conversation-001 (~14 secondi di durata). LangFuse ha raggruppato le tue trace per ID di sessione.

Clicca su conversation-001 per vedere l'intera conversazione:

Vista dettagli sessione di LangFuse che mostra due trace correlate con domande su rischi di sicurezza e strategie di mitigazione

Vedi entrambe le trace in ordine: Domanda 1 sui rischi di sicurezza e Domanda 2 sulla mitigazione. La sessione mostra costo totale ($0,05121 per entrambe le trace) e durata (14 secondi totali). Ogni trace appare con il suo input, output e contesto recuperato.

Questa vista della sessione ti mostra esattamente cosa ha vissuto un utente durante l'interazione. Se segnala un problema, non devi cercare tra le singole trace. Apri la sua sessione e vedi il flusso completo della conversazione.

Tracciare gli utenti

Finora hai tracciato le sessioni, ma che dire dei singoli utenti? Le app LLM reali devono sapere quale utente ha fatto quale richiesta. Quando qualcuno si iscrive, generi un ID univoco per lui. Poi alleghi quell'ID a ogni chiamata LLM che fa.

LangFuse ti consente di raggruppare le trace per ID utente oltre che per sessione. Questo ti dà un altro modo per organizzare i dati di osservabilità.

Ecco come aggiungere il tracciamento utente. Crea user_tracking.py:

from build_chain import build_qa_chain
from langfuse.langchain import CallbackHandler

# Build the Q&A chain
qa_chain = build_qa_chain()

# Set up LangFuse handler
langfuse_handler = CallbackHandler()

# Simulate a new user asking a question
user_response = qa_chain.invoke(
   {"input": "What security controls are recommended for AI systems?"},
   config={
       "callbacks": [langfuse_handler],
       "metadata": {
           "langfuse_session_id": "conversation-003",
           "langfuse_user_id": "user-12345"
       }
   }
)
print(f"Response: {user_response['answer']}")

Il campo langfuse_user_id tagga questa trace con un ID utente. Esegui lo script:

uv run python user_tracking.py

Vedrai:

Response: The recommended security controls for AI systems include:

1. Adaptive defenses: Incorporate machine learning-powered filters that continuously learn and adapt to new adversarial techniques.
2. Defense-in-depth: Introduce layered security mechanisms, such as refusal classifiers and real-time input monitoring, to fortify AI system integrity.
3. Data classification: Properly classify your data according to sensitivity.
......

Ora vai alla tua dashboard LangFuse. Clicca “Users” nella sidebar di sinistra e vedrai user-12345 elencato. Clicca sull’utente per vedere tutte le sue trace nelle diverse sessioni.

Questa vista utente ti aiuta a rispondere a domande come “Quanto ci è costato l’utente X questo mese?” o “Che domande continua a fare l’utente Y?”. Puoi tracciare il comportamento dei singoli utenti e fare debug di problemi specifici.

Gestione dei prompt in LangFuse

Il tuo sistema di Q&A ha un problema. Il prompt è sepolto nel codice. Per cambiare come risponde il sistema, devi modificare qa_chain.py, testare in locale e ridistribuire. Se un compagno di squadra vuole provare un approccio diverso, deve capire la struttura del tuo codice e creare un nuovo branch. Non puoi confrontare diverse versioni di prompt affiancate o fare rollback alla versione della settimana scorsa senza scavare nella cronologia git.

La gestione dei prompt risolve questo problema archiviando i prompt fuori dal codice. Li modifichi in una UI, li versi in automatico e li recuperi a runtime. Il tuo codice resta uguale mentre i prompt migliorano.

Il problema dei prompt in collaborazione

Guarda il prompt nella tua chain di Q&A:

prompt = ChatPromptTemplate.from_messages([
   ("system", "Use the given context to answer the question. If you don't know the answer, say you don't know. Keep the answer concise.\n\n{context}"),
   ("human", "{input}"),
])

Questo funziona per progetti in solitaria. Ma quando lavori in team o sei in produzione, i prompt hardcoded causano problemi:

  • Attrito nel deploy: ogni modifica al prompt richiede un deploy del codice. Non puoi fare A/B test di prompt diversi senza cambiare il codice dell’applicazione. Se vuoi provare “Sii breve e fattuale” invece di “Mantieni la risposta concisa”, devi fare commit, push e ridistribuire.
  • Nessun controllo di versione: Git traccia i cambiamenti del codice, ma non ti mostra quale versione di prompt ha performato meglio in produzione. Non puoi vedere metriche per “prompt v1” vs “prompt v2” o tornare rapidamente alla versione precedente senza un deploy di codice.
  • Colli di bottiglia nel team: i membri non tecnici non possono iterare sui prompt. Il tuo product manager ha idee per una formulazione migliore, ma deve chiedere a un ingegnere di fare la modifica. Questo rallenta la sperimentazione.
  • Difficoltà di test: confrontare variazioni di prompt significa eseguire più versioni del tuo codice. Non puoi testare risposte concise vs dettagliate fianco a fianco senza lavoro manuale.

La gestione dei prompt di LangFuse affronta questi problemi trattando i prompt come dati, non come codice.

Creazione e versionamento dei prompt

LangFuse archivia i tuoi prompt in una posizione centrale con versionamento automatico. Puoi crearli tramite UI o SDK.

Creare prompt nella UI

Vai alla tua dashboard LangFuse e clicca “Prompts” nella sidebar di sinistra. Clicca “New Prompt” per crearne uno.

Vedrai un form in cui puoi:

  • Dare un nome al prompt (usa document-qa-prompt)
  • Scegliere il tipo (text o chat)
  • Scrivere il template del prompt con variabili usando la sintassi {{variable}}
  • Impostare la configurazione come modello e temperatura
  • Aggiungere label per marcare le versioni (come production o staging)

Per il nostro sistema di Q&A, crea un prompt chat con due messaggi:

Messaggio di sistema:

Use the given context to answer the question. If you don't know the answer, say you don't know. Keep the answer concise.

{{context}}

Messaggio utente:

{{input}}

LangFuse rileverà automaticamente le variabili {{context}} e {{input}}.

Poi imposta la config a:

{
 "model": "gpt-4",
 "temperature": 0.0
}

Aggiungi la label production per segnarla come versione di produzione.

Una volta salvato, LangFuse crea la versione 1 del tuo prompt. Ogni volta che modifichi e salvi, crea una nuova versione. Le vecchie versioni restano disponibili.

Creare prompt via SDK

Puoi anche creare prompt usando il Python SDK:

from langfuse import Langfuse

langfuse = Langfuse()

langfuse.create_prompt(
   name="document-qa-prompt",
   type="chat",
   prompt=[
       {"role": "system", "content": "Use the given context to answer the question. If you don't know the answer, say you don't know. Keep the answer concise.\n\n{{context}}"},
       {"role": "user", "content": "{{input}}"}
   ],
   labels=["production"]
)

Questo crea lo stesso prompt in modo programmatico. Se chiami di nuovo create_prompt() con lo stesso nome, LangFuse aggiunge una nuova versione invece di sovrascrivere.

Controllo versione con label

LangFuse traccia ogni modifica ai prompt con numeri di versione (v1, v2, v3). Puoi anche assegnare label alle versioni. Le label aiutano a gestire i deploy:

  • production - la versione usata dalla tua app in produzione
  • staging - la versione nel tuo ambiente di staging
  • latest - punta automaticamente alla versione più recente

Quando migliori il tuo prompt, crei una nuova versione. Testala prima in staging assegnandole la label staging. Quando funziona bene, sposta la label production sulla nuova versione. La tua app in produzione prenderà automaticamente la modifica al prossimo fetch del prompt.

Testare varianti nel playground

La UI di LangFuse include un playground dove puoi testare i prompt prima di usarli nel codice. Puoi:

  • Provare valori diversi per le variabili
  • Confrontare più versioni affiancate
  • Vedere come le modifiche influenzano l'output
  • Condividere i risultati dei test con il tuo team

Questo permette ai membri non tecnici del team di sperimentare con la formulazione senza toccare il codice.

Integrare i prompt gestiti nel codice

Ecco come usare i prompt gestiti da LangFuse nella tua applicazione. Questo workflow mantiene il codice stabile mentre i prompt evolvono.

Passaggio 1: recuperare il prompt

Nel codice dell’applicazione, recupera il prompt da LangFuse invece di hardcodarlo:

from langfuse import Langfuse

langfuse = Langfuse()

# Get the production version
prompt = langfuse.get_prompt("document-qa-prompt", type="chat")

Questo recupera la versione etichettata production. LangFuse fa caching dei prompt lato client, quindi non c'è impatto di latenza sulle chiamate LLM.

Puoi anche recuperare versioni o label specifiche:

# Get version 2 specifically
prompt = langfuse.get_prompt("document-qa-prompt", version=2, type="chat")

# Get staging version
prompt = langfuse.get_prompt("document-qa-prompt", label="staging", type="chat")

# Get latest version (automatically maintained by LangFuse)
prompt = langfuse.get_prompt("document-qa-prompt", label="latest", type="chat")

Passaggio 2: compilare il prompt con le variabili

Il prompt recuperato è un template con {{variables}}. Compilalo sostituendo le variabili con i valori reali:

compiled_messages = prompt.compile(
   context="Retrieved document context goes here",
   input="What are the main security risks?"
)

Questo restituisce una lista di messaggi chat pronti da inviare al tuo LLM:

[
   {
       "role": "system",
       "content": "Use the given context to answer the question. If you don't know the answer, say you don't know. Keep the answer concise.\n\nRetrieved document context goes here"
   },
   {
       "role": "user",
       "content": "What are the main security risks?"
   }
]

Passaggio 3: usare il prompt compilato con il tuo LLM

Passa i messaggi compilati alla tua chiamata LLM. Il codice esatto dipende se stai usando LangChain, direttamente l’SDK di OpenAI o un altro framework.

Passaggio 4: collegare il prompt alle trace

Quando effettui una chiamata LLM con un prompt gestito da LangFuse, collegalo alla trace. Questo ti permette di vedere quale versione del prompt è stata usata per ogni chiamata LLM e tracciare metriche per versione di prompt:

from langfuse.langchain import CallbackHandler

langfuse_handler = CallbackHandler()

response = qa_chain.invoke(
   {"input": "What are the main security risks?"},
   config={"callbacks": [langfuse_handler]}
)

Nella tua dashboard LangFuse, vedrai le trace raggruppate per nome e versione del prompt. Questo ti mostra quali versioni di prompt costano di più, sono più lente o producono risultati migliori.

Passaggio 5: iterare senza modifiche al codice

È qui che la gestione dei prompt ripaga. Per migliorare il tuo prompt:

  1. Vai nella UI di LangFuse
  2. Modifica il prompt (crea automaticamente una nuova versione)
  3. Testalo nel playground
  4. Assegna la label staging per testarlo nel tuo ambiente di staging
  5. Sposta la label production per il deploy

Il tuo codice non cambia mai. La volta successiva che chiama get_prompt(), recupera la nuova versione.

Passaggio 6: rollback se necessario

Se il nuovo prompt performa peggio, torna indietro spostando la label production sulla versione precedente. Nessun deploy di codice richiesto.

Questo workflow separa il prompt engineering dallo sviluppo software. Il tuo team può iterare rapidamente sui prompt mentre il codice dell’app rimane stabile.

Approfondimenti: LangFuse supporta anche A/B test per dividere automaticamente il traffico tra versioni di prompt, webhook che notificano i tuoi sistemi quando i prompt cambiano e funzionalità di collaborazione come commenti e workflow di approvazione. Queste funzionalità avanzate aiutano i team più grandi a gestire i prompt su larga scala. Consulta la documentazione sulla gestione dei prompt per i dettagli.

Valutazione in LangFuse

Hai creato un sistema di Q&A, aggiunto osservabilità e impostato la gestione dei prompt. Ma come fai a sapere se le risposte sono buone? Al momento probabilmente stai testando manualmente. Fai una domanda, leggi la risposta e decidi se ha senso. Funziona per pochi esempi, ma non scala.

Cosa succede quando cambi il prompt? Devi ritestare tutto. E i casi limite? Non puoi ricordare ogni domanda che hai già testato. E quando fai il deploy in produzione, non hai modo di misurare se la versione 2 del tuo prompt performa meglio della versione 1.

La valutazione risolve questo misurando in modo sistematico le performance del tuo LLM. LangFuse ti offre strumenti per assegnare punteggi automaticamente alle risposte, confrontare versioni di prompt con metriche reali e intercettare problemi di qualità prima che li vedano gli utenti.

Approcci sistematici di valutazione LLM

Il testing manuale ti dice se una risposta specifica sembra buona. La valutazione sistematica ti dice se l’intero sistema funziona bene su centinaia o migliaia di esempi.

Ecco come funziona la valutazione sistematica in LangFuse:

  1. Crea un dataset di test: raccogli 20–50 domande che rappresentano l'uso reale, inclusi casi limite in cui la risposta non è nei documenti.
  2. Scegli metodi di scoring: decidi quali dimensioni di qualità contano per il tuo sistema di Q&A (le vedremo nella sezione successiva).
  3. Esegui il sistema sul dataset: elabora ogni domanda e registra i risultati su LangFuse come trace.
  4. Assegna punteggi alle risposte: applica automaticamente i tuoi metodi di scoring a ogni risposta.
  5. Analizza i risultati: LangFuse aggrega i punteggi sul tuo set di test e ti mostra quali esempi sono falliti.
  6. Itera e confronta: cambia il tuo prompt, riesegui il set di test e confronta le metriche per vedere se hai migliorato.

Questo processo sostituisce “Penso che questo prompt sia migliore” con “questo prompt ottiene 0,85 di rilevanza contro 0,72 della vecchia versione”.

Per una guida completa sugli approcci di valutazione e come implementarli in LangFuse, consulta la documentazione di panoramica sulla valutazione.

Capire la valutazione LLM-as-a-Judge

Devi dare un punteggio a centinaia di risposte. Farlo manualmente richiede ore. LLM-as-a-judge lo automatizza usando un altro LLM per valutare gli output del tuo LLM principale.

Come funziona

Dai a un LLM giudice tre cose: la domanda originale, la risposta del tuo sistema di Q&A e i criteri di valutazione. Il giudice legge la risposta e assegna un punteggio.

Per un sistema di Q&A, ti interessano diverse dimensioni di qualità. Ecco tre giudici che potresti creare:

Giudice di correttezza: “Valuta se questa risposta riflette correttamente le informazioni nel contesto fornito. Assegna 1 se completamente corretta, 0,5 se parzialmente corretta, 0 se errata o allucinata”.

Questo intercetta risposte che contraddicono i tuoi documenti o inventano fatti.

Giudice di rilevanza: “Valuta se questa risposta affronta direttamente la domanda posta. Assegna 1 se altamente rilevante, 0,5 se in parte rilevante, 0 se fuori tema”.

Questo garantisce che il sistema resti in tema invece di dare informazioni accurate ma irrilevanti.

Giudice di groundedness: “Valuta se questa risposta si basa solo sul contesto fornito. Assegna 1 se completamente ancorata al contesto, 0,5 se parzialmente, 0 se include informazioni non presenti nel contesto”.

Questo previene allucinazioni in cui l’LLM aggiunge fatti non presenti nei tuoi documenti.

Ogni giudice guarda una dimensione specifica della qualità. Esegui tutti e tre i giudici su ogni risposta e ottieni un profilo di qualità completo. Puoi aggiungere altri giudici per lo stile (è concisa?), il tono (è professionale?) o la gestione del rifiuto (dice “Non lo so” quando appropriato?).

Configurare i giudici in LangFuse

LangFuse ti permette di configurare LLM giudici tramite UI o API. Il processo di setup:

  1. Definisci il prompt del giudice: scrivi istruzioni chiare di scoring con criteri specifici per ciascun livello di punteggio.
  2. Scegli il modello del giudice: usa GPT-4, Claude o un altro LLM. Modelli più forti danno punteggi più accurati ma costano di più.
  3. Configura il giudice in LangFuse: crea un template di scoring che LangFuse applicherà automaticamente alle trace.
  4. Testa il giudice: eseguilo su alcuni esempi in cui conosci il punteggio corretto. Regola il prompt se il giudice è troppo severo o troppo indulgente.
  5. Applica al tuo dataset: LangFuse assegna i punteggi a tutte le tue trace automaticamente una volta che il giudice funziona bene.

I giudici girano in modo asincrono, quindi non rallentano la tua applicazione principale. Controlli i punteggi nella dashboard LangFuse dopo che i test sono finiti.

Quando i giudici funzionano bene

I giudici LLM funzionano meglio per criteri soggettivi difficili da misurare con il codice. Cose come tono, rilevanza e stile. Sono meno affidabili per fatti oggettivi. Se devi verificare che “2+2=4”, scrivi un controllo deterministico invece di usare un giudice.

Per il nostro sistema di Q&A, i giudici funzionano bene per rilevanza e groundedness, ma potresti combinarli con controlli deterministici per cose come “la risposta è sotto le 100 parole”.

Limitazioni da considerare

I giudici LLM non sono perfetti. Possono non essere d’accordo tra loro, avere bias verso certi stili di risposta ed effettuare errori assegnando punteggi alti a risposte sbagliate ma sicure di sé.

Gestisci questo testando i giudici su esempi in cui conosci il punteggio giusto, usando più giudici e facendo la media dei punteggi, e facendo controlli a campione per intercettare errori del giudice.

Nota di implementazione: i workflow di valutazione completi comportano impostare dataset, configurare giudici, eseguire valutazioni batch e analizzare i risultati. Richiedono più setup di quanto possiamo coprire in questo tutorial mantenendolo pratico. La documentazione su LLM-as-a-judge fornisce dettagli completi di implementazione, inclusi esempi di codice e best practice. Per approcci di scoring personalizzati oltre ai giudici LLM, vedi la guida ai punteggi personalizzati.

Il workflow che abbiamo delineato qui ti mostra la mentalità della valutazione. Una volta che hai trace e prompt gestiti in LangFuse, aggiungere una valutazione sistematica viene naturale. Costruisci set di test in modo incrementale, parti da giudici semplici e affina l'approccio man mano che capisci quali metriche contano per la tua applicazione.

Approfondimenti: LangFuse supporta anche la gestione dei dataset per organizzare i casi di test, funzioni di scoring personalizzate per controlli deterministici e valutazione continua che gira automaticamente sul traffico di produzione. Queste funzionalità ti aiutano a mantenere la qualità mentre il sistema scala. Consulta la panoramica sulla valutazione per il quadro completo.

Conclusione

Hai costruito un sistema di Q&A su documenti e imparato come i tre pilastri di LangFuse lavorano insieme. L’osservabilità ti ha mostrato cosa succede quando gira il tuo LLM. Vedi ogni trace, ogni costo, ogni token. La gestione dei prompt ha spostato i prompt fuori dal codice e in un sistema con controllo di versione in cui puoi iterare senza deploy. La valutazione ti ha dato modi per misurare la qualità in modo sistematico invece di indovinare. Queste funzionalità si connettono: le trace alimentano i dataset di valutazione, le versioni dei prompt si collegano alle metriche di performance, e l’intero sistema ti aiuta a capire se i cambiamenti migliorano o peggiorano le cose.

Inizia in piccolo con i tuoi progetti. Scegli una funzionalità. Magari aggiungi il tracing per vedere dove la tua app spende denaro, o sposta un prompt hardcoded nel sistema di gestione di LangFuse. I pattern che hai imparato con il nostro semplice esempio di Q&A scalano a pipeline RAG complesse, sistemi multi-agent e applicazioni in produzione che gestiscono migliaia di utenti. Consulta la documentazione di LangFuse per approfondimenti su funzionalità specifiche, o prova gli notebook di esempio che mostrano implementazioni reali. La prossima volta che costruirai con gli LLM, avrai gli strumenti per vedere cosa succede, controllare cosa cambia e misurare ciò che conta.

Bexruz (Bex) Tuychiev

Autore

Bexruz (Bex) Tuychiev

Sono un creator di contenuti sulla data science con oltre 2 anni di esperienza e uno dei più seguiti su Medium. Mi piace scrivere articoli dettagliati su AI e ML con un pizzico di sarcasmo, perché bisogna pur fare qualcosa per renderli un po’ meno noiosi. Ho pubblicato oltre 130 articoli e un corso su DataCamp, con un altro in arrivo. I miei contenuti sono stati visti da oltre 5 milioni di persone, 20.000 delle quali sono diventate follower sia su Medium che su LinkedIn. 

Argomenti

Correlato