AIAR — Local RAG with LLM-as-judge and a grounding loop
AIAR is a local-first retrieval-augmented generation framework for Python.
It runs against your own Ollama instance, ingests your
own documents, and ships three production-grade primitives out of the box:
hybrid retrieval, an LLM-as-judge that returns a structured Verdict, and a
grounding store that lets accepted corrections feed back into future answers.
It is built for developers, researchers, and AI hobbyists who want to own
their stack end to end — no cloud calls, no telemetry, no vendor lock-in.
Install
pip install aiar-rag
# or, with the full retrieval extras (BM25, cross-encoder reranker, HyDE):
pip install 'aiar-rag[rag]'
Note on the name: the distribution on PyPI is
aiar-ragbecauseaiarwas already taken. The import package remainsaiar— so your code usesimport aiar, but you install withpip install aiar-rag.
Prerequisites: Python 3.10+ and a running Ollama
daemon (default http://127.0.0.1:11434). Pull at least one chat model and
one embedding model, for example:
ollama pull qwen2.5:7b-instruct
ollama pull nomic-embed-text
Quickstart
from aiar.harness.pipeline import answer_prompt
result = answer_prompt("What did our Q3 deployment doc say about rollback?", judge=True)
print(result["answer"])
print(result["verdict"]) # {"label": "Supported" | "Unsupported" | ..., "rationale": "...", ...}
result also carries grounded, reground_applied, retrieval, and
latency_ms so you can wire the loop into your own UI or pipeline.
Why AIAR
Most local-RAG stacks stop at "retrieve and stuff into a prompt." AIAR treats the answer as the beginning of the loop, not the end. The judge catches hallucinations the moment they happen; the grounding store makes sure the same hallucination does not happen twice. The whole system runs on a laptop with a Qwen-class model and no external API calls — which means you can ship it into environments where cloud calls are not allowed, and you can audit every byte the model sees.
The three wedges
Hybrid retrieval
AIAR fuses lexical and semantic retrieval rather than picking one. Every
query runs through BM25 over a tokenized index and a vector search over
Ollama embeddings; the two ranked lists are merged with reciprocal-rank
fusion (RRF), then optionally reranked by a cross-encoder. HyDE-style query
rewriting and configurable top_k / fetch_k give you knobs without
forcing a tuning project on day one.
LLM-as-judge Verdict
Every answer can be graded by a second LLM call that returns a structured
Verdict: a label (Supported, Partially supported, Unsupported,
Off-topic), a rationale, and the citations actually relied on. The judge
sees the same retrieved context as the answerer, so its critique is grounded
in evidence — and downstream code can branch on verdict.label to gate,
retry, or escalate.
Grounding loop
When a Verdict is accepted (by a human, by automation, or by policy), the
answer plus its supporting context is persisted to a grounding store keyed
on the prompt. Next time a similar prompt arrives, AIAR reinjects that
grounding before the answerer runs and flags reground_applied=True. The
system stops re-making the same mistake — your corrections compound.
What is in the box
aiar.harness.pipeline.answer_prompt— the one-call entry point used in the Quickstart above.aiar.rag— hybrid retrieval, BM25 + vector + RRF, optional cross-encoder reranker, HyDE rewriting.aiar.eval— the LLM-as-judge with structuredVerdictschema.aiar.grounding— accepted-correction store and reground pipeline.aiar.harness.service— optional FastAPI service exposing/services/promptand/services/metafor other apps on the box.aiar.observability— call IDs, latency, and retrieval traces for every answer.
Integration contracts (for apps built on AIAR)
AIAR exposes stable, schema-versioned contracts so a consuming app can use the framework's truth (retrieval, grounding, ingest readiness, telemetry) instead of reimplementing it. Each shape has one serializer shared by the in-process Python API and the HTTP route, so local and remote callers get identical payloads. See docs/integration-contracts.md for the frozen field-level shapes.
- Pure retrieval (
aiar.retrieve.v1) —aiar.rag.retrieve_chunks(query, *, instance, k=8, category=None)andGET/POST /instances/{instance}/retrieve. Raw vector similarity; never invokes a generation model. - Grounding (
aiar.grounding.v1) —aiar.grounding.record_grounding(...)/lookup_grounding(...), keepinganswerandcorrectiondistinct and scoping records per instance. Legacy records remain readable. - Ingest result + readiness (
aiar.ingest.v1) —aiar.rag.ingest_documents( documents, *, instance, publish=False);health(instance)reportspublished,chunk_count,last_ingest_at,last_ingest_error. - Telemetry + capability manifest —
answer_prompt(..., include_sources=True)attaches the answerer's source set;GET /capabilitiesreturns the feature manifest a consumer gates on (never a version string);GET /calls/{call_id}returns a redacted trace;/healthzcarriesretrieve_schema_version. - Active-model reliability —
active_model_readyon/healthz&/services/metaandfeatures.generationon/capabilitiesflag when the configured model isn't pulled; generation then returns a structuredmodel_not_pulled4xx (not an opaque 503). Repoint live with authedPOST /services/model, or opt intoAIAR_ACTIVE_MODEL_FALLBACK=auto.
Configuration
AIAR reads AIAR_* environment variables for runtime configuration —
endpoints, model names, reranker toggles, grounding-store paths, instance
isolation, and so on. Sensible defaults work out of the box for a local
Ollama install; see PLAYBOOK.md for the full matrix.
NEXT STEPS
Tune retrieval quality with the worked guides in examples/feature-guides/,
starting with
improving-rag.md.
Contributing
PRs welcome. The deep-dive operator guide lives at PLAYBOOK.md — end-to-end walkthrough covering ingestion, the harness, the watcher GUI, regrounding, evals, and operational notes. Worked examples live under examples/feature-guides/improving-rag.md.
For framework-level discussion, file an issue.
License
Apache-2.0. See LICENSE, NOTICE, or the license field in
pyproject.toml.
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 aiar_rag-0.2.5.tar.gz.
File metadata
- Download URL: aiar_rag-0.2.5.tar.gz
- Upload date:
- Size: 725.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd703a2092d336b0b3e731836448b61892cf9c3ac14822661406ea7bd20a9e8e
|
|
| MD5 |
fce88b0848bb6aba407a8ea15b45ffca
|
|
| BLAKE2b-256 |
51cc9e12f98e67dba51d4db50371c57c722e4df852e3aa6fc8f96b6bbd67137b
|
File details
Details for the file aiar_rag-0.2.5-py3-none-any.whl.
File metadata
- Download URL: aiar_rag-0.2.5-py3-none-any.whl
- Upload date:
- Size: 710.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
acd8de6208a56263407a70908f89a8ff8a82a1651b011a6accd0273d235c26d2
|
|
| MD5 |
574fa3c69baccc73a17a40872ae339e1
|
|
| BLAKE2b-256 |
37aa9bcb353d29d88a14709fd2044ce0661c56b571fd7a66b65493cf6dba6214
|