Un agente che lavora alle tre di notte senza nessuno a guardarlo vale quanto la tua capacità di ricostruire dopo cosa ha fatto. «Stanotte ha bruciato 38 $ di token» è una brutta mattinata. «Ha bruciato 38 $ perché uno strumento di ricerca ha restituito una pagina vuota e il planner ha riprovato 400 volte» è un bug che sistemi prima di pranzo. Per la seconda frase servono le tracce.
Langfuse registra ogni chiamata LLM, ogni prompt, passo di strumento, conteggio di token e latenza come un albero in cui puoi cliccare. Se lo ospiti tu, quei prompt e quelle risposte — che spesso contengono dati dei clienti, output di API e qualche segreto finito lì per sbaglio — restano su un server che controlli, non nel pannello di qualcun altro.
Quanto costa tenerlo acceso
Langfuse v4 non è un piccolo binario, ma sei container: l'app web, un worker in background, Postgres, ClickHouse per gli eventi, Redis e MinIO per i file. L'abbiamo installato su un server di prova e abbiamo misurato circa 3,5 GB di RAM in uso con un progetto vuoto. A crescere è ClickHouse, perché lì finisce ogni span che invii.
| Carico | Piano |
|---|---|
| Una manciata di agenti, settimane di tracce | Medium-IP: 6 vCPU, 6 GB, 45 GB ($20/mese) |
| Una flotta di agenti, mesi di storico | Piani Pro, da 32 GB di RAM in su — su richiesta |
Sui piani più piccoli si installa, poi va in affanno appena ClickHouse e il worker vogliono memoria nello stesso momento. Io non scenderei sotto i 6 GB.
Dove vivono gli agenti? Se girano su altre macchine, scegli un piano con un IPv4 tutto suo: serve loro un endpoint HTTPS, e su un piano NAT l'indirizzo in uscita non è il tuo e dall'esterno si raggiunge solo la porta SSH. Se gli agenti girano su questo stesso server, Langfuse non deve mai affacciarsi su internet: per una prova basta Medium con NAT ($12/mese). Le località sono due, Germania e Finlandia; la disponibilità si vede al momento dell'ordine. Scegli quella più vicina agli agenti, non a te. I server si pagano in cripto, senza KYC.
Installazione
Su un server Ubuntu 24.04 o Debian 12 appena creato, come root. Prima Docker:
curl -fsSL https://get.docker.com | sh
Poi Langfuse, con segreti veri al posto dei valori di default del file compose:
git clone --depth 1 https://github.com/langfuse/langfuse.git
cd langfuse
PG=$(openssl rand -hex 16); MINIO=$(openssl rand -hex 16)
cat > .env <<EOF
NEXTAUTH_URL=https://langfuse.example.com
NEXTAUTH_SECRET=$(openssl rand -hex 32)
SALT=$(openssl rand -hex 32)
ENCRYPTION_KEY=$(openssl rand -hex 32)
POSTGRES_PASSWORD=$PG
DATABASE_URL=postgresql://postgres:$PG@postgres:5432/postgres
CLICKHOUSE_PASSWORD=$(openssl rand -hex 16)
MINIO_ROOT_PASSWORD=$MINIO
LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY=$MINIO
LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY=$MINIO
LANGFUSE_S3_BATCH_EXPORT_SECRET_ACCESS_KEY=$MINIO
REDIS_AUTH=$(openssl rand -hex 16)
TELEMETRY_ENABLED=false
EOF
chmod 600 .env
Due di quelle password vanno in coppia: quella di Postgres sta anche dentro DATABASE_URL, e quella di MinIO deve coincidere con le tre righe S3_..._SECRET_ACCESS_KEY. Per questo ciascuna viene da una sola variabile.
Ora la trappola. Il file compose pubblica l'app web sulla porta 3000 e MinIO sulla 9090 su tutte le interfacce, e le porte pubblicate da Docker scavalcano ufw. Lega entrambe a localhost, così l'unico ingresso resta il reverse proxy:
sed -i 's/- 3000:3000/- 127.0.0.1:3000:3000/; s/- 9090:9000/- 127.0.0.1:9090:9000/' docker-compose.yml
docker compose up -d
curl -s http://127.0.0.1:3000/api/public/health
L'ultimo comando dovrebbe stampare {"status":"OK", ...}. Il primo avvio esegue le migrazioni del database; nella nostra prova l'health check è passato circa 15 secondi dopo l'avvio dei container.
HTTPS davanti
Punta langfuse.example.com sull'IP del server, poi:
apt install -y caddy
cat > /etc/caddy/Caddyfile <<'EOF'
langfuse.example.com {
reverse_proxy 127.0.0.1:3000
}
EOF
systemctl reload caddy
ufw allow 22/tcp && ufw allow 80/tcp && ufw allow 443/tcp && ufw enable
Caddy ottiene il certificato da solo. Apri il sito, crea il tuo account (diventa la prima organizzazione), aggiungi un progetto e copia le sue chiavi pubblica e segreta.
Poi chiudi la porta dietro di te. Langfuse capisce AUTH_DISABLE_SIGNUP, ma il file compose di serie non la passa al container web, quindi serve una riga in più sotto langfuse-web:
sed -i 's|^ NEXTAUTH_SECRET: \(.*\)$| NEXTAUTH_SECRET: \1\n AUTH_DISABLE_SIGNUP: ${AUTH_DISABLE_SIGNUP:-false}|' docker-compose.yml
echo "AUTH_DISABLE_SIGNUP=true" >> .env
docker compose up -d
Da qui in poi un tentativo di registrazione riceve «Sign up is disabled». I colleghi li aggiungi dall'interno del progetto.
Inviare tracce da un agente
L'SDK Python avvolge le tue funzioni, e le chiamate annidate diventano span annidati:
python3 -m venv venv && . venv/bin/activate
pip install langfuse
export LANGFUSE_PUBLIC_KEY=pk-lf-...
export LANGFUSE_SECRET_KEY=sk-lf-...
export LANGFUSE_BASE_URL=https://langfuse.example.com
from langfuse import get_client, observe
langfuse = get_client() # legge le variabili LANGFUSE_*
@observe(name="fetch-prices")
def fetch_prices(pair: str) -> dict:
return {"pair": pair, "bid": 64210.5}
@observe(name="nightly-agent-run")
def run() -> str:
data = fetch_prices("BTC/USDT")
return f"done: {data['pair']}"
print(run())
langfuse.flush() # gli script brevi terminano prima che finisca l'invio in background
Non saltare LANGFUSE_BASE_URL. Senza, l'SDK manda tutto in silenzio al cloud di Langfuse, le tue chiavi lì non esistono e ti ritrovi a fissare un pannello vuoto.
Per verificare dalla console che gli span sono arrivati:
curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
"$LANGFUSE_BASE_URL/api/public/v2/observations?limit=5"
In v4 il vecchio endpoint /api/public/traces risponde con un errore sulla modalità events-only. È previsto, non è un'installazione rotta. In un agente vero avvolgi allo stesso modo la chiamata LLM e ogni strumento; in più Langfuse ha integrazioni per gli SDK LLM e i framework per agenti più diffusi, quindi spesso basta cambiare un import invece di riempire tutto di decoratori.
Cosa tenere d'occhio
- Disco. ClickHouse e MinIO conservano tutto ciò che invii.
docker system df -vmostra dove è finito lo spazio. Se tracci prompt e risposte lunghi, i 45 GB di Medium-IP si riempiono in settimane, non in anni. Controlla una volta al mese; quando ti va stretto, un piano Pro da 400 GB o più è su richiesta. - Aggiornamenti. Il file compose fissa la versione major (
:4).docker compose pull && docker compose up -dporta le correzioni al suo interno. Leggi il changelog prima di cambiare versione major: proprio con la v4 è sparito l'endpoint delle tracce. - Backup. Ciò che conta vive nei volumi Docker: Postgres tiene utenti, progetti e chiavi; ClickHouse e MinIO, le tracce. Copiali fuori dal server con una pianificazione.
Vale $20 al mese? Se i tuoi agenti spendono più di così in token — e la maggior parte degli agenti senza supervisione lo fa — sapere dove sono finiti i token si ripaga la prima volta che un ciclo va fuori controllo. Un piccolo agente che gira una volta al giorno non ha bisogno di niente di tutto questo: bastano un file di log e un contatore di token.
Correlati
- VPS per agenti IA: dove girano gli agenti stessi
- VPS per sistemi multi-agente: dimensionare un'intera flotta
- VPS per un proxy LiteLLM: un unico gateway per tutte le chiavi dei modelli, con limiti di spesa
- Piani Pro su richiesta: da 32 a 80 GB di RAM per una flotta di agenti
- Come configurare un firewall ufw
Commenti
Ancora nessun commento. Sii il primo.