Skip to main content

OpenAnchor

LLM token-attribution middleware — capture, attribute, and observe every LLM call, with real OpenTelemetry export and real semantic caching.

Tests PyPI Python 3.9+ License: Apache 2.0

What it is

OpenAnchor is an in-process SDK that sits alongside your LLM calls — via a LangChain middleware today, or by calling its collector API directly from any provider — and captures token-consumption events. It breaks usage down across six dimensions (phase, operation type, prompt template, session, model, and pattern) and exposes that data through a query API.

It also ships real OpenTelemetry span export and a real semantic-caching layer, both backed by actual embeddings and storage rather than mocked stand-ins.

Features / Highlights

  • Token capture + 6D attribution — phase, operation type, prompt template, session, model, and pattern, via TokenCollector / AttributionModel / Analytics.
  • Storage — in-memory and SQLite event stores (indexed, WAL, connection-reused) with optional retention/TTL purging.
  • LangChain middleware — OpenAnchorMiddleware wraps a runnable and captures usage transparently, reading real usage_metadata.
  • OpenTelemetry export — every capture_event is wrapped in a real OTEL span; tracing is off by default and enabled via configure_tracing(...).
  • Semantic caching — embedding-based cache with real cosine-similarity search, SQLite storage, and hit-rate stats; 12 MCP tools (cache_prompt_embedding, find_cached_similar, analyze_cache_hit_rate, ...).
  • Cost governance — okf_* token profiles, cost governance, and optimization tracking.
  • Privacy by default — raw prompt/response capture is off by default (hash + length only), and opt-in captures are redacted for common PII/secrets.
  • Docker image with a working entry point (python -m openanchor).

Who it's for / Use cases

  • Attributing LLM cost/token spend across sessions, models, and prompt templates in an existing app, without switching providers.
  • Wrapping a LangChain chain to capture usage transparently via OpenAnchorMiddleware.
  • Reducing repeat-call cost with real semantic caching.
  • Tracking optimization impact over time with the cost-governance and token-profile modules.

What it is not

  • Not a proxy or a hosted platform. OpenAnchor is an in-process SDK with no network hop and no separate services to run — unlike proxy/async-logging platforms such as Helicone.
  • Not framework-agnostic yet. The shipped integration is the LangChain middleware plus the direct collector API. The broader "drop-in across Cursor/Claude Code/Codex CLI/Deep Agents" pitch exists only in planning/ as an earlier, aspirational design.
  • Not a content logger by default. Raw prompt/response text is not captured unless you explicitly opt in.
  • Not production-certified. The project is classified Alpha; audit the privacy and MCP-connector defaults before relying on it in regulated environments.

Project status

Alpha (v0.6.1). The collector/attribution/analytics core, storage, LangChain middleware, OTEL export, semantic caching, the MCP tools, and the cost-governance modules are implemented and tested. See CHANGELOG.md for release history and docs/ for architecture and roadmap material.

Auto-instrumentation

Bridge OpenLLMetry/OpenInference instrumentors into OpenAnchor without changing your application code:

pip install "openanchor[auto-instrument]"
from openanchor import TokenCollector, enable_auto_instrumentation

collector = TokenCollector()
enable_auto_instrumentation(collector)  # enables every installed instrumentor

# Any OpenAI/Anthropic/LangChain call now produces a TokenEvent automatically.
print(collector.get_all_events())

The adapter maps gen_ai.usage.* / llm.token_count.* attributes, model, provider, session and latency into OpenAnchor's existing event model. It skips OpenAnchor's own spans to prevent recursion and deduplicates by trace/span id. If no instrumentor is installed it raises InstrumentationUnavailable rather than silently doing nothing.

Installation

pip install openanchor
# with OTLP exporter support:
pip install "openanchor[otel]"

Development install:

pip install -e ".[dev]"

Quick start

from openanchor import TokenCollector, Analytics, AttributionModel

collector = TokenCollector()
collector.set_session("session_1")

collector.capture_event(
    call_id="call_1",
    model="gpt-4",
    provider="openai",
    input_tokens=120,
    output_tokens=45,
)

attribution = AttributionModel(collector.store)
analytics = Analytics(collector, attribution)

summary = analytics.get_summary("session_1")
print(summary["total_tokens"], summary["by_operation"])

Or wrap a LangChain runnable directly:

from openanchor.middleware.langchain import OpenAnchorMiddleware

middleware = OpenAnchorMiddleware(project_name="my_app")
wrapped_chain = middleware(my_langchain_runnable)

result = wrapped_chain.invoke({"model": "gpt-4", "prompt": "..."})
print(middleware.get_session_stats())

Runnable examples live in examples/basic_usage.py and examples/mcp_openanchor.py.

Usage

Enable OpenTelemetry tracing:

from openanchor import configure_tracing

configure_tracing(exporter="console")  # safe default, no network calls
# or: configure_tracing(exporter="otlp", otlp_endpoint="http://localhost:4318/v1/traces")

Semantic caching:

from openanchor import SemanticCache
from openanchor._mcp_tools import OpenAnchorMCPHandler

cache = SemanticCache(cache_db_path="cache.db")
handler = OpenAnchorMCPHandler(cache)

await handler.cache_prompt_embedding("Summarize this report", response="...")
matches = await handler.find_cached_similar("Summarize this report for me")

Privacy controls:

from openanchor import SqliteEventStore
from openanchor.middleware.langchain import OpenAnchorMiddleware

store = SqliteEventStore("events.db", retention_days=30)
middleware = OpenAnchorMiddleware(
    store=store,
    capture_raw_content=False,       # default; only hash+length stored
    # capture_raw_content=True,      # opt in to store excerpts
    # redact_captured_content=True,  # default when opted in
)

Docker:

docker build -t openanchor .
docker run -p 8080:8080 openanchor
curl http://localhost:8080/health

Documentation

Known issues and deferred work

Blocked / failed:

  • OTel/OpenInference auto-instrumentation and more framework adapters.

Rejected / deferred:

  • A dashboard; export to Langfuse/Phoenix/Helicone.

Full shipped/blocked/rejected detail: QUEUE_STATUS.md.

Contributing

Contributions are welcome. Run the same checks CI runs:

pip install -e ".[dev]"
pytest tests/ -v
ruff check .
mypy openanchor/
bandit --ini .bandit -r openanchor/

License

This project is licensed under the Apache License 2.0.

Metadata

Release files for openanchor 0.6.3

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

Source distribution (sdist)

Source distribution for openanchor 0.6.3
File Size Uploaded Provenance
openanchor-0.6.3.tar.gz 85.6 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for openanchor 0.6.3
File Interpreter ABI Platform
openanchor-0.6.3-py3-none-any.whl Python 3 none any Details

Total release size: 155.0 kB

Release files / openanchor-0.6.3.tar.gz

Download URL openanchor-0.6.3.tar.gz
Size 85.6 kB
Tags Source
SHA-256 checksum
How to use checksums
b1dba6ece0223482a77d16d810e602f7e7b1515bdbfbdfa799ee76d54f96dbba
BLAKE2b-256 checksum
How to use checksums
29f800a760826b91998df87444d286992290fb02d3b01cca10ae410211855ab1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release files / openanchor-0.6.3-py3-none-any.whl

Download URL openanchor-0.6.3-py3-none-any.whl
Size 69.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ab3ff9dcb3130a635401c5f2b56ea692d896dde1a97d4dc4ce2f7d30cdb41291
BLAKE2b-256 checksum
How to use checksums
3c2e9329308c42c73db2add1eb4337683629c91aeece4963ef129a21ac8cff48
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Security for openanchor 0.6.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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