Build the safeguards
Eight explained steps, a source example and a checkpoint at each decision.
Read the tutorialPython / FastAPI / AI evaluation
Choose a pattern by the failure it addresses. Several safeguards can be necessary at once.
| Approach | Useful when | Decision or limitation |
|---|---|---|
| Prompt instructions | Describe desired model behavior | Do not enforce a schema or guarantee source support |
| Structured-output validation | Enforce shape and field constraints | A well-formed claim can still be false |
| Citation validation | Check source identity and applicability | Citation presence alone does not establish entailment |
| Narrow deterministic policy check | Validate a bounded structured domain | Does not generalize to arbitrary prose |
| Regression fixtures | Reproduce known failures cheaply | Do not estimate performance on a representative population |
| Live provider evaluation | Measure actual model behavior and usage | Needs controlled cases, recorded configuration and measured cost |
| Environment | What you can do | Scope |
|---|---|---|
| This browser lab | Click, compare, reset and inspect exact source | Actual Python runs in the open-source Pyodide runtime. Candidate answers and documents are deterministic fixtures; no live model is called. The exact policy validator is intentionally narrow and does not establish general factual accuracy or comprehensive prompt-injection resistance. |
| Independent download | Run the same prebuilt lab with Python’s local server | No package installation or automatic external calls needed for the prebuilt preview |
| Native exercise | Run language tests and the included local adapter or script | Requires the documented local toolchain; does not provision a cloud service |
The safeguarded evidence run matches all five expected fixture decisions. The slow run limits active tasks to two and cancels all five before returning. Active-at-finish is zero. These labels are regression cases, not an accuracy estimate.
Begin with an observable outcome, inspect the decisions that produced it, then test a repair. The companion tutorial explains the mechanism; the how-to guide takes the same source into an independent environment.
Ascertain describes Python/FastAPI engineering for its healthcare AI platform; this evaluation curriculum is a proposed extension of that work.
Eight explained steps, a source example and a checkpoint at each decision.
Read the tutorialUnderstand where each pattern helps and which tradeoffs remain.
Compare approachesDownload the independent environment, run the native checks and try a specific extension.
Open the how-to guideLab discussion / Python Evidence Evaluation Lab
Ask about the code, compare an approach, or describe an edge case. Reader comments are reviewed before publication.
Code walkthrough
These short excerpts connect the lab’s behavior to its implementation. Each example links to the full tutorial step for its context, tradeoffs and checkpoint. Names and dependencies belong to that source; the excerpts are not standalone programs.
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)
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
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}
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()
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"]