Qiro RAG
Local-first evidence retrieval and substantiation review for environmental marketing claims.
Qiro RAG owns Step 3 in the Qiro workflow:
Step 1 extract environmental claim signals
Step 1.5 group/protect claims
Step 2 assess potential regulatory issues
Step 3 check company evidence for support, limits, contradictions, and gaps
Step 4 produce a human-review report
It is not generic document chat and it is not a legal verdict engine. It turns a Step 2 issue into evidence questions, retrieves relevant company evidence, verifies source quotes, and emits a structured Step 3 review artifact.
Qiro RAG is a risk-review aid. It does not provide legal advice, determine illegality, guarantee compliance, or replace qualified counsel/compliance review.
What this demonstrates
- Local-first RAG architecture with no cloud calls by default.
- Evidence-pack ingestion for
md,txt,pdf,docx,xlsx,csv, plus optional local OCR. - SQLite-backed chunks, tables, metadata, hashes, and persisted embeddings.
- Keyword, semantic, and hybrid retrieval modes.
- Quote-backed citation verification to reduce hallucinated support.
- Heuristic offline judging plus opt-in Ollama/OpenAI-compatible LLM judges.
- Optional LangGraph workflow with typed nodes and local trace output.
- Human-review memory through
review_decisions.csvand proposed playbook patches.
Quick start
Install uv and run from the repository root:
git clone https://github.com/PPDEGRET/qiro-rag.git
cd qiro-rag
uv sync --dev
Run the synthetic evidence-pack demo:
uv run qiro-rag ingest examples/synthetic_eval/docs --pack ./.tmp/qiro-synth-pack --reset
uv run qiro-rag assess examples/synthetic_eval/findings/recyclable.json \
--pack ./.tmp/qiro-synth-pack \
--out ./.tmp/recyclable-step3.json
Expected status:
{
"claimId": "C-RECYCLABLE",
"status": "partially_supported",
"humanReviewRecommended": true
}
The full output includes verified source quotes and missing-evidence prompts for human review.
Optional LangGraph workflow
The default pipeline is direct typed Python. If you want node-level workflow tracing, install the optional workflow extra:
uv run --extra workflow qiro-rag assess examples/synthetic_eval/findings/recyclable.json \
--pack ./.tmp/qiro-synth-pack \
--out ./.tmp/recyclable-step3.json \
--workflow langgraph \
--trace-out ./.tmp/langgraph-trace.json
The LangGraph path emits the same public Step 3 JSON schema as the direct path. Framework objects stay out of output artifacts.
Common commands
uv run qiro-rag init-pack ./evidence-pack
uv run qiro-rag pull ./company-docs --target ./staged-docs
uv run qiro-rag ingest ./staged-docs --pack ./evidence-pack --reset
uv run qiro-rag embed --pack ./evidence-pack
uv run qiro-rag retrieve "carbon neutral delivery offset basis" --pack ./evidence-pack
uv run qiro-rag assess examples/step2/finding.json --pack ./evidence-pack --out step3_evidence.json
uv run qiro-rag models
uv run qiro-rag onboard
uv run qiro-rag learn --pack ./evidence-pack --propose playbook.patch.yaml
Model and privacy posture
Default behavior is local:
- no cloud model calls;
- no cloud embeddings;
- no telemetry;
- no raw document upload.
Opt-in judge profiles are available for local Ollama or OpenAI-compatible gateways:
uv run qiro-rag assess examples/step2/finding.json \
--pack ./evidence-pack \
--out step3_evidence.json \
--profile ollama-private-small
Only retrieved candidate passages are sent to an opt-in LLM judge, and returned citations still pass local quote verification.
Documentation
Repository map
src/qiro_rag/ Python package and CLI
src/qiro_rag/workflows/ Optional LangGraph workflow
docs/ Architecture, schemas, privacy, roadmap
examples/synthetic_eval/ Fictional regression evidence pack
tests/ Unit and pipeline tests
Verification
uv run ruff format --check .
uv run ruff check .
uv run pytest
uv run --extra workflow pytest
uv build
Related work
- Step 1 / Step 1.5 / Step 2 Qiro Analyzer (
qiroCLI): https://github.com/PPDEGRET/EMPCOAnalyzer - Step 4 launch-gate demo artifacts: https://github.com/PPDEGRET/qiro-launch-gate-demo
- This repository: Step 3 evidence retrieval/substantiation.
License
Apache-2.0. See LICENSE.
Metadata
Release files for qiro-rag 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| qiro_rag-0.1.0.tar.gz | 262.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| qiro_rag-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 309.1 kB
Release files / qiro_rag-0.1.0.tar.gz
| Download URL | qiro_rag-0.1.0.tar.gz |
|---|---|
| Size | 262.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3f5591f24cbb1641873f248fff269957f6250ebb7514f149cbe9ecc7101a9313
|
|
BLAKE2b-256 checksum How to use checksums |
2d0828f16e85e78c380e33824932bce308974ad7522ff889bb4d4e40c788526a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.20 {"installer":{"name":"uv","version":"0.11.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / qiro_rag-0.1.0-py3-none-any.whl
| Download URL | qiro_rag-0.1.0-py3-none-any.whl |
|---|---|
| Size | 46.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fa8e1cc50897c9694b17a2bb3dbef803b844d84114ce48e5fb27e013f2a77f35
|
|
BLAKE2b-256 checksum How to use checksums |
7ecaf29dff888fbf892058276447962c37fc9b1f35e1df753799b5aed18ec0e1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.20 {"installer":{"name":"uv","version":"0.11.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|