Skip to content

Latest commit

 

History

History
243 lines (185 loc) · 9.44 KB

File metadata and controls

243 lines (185 loc) · 9.44 KB

ragctl — command reference

Overview

ragctl is the operator-facing control-plane CLI for AgentContextOS. It bundles configuration, ingestion, retrieval, gateway, reliability, observability, and governance commands into a single binary that talks to local files, an in-process gateway, and the supporting infrastructure (Jaeger, etc.).

Most commands are self-contained, credential-free demos: they drive the real pipeline (or a real in-process FastAPI/gRPC/MCP gateway) against the noop SPI wiring, so every platform capability can be exercised on a laptop with no infrastructure. That makes ragctl both the operator tool and the fastest way to see any subsystem work end-to-end.

The surface today: 37 commands + 13 sub-command groups, all working except three scaffolds (plugin, logs, secret) that print a notice and exit 0.

Usage

# discover the surface
ragctl --help

# print the installed version
ragctl version

Run via the workspace until the standalone PyPI package lands: uv run ragctl <command>.

Command catalog

Ingestion pipeline (Phase 1)

Command What it does
parse Detect MIME, parse a file, print a structural summary (Step 1.3)
ocr Run an OCR plugin on an image, print region-aware results (Step 1.4)
chunk Parse, then chunk via HeadingAwareChunker (Step 1.5)
enrich parse → chunk → enrich; print enriched metadata (Step 1.6)
pii parse → chunk → enrich → PII; print detection outcomes (Step 1.7)
embed The pipeline end-to-end through embedding (Step 1.8)
ingest Full ingest pipeline against a folder or file (Step 1.10)

Retrieval & query understanding (Phase 2)

Command What it does
hybrid Hybrid RRF retrieval over an in-memory toy corpus (Step 2.5)
understand QueryUnderstandingPipeline over one query (Step 2.6)
rerank RerankPipeline over a tiny in-memory corpus (Step 2.7)
pack ContextPacker against a toy corpus (Step 2.8)
graphrag GraphRAG detect → summarize → retrieve over a toy graph (Step 2.9)
route Retrieval router classifying + dispatching a query (Step 2.10)
agent-loop AgentLoopV0 over a single query end-to-end (Step 2.11)

Gateway surfaces — in-process (Phase 3)

Command What it does
query Drive POST /v1/query against an in-process gateway (Step 3.1)
grpc-query Drive RagService.Query against an in-process gRPC server (Step 3.2)
mcp-serve Run the MCP server over stdio (Step 3.3)
mcp-query Drive the MCP query tool against an in-memory server (Step 3.3)
chat Drive POST /v1/chat/completions (OpenAI-compatible, Step 3.4)
embeddings Drive POST /v1/embeddings (OpenAI-compatible, Step 3.4)
agent Drive POST /v1/agent — agent loop over SSE (Step 3.6)
corpus (group) Inspect the corpus store + exercise the corpus router (Step 3.5)
webhooks (group) Exercise outbound webhook signing + delivery (Step 3.9)

Reliability (Phase 4)

Command What it does
fallback Fallback chain degrading a query gracefully (Step 4.2)
guard Hallucination guard checking an answer's faithfulness (Step 4.3)
breaker Circuit breaker isolating a failing backend (Step 4.4)
quota Quota enforcer admitting + throttling a tenant (Step 4.5)
perf Probe the in-process gateway's latency overhead (Step 4.6)

Observability & eval (Phases 0 + 5)

Command What it does
config (group) Validate and diff rag.yaml files (Step 0.4)
traces (group) Query distributed traces from Jaeger (Step 0.7)
eval (group) Run and inspect golden-set evaluations (Step 0.8 / 5.2)
provenance Per-query provenance: build → sign → store → verify (Step 5.1)
feedback Record explicit + implicit signals → aggregate (Step 5.4)
drift Seed a reference, feed a drifted current, report (Step 5.5)
experiments A/B analyzer: control + candidate samples → lift + CI (Step 5.7)
shadow Shadow mode end-to-end against in-process stubs (Step 5.7b)
ab A/B routing end-to-end against in-process stubs (Step 5.7c)

Governance & enterprise (Phase 6)

Command What it does
tenant (group) Inspect per-tenant config + resolve logical tenancy (Step 6.1)
audit Signed WORM audit export: seed → export → verify (Step 6.6b)
kms BYOK envelope encryption with an in-process key manager (Step 6.7)
scim SCIM 2.0 provisioning against an in-process directory (Step 6.8)
sso (group) Per-tenant SSO config + OIDC federation demo (Step 6.8)
airgap (group) Build / verify / install the air-gapped bundle (Step 6.9)
compliance (group) Compliance posture + data-retention / GDPR erasure demo (Step 6.10)

Commercial & pilots (Phase 7)

Command What it does
pilot (group) Onboard a design-partner pilot + report weekly KPIs (Step 7.4)
billing Metering → invoice flow: meter usage, then bill it (Step 7.9)

Scaffolds

Group Planned step What it will do
plugin 1.1 Manage SPI plugin registration
logs 5.6 Tail structured logs from the platform
secret 6.7 Manage tenant secrets

Scaffold commands exit 0 and print a one-line notice so operators can probe the planned interface without surprise.

Worked examples

ragctl config

ragctl config validate path/to/rag.yaml         # exits 0 on success, 1 otherwise
ragctl config validate path/to/rag.yaml --json  # machine-readable result
ragctl config diff path/a.yaml path/b.yaml      # show backend differences

ragctl query

uv run ragctl query "what is RAG?" --top-k 3

Spins up the in-process FastAPI gateway against the noop wiring and runs the full understand → route → rerank → pack pipeline — the quickest end-to-end smoke test there is.

ragctl eval

ragctl eval run tests/eval/golden/ --top-k 10 --output report.json
ragctl eval show report.json --verbose
ragctl eval run tests/eval/golden/ --ragas       # optional faithfulness scoring

--ragas requires the optional ragas extra:

pip install 'rag-config[eval]'

ragctl traces

ragctl traces                                                # default service, 20 traces
ragctl traces --service gateway --limit 50
ragctl traces --url http://jaeger.observability.svc:16686    # remote Jaeger

ragctl version

ragctl version           # → ragctl 0.1.0

Every other command follows the same shape — run it with --help for its flags; each prints a structured, human-readable walkthrough of its subsystem.

Shell completion

ragctl ships with Typer-powered completion for bash, zsh, fish, and PowerShell:

ragctl --install-completion        # install for the detected shell
ragctl --show-completion           # print the completion script to stdout
ragctl --show-completion zsh > _ragctl

Internals

The CLI lives in packages/ragctl/. The Typer app is constructed once in ragctl.main and exposed as the ragctl entry point via [project.scripts] in pyproject.toml.

Layout

packages/ragctl/
├── pyproject.toml          # rag-ragctl, depends on rag-core/config/observability + domain packages
├── README.md               # short package overview
└── src/ragctl/
    ├── __init__.py         # exports app, main, __version__
    ├── main.py             # root Typer app + all commands and sub-command groups
    └── py.typed            # type marker for downstream consumers

Design

The CLI keeps no business logic of its own. Each command is a thin adapter over a function exported from the corresponding domain package, and the gateway-surface commands build the same in-process app the test suite uses (build_app with noop SPIs) — so a ragctl run exercises exactly the code that ships.

The three remaining scaffold groups are constructed by the local helper _scaffold_app(group, step, help_text), which prints a "delivered in Step X.Y" notice and exits 0. This keeps the published command shape stable — operators can script against ragctl logs ... today and the same script keeps working when the real implementation lands.

Extension points

To add a new command or sub-command group:

  1. Create or import the domain logic in the appropriate package (rag-core, rag-config, the relevant packages/<domain>, etc.).
  2. In ragctl/main.py, register an @app.command() (or build a typer.Typer() sub-app and attach it with app.add_typer(...)).
  3. Update the Command catalog table in this file and the package README.
  4. Add tests under packages/ragctl/tests/.

To replace a scaffold with a real implementation:

  1. Remove the _scaffold_app(...) call for that group from main.py.
  2. Build the real sub-app the same way you would for a new group.
  3. Move the row out of the Scaffolds table in this file.

See also