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.2.tar.gz (146.4 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.2-py3-none-any.whl (187.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: llmobserve_sdk-0.3.2.tar.gz
  • Upload date:
  • Size: 146.4 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.2.tar.gz
Algorithm Hash digest
SHA256 c403d544a183b575835cbffa8725725fc4ac02725194c0903a8e6f591972b287
MD5 906cc2a46092b379ed325a59e5090e2f
BLAKE2b-256 47c9c7936803c0ae66d06db9fc7a6eb6fb746859b5d17e93013d29f2cbcc615e

See more details on using hashes here.

File details

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

File metadata

  • Download URL: llmobserve_sdk-0.3.2-py3-none-any.whl
  • Upload date:
  • Size: 187.6 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 05ee5dfead0d05d093c529742d5246fca28609609bc256d3dd179dd7aee2a959
MD5 061181ef50f4595edc1412c68341ee75
BLAKE2b-256 dcd1136a46b53697d6a9e8b80f7710aa97c66cb6145e3ebc2973e4a985dac8a4

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