Skip to main content

LangCore Audit Provider

A provider plugin for LangCore that wraps any BaseLanguageModel with structured audit logging. Pure decorator pattern — zero impact on inference results.

Note: This is a third-party provider plugin for LangCore. For the main LangCore library, visit google/langcore.

Installation

Install from source:

git clone <repo-url>
cd langcore-audit
pip install -e .

For OpenTelemetry support:

pip install -e ".[otel]"

Features

  • Pure decorator — wraps any existing provider without modifying behaviour
  • Pluggable sinks — log to files, Python logging, or OpenTelemetry spans
  • Structured records — each inference call produces an AuditRecord with:
    • Prompt hash (SHA-256)
    • Response hash (SHA-256)
    • Latency (ms) — per-prompt in sync, averaged in async
    • batch_total_ms — total wall-clock time for the entire async batch
    • Token usage (if available)
    • Model ID, timestamp, success/failure, score
    • Batch index and batch size
    • Optional truncated prompt/response samples (opt-in via sample_length)
  • Thread-safe — all sinks are safe for concurrent use
  • Fault-tolerant — sink errors are logged and swallowed, never affecting inference

Usage

Basic Usage with Logging Sink

import langcore as lx
from langcore_audit import AuditLanguageModel, LoggingSink

# Create the inner provider (any BaseLanguageModel)
inner_config = lx.factory.ModelConfig(
    model_id="litellm/azure/gpt-4o",
    provider="LiteLLMLanguageModel",
)
inner_model = lx.factory.create_model(inner_config)

# Wrap with audit logging
audit_model = AuditLanguageModel(
    model_id="audit/gpt-4o",
    inner=inner_model,
    sinks=[LoggingSink(logger_name="my_app.audit")],
)

# Use as normal — audit records are emitted automatically
result = lx.extract(
    text_or_documents="Contract text...",
    model=audit_model,
    prompt_description="Extract parties, dates, and obligations.",
)

JSON File Audit Trail

from langcore_audit import AuditLanguageModel, JsonFileSink

audit_model = AuditLanguageModel(
    model_id="audit/gpt-4o",
    inner=inner_model,
    sinks=[JsonFileSink("./audit_logs/extractions.jsonl")],
)

Each line in the output file is a JSON object:

{
  "model_id": "audit/gpt-4o",
  "prompt_hash": "a3f2...",
  "response_hash": "b7c1...",
  "latency_ms": 1234.56,
  "timestamp": "2026-02-21T10:30:00+00:00",
  "success": true,
  "score": 1.0,
  "token_usage": {"prompt_tokens": 150, "completion_tokens": 45, "total_tokens": 195},
  "batch_index": 0,
  "batch_size": 1,
  "batch_total_ms": null,
  "prompt_sample": null,
  "response_sample": null
}

OpenTelemetry Integration

from langcore_audit import AuditLanguageModel
from langcore_audit.sinks import OtelSpanSink

audit_model = AuditLanguageModel(
    model_id="audit/gpt-4o",
    inner=inner_model,
    sinks=[OtelSpanSink(tracer_name="my_service.llm")],
)

Multiple Sinks

from langcore_audit import (
    AuditLanguageModel,
    JsonFileSink,
    LoggingSink,
)

audit_model = AuditLanguageModel(
    model_id="audit/gpt-4o",
    inner=inner_model,
    sinks=[
        LoggingSink(),                              # Console/log output
        JsonFileSink("./audit/extractions.jsonl"),  # Persistent file
    ],
)

Prompt / Response Sampling

By default, prompt and response text is not stored in audit records (only hashes). Set sample_length to capture truncated samples for debugging:

audit_model = AuditLanguageModel(
    model_id="audit/gpt-4o",
    inner=inner_model,
    sinks=[LoggingSink()],
    sample_length=200,  # store first 200 chars of prompt & response
)

Async Usage

Async batches record both the per-prompt average (latency_ms) and the total batch wall-clock time (batch_total_ms) on every record:

results = await audit_model.async_infer(["prompt1", "prompt2"])
# Each AuditRecord will have:
#   latency_ms     = total / batch_size  (per-prompt average)
#   batch_total_ms = total wall-clock time for the full batch

Available Sinks

Sink Description
LoggingSink Emits records via Python logging as JSON strings
JsonFileSink Appends newline-delimited JSON to a file
OtelSpanSink Creates OpenTelemetry spans with audit attributes

Custom Sinks

Implement the AuditSink interface:

from langcore_audit.sinks import AuditSink
from langcore_audit.record import AuditRecord

class MyCustomSink(AuditSink):
    def emit(self, record: AuditRecord) -> None:
        # Send to your preferred destination
        data = record.to_dict()
        my_api.send_audit(data)

Development

pip install -e ".[dev]"
pytest

License

Apache 2.0

Metadata

Release files for langcore-audit 1.1.6

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

Source distribution (sdist)

Source distribution for langcore-audit 1.1.6
File Size Uploaded
langcore_audit-1.1.6.tar.gz 17.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for langcore-audit 1.1.6
File Interpreter ABI Platform
langcore_audit-1.1.6-py3-none-any.whl Python 3 none any Details

Total release size: 31.5 kB

Release files / langcore_audit-1.1.6.tar.gz

Download URL langcore_audit-1.1.6.tar.gz
Size 17.4 kB
Tags Source
SHA-256 checksum
How to use checksums
b01df4ed4f0017ef989d269c8de8fb03476d70c8bdfa23deebe2a20fd89f9d2d
BLAKE2b-256 checksum
How to use checksums
0b5b3f88353a898c6b21acd0721e03b1efe7c2ec3c8dcd615fdc945edbdf1d55
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 23, 2026.

Transparency log

Release files / langcore_audit-1.1.6-py3-none-any.whl

Download URL langcore_audit-1.1.6-py3-none-any.whl
Size 14.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
af77883bcb52e198dbf66e3822dcb003b24098f0f75a4ec599d23cb50852dd3f
BLAKE2b-256 checksum
How to use checksums
3db75fdd133c99ce9efba7577c08a205bb62f40cee1a26d73d77c64911f570c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 23, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.1.6 This release

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