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
Agentclass — the same power, embeddable in your code.
Table of contents
- Install
- Configure the model backend
- Connect your data
- Command line
- Python API
- Embedding in another app
- Scaling
- How it works
- Troubleshooting
- 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 installprintserror: externally-managed-environment, you skipped the virtual environment. Thevenvsteps 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
progressnotifications:{ requestId, event, … }withevent ∈ 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_THREADSso 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
predictloops (queue concurrency). - Stream over pub/sub, not a direct socket. Workers publish the
on_event/progressstream to a topic keyed byrequestId; 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
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 guepard_relml-0.2.1-cp313-cp313-macosx_15_0_arm64.whl.
File metadata
- Download URL: guepard_relml-0.2.1-cp313-cp313-macosx_15_0_arm64.whl
- Upload date:
- Size: 396.2 kB
- Tags: CPython 3.13, macOS 15.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8a448c1341cb216f0ac92c6e82c684aaaf261bf2782744271c911214b402637d
|
|
| MD5 |
f7188fc5104b1d2901aa3bbc54a062b6
|
|
| BLAKE2b-256 |
5ae83d65a8ef57f6d2c42c2cb25c271bbe218541ae410b205dd5a4a63a9d9445
|