Built for teams shipping RAG systems

friction-free analytics for RAG. See what your corpus and workload are teaching you.

Install quickly, plug into the stack you already run, and start measuring corpus health and workload observability from the signals your RAG system already produces. Corpulse turns indexing, retrieval, engagement, and live ask traffic into visibility around ghosts, duplicates, stale embeddings, request load, latency, and session behavior.

Useful on day one, clearer after retrievals, stronger after engagement accumulates, and richer once live workload traces start flowing through Ask AI.

Terminal
$ pip install corpulse[qdrant]
Why it matters

Corpus health changes before your dashboard tells the full story.

Corpulse helps teams see where retrieval quality and corpus trust can start slipping as documents, versions, and traffic accumulate.

  • Ghost Documents. Content that still appears in retrieval even though it has stopped earning meaningful usage.
  • Stale Content. Older or lagging material can keep competing with fresher sources when nobody is watching the corpus closely.
  • Weak Engagement Signals. Retrievals alone do not tell you whether the surfaced content keeps proving useful once users interact with it.
What Corpulse does

Add observability around the stack you already run.

Corpulse complements eval suites and golden-set testing by making everyday corpus behavior and live workload patterns easier to inspect.

You keep your own application flow, retrieval system, and evaluation workflow. Corpulse adds a low-friction analytics layer around document registration, retrieval activity, engagement, freshness, trust signals, and request-serving behavior so teams can spot issues earlier without replacing the rest of the stack.

Built to work alongside your process

Install it fast, integrate it into the workflow you already trust, and learn more as real retrieval, engagement, and workload-trace data starts to accumulate.

Workload observability complements corpus-health analytics and keeps the showcase focused on observing real request behavior rather than moving trace data in and out of the app.

What you learn, and when

Corpulse turns registered documents, retrieval logs, and engagement events into health signals that affect precision, freshness, and trust in your RAG stack.

day one

Start with structure-level signals such as duplicates, obsolete versions, and stale embeddings as soon as your corpus is registered, then layer in workload reporting as live requests begin to flow.

after retrievals

Retrieval activity adds context for which documents are being surfaced and which parts of the corpus may be drifting out of usefulness while serving reports start revealing latency and timeout patterns.

after engagement

Engagement sharpens the picture by showing which retrieved content keeps earning user attention, while session reports show how repeated questions and context reuse behave in practice.

Workload Traffic

Track request volume, token pressure, and request-component composition as live Ask AI traces accumulate.

Serving Latency

Inspect TTFT, TPOT, total latency, timeout rates, and slow contributors without building a separate tracing stack first.

Session Behavior

See follow-up depth, session duration, and repeated context reuse so you can understand how Ask AI traffic behaves over time.

Ghosts

Registered documents with no retrieval activity in the last 30 days, often pointing at dead or forgotten content.

Duplicates

Near-duplicate documents above the default 0.92 similarity threshold that waste context and confuse ranking.

Obsolete

Older versioned files superseded by newer ones, such as v1 versus v2 of the same spec or policy.

Stale

Documents whose source changed after embedding and are now more than 14 days behind the source of truth.

Suspects

Documents retrieved at least 5 times in the last 30 days but engaged with less than 15% of the time.

Install quickly. Observe workload without replacing your stack.

Capture live workload traces, inspect workload and serving reports, and keep the examples close to the shipped showcase so the landing-page promise remains proof-bound.

import asyncio

from corpulse import AsyncCorpulse
from corpulse.backends import AsyncPostgresBackend

async def main():
    backend = await AsyncPostgresBackend.create(
        "postgresql://user:pass@localhost/corpulse"
    )
    corpulse = AsyncCorpulse(backend=backend)

    await corpulse.log_rag_request(
        query="How do I set this up?",
        request_id="req-123",
        session_id="session-7",
        input_token_count=386,
        output_token_count=13,
        components=[
            {"type": "user_input", "token_count": 12},
            {"type": "vector_db", "token_count": 240},
        ],
        timings={
            "retrieval_ms": 185.0,
            "ttft_ms": 320.0,
            "tpot_ms": 42.0,
            "total_latency_ms": 1123.0,
        },
    )

asyncio.run(main())
# RAG request traces can stay hash-only in storage
# while still powering workload, serving, and session reports.

Analysis Methods

Explicit APIs for registration, workload traces, retrieval analytics, engagement tracking, and health reporting.

MethodDescriptionInputOutput
get_ghosts()Returns registered documents with no retrievals inside the 30-day ghost window.NoneList[GhostItem]
get_duplicates()Finds near-duplicate document pairs by cosine similarity using a 0.92 default threshold.threshold: float | NoneList[DuplicatePair]
get_obsolete()Marks older versioned filenames as obsolete when a newer vN document exists.NoneList[ObsoleteItem]
get_stale_embeddings()Returns documents whose source_updated_at is more than 14 days newer than embedded_at.NoneList[StaleItem]
get_suspects()Flags documents with at least 5 retrievals and less than 15% engagement over the window.window_days: int | NoneList[SuspectItem]
mean_reciprocal_rank()Retrieval-ordering proxy, not ground-truth relevance.window_days: int | Nonefloat
acceptance_rate()Convention-driven engagement signal, not a user/session metric.window_days: int | Nonefloat
report()Builds a summary plus top document rows so you can drive a dashboard directly.window_days: int | NoneHealthReport
log_rag_request()Captures live workload traces with hash-only identity, request components, token counts, and timing data.query, request_id, session_id, components, timingsNone
workload_report()Summarizes request traffic, token pressure, and request-component composition from captured traces.window_days: int | NoneWorkloadReportPayload
serving_report()Returns serving latency distributions, timeout/error rates, and slow-request contributors.window_days: int | NoneServingReportPayload
session_report()Aggregates session counts, turn depth, and repeated retrieval-context reuse from trace history.window_days: int | NoneSessionReportPayload