Skip to main content

PG Agent

License: MIT CI PyPI Python 3.10+

PG Agent is a multi-agent runtime for PostgreSQL that turns natural language into secure, executable query plans. It supports multi-turn conversations, schema-aware RAG, self-correcting execution, and result critique — all with zero infrastructure required beyond a Postgres database.


Architecture

User Question
     │
     ▼
 Supervisor (coordinator.py)
     │
     ├── RAG Pipeline ──► LongTermMemory (pgvector)
     │       └── Retrieves relevant schema context
     │
     ├── PlanningAgent ──► Gemini 2.5 Flash
     │       └── Decomposes question into typed steps (SQL / ANALYZE / SEARCH / VERIFY)
     │
     ├── ExecutionAgent
     │       ├── SecureSQLTool   — validates + runs SELECT queries
     │       ├── AnalyticsTool   — pandas/numexpr for math & aggregation
     │       └── SearchTool      — web search for external context
     │
     └── CriticAgent ──► Gemini 2.5 Flash
             └── Post-execution result validation

Key properties:

  • Multi-turn chat — conversation history is passed to the planner on every turn
  • Schema-aware RAG — your table/column schema is embedded in pgvector and retrieved per query
  • Self-correcting — failed SQL steps are re-planned up to 2 times automatically
  • Read-only enforcement — all queries are parsed with sqlglot; DROP, DELETE, UPDATE, etc. are blocked at the tool level
  • No LIMIT required — the SQL validator automatically adds LIMIT 1000 to unconstrained queries

Quick Start

1. Install

pip install pgagent-llm

Or from source:

git clone https://github.com/siddharth7786/pg-agent
cd pg-agent
pip install -e .

2. Configure Environment

Create a .env file or export these variables:

# Required
GEMINI_API_KEY=your_gemini_api_key
DATABASE_URL=postgresql://user:password@localhost:5432/your_db

# Optional — in-memory state is used if not set
REDIS_URL=redis://localhost:6379

3. First-Time Setup

Run once to create the long_term_memory table and enable the required PostgreSQL extensions (pgvector, pg_trgm):

pg-agent setup

4. Index Your Schema

Scan your database schema and store it in pgvector so the planner can write accurate SQL:

pg-agent --index ask "What tables do I have?"

Re-run with --index any time your schema changes.


CLI Reference

Commands

Command Description
pg-agent setup One-time setup: enables pgvector/pg_trgm and creates memory tables
pg-agent ask "<question>" Ask a single question and get a result
pg-agent chat Start an interactive multi-turn session

Global Flags

Flag Description
--index Re-index the database schema before running
--verbose, -v Show full internal logs (planning, execution, critique)

ask Flags

Flag Default Description
--pattern SEQUENTIAL Orchestration pattern: SEQUENTIAL or PARALLEL
--retries 1 Max planning retries on execution failure
--redis $REDIS_URL Override Redis URL

chat Flags

Flag Default Description
--pattern SEQUENTIAL Orchestration pattern: SEQUENTIAL or PARALLEL
--redis $REDIS_URL Override Redis URL

Examples

# Single question
pg-agent ask "Who are the top 5 customers by total payments?"

# Index schema and ask in one shot
pg-agent --index ask "What tables exist and how are they related?"

# With verbose logging
pg-agent -v ask "What is the total revenue per store?"

# Interactive chat
pg-agent chat

# Chat with verbose output
pg-agent -v chat

# Override Redis for this session
pg-agent chat --redis redis://localhost:6379

Chat Session Commands

Inside pg-agent chat:

Input Action
Any question Plan and execute against your database
index Re-index the database schema
exit or quit End the session
Ctrl+C End the session

Python Library Usage

Embed PG Agent directly in your application:

import asyncio
from pg_agent.orchestration.coordinator import Supervisor, CoordinationPattern

async def main():
    agent = Supervisor(
        api_key="your-gemini-key",
        db_url="postgresql://user:pass@localhost:5432/db",
        redis_url="redis://localhost:6379",  # optional
    )

    # Index schema once (or after migrations)
    await agent.index_database_schema()

    # Single question
    state = await agent.orchestrate(
        session_id="session-123",
        pattern=CoordinationPattern.SEQUENTIAL,
        question="What is the total revenue per store?"
    )

    print(state.plan.reasoning)
    for step in state.plan.steps:
        print(f"[{step.id}] {step.description}: {state.results.get(step.id)}")

asyncio.run(main())

For multi-turn conversations, reuse the same session_id across calls — the supervisor persists and passes conversation history automatically.


How It Works

Planning

The PlanningAgent sends your question (plus schema context from RAG) to Gemini and receives a structured JSON plan with typed steps:

Step Type Tool When used
SQL SecureSQLTool Any database query
ANALYZE AnalyticsTool Math, aggregation, combining results
SEARCH SearchTool External web context
VERIFY Internal Checking prior step results

Execution

The ExecutionAgent runs steps with dependency resolution — steps with depends_on wait for their dependencies before starting. A circuit breaker halts execution after 5 failures in 60 seconds.

Self-Correction

If a SQL step fails, the planner receives the error message and the failed query, and generates a corrected plan. This happens up to 2 times per question.

Critique

After execution, the CriticAgent asks Gemini whether the results actually answer the original question. If not, a warning is logged (results are still returned).

Schema RAG

When you run --index, fetch_schema() reads information_schema for all public tables, columns, and foreign key relationships. Each table and relationship is embedded with gemini-embedding-001 (768 dimensions) and stored in pgvector. On each question, the top-10 most relevant schema chunks are retrieved and injected into the planner's system prompt.

State Persistence

Session state (plan, results, conversation history) is stored as JSON, either in Redis (if REDIS_URL is set) or in-memory. The same session_id is reused across turns in chat mode, enabling multi-turn context while resetting the plan and results for each new question.


Database Requirements

Requirement Notes
PostgreSQL 14+ Required
pgvector extension Installed by pg-agent setup; requires superuser on managed DBs
pg_trgm extension Installed by pg-agent setup; used for hybrid keyword search

Manual Extension Install (if setup lacks permissions)

CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS pg_trgm;

Development

# Install with dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Lint
ruff check src/

# Type check
mypy src/

# Security scan
bandit -r src/

License

MIT — see LICENSE for full text.

Metadata

Release files for pgagent-llm 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 pgagent-llm 0.1.0
File Size Uploaded Provenance Actions
pgagent_llm-0.1.0.tar.gz 37.8 kB Without provenance Details for pgagent_llm-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pgagent-llm 0.1.0
File Interpreter ABI Platform Actions
pgagent_llm-0.1.0-py3-none-any.whl Python 3 none any Details for pgagent_llm-0.1.0-py3-none-any.whl

Total release size: 73.0 kB

Release files / pgagent_llm-0.1.0.tar.gz

Download URL pgagent_llm-0.1.0.tar.gz
Size 37.8 kB
Tags Source
SHA-256 checksum
How to use checksums
da687b508b654c170ba8be9ec5b434962591ba24186e13b9d0a7f65ff759d143
BLAKE2b-256 checksum
How to use checksums
1378cfc10ad067cb94f7fff049a42bd97e33ca0ff4144c9a8102359ba8335be9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

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

Download URL pgagent_llm-0.1.0-py3-none-any.whl
Size 35.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4295ad1744ecbfe3b060a6baaea85d852f3fc936d320704af9fc28a670f06c7d
BLAKE2b-256 checksum
How to use checksums
fd843a86bb0364fa818b52080867ea7743b74055da71796b0a99073e83d8b8a7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Security for pgagent-llm 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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

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