Skip to main content

LangCore audit-logging provider — decorator that wraps any provider with structured audit trails

Project description

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

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

langcore_audit-1.1.6.tar.gz (17.4 kB view details)

Uploaded Source

Built Distribution

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

langcore_audit-1.1.6-py3-none-any.whl (14.1 kB view details)

Uploaded Python 3

File details

Details for the file langcore_audit-1.1.6.tar.gz.

File metadata

  • Download URL: langcore_audit-1.1.6.tar.gz
  • Upload date:
  • Size: 17.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for langcore_audit-1.1.6.tar.gz
Algorithm Hash digest
SHA256 b01df4ed4f0017ef989d269c8de8fb03476d70c8bdfa23deebe2a20fd89f9d2d
MD5 cb5b5cbf94c29eb1b3b018622c6ec80b
BLAKE2b-256 0b5b3f88353a898c6b21acd0721e03b1efe7c2ec3c8dcd615fdc945edbdf1d55

See more details on using hashes here.

Provenance

The following attestation bundles were made for langcore_audit-1.1.6.tar.gz:

Publisher: release.yml on IgnatG/langcore-audit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file langcore_audit-1.1.6-py3-none-any.whl.

File metadata

  • Download URL: langcore_audit-1.1.6-py3-none-any.whl
  • Upload date:
  • Size: 14.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for langcore_audit-1.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 af77883bcb52e198dbf66e3822dcb003b24098f0f75a4ec599d23cb50852dd3f
MD5 350e29630d22746b65cc39180d999cb4
BLAKE2b-256 3db75fdd133c99ce9efba7577c08a205bb62f40cee1a26d73d77c64911f570c6

See more details on using hashes here.

Provenance

The following attestation bundles were made for langcore_audit-1.1.6-py3-none-any.whl:

Publisher: release.yml on IgnatG/langcore-audit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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