Configuration¶
pyproject.toml¶
[tool.agentsnap]
judge_model = "openai/gpt-4o-mini"
judge_base_url = "https://openrouter.ai/api/v1"
semantic_threshold = 0.92 # final agent output (strict)
llm_threshold = 0.75 # intermediate LLM responses (tolerant)
mode = "live" # "live" (default) or "replay"
pytest ini options¶
These can also be set as pytest ini options in pyproject.toml or pytest.ini:
[tool.pytest.ini_options]
agentsnap_judge_model = "openai/gpt-4o-mini"
agentsnap_judge_base_url = "https://openrouter.ai/api/v1"
agentsnap_semantic_threshold = "0.92"
agentsnap_llm_threshold = "0.75"
Pytest flags¶
| Flag | Description |
|---|---|
--agentsnap-record |
Force re-record all snapshots, overwriting existing goldens |
--agentsnap-instrument |
Auto-patch all installed LLM SDKs (zero-instrumentation mode) |
--agentsnap-replay |
Force replay mode for every test in the session |
--agentsnap-live |
Force live mode for every test in the session |
pytest --agentsnap-record # re-record everything
pytest --agentsnap-instrument # capture raw clients without adapters
pytest --agentsnap-replay # force replay mode
pytest --agentsnap-live # force live mode
Thresholds¶
Two independent thresholds control the semantic layer:
| Threshold | Default | Applies to |
|---|---|---|
semantic_threshold |
0.92 |
Final output — the agent's actual answer |
llm_threshold |
0.75 |
Intermediate llm_call[n] responses — tolerates natural phrasing variance |
The lower llm_threshold is intentional: LLM phrasing varies even for identical prompts, so intermediate responses are held loosely. The final output is held tightly.
Tune per-test:
# Critical factual agent — hold output tightly
with AgentAsserter("rag_agent", semantic_threshold=0.97) as a: ...
# Creative agent — allow more paraphrasing
with AgentAsserter("writer_agent", semantic_threshold=0.75) as a: ...
Tune globally in pyproject.toml:
[tool.agentsnap]
semantic_threshold = 0.95
llm_threshold = 0.80
structural_tolerance¶
Configurable via pyproject.toml, pytest ini options, or a per-test override on AgentAsserter(structural_tolerance=...), instead of being hardcoded.
structural_tolerance is an edit-distance budget: the structural check (and the model-tools check) only fails once the Levenshtein distance between the old and new tool-name sequences exceeds this value.
Dual-role note: structural_tolerance applies to BOTH the executed-tool sequence (the structural check) and the model-requested tool sequence (the model_tools check described in Model tools). Relaxing it to tolerate flaky tool ordering in your own code also relaxes how much the model itself is allowed to drift in which tool it asks for — there is no separate knob for the two.
Environment variables¶
| Variable | Purpose |
|---|---|
AGENTSNAP_JUDGE_API_KEY |
Explicit key override — always wins |
AGENTSNAP_JUDGE_MODEL |
Model override (default: openai/gpt-4o-mini) |
AGENTSNAP_JUDGE_BASE_URL |
Base URL override (default: OpenRouter) |
OPENROUTER_API_KEY |
Auto-used when judge_base_url contains openrouter.ai |
OPENAI_API_KEY |
Auto-used when judge_base_url contains api.openai.com |
ANTHROPIC_API_KEY |
Auto-used when judge_base_url contains anthropic.com |
Judge key resolution¶
The LLM judge uses a small language model to compare outputs instead of embeddings — more accurate for factual content.
agentsnap resolves the API key automatically — you do not need a separate key. It checks in this order:
AGENTSNAP_JUDGE_API_KEY— explicit override, always wins- The provider-specific key that matches
judge_base_url:
judge_base_url contains |
Key used automatically |
|---|---|
openrouter.ai (default) |
OPENROUTER_API_KEY |
api.openai.com |
OPENAI_API_KEY |
anthropic.com |
ANTHROPIC_API_KEY |
api.groq.com |
GROQ_API_KEY |
api.mistral.ai |
MISTRAL_API_KEY |
api.cohere.com |
COHERE_API_KEY |
Once any matching key is found, the snapshot pytest fixture enables the LLM judge automatically — no code changes needed in tests.
To use a different provider, change judge_base_url in pyproject.toml and set the matching env var:
export OPENAI_API_KEY=sk-...
[tool.agentsnap]
judge_base_url = "https://api.openai.com/v1"
judge_model = "gpt-4o-mini"
Key resolution is implemented in config._resolve_api_key(); the _PROVIDER_KEY_MAP in agentsnap/config.py is where new provider entries are added.
See the API reference for LLMJudge and DiffConfig.