RAGWatch
Quality scores in your RAG traces — computed, not just recorded.
RAGWatch is an OpenTelemetry-native Python SDK that adds semantic quality scores to your RAG traces. Unlike generic tracing tools, RAGWatch computes chunk_relevance_score inline via cosine similarity — zero LLM calls, ~1-5 ms overhead.
Installation
Using uv:
uv add ragwatch # Core SDK
uv add ragwatch --extra langgraph # + LangGraph adapter
uv add ragwatch --extra crewai # + CrewAI adapter
Quickstart
import ragwatch
from ragwatch import RAGWatchConfig, SpanKind, trace
from ragwatch.instrumentation.evaluators import chunk_relevance_score
# Configure with your OTel exporter
from opentelemetry.sdk.trace.export import ConsoleSpanExporter
ragwatch.configure(RAGWatchConfig(
service_name="my-rag-app",
exporter=ConsoleSpanExporter(),
))
@trace("ragwatch.embedding.generate", span_kind=SpanKind.EMBEDDING)
def embed_query(text: str) -> list[float]:
# Your embedding API call here
return [0.5, 0.3, 0.2]
@trace("ragwatch.retrieval.search", span_kind=SpanKind.RETRIEVER)
def retrieve_chunks(query: str) -> list[dict]:
chunk_embeddings = [[0.5, 0.3, 0.2], [0.1, 0.9, 0.0]]
scores = chunk_relevance_score(chunk_embeddings)
return [{"text": "chunk", "score": s} for s in scores]
@trace("ragwatch.response.emit", span_kind=SpanKind.CHAIN)
def generate_response(chunks: list[dict]) -> str:
return "Generated response"
# Run your pipeline
embedding = embed_query("What is RAG?")
chunks = retrieve_chunks("What is RAG?")
response = generate_response(chunks)
Development
# Install dependencies
uv sync
# Run tests
uv run pytest -v
# Run specific test
uv run pytest tests/test_tracer.py -v
How It Works
- Embedding stage:
@tracewithSpanKind.EMBEDDINGstores the query embedding in OTel context - Retrieval stage:
chunk_relevance_score()reads the stored embedding and computes cosine similarity against each chunk - Scores appear on spans:
chunk.relevance_score(average) andchunk.relevance_scores(per-chunk) are set as span attributes
Framework Adapters
LangGraph
from ragwatch.adapters.langgraph import node, workflow
@node("retrieve-node")
def retrieve_node(state):
return {**state, "docs": ["doc1"]}
@workflow("rag-pipeline")
def run_pipeline(input_data):
return retrieve_node(input_data)
CrewAI
from ragwatch.adapters.crewai import node, endpoint
@node("researcher")
def researcher(task):
return {"findings": "data"}
@endpoint("research-crew")
def run_crew(topic):
return researcher(topic)
User Feedback
from ragwatch import record_feedback
record_feedback(trace_id="abc123", score=0.85)
Auto I/O Tracking
All decorators automatically capture function arguments as input.value and return values as output.value (4KB truncation). Disable per-decorator:
@trace("my-span", auto_track_io=False)
def my_func():
...
Use with OpenLLMetry
RAGWatch complements OpenLLMetry — use both together:
# OpenLLMetry: auto-trace LLM calls
from opentelemetry.instrumentation.openai import OpenAIInstrumentor
OpenAIInstrumentor().instrument()
# RAGWatch: add quality scores to RAG stages
import ragwatch
ragwatch.configure(RAGWatchConfig(service_name="my-app"))
API Reference
| Export | Description |
|---|---|
configure(config) |
Initialize RAGWatch with a RAGWatchConfig |
trace(span_name, span_kind, auto_track_io) |
Decorator for tracing functions |
record_feedback(trace_id, score) |
Record user feedback score |
chunk_relevance_score(chunk_embeddings) |
Compute relevance scores |
RAGWatchConfig |
Configuration dataclass |
SpanKind |
OpenInference span kind enum |
Requirements
- Python 3.11+
- opentelemetry-sdk 1.24.0
- opentelemetry-api 1.24.0
License
MIT
Metadata
Release files for ragwatch 0.1.7
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ragwatch-0.1.7.tar.gz | 67.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ragwatch-0.1.7-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 116.3 kB
Release files / ragwatch-0.1.7.tar.gz
| Download URL | ragwatch-0.1.7.tar.gz |
|---|---|
| Size | 67.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
70ea7fc59681e5fd3b35eb9bccc61283507de62701192a63d062e40ffbc215e0
|
|
BLAKE2b-256 checksum How to use checksums |
ebe4ecad4952e78a8db1cadb666554eb07158590f7626c9510484fd95bb2ead2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / ragwatch-0.1.7-py3-none-any.whl
| Download URL | ragwatch-0.1.7-py3-none-any.whl |
|---|---|
| Size | 49.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8f7aa4b3edb47ba88d8279d752e733a443dd05bf9337620f6b19346309fc656e
|
|
BLAKE2b-256 checksum How to use checksums |
f2aea57fbf552886c260975994a3c1c3f508cda1277194e27259926de8f6f731
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|