Quality observability for RAG and agents — Brazilian-Portuguese vertical with claim-by-claim hallucination diagnosis, trajectory quality, tool-use correctness, and goal completion metrics.
Project description
aferiq-eval
Quality observability for RAG and agents — vertical for the Brazilian market. PT-BR judge prompts hand-tuned for BR patterns (Lei nº, CNPJ/CPF, Receita Federal, INSS, BACEN, ANPD), claim-by-claim hallucination diagnosis, trajectory + tool-use evaluation for LangGraph / AgentExecutor / OpenAI Assistants.
pip install aferiq-eval, thenimport aferiq. The legacy namespaceragevalis kept as a parallel alias — bothimport aferiqandimport ragevalwork and expose the same API — but new code should lead withimport aferiq.
Install
pip install aferiq-eval
# Optional integrations:
pip install 'aferiq-eval[langchain]' # LangChain (RAG + AgentExecutor)
pip install 'aferiq-eval[langgraph]' # LangGraph
pip install 'aferiq-eval[openai]' # OpenAI SDK + Assistants
pip install 'aferiq-eval[anthropic]' # Anthropic SDK
RAG eval (single-turn)
from rageval import evaluate
result = evaluate(
queries=["Qual o prazo do CDC pra arrependimento?"],
contexts=[["Art. 49 do CDC: o consumidor pode desistir em 7 dias."]],
answers=["O CDC garante 7 dias contados do recebimento."],
metrics=["faithfulness", "hallucination"],
language="pt", # default
)
print(result) # rich-rendered table
result.to_dict() # JSON-friendly
result.aggregate # {"faithfulness": 0.95, "hallucination": 0.92}
Ship to the cloud — one line
Set AFERIQ_DSN in your env (copy it from the dashboard → API keys), then:
import aferiq
aferiq.start() # reads AFERIQ_DSN, auto-patches openai/anthropic
# From here, every openai/anthropic call is captured automatically —
# no decorator, no callback. Just use the SDKs as you already do.
Set the env var before
import openairuns, or callaferiq.start()first — the auto-patch instruments whatever is imported after it.
Capturing a custom RAG function with @trace
For your own RAG/agent function (not a raw SDK call), decorate it:
import aferiq
@aferiq.trace
def my_rag(query: str, context: list[str]) -> str:
chunks = retriever.search(query)
return llm.generate(query, chunks)
my_rag("Qual o aviso prévio mínimo na CLT?", ["..."])
With AFERIQ_DSN set in the env, the bare @aferiq.trace ships traces on
its own — the first decorated call wires up cloud shipping from the env. No
env set and no handler registered → the decorator is a zero-overhead
pass-through. Want explicit control instead? Register your own handler:
from aferiq import register_trace_handler
captured: list = []
register_trace_handler(captured.append) # collect locally, e.g. for batch eval
Agent eval (multi-step)
For LangChain AgentExecutor, LangGraph state machines, or OpenAI Assistants
— no decorator needed. Run your application under aferiq-trace-run, attach
the agent callback, and full trajectories (LLM calls + tool calls + tokens +
latency) get captured automatically.
aferiq-trace-run python my_agent.py
from rageval.integrations.agent_callback import AferiqAgentCallbackHandler
handler = AferiqAgentCallbackHandler(goal="Qual o prazo do CDC?")
agent_executor.invoke(
{"input": "Qual o prazo do CDC?"},
config={"callbacks": [handler]},
)
# handler.last_trace is an AgentTrace; also broadcast to registered handlers
The dashboard at https://www.aferiq.com.br auto-detects trace shape: agent runs render as a step-by-step tree; RAG traces render claim-by-claim with PT-BR categorisation (lei_inventada, cnpj_fabricado, etc.).
CLI
export OPENAI_API_KEY=sk-...
# RAG eval
aferiq-eval evaluate --dataset rag_traces.jsonl --metrics faithfulness,hallucination
# Agent eval
aferiq-eval evaluate-agent --dataset agent_traces.jsonl \
--metrics trajectory_quality,goal_completion,cost_efficiency
Examples
Runnable demos under examples/:
langchain_agent_executor.py— calculator + search agentlanggraph_agent.py— state-machine agentopenai_assistants.py— Assistants API streaming
Supported judge models
Anything litellm supports — OpenAI, Anthropic,
Google, Maritaca Sabiá, Ollama. Default: gpt-4o-mini (cheapest with
acceptable quality on PT-BR judging).
Caching
By default, identical (prompt, model, temperature) tuples are cached on
disk under ~/.cache/rageval. Repeated evals don't re-call the LLM.
from rageval.cache import DiskCache, MemoryCache, NullCache
DiskCache() # default location
DiskCache("/custom/path") # custom location
MemoryCache() # in-process, tests
NullCache() # disable caching
Dev
git clone https://github.com/leo94pena/rag_eval
cd rag_eval/packages/lib
pip install -e ".[dev]"
pytest --cov=rageval # tests
ruff check src tests # lint
mypy --strict src # type-check
Documentation
- Full docs: https://docs.aferiq.com.br (coming soon)
- Issues + roadmap: https://github.com/ileoh/aferiq/issues
- LGPD + data handling: auth in São Paulo (Supabase) · traces in ClickHouse
Cloud us-east-1 under SCC + signed DPA per LGPD Art. 33 ·
redact_pii=Trueflag strips CPF/CNPJ/email/phone before transmission · TLS in transit · AES-256-GCM at rest for sensitive fields.
License
Proprietary — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aferiq_eval-0.7.0.tar.gz.
File metadata
- Download URL: aferiq_eval-0.7.0.tar.gz
- Upload date:
- Size: 116.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a4477de2f2971ec79970fe8469645dd063f6656b8188f3f6a36c216e24955a26
|
|
| MD5 |
32ed54db5b92ba8d32a813c70c1ef7f5
|
|
| BLAKE2b-256 |
52968d6909d9661d2fc7d17b777e4573ff67f65ad1ce30e3b512f1cd240fc9fd
|
Provenance
The following attestation bundles were made for aferiq_eval-0.7.0.tar.gz:
Publisher:
release-lib.yml on ileoh/aferiq
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aferiq_eval-0.7.0.tar.gz -
Subject digest:
a4477de2f2971ec79970fe8469645dd063f6656b8188f3f6a36c216e24955a26 - Sigstore transparency entry: 1629375393
- Sigstore integration time:
-
Permalink:
ileoh/aferiq@50561d0d1242d7d414957ae90dd228a91ace9faf -
Branch / Tag:
refs/tags/v0.7.0 - Owner: https://github.com/ileoh
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-lib.yml@50561d0d1242d7d414957ae90dd228a91ace9faf -
Trigger Event:
push
-
Statement type:
File details
Details for the file aferiq_eval-0.7.0-py3-none-any.whl.
File metadata
- Download URL: aferiq_eval-0.7.0-py3-none-any.whl
- Upload date:
- Size: 89.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b40da44a4427237d01bd2bd1237f573eec36a5bf1ff68545f846f0f980419dbc
|
|
| MD5 |
9b37428527ac8a0b198038fc26a440d1
|
|
| BLAKE2b-256 |
2f6b0604d3da0752a93ec301b056c1605f9b3f3bf58ef01d885dd3bbe49e90e1
|
Provenance
The following attestation bundles were made for aferiq_eval-0.7.0-py3-none-any.whl:
Publisher:
release-lib.yml on ileoh/aferiq
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aferiq_eval-0.7.0-py3-none-any.whl -
Subject digest:
b40da44a4427237d01bd2bd1237f573eec36a5bf1ff68545f846f0f980419dbc - Sigstore transparency entry: 1629375405
- Sigstore integration time:
-
Permalink:
ileoh/aferiq@50561d0d1242d7d414957ae90dd228a91ace9faf -
Branch / Tag:
refs/tags/v0.7.0 - Owner: https://github.com/ileoh
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-lib.yml@50561d0d1242d7d414957ae90dd228a91ace9faf -
Trigger Event:
push
-
Statement type: