neuron-explorer
Qwen3.5‑4B 전용 조향형 뉴런 탐색기, 모든 MLP 뉴런을 밀어 결과를 보관·탐색
오픈소스 LLM 가시성 도구로 프롬프트·완료·지연·토큰·비용을 추적하고, Postgres에 몇 분 만에 자체 호스팅
Open-source LLM observability. Trace prompts, completions, latency, tokens and cost across OpenAI, Anthropic and any OpenTelemetry app. Self-host on Postgres in minutes.
개발 도구Python · TypeScriptGitHub @dheerajkarwasra온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Open-source LLM observability. See every prompt, completion, token, cost, latency and error as traces and sessions. Python SDK, OTLP ingest, OpenAI/Anthropic gateway. Self-host on one Postgres.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Open-source observability for LLM applications. Add three lines to your Python app, or change one base_url, and see each LLM call: prompts and completions, latency, time to first token, token usage, cost and errors, grouped into traces and user sessions.README 전문 보기 ↗Open-source observability for LLM applications, on one Postgres.
Live demo · Docs · Features · Getting started · How it works · Discussions
Spanlight records every LLM call your application makes: prompts and completions, latency, time to first token, tokens, cost and errors, grouped into traces and user sessions. Send traces with the Python or TypeScript SDK, any OpenTelemetry exporter over OTLP/HTTP, or by changing one base_url to the built-in gateway. Then go past tracing: audit what each call cost, check it against the provider's bill, find out why calls fail, and review yesterday's traffic every morning.
[!TIP] Want to look before you install? The live demo runs on real Claude calls under a small monthly budget.
Retry-After, truncated outputs, tool loops, cost and latency spikes and more), each with its evidence and a suggested fix. Provider health tells a provider outage or rate limit apart from your own bug, with the provider's status page incidents alongside.POST /v1/otlp/traces (OTLP over HTTP, as JSON or protobuf; gRPC through an OpenTelemetry Collector) reads the GenAI conventions (gen_ai.*, also written by LiteLLM), OpenInference, OpenLLMetry (Traceloop) and the Vercel AI SDK, and counts usage once across nested spans. Recorded fixtures cover LangChain, LangGraph, LlamaIndex, Pydantic AI and the OpenAI Agents SDK. A Python SDK is on PyPI; a TypeScript SDK for Node.js is in (its npm release job is ready; install it from a tarball until the first release).[!NOTE] Spanlight is pre-1.0. The current server release is 0.7.0 (changelog), and the Python SDK on PyPI is 0.2.1.
git clone https://github.com/dheerajkarwasra/spanlight.git
cd spanlight
cp deploy/.env.example deploy/.env # fill in POSTGRES_PASSWORD, APP_DB_PASSWORD and SECRET_KEY
docker compose -f deploy/compose.yaml --env-file deploy/.env up -d
This pulls the released images named in deploy/.env (SPANLIGHT_IMAGE and SPANLIGHT_WEB_IMAGE). To build from the checkout instead, comment out those two lines and add --build.
Open http://localhost:8080, create an account, and follow the setup wizard to create a project and an API key.
[!TIP] Generate each secret with
python3 -c "import secrets; print(secrets.token_urlsafe(32))". To host it instead, see deploy to Railway.
Install the SDK with the extra for your provider (anthropic or openai):
pip install "spanlight[anthropic]"
import spanlight
from anthropic import Anthropic
spanlight.init(api_key="spl_live_…", host="http://localhost:8080")
client = spanlight.wrap_anthropic(Anthropic())
@spanlight.observe()
def answer(question: str) -> str:
reply = client.messages.create(
model="claude-haiku-5-5",
max_tokens=300,
messages=[{"role": "user", "content": question}],
)
return reply.content[0].text
Add a provider credential and a gateway key in the dashboard (Gateway), then point your existing client at Spanlight:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8080/gw/v1", api_key="spl_gw_…")
For Anthropic, use Anthropic(base_url="http://localhost:8080/gw", api_key="spl_gw_…").
Point any OTLP/HTTP exporter at http://localhost:8080/v1/otlp/traces with the header Authorization: Bearer spl_live_…. JSON and protobuf are both accepted. See the OTLP guide for the attributes each library sends.
The wizard shows your first trace live. From there you have the overview dashboard, the trace explorer, sessions, cost, attribution and the Doctor.
In one sentence: your app sends a record of every LLM call to Spanlight, Spanlight prices it, stores it in Postgres and checks it for problems, and you read the results in the dashboard.
flowchart LR
app["Your app"]
subgraph spanlight["Spanlight (one Docker image)"]
web["web<br/>dashboard and docs"]
api["api<br/>receives calls, prices them,<br/>answers the dashboard"]
gw["gateway<br/>optional proxy to providers"]
worker["worker<br/>background jobs"]
pg[("Postgres<br/>the only database")]
end
llm["OpenAI / Anthropic /<br/>OpenAI-compatible<br/>(Gemini, Bedrock)"]
app -- "SDK or OpenTelemetry" --> api
app -- "or change base_url" --> gw
gw --> llm
gw --> api
web --> api
api --> pg
worker --> pg
Pick one of three ways in. They all end up in the same place:
| Way in | What you change | Good for |
|---|---|---|
| Python SDK | spanlight.init() and wrap your OpenAI or Anthropic client | Python apps; adds your own steps with @observe |
| OpenTelemetry | Point any OTLP/HTTP exporter at /v1/otlp/traces | Any language or framework (LangChain, LlamaIndex, Vercel AI SDK, …) |
| Gateway | Change your client's base_url to Spanlight | No code changes; also adds retries, fallbacks, caching and budgets |
The SDK sends calls in the background, compressed and in batches, and never throws an error into your code.
When a batch arrives, the api does five things, in one database transaction:
The worker runs on its own schedule, so the dashboard stays fast:
| Every | Job |
|---|---|
| 30 seconds | send alert and notification emails, Slack and webhook messages |
| minute | evaluate alert rules; pick traces for automatic evaluation |
| 5 minutes | hourly rollups for charts; read provider status pages |
| 15 minutes | the Doctor's 15 detectors (retry storms, truncated outputs, cost spikes, …); spend by customer or feature; daily cost totals |
| hour | delete traces past the project's retention; clean expired sessions and gateway cache |
| day | fetch the provider's bill and compare it with traced spend; queue yesterday's traces worth reviewing |
The dashboard shows traces, sessions, costs, Doctor findings, alerts, evals and the gateway, for your projects only. Every project's data is isolated by Postgres row-level security, so even a bug in a query cannot show one team another team's traces.
Everything above, the job queue included, runs on a single Postgres database. There is no ClickHouse, Redis or separate queue to install, back up or upgrade. The trade-off is scale: one api process handles about 2,000 spans per second on a laptop, which covers most teams; the decision records explain each choice.
| Path | What it is |
|---|---|
backend/ | FastAPI, SQLAlchemy 2 (async), Alembic, the Postgres job queue and the CLI |
frontend/ | React 19, TypeScript, TanStack Router and Query, Tailwind v4, Radix, Recharts |
sdks/python/ | The spanlight SDK: @observe, spans, and the OpenAI and Anthropic wrappers |
sdks/typescript/ | The spanlight npm package for Node.js: observe, withSpan, and the OpenAI and Anthropic wrappers |
deploy/ | Dockerfile, Caddyfile, Compose file, Prometheus example and Grafana dashboard |
docs-site/ | The documentation site, served by every instance at /docs/ |
docs/ | Decision records, runbooks, security documents and API notes |
/docs/.@observe and span API, the wrappers and delivery guarantees.observe and withSpan, and delivery guarantees.Have a question or an idea? Start a thread in Discussions. Found a bug? Open an issue.