Skip to main content

guepard-relml

RelML is a natural-language agent over your relational database. You ask a question in plain English; it inspects your schema, decides what to predict, trains a model on your data, checks itself against held-out rows, and answers — no ML code and no feature engineering on your side.

  • CLI: relml-agent — an interactive assistant for your database.
  • Python: the Agent class — the same power, embeddable in your code.

Table of contents

  1. Install
  2. Configure the model backend
  3. Connect your data
  4. Command line
  5. Python API
  6. Embedding in another app
  7. Scaling
  8. How it works
  9. Troubleshooting
  10. License

Install

Requires Python 3.9+. Always install into a virtual environment:

python3 -m venv .venv
source .venv/bin/activate       # Windows: .venv\Scripts\activate
pip install guepard-relml

Verify it imported and the CLI is on your PATH:

python -c "import guepard.qwery.relml._relml_core as c; print('core ok:', hasattr(c, 'train'))"
relml-agent --help

Debian/Ubuntu: if pip install prints error: externally-managed-environment, you skipped the virtual environment. The venv steps above are the fix — do not use --break-system-packages.


Configure the model backend (AWS Bedrock)

The agent is powered by Claude on AWS Bedrock. Provide credentials as environment variables, or put them in a .env file in the directory you run relml-agent from:

export AWS_BEARER_TOKEN_BEDROCK=your-bedrock-api-key
export AWS_REGION=us-east-1
export RELML_AGENT_MODEL=us.anthropic.claude-sonnet-4-5-20250929-v1:0
variable purpose
AWS_BEARER_TOKEN_BEDROCK required — your Bedrock API key (AWS console → Bedrock → API keys)
AWS_REGION the region your Bedrock access is in (default us-east-1)
RELML_AGENT_MODEL the Bedrock model id to use
RELML_AGENT_BACKEND optional — set to bedrock to be explicit (auto-selected when the token is present)

Before the first run, open the Bedrock console → Model access and make sure the Claude model above is enabled for your region.

Other backends. RelML can also use the Anthropic API directly (RELML_AGENT_BACKEND=anthropic, ANTHROPIC_API_KEY=…) or Ollama (RELML_AGENT_BACKEND=ollama, OLLAMA_API_KEY=…).


Connect your data

Tell RelML where your data lives via --source (CLI) or the first argument to Agent(...) (Python). Three source types are supported.

1. A PostgreSQL database

Pass a connection string — libpq keyword form or a URL. The database is opened read-only; RelML never writes to it.

relml-agent --source "dbname=mydb host=localhost user=me password=secret"
relml-agent --source "postgresql://me:secret@localhost:5432/mydb"

The first Postgres run downloads DuckDB's postgres extension, so it needs network access once.

2. A folder of CSV / Parquet files

Every .csv / .parquet file in the folder becomes a table (named after the file). Great for quick experiments.

relml-agent --source ./my_data

3. A single CSV / Parquet file

relml-agent --source ./sales.parquet

Command line

relml-agent has two modes.

Interactive — omit the question to open a REPL you can converse with:

relml-agent --source ./my_data

One-shot — pass a question to get a single answer and exit:

relml-agent "which customers are most likely to churn next month?" --source ./my_data

Run relml-agent --help for the full flag list.

REPL commands

Inside the interactive session, type a question, or a /command (these inspect state without spending model calls):

command what it does
/tables list tables — row counts, primary/foreign keys, detected column types
/schema [table] show columns, types, and keys (all tables, or just one)
/sql <query> run a read-only SQL query and print the rows
/models models trained this session, with their held-out metrics
/model <id> full detail on one model (features used, hyper-parameters)
/predict <id> [k] run a trained model; show the top-k predictions
/evaluate <id> critique a model against leakage-free baselines
/plot terminal chart of actual vs predicted
/source <src> connect to a different database (resets models)
/help list all commands
/quit exit

A typical session

$ relml-agent --source ./ecommerce
› /tables
  customers (12,043 rows, pk customer_id)
  orders    (98,220 rows, pk order_id, fk customer_id → customers)
  ...
› will customer 5512 order again in the next 30 days?
  [the agent explores the data, trains a model, and answers with a probability]
› /plot
  [actual vs predicted over the backtest]
› /quit

Python API

from guepard.tools.agent import Agent

# source: a CSV/Parquet folder, a single file, or a Postgres connection string
agent = Agent("./my_data")

answer = agent.ask("Forecast next week's daily order volume.")
print(answer)

Quiet mode — suppress the live progress output (useful in scripts/services):

agent = Agent("./my_data", verbose=False)
print(agent.ask("Rank customers by churn risk."))

Choose the backend/model in code (overrides the environment):

from guepard.tools.agent import Agent, LLMClient

client = LLMClient(backend="bedrock",
                   model="us.anthropic.claude-sonnet-4-5-20250929-v1:0")
agent = Agent("dbname=mydb host=localhost user=me password=secret", client=client)
print(agent.ask("Which drivers are most at risk of a DNF next race?"))

Agent(...) options

argument default meaning
source CSV/Parquet folder or file, or a Postgres connection string
verbose True stream the agent's progress to the terminal
client auto an LLMClient to control backend/model/region
max_steps 40 max reasoning/tool steps per question
max_tokens 4096 max tokens per model call
pg_schema None for Postgres, restrict to a specific schema

agent.ask(question: str) -> str returns the final natural-language answer.


Embedding in another app

RelML gives you three integration surfaces — pick by where the client lives.

In-process (Python) — the on_event callback

Pass a callback to Agent(...) and receive every step as it happens — wire it to your logs, a UI, or a progress bar:

from guepard.tools.agent import Agent

def on_event(event: str, data: dict):
    # event: "text" | "tool_call" | "tool_result" | "error" | "connected"
    # data:  {"agent": "...", "name": <tool>, "text": "...", ...}
    my_logger.info("relml", event=event, **data)

agent = Agent("./data", on_event=on_event, verbose=False)   # verbose=False: don't also print
answer = agent.ask("Which customers will churn?")

text is the agent's reasoning/answer as it streams; tool_call / tool_result mark each step it takes (run_sql, train_model, predict, …).

Subprocess (any language) — --json

Emits newline-delimited JSON events on stdout, then a final result (stderr is logs). Good for spawning from Node/Go/etc.:

relml-agent --json --source ./data "Which customers will churn?"

Long-lived sidecar — relml-serve

A persistent JSON-RPC service over stdin/stdout (LSP-style Content-Length: N\r\n\r\n<json> framing, stderr = logs). The host spawns it once and drives it:

  • methods: initialize, predict, plot, infer, list_models, explain, delete_model, cancel, shutdown
  • streaming progress notifications: { requestId, event, … } with event ∈ connected | text | tool_call | tool_result | error
  • keeps a warm session (DB + model registry) across requests; supports cancel

predict / infer / plot run the LLM agent; list_models / explain / delete_model are deterministic (no LLM) and read the persisted model registry — so they can be served statelessly (see Scaling).


Scaling

RelML requests are heavy and long-running (an LLM agent loop plus C++ model training). The scalable shape is a queue-backed worker pool with progress fanned out over pub/sub, feeding a shared model registry that a separate stateless serve tier reads.

  • Split train from serve. predict / ask (LLM + training) → async jobs on an autoscaled worker pool. list_models / explain / prediction-by-model (no LLM) → stateless replicas. Train once, serve many — RelML fingerprints each task, so a repeat question reuses the trained model instead of retraining.
  • Externalize the registry. Trained models persist under RELML_HOME (default ~/.relml). Point it at shared storage (a shared volume / object store) so any replica loads any model — this is what makes the serve tier stateless.
  • One agent per process. The orchestration is synchronous (GIL) — scale by process/container count, not threads. Set OMP_NUM_THREADS so the C++ trainer's BLAS threads don't oversubscribe CPU when you pack workers.
  • Bound Bedrock concurrency. It is your rate-limit and cost ceiling — cap the number of concurrent predict loops (queue concurrency).
  • Stream over pub/sub, not a direct socket. Workers publish the on_event / progress stream to a topic keyed by requestId; a gateway relays it to the client over WebSocket/SSE. It survives worker restarts and fans out to multiple viewers.
 client ──POST /job──►  gateway ──enqueue──►  queue ──►  worker pool (N, autoscaled)
        ◄──WebSocket──   (stateless)                        Agent(on_event=publish)
              ▲                                                    │
              └──────────── pub/sub (per requestId) ◄─────────────┘
                                                     trained model ─► RELML_HOME (shared)
                                                                        │
                                       stateless serve tier ◄───────────┘  list_models / explain

How it works

From one question, RelML runs a loop: describe your schema and key graph → explore the data with read-only SQL → frame a supervised task (target, features, train/validation split) → train a model → evaluate it against held-out rows and leakage-free baselines → iterate until the gains are marginal → answer you in plain language. Predictions can be written back as a queryable table so you can inspect them with /sql.


Troubleshooting

symptom fix
error: externally-managed-environment you skipped the venv — see Install.
no credentials found … set AWS_BEARER_TOKEN_BEDROCK (and AWS_REGION), or another backend's key.
Bedrock AccessDenied / model errors enable the model in Bedrock → Model access for your region, and check AWS_REGION.
No .csv/.parquet files found in … point --source at a folder that actually contains .csv/.parquet files, or at a single file.
Postgres connection fails verify the DSN; the DB must be reachable and the first run needs network to fetch the postgres extension.
command not found: relml-agent activate the venv where you installed it (source .venv/bin/activate).

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

guepard_relml-0.2.1-cp313-cp313-macosx_15_0_arm64.whl (396.2 kB view details)

Uploaded CPython 3.13macOS 15.0+ ARM64

File details

Details for the file guepard_relml-0.2.1-cp313-cp313-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for guepard_relml-0.2.1-cp313-cp313-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 8a448c1341cb216f0ac92c6e82c684aaaf261bf2782744271c911214b402637d
MD5 f7188fc5104b1d2901aa3bbc54a062b6
BLAKE2b-256 5ae83d65a8ef57f6d2c42c2cb25c271bbe218541ae410b205dd5a4a63a9d9445

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page