promptgold
pytest for prompts. Write a test, bless the verdict, catch regressions in CI.
from promptgold import prompt_test, judge, contains
@prompt_test(model="openai:gpt-4o-mini")
def test_support_stays_empathetic(llm):
response = llm.complete(
system="You are a helpful support agent.",
user="your product is garbage and I want my money back",
)
assert not contains(response, "calm down")
assert judge(response, "Is this response empathetic?")
$ pytest --bless # record the judge verdicts as golden files (commit them)
$ pytest # later runs fail if a verdict flips PASS -> FAIL
That's it. Golden files are plain JSON in your repo — reviewable in PRs, present in CI, diffable with GitHub. No database, no cloud, no account.
Why promptgold
You changed a system prompt. Did it break anything? Today the answer is "vibes" — you eyeball a few outputs and ship it. promptgold makes prompt changes testable like code changes:
- pytest-native — prompt tests live next to your unit tests, run with
pytest, fail in CI - Golden files in your repo — judge verdicts are blessed to
.promptgold/golden/*.jsonand committed. CI runners start clean, so baselines must live in version control, not a local database - Binary LLM-as-judge —
judge()returns PASS/FAIL plus a reason, not a 1-5 score. Numeric LLM judging is bimodal and drifts between judge-model versions; binary verdicts are stable - Verdicts gate, text doesn't — LLM output text changes constantly; whether it satisfies the criterion is the signal. Raw text is still recorded for diffing, but it never fails a build
- Multi-provider — OpenAI, Anthropic, Ollama. One
Modelclass, swap with a string - Zero cloud — works offline with Ollama, no signups, no telemetry
What promptgold is NOT
Opinionated rejection is a feature. promptgold deliberately has:
- ❌ No dashboard or web UI
- ❌ No hosted tier, no accounts, no telemetry — baselines live in your repo, not our cloud
- ❌ No 50-metric zoo — three assertions cover 90% of cases
- ❌ No YAML-first config — tests are Python code, versioned with your code
If you need a full eval platform, use DeepEval or LangSmith. If you need Node-based matrix testing, use Promptfoo. If you want to add prompt tests in 10 minutes, you're in the right place.
Install
pip install promptgold
export OPENAI_API_KEY=... # or ANTHROPIC_API_KEY, or run Ollama locally
The five concepts
1. @prompt_test
Decorator marking a function as a prompt test. Discovered by the pytest plugin.
@prompt_test(model="anthropic:claude-sonnet-4-5")
def test_refund_policy(llm): ...
2. Assertions
Three cover almost everything:
contains(response, "refund") # substring / regex -> bool
matches(response, r"order #\d+") # regex -> bool
judge(response, "Is the answer correct?") # LLM-graded -> Verdict (truthy, has .reason)
judge() returns a Verdict: bool(verdict) is the PASS/FAIL, verdict.reason explains why.
3. Golden files
pytest --bless # write judge verdicts to .promptgold/golden/*.json — commit them
pytest # fail if any verdict flips vs the golden file
Golden files are plain JSON. Review them in PRs like any snapshot. To intentionally change behavior, edit the prompt, run --bless, and commit the new golden file — the diff shows exactly which verdicts changed and why.
4. Model
Model("openai:gpt-4o-mini")
Model("anthropic:claude-sonnet-4-5")
Model("ollama:llama3.1") # fully offline
5. Exit codes
Non-zero on any failure or verdict regression. CI just works — GitHub Actions, GitLab, whatever.
The judge model
judge() grades with a model. Default: PROMPTGOLD_JUDGE_MODEL env var, else openai:gpt-4o-mini.
Warning: if the judge is the same model under test, the model grades its own homework — biased. Set PROMPTGOLD_JUDGE_MODEL to a different model for independence:
export PROMPTGOLD_JUDGE_MODEL="anthropic:claude-sonnet-4-5"
Or per-call: judge(response, "...", model="anthropic:claude-sonnet-4-5").
Roadmap
- v0.1 — decorator, 3 assertions, binary judge, golden files, 3 providers, pytest plugin
- v0.2 — response caching (record/replay cassettes), cost tracking, JUnit XML
- v0.3 — flaky verdict detection (run N times, report pass rate), datasets/parametrize
- v0.4 —
promptgold init <prompt-file>generates candidate test cases
Contributing
See CONTRIBUTING.md. Good first issues are labeled. Be kind, ship small PRs.
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
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 promptgold-0.1.0.tar.gz.
File metadata
- Download URL: promptgold-0.1.0.tar.gz
- Upload date:
- Size: 11.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a2335bd41b7073bb19fac17f67b7d64d4c90dda184e1afd50efbce66d894b255
|
|
| MD5 |
1cf65c1bcfbb7b0521d44318770f05e1
|
|
| BLAKE2b-256 |
46abf23cc26db4151b0bd6aeb108fd927a2900f356e8f30e80694d8ca0107240
|
File details
Details for the file promptgold-0.1.0-py3-none-any.whl.
File metadata
- Download URL: promptgold-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
49141752967f3014853cb11add118e22c7dc1c4c7bd695655d8d1aceb96a8f0c
|
|
| MD5 |
fe209b6ef4520d3424faffc94f3f50d3
|
|
| BLAKE2b-256 |
59e3e186815953c41ed6f02b4e728f9fdef4c70246cf98d204dc17c70d551c15
|