Spanlens - plataforma open source de observabilidade para ver chamadas de LLM e traces de agentes em um só lugar
(spanlens.io)Olá. Estou criando o Spanlens, uma plataforma open source de observabilidade para ver, em um só lugar, logs de chamadas de LLM, rastreamento de custos e traces de agentes.
Por que criei isso
Ao usar LLMs em projetos paralelos pessoais, havia duas coisas que continuavam me incomodando.
Uma delas era o rastreamento de custos.
Tudo começou quando eu estava criando uma extensão de navegador baseada em GPT e me assustei pela primeira vez ao receber a fatura da OpenAI no fim do mês. Como universitário, não era um valor muito alto, mas eu via o total e não conseguia saber separadamente quanto cada funcionalidade havia custado nem quanto, em média, cada modelo estava consumindo em tokens. Então eu repetia sempre o mesmo processo: enfiava console.log no código, exportava para CSV, somava no Excel e calculava estimativas multiplicando pelos preços por modelo.
A outra era o debugging de agentes.
Foi algo que vivi na prática ao integrar o LangGraph ao Spanlens: quando um trace com várias chamadas de LLM misturadas levava 30 segundos, eu precisava abrir os logs e seguir tudo manualmente para entender
- em qual nó o tempo estava sendo gasto
- por que a mesma ferramenta havia sido chamada duas vezes
- em que momento o state do LangGraph havia mudado
Criei o Spanlens para tentar reduzir esses dois problemas.
Principais recursos
- Integração com uma única linha de
baseURL
Se você trocar o baseURL dos SDKs da OpenAI/Anthropic/Gemini para algo como https://api.spanlens.io/proxy/openai/v1, requisições, respostas, tokens e custos passam a ser registrados automaticamente. As respostas são repassadas por passthrough, então streaming, tool calling e JSON mode funcionam exatamente como no original.
Nos casos em que é necessário usar wrapping, como em agentes, disponibilizamos um SDK para injetar trace_id e span_id, de forma que as relações de pai e filho também sejam registradas.
- Trace de agentes + visão de topologia do LangGraph
Você pode ver o trace não apenas em uma timeline cronológica, mas também sobreposto aos nós reais do grafo. Se o agente foi construído com LangGraph, dá para ver em uma única tela em qual nó o tempo foi gasto e quais arestas são percorridas com mais frequência.
- Análise automática de Critical Path
A cadeia de chamadas que mais consome latência dentro de um trace é destacada automaticamente. A ideia foi reduzir o número de cliques até encontrar a resposta para a pergunta: “por que este trace ficou lento?”.
- Comparação estatística A/B de prompts
Compara duas versões do mesmo prompt com base em latência, custo e uso de tokens. Em vez de mostrar apenas a diferença de médias, aplica o teste t de Welch para exibir diferenças levando em conta também a variância da amostra. Incluí isso para que seja possível dizer não apenas “a média parece um pouco menor”, mas “há uma diferença significativa”.
- Self-hosting
Você pode subir em seu próprio servidor com uma imagem Docker. O mesmo código da versão SaaS está disponível integralmente no repositório público. Todo o código está sob licença MIT.
Como foi implementado
Atualmente, o pipeline funciona mais ou menos assim.
- As requisições do proxy são recebidas com Hono, que separa o cabeçalho Authorization e os metadados
X-Spanlens-*; a chave do provider é descriptografada com AES-256-GCM e usada apenas em memória imediatamente antes da chamada. - Em respostas com streaming,
body.tee()devolve o stream original imediatamente ao cliente, enquanto a cópia é processada em background por um parser que calcula tokens e custos. - Os logs são enviados de forma assíncrona para o ClickHouse. Se o
INSERTfalhar, eles ficam guardados em uma fila de fallback no Supabase, e um cron faz novas tentativas. Assim, o modelo é fire-and-forget, mas tentando evitar perda de dados. - Os preços dos modelos ficam em uma tabela do banco e são armazenados em cache com TTL de 5 minutos usando stale-while-revalidate. Um preço de fallback funciona como rede de segurança para cold start.
No começo era apenas um proxy simples, mas ao usar na prática percebi que o mais importante não eram os logs brutos, e sim traces normalizados. Para encontrar a resposta para “por que este trace ficou lento?”, não basta a ordem das chamadas; é preciso ver relações de pai e filho, chamadas paralelas e o Critical Path. Foi daí que surgiram recursos como a visão de topologia do LangGraph e o Critical Path automático.
A stack é Next.js 14, Hono, Supabase Postgres, ClickHouse, tudo em um monorepo TypeScript com pnpm.
Pontos em que ainda estou pensando
-
Quero que o self-hosting seja possível com uma única linha de
docker run, mas para isso também seria preciso incluir o Supabase Postgres. Hoje, partindo da premissa de Supabase gerenciado, odocker-composeusa 3 contêineres: web, server e ClickHouse. Estou em dúvida entre criar também uma opção de self-hosting para o Supabase ou manter a premissa de serviço gerenciado. -
A comparação A/B de prompts já inclui o cálculo do teste t de Welch, mas ainda não decidi se vale mais a pena mostrar o p-value diretamente ou apenas um badge com a conclusão (significativo/não significativo). Também estou pensando em como exibir um aviso quando a amostra for pequena (
n<30). -
Na visão de topologia do LangGraph, nós, arestas e Critical Path são visualizados, mas deixei de fora propositalmente as mudanças no state channel porque geravam ruído demais. Gostaria de ouvir opiniões sobre se o rastreamento de mudanças de state é mais importante no debugging real ou se o nível atual está adequado.
É um projeto que começou a partir de desconfortos que vivi na prática e que venho refinando continuamente.
[ Spanlens ]
Web: https://www.spanlens.io
GitHub: https://github.com/spanlens/Spanlens
Guia de self-hosting: https://www.spanlens.io/docs/self-host
Ficarei muito grato por qualquer feedback sobre UX do dashboard, visualização de traces, forma de integração do proxy, experiência de self-hosting ou qualquer outro ponto de vista. Em especial, se houver algum provider que você gostaria que fosse suportado além de OpenAI/Anthropic/Gemini, por favor me avise nos comentários.
Há uma versão demo no site, então agradeço muito o interesse.
Atualmente a UI está em inglês, e o suporte a português também será adicionado em breve.
Ainda não há comentários.