How it works
The test structure you already know
- 1
given()Describe the case
A question, the answer you expect, plus the context or tool calls it should use.
- 2
when()Call your app
Pass any function: a LangChain4j AI service, a REST client, your own pipeline.
- 3
then()Assert on quality
Set score thresholds per metric. A regression fails the build like any other test.
Metrics
Measure what matters in your LLM app
Answer Correctness
Compares the claims in an answer against your ground truth.
Read more →LLM judgeFaithfulness
Catches hallucinations: is every claim backed by the given context?
Read more →LLM judgeAnswer Relevance
Does the answer actually address the question that was asked?
Read more →EmbeddingsSemantic Similarity
Embedding distance between the answer and a reference answer.
Read more →DeterministicTool Call Accuracy
Verifies your agent called the right tools with the right arguments.
Read more →DeterministicBLEU & ROUGE
Classic n-gram and LCS overlap scores, fast and free to run.
Read more →Modules
Pick only what you need
rage4jCore
Evaluators, samples and aggregation. Use it anywhere, not only in tests.
rage4j-assertAssert
The fluent given / when / then API for LLM assertions in your test suite.
rage4j-persistPersist
Write every evaluation to JSON Lines to track quality across runs.
rage4j-persist-junit5Persist JUnit 5
One annotation manages the store lifecycle for a whole test class.
Installation
Add one test dependency
Rage4J is on Maven Central. It builds on LangChain4j, so bring the model provider you already use, such as OpenAI or Ollama.
- Maven
- Gradle
<dependency>
<groupId>dev.rage4j</groupId>
<artifactId>rage4j-assert</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>
testImplementation("dev.rage4j:rage4j-assert:2.0.2")
Stop eyeballing LLM output.
Write your first evaluation test in five minutes.
