Skip to main content
Foundation6–10 hours

Resilient AI API Client

Build a production-ready LLM API client with structured output, validation, retries, timeouts, idempotency, tracing, and tests.

Python typingasync IOPydanticretriesobservabilitytesting

Scenario

Task

An internal service must call an LLM to classify support requests. Responses must be structured, repeated requests must be safe, and failures must be measurable and reproducible.

Step-by-step execution

1. Define the contract

Outcome: Requests and responses have a stable typed shape.

Tasks

  • Define the input model
  • Create the output schema
  • Define validation errors
  • Add a correlation ID

Checks

  • Invalid responses never pass silently
  • The schema has unit tests

2. Implement the transport layer

Outcome: The client controls network behavior explicitly.

Tasks

  • Add an async request path
  • Set connect and read timeouts
  • Handle 429 and 5xx responses
  • Add exponential backoff with jitter

Checks

  • Retries are bounded
  • The retry policy does not repeat non-retryable errors

3. Add observability

Outcome: Every call can be explained after execution.

Tasks

  • Log the request ID
  • Measure latency
  • Record token usage and retry count
  • Do not log secrets or PII

Checks

  • A single request can be traced end to end
  • Sensitive data never reaches logs

4. Build tests and failure simulation

Outcome: Known failure modes can be reproduced locally.

Tasks

  • Mock a timeout
  • Mock a 429 response
  • Return malformed JSON
  • Test a duplicate request

Checks

  • Every failure path has assertions
  • A repeated idempotent request does not create a duplicate

Acceptance criteria

  • Types pass validation
  • All tests are green
  • Retries are bounded
  • Invalid structured output returns an explicit error
  • A latency/retry/cost report exists

Assessment rubric

How the result is assessed

Passing score: 70/100 · Distinction: 90/100

Contracts and validation

Requests, responses, and errors have an explicit typed shape.

25 points

Insufficient

The schema is incomplete or errors are swallowed.

Competent

Core contracts are typed and tested.

Strong

Contracts are versioned, and failure modes have dedicated types and tests.

Evidence required

  • ✓ Link to code or artifact
  • ✓ Short README explaining decisions
  • ✓ Test output or runtime evidence
  • ✓ Examples of valid and invalid responses

Transport-layer reliability

Timeouts, retries, backoff, rate limits, and idempotency are implemented with safe bounds.

30 points

Insufficient

Retries are unbounded or retryable and non-retryable errors are mixed.

Competent

Retry and timeout policies are bounded and tested.

Strong

Jitter, a circuit breaker, or multi-model fallback is demonstrated with evidence.

Evidence required

  • ✓ Link to code or artifact
  • ✓ Short README explaining decisions
  • ✓ Test output or runtime evidence
  • ✓ Failure simulation for timeout, 429, and 5xx

Observability

Every call is explainable through request ID, latency, retries, usage, and safe logs.

20 points

Insufficient

There is no end-to-end correlation or sensitive data appears in logs.

Competent

Request ID, latency, usage, and redaction are implemented.

Strong

Distributed traces, dashboards, or alert thresholds are implemented.

Evidence required

  • ✓ Link to code or artifact
  • ✓ Short README explaining decisions
  • ✓ Test output or runtime evidence
  • ✓ Example trace or structured log

Testing and reproducibility

Success and failure paths can be reproduced automatically.

25 points

Insufficient

Only the happy path is tested.

Competent

Unit and integration tests cover the main failure modes.

Strong

Concurrency/load tests and stable regression fixtures are included.

Evidence required

  • ✓ Link to code or artifact
  • ✓ Short README explaining decisions
  • ✓ Test output or runtime evidence
  • ✓ Test matrix for key scenarios