Evaluate and gate your LLM app — locally and in CI.
One product, two surfaces. Write assertion suites once in plune.yaml,
run them anywhere with the CLI, and catch regressions on every pull request with the GitHub
Action. Provider-agnostic — and the mock provider keeps CI free.
Write evals once. Run them everywhere.
The same plune.yaml drives a local
run on your machine and the gate on your pull requests — no second config, no drift.
AI-powered assertion testing for LLM apps. Describe the checks in one plune.yaml; Plune calls the model, evaluates each assertion, caches results, and reports pass/fail with token cost.
- plune init · run · report · diff
- 10 built-in assertion types
- Programmatic API — import { run } from "@plune-ai/cli"
A thin GitHub Action that wraps the CLI. On every PR it runs your evals, compares against the base branch, and leaves a single sticky comment with the diff — with optional fail-on-regression.
- Sticky PR diff — which evals regressed, which improved
- fail-on-regression gates merges (opt-in)
- Mock provider by default — zero cost, fork-safe
From plune.yaml to a green gate.
Define your checks once. Run them locally while you build, then let the Action re-run them on every pull request and block the merge if quality drops.
- 1 Define
Describe the checks in one file
A provider, a prompt with
{{vars}}from your dataset, and the assertions each row must pass.version: 1 provider: type: anthropic model: claude-3-5-sonnet-latest evals: - id: faq-grounding prompt: "Answer using only the provided context. {{question}}" dataset: datasets/faq.jsonl assertions: - type: llm-judge criteria: "Grounded in the context; invents no facts." - type: contains-any values: ["refund", "return"]
- 2 Evaluate
Run it locally while you build
plune runcalls the model on every dataset row, evaluates each assertion, caches results, and reports pass/fail with token cost. Exit code1on any failure.$ plune run✔ faq-grounding · 2/2 assertions · 12 rows12/12 passed · 0 failed · 0 errored · $0.0142 - 3 Gate
Catch regressions on the pull request
eval-action re-runs the suite on the PR head and the base branch, diffs them, and posts a sticky comment. With
fail-on-regressionapassed → failedtransition turns the check red.# .github/workflows/plune-eval.yml - uses: plune-ai/eval-action@v1 with: config: plune.yaml fail-on-regression: true
◆ Plune eval diff 1 regression · 0 improvementsevalbase → PRfaq-grounding passed → failed ⬇ regression✕ Plune detected a quality regression (pass→fail) — check failed.
Regressions stop slipping through.
You tweak a prompt to fix one case. Three other cases quietly get worse. Nothing fails — there's nothing checking — so it merges. You find out from a user, in production, days later.
The same change re-runs the whole suite on the PR. The diff shows exactly which evals went
passed → failed, the check turns red, and the regression never
reaches main.
Ten ways to assert behaviour.
From plain string checks to JSON-schema, LLM-as-judge, and RAG metrics — mix and match per
eval, or set defaults.assertions across the whole suite.
-
exact-matchoutput equals value (optional trim, ignore_case) -
containsoutput contains value -
contains-anyoutput contains at least one of values -
contains-alloutput contains every one of values
-
json-schemaoutput validates against the JSON schema
-
llm-judgean LLM grades the output against criteria -
semantic-similarityembedding similarity to reference ≥ threshold
-
faithfulnessoutput is grounded in the context -
answer-relevanceoutput actually answers the question -
context-precisioncontext is relevant to the question
Bring your own model. Pay nothing in CI.
Switch backends with one line in plune.yaml —
the API key is read from the environment by provider type, never written to disk. And the
built-in mock provider runs your suite with no key, zero cost, and fully
deterministic output — so pull-request checks stay free.
Don't want to write every test by hand?
Cairn is our open-source QA agent. It logs in, explores your
app, designs methodology-based test cases, and generates self-repairing
@playwright/test specs — the front of the
funnel into the Plune quality stack.
Ship LLM features with confidence.
Install the CLI, write your first plune.yaml, and add the Action to
your repo. Both MIT, both free.