SSD Nodes Learn Hosting plans →
Guias Matt ConnorPor Matt Connor

Hospede o Langfuse no seu VPS para rastrear agentes

Execute o Langfuse no seu VPS: veja o limite real de recursos, fixe tags de imagem, configure TLS, retenção do ClickHouse e backups testados.

Por que rastrear um agente de IA

Aloja o Langfuse no seu próprio servidor para ver o que o seu agente realmente fez durante uma execução. O Langfuse é uma ferramenta de observabilidade de LLM (modelo de linguagem de grande escala) de código aberto. Regista cada prompt, cada resposta do modelo, cada chamada a uma ferramenta e cada token. Depois, agrupa esses dados num único trace que pode abrir e consultar. Ao executá-lo no seu próprio VPS, esses prompts nunca saem de um servidor que controla.

A razão é simples. Não pode corrigir um problema de custos ou de qualidade que não consegue ver. Uma fatura do fornecedor informa que terça-feira custou quatro vezes mais do que segunda-feira. Um trace mostra qual execução do agente causou isso, qual prompt cresceu para 40,000 tokens e qual ciclo de retry foi executado nove vezes antes de desistir. A fatura fornece o número. O trace mostra o código que o produziu.

Este guia usa três termos. Um trace é uma execução completa do agente, do início ao fim. Uma observation é uma etapa dessa execução: um span para código normal ou uma generation para uma chamada a um modelo. Um score é um número associado a um trace, atribuído por uma revisão humana ou por um avaliador automatizado. O Langfuse usa OpenTelemetry (OTel), o padrão independente de fornecedor para tracing distribuído. Assim, a instrumentação que já possui pode enviar dados para ele.

O que a instalação self-hosted do Langfuse realmente executa

O Langfuse v4 não é um único container. É composto por dois containers de aplicação e quatro serviços de armazenamento. Numa única VPS, os seis são executados no seu servidor.

  • langfuse-web disponibiliza a interface web e a API de ingestão.
  • langfuse-worker processa a fila em segundo plano. Analisa os lotes de ingestão, calcula os custos e executa o trabalho noturno de retenção.
  • Postgres armazena dados transacionais, como utilizadores, organizações, projetos, chaves de API e prompts.
  • ClickHouse armazena os próprios dados de traces, ou seja, observações e scores. É um armazenamento colunar concebido para consultas analíticas. Por isso, um dashboard sobre mais de cem milhões de linhas continua a responder rapidamente.
  • Redis é a fila e a cache entre o serviço web e o worker.
  • MinIO fornece armazenamento de objetos compatível com S3 no próprio servidor. Armazena cada evento bruto recebido e qualquer ficheiro multimédia anexado.

O Langfuse publica os recursos mínimos para cada componente que executa. O gráfico mostra os três componentes que realizam o processamento.

GráficoLangfuse published minimum resources per component
Os dados por trás deste gráfico
[
  {
    "label": "ClickHouse",
    "cpu_cores": 2,
    "memory_gib": 8
  },
  {
    "label": "Langfuse web",
    "cpu_cores": 2,
    "memory_gib": 4
  },
  {
    "label": "Langfuse worker",
    "cpu_cores": 2,
    "memory_gib": 4
  }
]

O ClickHouse sozinho requer 8 GiB de memória. O container web e o worker requerem 4 GiB cada. Esses são os valores mínimos publicados para os 3 componentes mostrados no gráfico. A mesma página indica 4 GiB para o Postgres, 1.5 GiB para o Redis ou Valkey e 4 GiB para o MinIO. Assim, os valores mínimos dos seis componentes totalizam 25.5 GiB. O guia oficial de Docker Compose do projeto recomenda pelo menos 4 cores, 16 GiB de memória e cerca de 100 GiB de armazenamento para uma única máquina. Isso é inferior à soma dos valores mínimos dos componentes. Portanto, considere 16 GiB como o mínimo necessário para um servidor Compose partilhado, não como margem disponível.

Não tente executar isto num plano de 2 GiB. O ClickHouse inicia e aceita escritas durante algum tempo, mas depois termina durante uma operação de merge em segundo plano, porque essa operação carrega partes grandes de uma tabela para a memória. Verá docker compose ps a indicar o container clickhouse como restarting, dmesg a apresentar uma linha semelhante a Out of memory: Killed process 1234 (clickhouse-serv), e todos os dashboards do Langfuse a devolver 500. Sob uma carga menor, o ClickHouse recusa a consulta e regista DB::Exception: Memory limit (total) exceeded. O valor a considerar no planeamento é 16. Se a mesma VPS também tiver de executar outros serviços, reserve recursos adicionais para eles. Até uma stack relativamente leve, como um espaço de trabalho AFFiNE self-hosted, precisa dos seus próprios gigabytes, e o ClickHouse não devolverá memória.

Implante o Langfuse com Docker Compose

Clone o repositório. A stack, a configuração entre serviços e o ambiente predefinido estão todos no seu docker-compose.yml.

git clone https://github.com/langfuse/langfuse.git
cd langfuse

Todos os valores que tem de alterar estão marcados com # CHANGEME nesse ficheiro. Gere primeiro os três segredos da aplicação.

openssl rand -base64 32   # NEXTAUTH_SECRET
openssl rand -base64 32   # SALT
openssl rand -hex 32      # ENCRYPTION_KEY

ENCRYPTION_KEY tem de ter 256 bits, escritos como 64 caracteres hexadecimais. É exatamente isso que openssl rand -hex 32 imprime. Este valor cifra dados sensíveis em repouso, incluindo quaisquer chaves de fornecedores de LLM que armazene na instância. Se o alterar depois de existirem dados, essas linhas deixam de poder ser decifradas. Trate-o, por isso, como permanente desde o primeiro arranque. SALT é usado para calcular o hash das suas chaves da API do Langfuse. Alterá-lo invalida todas as chaves que os seus agentes já estejam a usar.

Defina depois POSTGRES_PASSWORD, CLICKHOUSE_PASSWORD, REDIS_AUTH e MINIO_ROOT_PASSWORD. A palavra-passe do MinIO aparece em quatro locais: uma vez como MINIO_ROOT_PASSWORD e depois como LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY, LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY e LANGFUSE_S3_BATCH_EXPORT_SECRET_ACCESS_KEY. Se falhar um deles, o MinIO rejeita esse cliente com SignatureDoesNotMatch. A mensagem aparece no log do worker, enquanto a interface web continua a parecer saudável. Manter estes valores num ficheiro env, em vez de os guardar no ficheiro compose versionado, é o padrão abordado em ficheiros env e segredos do Docker Compose.

Fixe as tags das imagens antes de começar

O ficheiro fornecido usa docker.langfuse.com/langfuse/langfuse:4 e docker.langfuse.com/langfuse/langfuse-worker:4. Essas tags mudam. O Langfuse executa automaticamente as migrações do Postgres e do ClickHouse durante o arranque. Assim, um docker compose pull de rotina meses depois pode transformar-se numa migração de schema não planeada numa base de dados que não tinha backup nessa manhã. Fixe ambas numa só release, num docker-compose.override.yml. O Compose aplica esse ficheiro sobre o ficheiro fornecido, para que um git pull posterior não substitua as suas alterações. As mesmas imagens são publicadas no Docker Hub, de onde o override abaixo as obtém.

services:
  langfuse-web:
    image: docker.io/langfuse/langfuse:4.72.0
  langfuse-worker:
    image: docker.io/langfuse/langfuse-worker:4.72.0

A versão 4.3.1 era a versão atual da série 4.3 em agosto de 2026. Desde então, as releases têm sido frequentes, e a v4.56.0 era a versão mais recente no GitHub em 11 de outubro de 2026. O override acima usa a v4.72.0, a versão mais recente no GitHub em 31 de outubro de 2026. Consulte a página de releases do projeto no GitHub, fixe a versão que estiver atual no dia da implantação e altere esse número de forma deliberada. Algumas imagens de armazenamento no ficheiro fornecido também devem ser tratadas da mesma forma, porque as respetivas tags também mudam. postgres:17, o valor predefinido de uma variável POSTGRES_VERSION, e redis:7 seguem uma versão principal. O ficheiro fornecido usa agora uma tag de versão exata para docker.io/clickhouse/clickhouse-server, fixando uma versão exata do ClickHouse. Esta regra não é específica do Langfuse: um monitor de treinos openGym alojado localmente executa uma fração desta stack e ainda assim requer uma tag git identificada, porque qualquer aplicação que migre a própria base de dados durante o arranque pode transformar um pull de rotina numa alteração de schema.

Inicie a stack.

docker compose up -d
docker compose ps
docker compose logs -f langfuse-worker

O primeiro arranque executa as migrações. Aguarde dois ou três minutos antes de testar qualquer resposta. O contentor web regista Ready quando fica disponível. docker compose ps deve listar seis serviços no estado running. Se um contentor reiniciar continuamente, o respetivo log contém a causa. As migrações do ClickHouse são aplicadas quando o contentor web arranca. Por isso, um CLICKHOUSE_MIGRATION_URL inválido aparece em docker compose logs langfuse-web, não no log do worker que está a monitorizar. Essa variável usa o protocolo nativo do ClickHouse na porta 9000, não a porta HTTP 8123. Apontá-la para 8123 impede as migrações de arranque do contentor web. O worker executa as migrações em background mais lentas. É no seu log que essas migrações são registadas.

Verifique o estado a partir do próprio servidor.

curl -s "http://localhost:3000/api/public/health?failIfDatabaseUnavailable=true"
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3000/api/public/ready

Uma chamada /api/public/health simples apenas confirma que o processo da API está ativo, porque, por predefinição, não verifica a base de dados. A forma failIfDatabaseUnavailable=true é a adequada para configurar num monitor. Devolve 503 quando a base de dados está inacessível. /api/public/ready devolve 200 quando o contentor web está pronto para receber tráfego e 500 depois de lhe ser ordenado que termine. Ambas são verificações HTTP normais. Assim, uma página de estado do Uptime Kuma pode monitorizá-las e indicar que a stack está indisponível antes de os seus agentes detetarem o problema.

Coloque o TLS à frente e feche as portas adicionais

O ficheiro Compose fornecido publica 3000:3000 para o contentor web e 9090:9000 para o MinIO. Ambos fazem bind em todas as interfaces. Num IP público, isto significa que qualquer pessoa que faça uma varredura à porta 3000 chega à página de registo, e qualquer pessoa que faça uma varredura à porta 9090 está a aceder ao bucket que contém os seus prompts brutos.

Uma regra de firewall, por si só, não as fecha. O Docker escreve as suas próprias regras DNAT na tabela nat, e essas regras são avaliadas antes de os pacotes chegarem às regras de filtragem do ufw. Por isso, ufw deny 3000 mantém a porta publicada aberta. Este problema é suficientemente comum para ter um guia próprio: porque as portas publicadas pelo Docker ignoram o ufw. Em vez disso, faça bind em loopback no ficheiro de override. Use !override com Docker Compose 2.24.4 ou posterior para substituir as portas publicadas; uma lista simples é combinada com os bindings originais.

services:
  langfuse-web:
    ports: !override
      - "127.0.0.1:3000:3000"
    environment:
      NEXTAUTH_URL: https://langfuse.example.com
  minio:
    ports: !override
      - "127.0.0.1:9090:9000"
      - "127.0.0.1:9091:9001"

NEXTAUTH_URL tem de ser o endereço público exato, incluindo o esquema, porque o fluxo de início de sessão constrói o URL de callback a partir desse valor. Se o deixar como http://localhost:3000 atrás de um proxy HTTPS, o ciclo de início de sessão redireciona o browser para um endereço a que não consegue chegar.

Agora aponte um reverse proxy para 127.0.0.1:3000 e deixe-o gerir o certificado. Para usar Traefik no mesmo projeto Compose, encaminhe para langfuse-web:3000 através da rede Compose, usando os labels descritos em executar várias aplicações atrás de um reverse proxy Traefik. O Caddy faz o mesmo trabalho em duas linhas se o Langfuse for a única aplicação no servidor. Verifique com curl -sI https://langfuse.example.com/api/public/ready e confirme depois, a partir de outra máquina, que curl http://YOUR_IP:3000 não consegue estabelecer ligação.

Há uma ressalva relativa ao MinIO. O Langfuse fornece URLs pré-assinados que apontam para esse endpoint S3, tanto aos SDKs que fazem upload de media como ao browser que a carrega. Por isso, se utilizar traces multimodais com imagens ou áudio, um MinIO disponível apenas em loopback impede o upload desses anexos a partir de outras máquinas e impede o seu carregamento no browser. Consulte a página de configuração do armazenamento de blobs antes de colocar o serviço atrás de um proxy, porque o endpoint escrito no URL pré-assinado, LANGFUSE_S3_MEDIA_UPLOAD_ENDPOINT, tem de corresponder ao endereço que publica. Os traces de texto simples não são afetados.

Crie a sua conta na primeira visita e mantenha depois a instância sob o seu controlo. Defina AUTH_DISABLE_SIGNUP=true depois de a sua conta existir, para que uma pessoa externa que aceda à página não possa fazer registo. O Langfuse também tem LANGFUSE_ALLOWED_ORGANIZATION_CREATORS, que limita quem pode criar organizações, mas esta opção é uma funcionalidade do Enterprise Edition e só produz efeito com uma license key. Se já estiver a executar Authentik como o seu próprio fornecedor de identidade, o Langfuse aceita uma ligação OIDC padrão. Assim, as contas são criadas e removidas juntamente com as restantes aplicações, em vez de ficarem numa lista de palavras-passe conhecida apenas por este servidor.

Envie o seu primeiro trace

Crie um projeto na interface web e copie as chaves pública e secreta nas definições do projeto. O SDK Python lê três variáveis de ambiente.

export LANGFUSE_PUBLIC_KEY="pk-lf-..."
export LANGFUSE_SECRET_KEY="sk-lf-..."
export LANGFUSE_BASE_URL="https://langfuse.example.com"

LANGFUSE_BASE_URL é o nome da variável no SDK v4, lançado em março de 2026. O código e os guias mais antigos usam LANGFUSE_HOST. Se os seus traces estiverem a chegar ao Langfuse Cloud em vez do seu servidor, a causa é a ausência da URL base, porque o valor predefinido aponta para a instância alojada.

O SDK Python v5 atual requer Python 3.11 ou posterior e o Langfuse self-hosted v4.59.0 ou posterior, requisito cumprido pelo servidor fixado acima.

pip install langfuse opentelemetry-instrumentation-anthropic anthropic
import os
from anthropic import Anthropic
from langfuse import get_client, observe
from opentelemetry.instrumentation.anthropic import AnthropicInstrumentor

AnthropicInstrumentor().instrument()
langfuse = get_client()
client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

@observe(as_type="tool")
def lookup_order(order_id: str) -> str:
    return f"order {order_id}: shipped"

@observe()
def handle_request(question: str) -> str:
    context = lookup_order("A-1042")
    message = client.messages.create(
        model="claude-haiku-4-5",
        max_tokens=512,
        messages=[{"role": "user", "content": f"{context}\n\n{question}"}],
    )
    return message.content[0].text

if __name__ == "__main__":
    assert langfuse.auth_check()
    print(handle_request("Where is my order?"))
    langfuse.flush()

O decorador @observe abre uma observação em torno da função, captura os respetivos argumentos e valor devolvido e cria essa observação dentro da observação que já estiver ativa. AnthropicInstrumentor é a instrumentação OpenTelemetry para o cliente Anthropic e transforma cada chamada messages.create numa geração com o nome do modelo, o consumo de tokens e a latência, sem alterar o ponto de chamada.

Duas chamadas fazem as verificações por si. langfuse.auth_check() devolve False para chaves inválidas ou uma URL base incorreta, o que é mais rápido do que tentar perceber por que motivo o dashboard está vazio. langfuse.flush() bloqueia até os spans em fila serem enviados. Os processos de curta duração precisam dessa chamada porque o SDK envia os dados em lotes em segundo plano e um script que termina imediatamente leva consigo o lote ainda não enviado. Se uma equipa inteira estiver a enviar traces, em vez de apenas um script, defina essas três variáveis uma vez no gateway pelo qual os agentes de todos já passam, em vez de as definir na shell de cada pessoa. É assim que um harness OneCLI self-hosted mantém instrumentadas as execuções de todos os colegas, enquanto as chaves permanecem num único local.

Por que o ClickHouse continua a crescer?

Os traces são os dados que crescem mais rapidamente na maioria das instalações self-hosted. Cada execução de um agente grava uma linha por etapa, e as entradas e saídas são armazenadas integralmente. Por isso, um agente comunicativo com prompts longos produz muito mais bytes por dia do que a aplicação que está a monitorizar. Se não houver intervenção, o ClickHouse enche o disco. Quando o disco fica cheio, a ingestão para em vez de apenas ficar mais lenta.

Aqui crescem duas coisas distintas, e cada uma precisa de uma correção diferente.

A primeira são os seus próprios dados de traces. A correção é a configuração de retenção. Numa instância self-hosted, a retenção de dados é uma funcionalidade da Enterprise Edition e precisa de uma chave de licença. Sem uma chave, o Langfuse mantém traces, observações, scores e media indefinidamente. Dimensione o disco para esse cenário e dependa do alerta de disco no final desta secção. Com uma licença, os proprietários e administradores do projeto abrem as definições do projeto e definem um período de retenção em dias. O Langfuse aceita um mínimo de 3 dias. Todas as noites, um job seleciona traces, observações, scores e ativos de media mais antigos do que esse período e elimina-os do ClickHouse e do armazenamento de blobs, exceto a media associada a itens de datasets guardados. O job precisa da permissão DeleteObject no bucket, que as credenciais root do MinIO no ficheiro compose predefinido já possuem. A eliminação é permanente. Configure primeiro uma exportação para armazenamento de blobs se precisar de manter um histórico de longo prazo. Não escreva manualmente cláusulas TTL nas tabelas do próprio Langfuse. É o job de retenção que mantém o ClickHouse e o bucket sincronizados, e um TTL manual elimina dados apenas de um dos lados.

Escolha o período com base no uso real. A análise de custos e qualidade acontece com dados de alguns dias, não de meses. Trinta dias é um bom ponto de partida para uma equipa pequena. 14 dias são suficientes se só abrir um trace quando algo falha.

A segunda coisa são as próprias tabelas de logs do sistema do ClickHouse. Isto surpreende algumas pessoas, porque o disco continua a crescer depois de a retenção ser configurada. O ClickHouse grava trace_log, text_log, opentelemetry_span_log, metric_log, asynchronous_metric_log e latency_log para os seus próprios diagnósticos. Estas tabelas são fornecidas sem TTL, e o Langfuse nunca as lê. Primeiro, descubra exatamente onde o espaço em disco foi usado.

SELECT table, formatReadableSize(size) AS size, rows FROM (
    SELECT table, database, sum(bytes) AS size, sum(rows) AS rows
    FROM system.parts
    WHERE active
    GROUP BY table, database
    ORDER BY size DESC
)

Execute-o com docker compose exec clickhouse clickhouse-client --password "$CLICKHOUSE_PASSWORD". Se as tabelas do sistema estiverem entre as maiores, desative-as com um overlay de configuração, porque o ClickHouse aplica todos os ficheiros em /etc/clickhouse-server/config.d/ sobre a configuração principal no arranque.

<clickhouse>
    <trace_log remove="1"/>
    <text_log remove="1"/>
    <opentelemetry_span_log remove="1"/>
    <asynchronous_metric_log remove="1"/>
    <metric_log remove="1"/>
    <latency_log remove="1"/>
</clickhouse>

Monte-o e reinicie o ClickHouse.

services:
  clickhouse:
    volumes:
      - ./clickhouse-config.d/system-logs.xml:/etc/clickhouse-server/config.d/system-logs.xml:ro

Isto impede novas gravações. As linhas que já estão no disco permanecem lá. Por isso, recupere o espaço explicitamente com DROP TABLE IF EXISTS system.trace_log e faça o mesmo para cada tabela removida. Se preferir manter os diagnósticos, a alternativa é configurar um TTL agressivo em cada tabela em vez de remove="1", conforme descrito na documentação de escalabilidade do Langfuse. Essas diretivas TTL só são aplicadas quando uma tabela do sistema é criada pela primeira vez. Numa instalação existente, a mesma documentação também explica como aplicar as alterações às tabelas existentes.

Vale a pena conhecer mais uma tabela. blob_storage_file_log regista os ficheiros de eventos carregados para o bucket. Se também definir uma política de ciclo de vida no bucket, configure um TTL correspondente na tabela para evitar que os dois fiquem dessincronizados.

ALTER TABLE blob_storage_file_log MODIFY TTL created_at + INTERVAL 30 DAY DELETE;

Configure também um alerta simples df -h no disco de dados. Os traces não crescem de forma uniforme. Crescem no dia em que implementa um novo agente. O primeiro sinal disso não deve ser a falha da ingestão.

Faça backup do Postgres e do ClickHouse

Um backup do Langfuse tem três partes. O Postgres armazena os seus utilizadores, organizações, projetos e chaves de API. O ClickHouse armazena os traces. O MinIO armazena os eventos em bruto. Se restaurar apenas o Postgres, terá um login funcional, mas sem histórico. Se restaurar apenas o ClickHouse, terá histórico que ninguém consegue consultar porque não pode iniciar sessão. Esta separação não é exclusiva do Langfuse. Uma central de suporte Chatwoot autoalojada tem a mesma estrutura: um dump do Postgres feito sem o diretório de uploads restaura as conversas, mas todos os anexos desaparecem.

O Postgres é um pg_dump simples. É este o formato usado pela documentação de backup do Langfuse numa instalação Docker.

docker compose exec -T postgres pg_dump -U postgres postgres \
  | gzip > langfuse-pg-$(date +%F).sql.gz

O ClickHouse requer mais cuidado, porque copiar um diretório de dados ativo enquanto estão a decorrer merges não produz um backup consistente. Numa única máquina, a abordagem simples é parar o container e arquivar o volume.

docker compose stop clickhouse
docker volume ls | grep clickhouse
docker run --rm -v langfuse_langfuse_clickhouse_data:/data -v "$PWD":/backup alpine \
  tar czf /backup/langfuse-ch-$(date +%F).tar.gz -C /data .
docker compose start clickhouse

Use o nome do volume apresentado por docker volume ls, não o nome escrito no YAML. O ficheiro declara langfuse_clickhouse_data, e o Compose acrescenta-lhe o nome do projeto. Assim, um clone num diretório chamado langfuse produz langfuse_langfuse_clickhouse_data. Se usar o nome errado, docker run cria um novo volume vazio sem apresentar um erro, e o seu arquivo não contém nada.

O Langfuse envia os dados de eventos em bruto para o bucket em cada pedido de ingestão e volta a lê-los para repetir os jobs de ingestão que falharam. Por isso, uma paragem curta do ClickHouse significa sobretudo que o worker repetirá os jobs depois. Faça isto num período de pouca utilização e mantenha a paragem curta. Numa instância com mais atividade, a instrução BACKUP DATABASE default TO S3(...) do próprio ClickHouse escreve um backup consistente sem parar o servidor. O MinIO é a terceira peça. mc mirror ou a replicação do MinIO para um bucket externo cobre essa parte. Independentemente do método usado, retire o backup do servidor. É para isso que servem os backups restic encriptados num VPS.

O Redis armazena a fila e a cache. Se o perder, os jobs em espera serão descartados, mesmo que os respetivos ficheiros de eventos em bruto continuem no bucket.

A ressalva sobre consistência é real e deve ser indicada claramente. O Postgres e o ClickHouse são exportados em momentos diferentes. Por isso, uma restauração pode deixar uma linha de projeto sem traces ou traces pertencentes a um projeto que já não existe. O Langfuse tolera esta situação, mas faça os dois dumps com pouca diferença de tempo e numa janela de pouco tráfego. O bucket de eventos é a verdadeira rede de segurança, porque o Langfuse envia para lá os dados de eventos em bruto em cada pedido de ingestão.

Restaure num stack de teste pelo menos uma vez. Assim, descobre agora que o nome do volume está errado, em vez de descobrir durante uma indisponibilidade.

O que analisar primeiro

Quatro itens justificam o seu lugar na primeira semana.

  • Custo por trace. O Langfuse calcula o custo com base no nome do modelo e no uso de tokens. Ordene os traces por custo e leia o mais caro do início ao fim. Normalmente, a causa é um prompt que cresceu: um documento inteiro colado no contexto ou um histórico de conversa que ninguém reduz. Quando conseguir ver isso, controlar o custo de um agente de IA deixa de ser uma estimativa e passa a ser uma tarefa de engenharia.
  • Divisão do uso de tokens entre entrada e saída. Os tokens de entrada são numerosos e baratos. Os tokens de saída são poucos e caros. Os tokens de entrada em cache são ainda mais baratos. A mesma contabilidade é explicada em como é contabilizado o uso de tokens do Claude Code e aplica-se a qualquer agente que escreva.
  • Percentis de latência. A mediana oculta o problema. É nos p95 e p99 que ocorrem os timeouts. Dentro de um loop de agente, uma chamada de ferramenta lenta no p95 é multiplicada pelo número de iterações.
  • Chamadas de ferramentas que falharam. Filtre as observações pelo nível ERROR. Uma ferramenta que falha 5% das vezes pode não aparecer numa taxa agregada de sucesso, mas fica evidente nos traces, onde é possível monitorizar o modelo a tentar novamente e depois a consumir tokens para contornar o problema.

Defina a janela de retenção e escolha o dashboard que vai consultar semanalmente, no mesmo dia em que fizer o deploy. Uma ferramenta de observabilidade que ninguém abre é uma base de dados que acaba por encher um disco.

FAQ

Quanta memória é necessária para executar o Langfuse com alojamento próprio?

Reserve 4 núcleos de CPU e 16 GiB de memória. É o que o guia do Langfuse para Docker Compose recomenda para uma única máquina virtual. Reserve também cerca de 100 GiB de armazenamento. Os requisitos mínimos publicados para os componentes são 8 GiB para o ClickHouse e 4 GiB para cada um dos contentores web e worker. A mesma página indica 4 GiB para o Postgres, 1.5 GiB para o Redis e 4 GiB para o MinIO. Os seis componentes totalizam 25.5 GiB, mais do que os 16 GiB recomendados para o Compose.

Porque é que o disco do ClickHouse continua a encher depois de definir a retenção de dados?

A configuração de retenção aplica-se apenas aos dados próprios do Langfuse. O ClickHouse escreve separadamente as tabelas de diagnóstico trace_log, text_log, opentelemetry_span_log, metric_log, asynchronous_metric_log e latency_log. Essas tabelas não têm TTL. Consulte system.parts agrupado por tabela para ver qual ocupa mais espaço. Depois, desative as tabelas não utilizadas com uma entrada remove="1" num ficheiro sob /etc/clickhouse-server/config.d/, reinicie o ClickHouse e elimine as tabelas existentes para recuperar o espaço já utilizado.

Qual é o período mínimo de retenção de dados no Langfuse?

Três dias. A retenção é definida por projeto nas definições do projeto ou através da Organization Management API. Um job noturno elimina traces, observações, scores e ativos de media mais antigos do que esse período no ClickHouse e no armazenamento de objetos, exceto os media associados a itens de datasets guardados. Numa instância com alojamento próprio, esta é uma funcionalidade da Enterprise Edition que requer uma license key. Sem essa chave, os dados são mantidos indefinidamente. A eliminação não pode ser desfeita. Configure primeiro uma exportação para armazenamento de objetos se precisar de manter o histórico além desse período.

Tenho de fazer backup do Postgres e do ClickHouse?

Sim, porque armazenam dados diferentes. O Postgres armazena utilizadores, organizações, projetos e API keys. O ClickHouse armazena os próprios dados dos traces. Uma restauração apenas do Postgres deixa uma instância na qual é possível iniciar sessão, mas sem dados. Faça também backup do bucket do MinIO. Este contém os eventos brutos que o Langfuse persiste quando os recebe e é o elemento mais próximo de uma fonte de verdade na stack.

Posso apontar uma configuração OpenTelemetry existente para uma instância do Langfuse com alojamento próprio?

Sim. O Langfuse v4 e os respetivos SDKs atuais são baseados em OpenTelemetry. As instrumentações OTel do Anthropic e do OpenAI exportam diretamente para o Langfuse. Em Python, execute pip install langfuse opentelemetry-instrumentation-anthropic, chame AnthropicInstrumentor().instrument() uma vez no arranque e defina LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY e LANGFUSE_BASE_URL para o seu próprio host. Confirme com langfuse.auth_check() antes de procurar um dashboard em falta.

Este artigo foi útil?