Skip to content

Add retry mechanism for transient LLM failures and completeness tracking - #77

Merged
MaximilianAnzinger merged 2 commits into
mainfrom
feature/retry-mechanism
Aug 25, 2026
Merged

Add retry mechanism for transient LLM failures and completeness tracking#77
MaximilianAnzinger merged 2 commits into
mainfrom
feature/retry-mechanism

Conversation

@MaximilianAnzinger

Copy link
Copy Markdown
Collaborator

Summary

  • Retry transient LLM failures with exponential backoff in the provider layer (template method pattern: generate() wraps _do_generate() with retry logic). Transient errors (408, 429, 5xx, connection/timeout) are retried up to 4 times with 30s base delay and 5 min cap. Non-transient errors (400, 401, 403, 404, ValueError) propagate immediately.
  • Track every missing cell via a completeness report. After runner.run(), get_completeness_report() returns expected/present/skipped/failed counts. Transient failures (retries exhausted) are distinguished from legitimate skips (e.g. distractor metric on true/false questions). A completeness.json is written to the run bundle, and the process exits non-zero when transient failures remain.
  • Fix pre-existing lint issues in the changed file set (import sorting, tz-aware datetimes, type hint modernization).

Motivation

A real benchmark run (8 models, 4 quizzes, 9 metrics, 288 expected cells) produced only 279 results. One cell vanished due to a 503 queue timeout — _evaluate_question caught it, logged it, returned None, and the row silently disappeared. The upcoming research sweep (~63,500 calls) cannot tolerate silent data loss.

Configuration

Retry parameters are configurable per evaluator in YAML:

evaluators:
  logos_llama:
    provider: openai_compatible
    model: meta-llama/...
    retry_max_attempts: 5
    retry_base_delay: 60
    retry_max_delay: 300
Parameter Default Rationale
retry_max_attempts 4 1 initial + 3 retries
retry_base_delay 30s First wait ~30s, then ~60s, ~120s, capped at 5 min
retry_max_delay 300s 5 min cap prevents absurd waits

Test plan

  • test_transient_503_is_retried — 503 triggers retry, succeeds on second attempt
  • test_non_transient_400_not_retried — 400 propagates immediately, no sleep
  • test_transient_failure_reports_incompleteTransientLLMErrorcomplete: false
  • test_skipped_error_does_not_fail_completenessValueError → skip, complete: true
  • All 203 existing tests pass
  • ruff, black, mypy clean on changed files

🤖 Generated with Claude Code

MaximilianAnzinger and others added 2 commits August 25, 2026 02:10
Resolve all ruff, black, and mypy issues: add type annotation for
_call_with_retry, fix import sorting, modernize type hints in conftest,
add tz-aware datetime calls, and clean up pre-existing lint warnings
surfaced by the changed file set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@MaximilianAnzinger MaximilianAnzinger added this to the 2.0.0 milestone Aug 25, 2026
@MaximilianAnzinger
MaximilianAnzinger merged commit 8600458 into main Aug 25, 2026
5 checks passed
@MaximilianAnzinger
MaximilianAnzinger deleted the feature/retry-mechanism branch August 25, 2026 00:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant