Skip to main content

pydantic-rag-agent

A retrieval-augmented generation (RAG) agent built on Pydantic and managed with uv.

Status: feature-complete for a local, single-user deployment. M0–M5 are done and M6 is closed apart from OPS-1 (instrumentation), which is deliberately out of scope. Ingestion, retrieval, the agent, the API, the CLI and the Streamlit UI all work; the suite runs offline at 92% branch coverage. main is the state described in docs/overview.md; the ordered plan behind it is in docs/features/ and docs/roadmap.md.

Why uv?

Dependency resolution and virtualenv handling live in one fast tool, and uv.lock pins the exact graph so your CI and your laptop agree on what "it works" means.

Documentation

Full documentation lives in docs/ — start with the documentation index or the project overview. Design rationale is recorded as decision records.

Coding agents should read AGENTS.md first.

Requirements

  • uv 0.13 or newer
  • Python 3.11+ — uv will fetch and manage the interpreter for you if needed

Install

uv add "pydantic-rag-agent"               # core: agent, loaders, CLI, in-memory store
uv add "pydantic-rag-agent[chroma]"       # plus the default persistent store
uv add "pydantic-rag-agent[chroma,ui]"    # plus the Streamlit UI
uv add "pydantic-rag-agent[chroma,api]"   # plus the FastAPI integration
uv add "pydantic-rag-agent[chroma,s3]"    # plus originals in a bucket
uv add "pydantic-rag-agent[all]"          # everything

The core install has no vector database: it runs with the in-memory store, which is fine for a script that ingests and asks in one go. Anything the agent does not need at import time is an extra, and a missing one tells you which to install.

Not on PyPI yet. The first release is milestone 7 — see docs/features/ and ADR 0013. Until then, install from the repository as below.

As a library, from the repository today (and from PyPI once published):

from pydantic_rag_agent import RagAgent

agent = RagAgent.from_env()
agent.ingest_sync("./docs")
print(agent.ask_sync("How long are backups retained?").text)

The async methods (await agent.ask(...), async for update in agent.stream(...)) are what a web app wants; the sync helpers exist so a script does not have to become async to ask one question. Answers carry citations back to the source document, including the locator of the stored original (file:// or s3://).

Already have a FastAPI app? Mount the router instead of running a second service:

from contextlib import asynccontextmanager

from fastapi import FastAPI

from pydantic_rag_agent import RagAgent
from pydantic_rag_agent.integrations.fastapi import create_router

agent = RagAgent.from_env()


@asynccontextmanager
async def lifespan(app: FastAPI):
    await agent.check_index()
    try:
        yield
    finally:
        await agent.aclose()


app = FastAPI(lifespan=lifespan)
app.include_router(create_router(agent), prefix="/knowledge")

The router brings the routes; your app keeps its lifespan, its auth and its shutdown.

Any OpenAI-speaking chat UI can be pointed at the agent instead of a bespoke frontend:

from pydantic_rag_agent.integrations.fastapi import create_openai_router

app.include_router(create_openai_router(agent, model_id="acme-knowledge"), prefix="/openai")

Point the client at https://your-host/openai/v1. Requests are stateless (the client sends the thread), caller-supplied system messages are ignored, and answers carry a Sources: footer. serve already exposes the same route at /v1, so a chat UI can be pointed at a running server without writing any code — --openai-model-id chooses the name the client shows. See ADR 0014.

Getting started from the repository

# Clone and enter the project
git clone git@github.com:hanku4u/pydantic-rag-agent.git
cd pydantic-rag-agent

# Create .venv and install the project plus its dependencies
uv sync

# Provide the one credential: chat, captions, and embeddings all use it
cp .env.example .env
# then edit .env and set OPENROUTER_API_KEY

# Index and ask — the agent runs in this process, no server needed
uv run pydantic-rag-agent ingest ./docs
uv run pydantic-rag-agent ask "How long are backups retained?"

# Optional: the API and web UI together
uv run pydantic-rag-agent dev

The terminal answer streams and ends with a table of the sources it cited. The chat UI from dev is at http://127.0.0.1:8501. --api-url makes any command talk to a running server instead of building the agent locally.

Day-to-day commands

Task Command
Install or refresh dependencies uv sync
Add a runtime dependency uv add <package>
Add a dev-only dependency uv add --dev <package>
Remove a dependency uv remove <package>
Run a command inside the venv uv run <command>
Run a script without installing it uv run path/to/script.py

Project layout

pydantic-rag-agent/
├── pyproject.toml            # project metadata, dependencies, CLI entry point
├── uv.lock                   # exact resolved versions — commit this
├── .python-version           # interpreter uv should use
├── AGENTS.md                 # orientation for coding agents
├── docs/                     # design, backlog, decisions — start at docs/README.md
├── src/
│   └── pydantic_rag_agent/
│       ├── __init__.py       # package marker, no import-time side effects
│       └── cli.py            # command-line entry point (`main`)
└── README.md

The src/ layout keeps the package importable from an installed build rather than by accident from the working directory, which is what makes uv run pytest behave the same as a real install.

Configuration

Settings are a tree of six nodes — provider, embeddings, vector store, storage, ingestion, agent — read from PRAGENT_* environment variables via pydantic-settings. Nesting is addressed with a double underscore: PRAGENT_PROVIDER__MODEL, PRAGENT_AGENT__TOP_K. Each node can also be constructed in code, which is how the library is used.

Credentials keep their conventional names (OPENROUTER_API_KEY) and are never read from a committed file. Every variable, its default, and the mapping from the pre-0.1.0 flat names are in docs/reference/configuration.md.

The .gitignore ignores .env and any .env.* file except .env.example.

Contributing

  1. uv sync to get a working environment.
  2. Pick a feature ID from the backlog and reference it in your commit subject.
  3. Add tests under tests/ next to the module they cover.
  4. uv run pytest before opening a pull request.

License

MIT. Use it, fork it, ship it — just keep the copyright notice.

The dependency stack is deliberately permissive end to end; the one AGPL package that previously blocked this was replaced. See docs/reference/dependencies.md for the details, and ADR 0007 for the reasoning.

Metadata

Release files for pydantic-rag-agent 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pydantic-rag-agent 0.1.0
File Size Uploaded Provenance
pydantic_rag_agent-0.1.0.tar.gz 84.8 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for pydantic-rag-agent 0.1.0
File Interpreter ABI Platform
pydantic_rag_agent-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 190.7 kB

Release files / pydantic_rag_agent-0.1.0.tar.gz

Download URL pydantic_rag_agent-0.1.0.tar.gz
Size 84.8 kB
Tags Source
SHA-256 checksum
How to use checksums
4582f2206d8ae957edbcf787920e8e3eb1278bcef8a7d6993333d611b9b927e8
BLAKE2b-256 checksum
How to use checksums
cb8b36311f267c1f74fb2a5d95086f1ae1dce5d53517b20a0d065dc2c003a74c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / pydantic_rag_agent-0.1.0-py3-none-any.whl

Download URL pydantic_rag_agent-0.1.0-py3-none-any.whl
Size 105.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ace0758c56831b18671bed851179f208a86c1fdc10f406eab37584114b104144
BLAKE2b-256 checksum
How to use checksums
da9ce576f820430974274e1f075950889ca695a3e714377345fdba9e91a887dc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for pydantic-rag-agent 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page