Automatic cost tracking and observability for LLM applications
Project description
LLM Observe SDK
Automatic cost tracking and observability for LLM applications
Track costs, tokens, latency, and errors for OpenAI, Anthropic, and other LLM providers with just 2 lines of code.
Features
- โ Auto-instrumentation - No code changes needed beyond initialization
- ๐ Real-time tracking - Costs, tokens, latency, errors
- ๐ Hierarchical tracing - Track agents, tools, and workflows
- ๐ฅ Customer attribution - Track costs per end-user
- ๐ฏ Zero overhead - Async buffering, sub-millisecond impact
- ๐ Privacy-first - Optional prompt/response capture
- ๐ Production-ready - Battle-tested, scalable architecture
Supported Providers
- OpenAI (GPT-4, GPT-3.5, embeddings, images, audio, etc.)
- Pinecone (vector database operations)
- More coming soon! (Anthropic, Cohere, etc.)
Quick Start
1. Install
pip install llmobserve
2. Get Your API Key
Sign up at llmobserve.com to get your API key.
3. Add 2 Lines of Code
from llmobserve import observe
from openai import OpenAI
# Initialize observability
observe(
collector_url="https://api.llmobserve.com",
api_key="llmo_sk_your_key_here"
)
# Use OpenAI as normal - all calls are tracked automatically!
client = OpenAI()
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Hello!"}]
)
That's it! ๐ View your costs and metrics at app.llmobserve.com
Advanced Usage
Track Agents & Workflows
Automatic Tracking (Zero Config):
from llmobserve import observe
from langchain.agents import AgentExecutor
observe(
collector_url="https://api.llmobserve.com",
api_key="llmo_sk_your_key_here"
)
# Agent tracking happens automatically - no manual labeling needed!
agent = AgentExecutor(...)
result = agent.run("query") # Automatically tracked as agent
Manual Labeling (Optional, for Better UX):
from llmobserve import observe, section
observe(
collector_url="https://api.llmobserve.com",
api_key="llmo_sk_your_key_here"
)
# Hierarchical tracking (optional - improves dashboard UX)
with section("agent:research_assistant"):
with section("tool:web_search"):
# Your search logic
results = search_web(query)
with section("tool:summarize"):
# Your summarization logic
summary = summarize(results)
Key Points:
- โ Costs are always tracked via HTTP interception (works everywhere)
- โ Framework agents auto-tracked (LangChain, CrewAI, AutoGen, LlamaIndex)
- โ Manual labeling is optional (improves dashboard UX but not required)
- โ Untracked costs still shown (labeled as "untracked" in dashboard)
Dashboard shows:
agent:research_assistant $0.50 (10 calls)
โโ tool:web_search $0.002 [ok]
โโ tool:summarize $0.001 [ok]
untracked $0.10 (5 calls) โ Costs without agent labels
Track Costs Per Customer
from llmobserve import observe, set_customer_id
observe(
collector_url="https://api.llmobserve.com",
api_key="llmo_sk_your_key_here"
)
# Set customer ID for cost attribution
set_customer_id("customer_xyz")
# All subsequent API calls are attributed to this customer
client = OpenAI()
response = client.chat.completions.create(...)
Decorator Style
from llmobserve import trace
@trace(agent="customer_support")
async def handle_support_request(message: str):
# All OpenAI calls inside are automatically tracked
response = await client.chat.completions.create(...)
return response
Framework Integration
FastAPI
from fastapi import FastAPI
from llmobserve import ObservabilityMiddleware, observe
app = FastAPI()
app.add_middleware(ObservabilityMiddleware)
observe(
collector_url="https://api.llmobserve.com",
api_key="llmo_sk_your_key_here"
)
@app.post("/chat")
async def chat(request: Request):
# Context is auto-reset per request
# All OpenAI calls are tracked
response = await client.chat.completions.create(...)
return response
Flask
from flask import Flask
from llmobserve import flask_before_request, observe
app = Flask(__name__)
app.before_request(flask_before_request)
observe(
collector_url="https://api.llmobserve.com",
api_key="llmo_sk_your_key_here"
)
@app.route("/chat")
def chat():
# Context is auto-reset per request
response = client.chat.completions.create(...)
return response
What Gets Tracked
For every LLM API call:
- โ Costs - Calculated using latest pricing
- โ Tokens - Input, output, and cached tokens
- โ Latency - Request duration in milliseconds
- โ Status - Success, error, timeout, etc.
- โ Model - Which model was used
- โ Provider - OpenAI, Anthropic, etc.
- โ Section/Agent - Hierarchical context
- โ Customer ID - For cost attribution
- โ Timestamps - When the call was made
- โ ๏ธ Prompts/Responses - Optional (disabled by default)
Configuration
Environment Variables
# Disable observability
LLMOBSERVE_DISABLED=1
# Enable content capture (prompts/responses)
ALLOW_CONTENT_CAPTURE=true
Custom Flush Interval
observe(
collector_url="https://api.llmobserve.com",
api_key="llmo_sk_your_key_here",
flush_interval_ms=1000 # Flush every 1 second (default: 500ms)
)
Dashboard Features
Visit app.llmobserve.com to view:
- ๐ฐ Cost Overview - Total spend, trends, by provider/model
- ๐ Run Details - Individual request breakdowns
- ๐ฏ Agent Analytics - Which agents/workflows cost the most
- ๐ฅ Customer Breakdown - Cost per end-user
- ๐จ Alerts - Cost spikes, errors, anomalies
- ๐ Insights - Auto-detected inefficiencies
Self-Hosting
Want to run your own instance?
git clone https://github.com/yourusername/llmobserve
cd llmobserve
# Start collector API
cd collector
pip install -r requirements.txt
uvicorn main:app --port 8000
# Start dashboard
cd ../web
npm install
npm run dev
See DEPLOYMENT.md for production deployment guide.
Architecture
โโโโโโโโโโโโโโโโโโโ
โ Your App โ
โ + llmobserve โ โ Auto-instruments OpenAI & Pinecone
โ SDK โ
โโโโโโโโโโฌโโโโโโโโโ
โ POST /events
โ
โโโโโโโโโโโโโโโโโโโ
โ Collector API โ โ FastAPI + PostgreSQL
โ (Backend) โ
โโโโโโโโโโฌโโโโโโโโโ
โ GET /runs, /stats
โ
โโโโโโโโโโโโโโโโโโโ
โ Dashboard โ โ Next.js + Clerk
โ (Frontend) โ
โโโโโโโโโโโโโโโโโโโ
FAQ
Q: Does this slow down my app? A: No. Events are buffered asynchronously with sub-millisecond overhead.
Q: Are my prompts/responses sent to your servers?
A: No, by default only metadata is sent (tokens, cost, latency). Set ALLOW_CONTENT_CAPTURE=true to enable content logging.
Q: Can I use this in production? A: Yes! It's production-ready and tested at scale.
Q: What about other LLM providers? A: Anthropic, Cohere, and others coming soon! Request support via GitHub issues.
Q: How much does it cost? A: Free tier includes 10K tracked API calls/month. See pricing.
Contributing
We welcome contributions! See CONTRIBUTING.md.
License
MIT License - see LICENSE
Support
- ๐ Documentation
- ๐ GitHub Issues
- ๐ฌ Discord Community
- ๐ง Email Support
Made with โค๏ธ by the LLM Observe team
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file llmobserve-0.3.0.tar.gz.
File metadata
- Download URL: llmobserve-0.3.0.tar.gz
- Upload date:
- Size: 107.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d34f8efbf25572ee0dfe9ed6db84a4b927de9bbb4ec071f28142d79c71ac2c2f
|
|
| MD5 |
e50a208420db589c443f53a7822a3222
|
|
| BLAKE2b-256 |
babc99b6797aa583bec6706f690da54a148498c8eb248f98ab8354c3949139a0
|
File details
Details for the file llmobserve-0.3.0-py3-none-any.whl.
File metadata
- Download URL: llmobserve-0.3.0-py3-none-any.whl
- Upload date:
- Size: 130.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7fff7de2d8042141dd8f2299ad8c39672eb490f91192273657752477ae6e10cc
|
|
| MD5 |
ec39b9dae9702626ea68dd09e101e1f2
|
|
| BLAKE2b-256 |
e9aae9574b98039b4c9b904af199ca34526adada6139055b477486fe1c6c574d
|