Adds documentation and fixes

This commit is contained in:
2026-01-23 14:49:44 -03:00
parent 9eecd617b3
commit 4e9e18faea
6 changed files with 1058 additions and 7 deletions

319
docs/langfuse-guide.md Normal file
View File

@@ -0,0 +1,319 @@
# Guia de Integracao Langfuse
Este guia explica como o Langfuse esta integrado ao assistente e como utilizar suas funcionalidades de scoring e observabilidade.
## Indice
- [O que e Langfuse](#o-que-e-langfuse)
- [Configuracao Inicial](#configuracao-inicial)
- [Sistema de Scores](#sistema-de-scores)
- [Adicionando Novos Scores](#adicionando-novos-scores)
- [Visualizando Metricas](#visualizando-metricas)
- [Boas Praticas](#boas-praticas)
## O que e Langfuse
Langfuse e uma plataforma de observabilidade para aplicacoes LLM que permite:
- Rastrear todas as chamadas ao modelo
- Adicionar scores e metricas customizadas
- Analisar performance e custos
- Debugar conversas problematicas
## Configuracao Inicial
### 1. Credenciais
As credenciais do Langfuse sao armazenadas no AWS Secrets Manager:
```python
# Recuperando credenciais
from tools import secrets
import json
secrets_data = json.loads(secrets.get_secret())
public_key = secrets_data['api-langfuse-public']
secret_key = secrets_data['api-langfuse-secret']
```
### 2. Inicializacao do Cliente
```python
from langfuse import Langfuse
from langfuse.langchain import CallbackHandler
# Cliente principal para spans e scores
langfuse = Langfuse(
public_key=public_key,
secret_key=secret_key,
host="http://SEU_HOST_LANGFUSE:3000"
)
# Callback handler para integracao automatica com LangChain
langfuse_handler = CallbackHandler()
```
### 3. Integracao com LangGraph
```python
# Adicionar o handler na configuracao do agente
config = {
"configurable": {"thread_id": "abc123"},
"callbacks": [langfuse_handler]
}
# Executar o agente
for step in agent_executor.stream({"messages": input_message}, config, stream_mode="values"):
# processamento...
pass
# IMPORTANTE: Flush para garantir envio dos dados
langfuse.flush()
```
## Sistema de Scores
### Scores Atuais
O sistema atual utiliza os seguintes scores:
| Score | Tipo | Descricao |
|-------|------|-----------|
| `Miss` | CATEGORICAL | Indica quando o agente nao encontrou a resposta |
| `Origem` | CATEGORICAL | Canal de origem da pergunta (web, app, etc.) |
| `Email` | CATEGORICAL | Email do usuario para rastreabilidade |
### Como os Scores sao Registrados
```python
# Score de "Miss" - quando nao encontra resposta
@tool
def out_of_scope_and_dont_know_answer():
with langfuse.start_as_current_span(name="my-operation") as span:
span.score_trace(
name="Miss",
value="True",
data_type="CATEGORICAL"
)
return "Mensagem de resposta padrao..."
# Scores de metadados - origem e email
with langfuse.start_as_current_span(name="my-operation") as span:
span.score_trace(
name="Origem",
value=origem,
data_type="CATEGORICAL"
)
span.score_trace(
name="Email",
value=email,
data_type="CATEGORICAL"
)
```
## Adicionando Novos Scores
### Tipos de Score Disponiveis
1. **CATEGORICAL** - Para valores de categorias (string)
2. **NUMERIC** - Para valores numericos (int/float)
3. **BOOLEAN** - Para valores verdadeiro/falso
### Exemplos de Novos Scores
#### Score de Satisfacao do Usuario
```python
def add_user_satisfaction_score(span, satisfaction_rating):
"""
Adiciona score de satisfacao do usuario (1-5)
"""
span.score_trace(
name="user_satisfaction",
value=satisfaction_rating,
data_type="NUMERIC"
)
```
#### Score de Tempo de Resposta
```python
import time
def add_response_time_score(span, start_time):
"""
Adiciona score de tempo de resposta em segundos
"""
response_time = time.time() - start_time
span.score_trace(
name="response_time_seconds",
value=response_time,
data_type="NUMERIC"
)
```
#### Score de Documentos Consultados
```python
def add_documents_used_score(span, num_documents):
"""
Registra quantos documentos foram consultados
"""
span.score_trace(
name="documents_consulted",
value=num_documents,
data_type="NUMERIC"
)
```
#### Score de Qualidade da Resposta
```python
def add_response_quality_score(span, quality_level):
"""
Classifica qualidade da resposta
Valores: "excellent", "good", "fair", "poor"
"""
span.score_trace(
name="response_quality",
value=quality_level,
data_type="CATEGORICAL"
)
```
#### Score de Feedback Explicito
```python
def add_feedback_score(span, was_helpful):
"""
Registra se o usuario achou a resposta util
"""
span.score_trace(
name="user_found_helpful",
value="True" if was_helpful else "False",
data_type="CATEGORICAL"
)
```
### Implementacao Completa de Scoring
```python
class LangfuseScorer:
"""
Classe utilitaria para gerenciar scores do Langfuse
"""
def __init__(self, langfuse_client):
self.langfuse = langfuse_client
def score_interaction(self, span, metrics: dict):
"""
Adiciona multiplos scores de uma vez
Args:
span: Span atual do Langfuse
metrics: Dicionario com metricas
{
"origem": "web",
"email": "user@example.com",
"response_time": 2.5,
"documents_used": 3,
"found_answer": True
}
"""
# Scores categoricos
if "origem" in metrics:
span.score_trace(name="Origem", value=metrics["origem"], data_type="CATEGORICAL")
if "email" in metrics:
span.score_trace(name="Email", value=metrics["email"], data_type="CATEGORICAL")
# Scores numericos
if "response_time" in metrics:
span.score_trace(name="response_time", value=metrics["response_time"], data_type="NUMERIC")
if "documents_used" in metrics:
span.score_trace(name="documents_used", value=metrics["documents_used"], data_type="NUMERIC")
# Scores booleanos (como categoricos)
if "found_answer" in metrics:
span.score_trace(
name="found_answer",
value="True" if metrics["found_answer"] else "False",
data_type="CATEGORICAL"
)
```
## Visualizando Metricas
### Acessando o Dashboard
1. Acesse a interface web do Langfuse: `http://SEU_HOST:3000`
2. Navegue ate "Traces" para ver todas as execucoes
3. Use filtros por score para analises especificas
### Queries Uteis
#### Encontrar conversas sem resposta
- Filtrar por: `score.Miss = "True"`
#### Analise por canal de origem
- Agrupar por: `score.Origem`
#### Metricas de performance
- Ordenar por: `score.response_time`
## Boas Praticas
### 1. Sempre fazer Flush
```python
# No final de cada execucao
langfuse.flush()
```
### 2. Usar Nomes Consistentes
```python
# BOM - nomes consistentes e descritivos
span.score_trace(name="user_satisfaction", value=5, data_type="NUMERIC")
span.score_trace(name="response_quality", value="good", data_type="CATEGORICAL")
# EVITAR - nomes inconsistentes
span.score_trace(name="sat", value=5, data_type="NUMERIC")
span.score_trace(name="Quality", value="good", data_type="CATEGORICAL")
```
### 3. Documentar Valores Possiveis
Para scores CATEGORICAL, documente os valores possiveis:
```python
# response_quality: "excellent" | "good" | "fair" | "poor"
# user_type: "vendor" | "subvendor" | "supervendor" | "support"
# channel: "web" | "api" | "whatsapp" | "slack"
```
### 4. Tratar Erros
```python
try:
with langfuse.start_as_current_span(name="operation") as span:
span.score_trace(name="metric", value=value, data_type="CATEGORICAL")
except Exception as e:
print(f"Erro ao registrar score: {e}")
# Continua execucao sem falhar
```
### 5. Nao Bloquear por Metricas
```python
# Scores nao devem impactar a resposta ao usuario
# Se o Langfuse falhar, a conversa deve continuar
```
## Referencias
- [Documentacao Oficial Langfuse](https://langfuse.com/docs)
- [Langfuse Python SDK](https://langfuse.com/docs/sdk/python)
- [Integracao LangChain](https://langfuse.com/docs/integrations/langchain)