Python SDK Reference
PromptDiff provides fully typed, async-first Python APIs for custom evaluation pipelines and seamless pytest integration.
High-Level API: promptdiff.compare
The simplest programmatic way to run a prompt regression test in Python:
import promptdiff
from promptdiff.core.models import TestCase
report = promptdiff.compare(
v1="prompts/support_v1.txt",
v2="prompts/support_v2.txt",
dataset=[
TestCase(id="tc1", vars={"query": "How do I reset my password?"}),
TestCase(id="tc2", vars={"query": "Request a billing refund."}),
],
model="gpt-4o",
mock=True,
assertions=["cost_delta <= 15%", "latency_delta <= 20%"],
)
print(f"Passed: {report.verdict.passed}")
print(f"Cost Delta: {report.verdict.cost_delta_pct:.1f}%")
print(f"Failed Assertions: {report.verdict.failed_assertions}")
Token Compression API: promptdiff.shrink
Compresses prompts programmatically using reflexive meta-prompt optimization:
import promptdiff
from promptdiff.core.models import TestCase
result = promptdiff.shrink(
prompt="Please kindly act as an AI assistant and answer the following question: {{query}}",
dataset=[TestCase(id="1", vars={"query": "Explain quantum computing"})],
target_reduction=0.25,
mock=True,
)
print(f"Original Tokens: {result.original_tokens}")
print(f"Compressed Tokens: {result.compressed_tokens}")
print(f"Compressed Prompt: {result.compressed_prompt}")
Core Pipeline: PromptDiffRunner
For advanced evaluation pipelines with custom providers and evaluators:
import asyncio
from promptdiff.core.models import PromptVersion, TestCase
from promptdiff.core.runner import PromptDiffRunner
from promptdiff.evaluators.registry import get_evaluators
from promptdiff.providers.registry import get_provider
async def main():
runner = PromptDiffRunner(
v1_prompt=PromptVersion(name="v1", template="Summarize: {{text}}"),
v2_prompt=PromptVersion(name="v2", template="Summarize concisely in bullet points: {{text}}"),
provider_v1=get_provider("gpt-4o", force_mock=True),
provider_v2=get_provider("gpt-4o", force_mock=True),
evaluators=get_evaluators(["latency", "cost", "json_validity"]),
)
report = await runner.run(
[TestCase(id="tc1", vars={"text": "PromptDiff is an enterprise prompt regression testing tool."})]
)
print(f"Evaluation verdict: {report.verdict.passed}")
asyncio.run(main())
Pytest Fixtures
When promptdiff-eval is installed, the pytest plugin fixtures are automatically available across your test suites:
1. Asynchronous Fixture: prompt_diff
# tests/test_prompts.py
import pytest
from promptdiff.core.models import TestCase
@pytest.mark.asyncio
async def test_support_prompt_regression(prompt_diff):
report = await prompt_diff.compare(
v1="prompts/support_v1.txt",
v2="prompts/support_v2.txt",
test_cases=[
TestCase(id="tc1", vars={"query": "Reset password"}),
TestCase(id="tc2", vars={"query": "Billing question"}),
],
model="gpt-4o",
mock=True,
)
assert report.verdict.passed, f"Regression detected: {report.verdict.failed_assertions}"
2. Synchronous Fixture: promptdiff_eval
def test_greeting_prompt(promptdiff_eval):
report = promptdiff_eval(
v1="Hello {{name}}, how can I help you today?",
v2="Hi {{name}}! How can I assist?",
vars={"name": "Alice"},
mock=True,
)
assert report.verdict.passed
Custom Evaluator Implementation
Create domain-specific evaluation metrics by subclassing BaseEvaluator:
from promptdiff.evaluators.base import BaseEvaluator
from promptdiff.core.models import EvaluationResult, TestCase
class WordCountEvaluator(BaseEvaluator):
name = "word_count"
async def evaluate(self, response: str, test_case: TestCase) -> EvaluationResult:
count = len(response.split())
return EvaluationResult(
metric_name="word_count",
score=float(count),
passed=count < 100,
metadata={"word_count": count},
)