Skip to main content

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.

PyPI version Python Versions License: MIT

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


Made with ❤️ by the LLM Observe team

Metadata

Release files for llmobserve-sdk 0.3.7

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for llmobserve-sdk 0.3.7
File Size Uploaded
llmobserve_sdk-0.3.7.tar.gz 146.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for llmobserve-sdk 0.3.7
File Interpreter ABI Platform
llmobserve_sdk-0.3.7-py3-none-any.whl Python 3 none any Details

Total release size: 335.0 kB

Release files / llmobserve_sdk-0.3.7.tar.gz

Download URL llmobserve_sdk-0.3.7.tar.gz
Size 146.9 kB
Tags Source
SHA-256 checksum
How to use checksums
974287ae4b790e92a45c7c063f1be23148733e60a5193052dae0b2024b3b573d
BLAKE2b-256 checksum
How to use checksums
104742c21911ea1f48f00e8f2997f48f674c0f901093d9cf1e85dfc28d6c6801
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / llmobserve_sdk-0.3.7-py3-none-any.whl

Download URL llmobserve_sdk-0.3.7-py3-none-any.whl
Size 188.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6d99aa264d2364cf67794f621d41f570d12acc745a1e882282c69974f4b83d70
BLAKE2b-256 checksum
How to use checksums
98a1fb6035ae1547e1b90ddd87bc93eef3163aec89d998821b647b52c99dc4c7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

0.3.7 This release

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page