By Chason ArthurRevision 157.024Published Updated

Python / FastAPI / AI evaluation

Build the safeguards.

Follow Python Evidence Evaluation Lab from its visible failure to a testable implementation. Each step names one decision and a checkpoint.

  1. Define the answer’s permitted job
  2. Keep retrieval separate from generation
  3. Reject an invalid output shape
  4. Check authority, version and the actual claim
  5. Treat document instructions as data
  6. Bound concurrency and queue wait
  7. Evaluate decisions, including abstention
  8. Move the same engine behind FastAPI

Step 1 of 8

Define the answer’s permitted job

This exercise answers a narrow fictional return-policy question. It is not a general assistant. Its output contract contains text, citation IDs and an integer return period. Defining the job makes it possible to describe a useful abstention and write expected decisions.

{"text":"…","citations":["returns-v2"],"return_days":14}

Checkpoint: Identify which fields can be validated structurally and which require source evidence.

Step 2 of 8

Keep retrieval separate from generation

A simple token-overlap retriever ranks the invented documents. The candidate answers are recorded fixtures, so the same inputs can be tested repeatedly without a provider. Retrieval relevance, source authority and answer support are different questions; none is guaranteed by the others.

docs = retrieve(question, DOCUMENTS)

Checkpoint: Find a retrieved source that is related but inactive.

Step 3 of 8

Reject an invalid output shape

The validator requires an exact set of fields, a nonempty list of citation strings and a true integer period. Python booleans are a special case because bool subclasses int; the example uses an exact type check. A valid schema is a useful boundary, but it cannot establish a true claim.

type(answer["return_days"]) is int

Checkpoint: Explain why a perfectly shaped answer can still be wrong.

Step 4 of 8

Check authority, version and the actual claim

The active policy allows 14 days; the superseded policy allowed 30. A citation must identify an active relevant record, and the structured claim must match it. The text check is deliberately exact. General natural-language support would require a broader design and separately evaluated failure modes.

allowed = {d["id"]: d for d in docs if d.get("active") and "days" in d}

Checkpoint: Inspect why the stale 30-day answer is rejected.

Step 5 of 8

Treat document instructions as data

The hostile fixture tells the assistant to reveal an admin token, but it is not a trusted application instruction. The candidate is rejected because it lacks an authoritative return-policy source. This does not exercise a real model’s susceptibility; a live adversarial evaluation is a separate experiment.

# No document text is executed or promoted to application policy.

Checkpoint: Distinguish the fixture rejection from a claim that all prompt injection has been solved.

Step 6 of 8

Bound concurrency and queue wait

The safe workflow admits two active tasks through a semaphore. Each task’s timeout surrounds both acquisition and work, so queued tasks cannot wait indefinitely before their clock starts. TaskGroup waits for child completion or cancellation before the result is returned.

async with asyncio.timeout(.04):
    async with sem:
        await work()

Checkpoint: Run slow mode and check peak active tasks and deadline exits.

Step 7 of 8

Evaluate decisions, including abstention

Each of the five fixtures declares whether acceptance is expected. The result table shows actual and expected decisions with reasons. A five-case perfect score means those regression cases passed; it is not a representative accuracy, safety or business-impact measurement.

correct += int(actual_accept == expected_accept)

Checkpoint: Add a deliberately wrong accepted answer and watch the score change.

Step 8 of 8

Move the same engine behind FastAPI

The local adapter uses Pydantic allowlists, a bounded run gate and a total deadline. It binds only to loopback and makes no model calls. A future provider adapter needs its own authentication, usage accounting, cancellation behavior and evaluation record before any live-performance claims.

class Experiment(BaseModel):
    preset: Literal["evidence","injection","slow"]
    variant: Literal["broken","safe"]

Checkpoint: Call the local endpoint with an unknown preset and verify that input validation rejects it.

Practice the interview explanation

  1. Does a citation establish that the source supports the claim?
  2. What is the scope of the validator, and how would you measure what it misses?
  3. Does the deadline include queue time, and what happens to canceled child work?

Use the experiment as an example. State the failure, explain the chosen boundary, show the test and name the tradeoff. Keep measured results separate from production assumptions.

Read the primary documentation

Ascertain describes Python/FastAPI engineering for its healthcare AI platform; this evaluation curriculum is a proposed extension of that work.

Related role from the job review

Choose your next step

Build the safeguards

Eight explained steps, a source example and a checkpoint at each decision.

Read the tutorial

Compare the alternatives

Understand where each pattern helps and which tradeoffs remain.

Compare approaches

Run and extend it locally

Download the independent environment, run the native checks and try a specific extension.

Open the how-to guide