Skip to main content

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.

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

llmobserve_sdk-0.3.0.tar.gz (145.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

llmobserve_sdk-0.3.0-py3-none-any.whl (186.2 kB view details)

Uploaded Python 3

File details

Details for the file llmobserve_sdk-0.3.0.tar.gz.

File metadata

  • Download URL: llmobserve_sdk-0.3.0.tar.gz
  • Upload date:
  • Size: 145.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for llmobserve_sdk-0.3.0.tar.gz
Algorithm Hash digest
SHA256 3c139fe6dc7387d7cf719b758cb13940c569ec9c750bb4ba29bcd7a71c1e255b
MD5 3740b1ab376e9c3dd668ee52884f5794
BLAKE2b-256 854684d464ed538788b6a05ded101b79f9eb1e6dc0cae2dfe514ed2dda8308ce

See more details on using hashes here.

File details

Details for the file llmobserve_sdk-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: llmobserve_sdk-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 186.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for llmobserve_sdk-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3f3fa09aa4b368538b68927172ae590ddf4026b206e2a2ac39af237796c58523
MD5 e52a62d373145faec4a5f748c3543575
BLAKE2b-256 9d8122a3277b00d2f237b01fdf4ddb98ae2b6783818a2a83704c608428bef913

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page