ragR is an R package for building, running, logging, and
evaluating retrieval-augmented generation workflows.
It provides:
The package is designed for research, coursework, experimentation, and reproducible retrieval-augmented generation evaluation workflows.
ragR can ingest documents, divide text into chunks,
generate embeddings, and store the chunks and embeddings in a local
R-native vector store.
Supported file types depend on the available R and system
dependencies. Plain text ingestion is the simplest option. PDF ingestion
may require the pdftools R package and the Poppler system
library.
The vector-store location must be supplied explicitly by the caller. For example, a user may choose a persistent project location such as:
db/vectorstore.rds
or a temporary location created with tempfile().
Runtime vector-store files are not part of the installed package.
For a user question, the retrieval-augmented generation pipeline:
The primary user-facing function is:
query_rag()The vector-store path must be supplied explicitly.
The API-level system_prompt is passed as a system
message to the chat model. It is not inserted into the constructed
retrieval-augmented generation prompt.
ragR can log interactions to a user-selected RDS
file.
Each logged row includes:
qa_id;question;prompt_final;answer_model;answer_reference;collection;retrieved_ids;retrieved_texts;chat_model;embedding_model; andtimestamp.The answer_reference column is optional. It can be
completed later for controlled evaluation experiments. When it is absent
or empty, some evaluation functions may use answer_model
where needed.
The package does not select a default question-answer log location. Paths must be supplied explicitly to the persistence functions.
ragR computes evaluation metrics inspired by Retrieval
Augmented Generation Assessment, including:
The main metric functions are:
compute_ragas_metrics()
compute_ragas_metrics_llm()In the current package version, these metrics are scored using large language models. Deterministic approximation metrics are not included.
Metric values may be NA when a score cannot be computed,
required inputs are unavailable, or external model scoring fails.
Metrics and reports are written only to locations explicitly supplied by the caller.
The source repository includes a development Plumber server for chatbot and evaluation frontends.
Current routes are:
| Endpoint | Method | Purpose |
|---|---|---|
/chat |
POST | Ask a retrieval-augmented generation question and log the interaction |
/ragas |
GET | Compute and return evaluation metrics and a summary |
/ragas/report |
POST | Compute metrics and save report artifacts |
/ragas/clear |
POST | Clear the question-answer log, metrics, and report files |
/clear |
POST | Clear one vector-store collection |
/clear_all |
POST | Clear the entire vector store |
There is no ingestion endpoint in the current minimal API. Document ingestion is performed through package functions or development scripts.
The API server configures storage paths on the server side. File paths are not accepted from client JSON request bodies.
install.packages("remotes")
remotes::install_github("aimalrehman92/ragR")Clone the repository:
git clone https://github.com/aimalrehman92/ragR.git
cd ragRInstall development tools if needed:
install.packages(c("pkgload", "testthat", "roxygen2"))Load the package during development:
pkgload::load_all()Or install it locally:
install.packages(".", repos = NULL, type = "source")The GitHub repository may include development-environment files. When
using renv, restore the environment with:
install.packages("renv")
renv::restore()Depending on the operating system, some dependencies may require
additional system libraries. PDF ingestion through
pdftools, for example, may require Poppler.
ragR reads the OpenAI API key from:
OPENAI_API_KEY
The key can be added to a user-level .Renviron file:
usethis::edit_r_environ("user")Add a line such as:
OPENAI_API_KEY=your_key_here
Restart R after editing the file.
Most package tests use synthetic data and do not require an OpenAI API key. Functions that call OpenAI models require a valid API key and internet access.
All runtime paths are selected explicitly.
The following example uses a temporary directory:
library(ragR)
runtime_dir <- file.path(
tempdir(),
"ragR-example"
)
dir.create(
runtime_dir,
recursive = TRUE,
showWarnings = FALSE
)
vectorstore_path <- file.path(
runtime_dir,
"vectorstore.rds"
)
qa_log_path <- file.path(
runtime_dir,
"qa_log.rds"
)
qa_metrics_path <- file.path(
runtime_dir,
"qa_metrics.rds"
)
report_dir <- file.path(
runtime_dir,
"reports"
)For persistent work, replace runtime_dir with a
directory chosen by the user.
library(ragR)
input_paths <- c(
"data-raw/my_document.txt"
)
ingest_documents(
paths = input_paths,
vectorstore_path = vectorstore_path,
collection = "default",
embedding_model = "text-embedding-3-small"
)For PDF ingestion, use a PDF path such as:
input_paths <- c(
"data-raw/my_document.pdf"
)PDF ingestion may require pdftools and Poppler.
library(ragR)
res <- query_rag(
question = "What is this document about?",
collection = "default",
vectorstore_path = vectorstore_path,
top_k = 5L,
embedding_model = "text-embedding-3-small",
chat_model = "gpt-4o-mini",
temperature = 0,
max_output_tokens = 300L,
system_prompt = "You are a helpful assistant."
)
cat(res$answer)The result includes:
answer;retrieved;prompt; andlibrary(ragR)
qa_log <- qa_log_empty()
qa_log <- log_rag_interaction(
qa_log = qa_log,
question = "What is this document about?",
rag_result = res,
collection = "default",
chat_model = "gpt-4o-mini",
embedding_model = "text-embedding-3-small"
)
save_qa_log(
qa_log = qa_log,
path = qa_log_path
)
qa_log <- load_qa_log(
path = qa_log_path
)library(ragR)
qa_log <- load_qa_log(
path = qa_log_path
)
qa_metrics <- compute_ragas_metrics(
qa_log,
judge_model = "gpt-4o-mini",
embedding_model = "text-embedding-3-small"
)
save_qa_metrics(
qa_metrics = qa_metrics,
path = qa_metrics_path
)
summary_tbl <- summarize_ragas(
qa_metrics
)
print(summary_tbl)library(ragR)
generate_ragas_report(
qa_log_path = qa_log_path,
qa_metrics_path = qa_metrics_path,
output_dir = report_dir,
judge_model = "gpt-4o-mini"
)This writes:
<qa_metrics_path>
<report_dir>/ragas_summary.csv
<report_dir>/ragas_means.png
All three locations are controlled by the caller.
Clear a question-answer log:
clear_qa_log(
path = qa_log_path
)Clear saved metrics:
clear_qa_metrics(
path = qa_metrics_path
)Clear one vector-store collection:
vectorstore_delete_collection(
collection = "default",
path = vectorstore_path
)Clear the entire vector store:
vectorstore_clear_all(
path = vectorstore_path
)The source repository includes:
scripts/dev/run_api.R
Run it from the project root:
Rscript scripts/dev/run_api.RBy default, the server stores runtime files under a temporary directory.
To use a persistent directory, set RAGR_API_DATA_DIR
before starting the server.
On macOS or Linux:
export RAGR_API_DATA_DIR="/path/to/ragR-api-data"
Rscript scripts/dev/run_api.RFrom R:
Sys.setenv(
RAGR_API_DATA_DIR = "/path/to/ragR-api-data"
)
source("scripts/dev/run_api.R")The local backend runs at:
http://127.0.0.1:8000
Interactive Swagger documentation is available at:
http://127.0.0.1:8000/__docs__/
The development server uses the configured data directory to construct:
vectorstore.rds
qa_log.rds
qa_metrics.rds
ragas/
/chatAsk a retrieval-augmented generation question and log the interaction.
Example request body:
{
"question": "What is the document about?",
"collection": "default",
"top_k": 5
}Example R request:
library(httr2)
resp <- request(
"http://127.0.0.1:8000/chat"
) |>
req_method("POST") |>
req_body_json(
list(
question = "What is the document about?",
collection = "default",
top_k = 5
)
) |>
req_perform()
resp_body_json(
resp,
simplifyVector = TRUE
)The interaction is appended to the question-answer log configured by the server.
/ragasCompute evaluation metrics from the configured question-answer log and return the metrics and summary.
library(httr2)
resp <- request(
"http://127.0.0.1:8000/ragas"
) |>
req_method("GET") |>
req_perform()
resp_body_json(
resp,
simplifyVector = TRUE
)/ragas/reportCompute metrics and save report artifacts to server-configured locations.
library(httr2)
resp <- request(
"http://127.0.0.1:8000/ragas/report"
) |>
req_method("POST") |>
req_perform()
resp_body_json(
resp,
simplifyVector = TRUE
)/ragas/clearClear the configured question-answer log, saved metrics, and report directory.
library(httr2)
resp <- request(
"http://127.0.0.1:8000/ragas/clear"
) |>
req_method("POST") |>
req_perform()
resp_body_json(
resp,
simplifyVector = TRUE
)/clearClear one vector-store collection.
Example request body:
{
"collection": "default"
}When collection is omitted, "default" is
used.
/clear_allClear all collections from the configured vector store.
library(httr2)
resp <- request(
"http://127.0.0.1:8000/clear_all"
) |>
req_method("POST") |>
req_perform()
resp_body_json(
resp,
simplifyVector = TRUE
)The source repository includes development scripts under
scripts/dev/. They are intended for local experimentation
and reproducibility and are excluded from the package build.
scripts/dev/demo_clear_collection.R
scripts/dev/demo_clear_db.R
scripts/dev/demo_ingest.R
scripts/dev/demo_rag.R
scripts/dev/run_api.R
scripts/dev/qa/clear_qa_state.R
scripts/dev/qa/collect_qa.R
scripts/dev/qa/compute_metrics.R
scripts/dev/qa/export_for_ragas_python.R
scripts/dev/qa/insert_gt.R
scripts/dev/qa/run_eval_loop.R
scripts/dev/qa/run_eval_pipeline.R
scripts/dev/qa/visualize_metrics.R
Some evaluation scripts are intended for controlled experiments in
which answer_reference has already been populated. The API
workflow does not require answer_reference.
ragR/
├── DESCRIPTION
├── NAMESPACE
├── README.md
├── .Rbuildignore
├── .gitignore
├── R/
├── inst/
│ └── api/
├── man/
├── tests/
└── scripts/
└── dev/
Runtime artifacts may be stored in any user-selected directory. Common development locations include:
db/
reports/ragas/
data-raw/
These are development or runtime folders and are not package data.
Load the local package and run the tests:
pkgload::load_all()
testthat::test_dir("tests/testthat")Run an R package check with:
rcmdcheck::rcmdcheck(
args = "--as-cran"
)When devtools is available, the equivalent commands
are:
devtools::test()
devtools::check(args = "--as-cran")The package tests use synthetic data and avoid requiring an OpenAI API key or internet access.
Runtime files should generally not be committed unless they are intentionally included for reproducibility.
Examples include:
vectorstore.rds
qa_log.rds
qa_metrics.rds
ragas_summary.csv
ragas_means.png
The exact locations are selected by the user or server configuration.
GPL-3