RAG over FHIR Data on AWS HealthLake and Azure Health Data Services: Retrieval That Respects the Record

Retrieval-augmented generation (RAG) grew up on documents: split the text, embed the pieces, fetch the nearest ones, hand them to a model. Point that pipeline at a FHIR server and it runs without complaint. It will also, sooner or later, quote a lab value that was entered in error, miss an allergy because it ranked sixth, or return a result that belongs to a different patient with a similar history.

A FHIR record is not a document corpus. It is a graph of coded, dated, status-bearing resources, most of which have an exact answer that a search parameter can find better than an embedding can. This article sets out a retrieval design that respects that, shows it running against synthetic data, and maps it onto AWS HealthLake and the FHIR service in Azure Health Data Services as they stood on 21 July 2026.

⚠️
A REFERENCE PATTERN, NOT A CLINICAL SYSTEM

Everything here is illustrated with synthetic data and has not been clinically validated. A system that summarises or answers questions about patient records can influence care. It needs a clinical safety case, a hazard log, a named clinical safety officer and local governance before any clinician relies on it.

Why FHIR is not a document corpus

  • Most questions have one right answer. “What is the latest HbA1c?” is a query on Observation by LOINC code, sorted by date. Similarity search can only approximate what FHIR search returns exactly.
  • Status changes meaning. An observation marked entered-in-error, a condition whose verification status is refuted and a medication request that is stopped are all in the record. None of them is a current fact about the patient.
  • Raw JSON embeds badly. A serialised resource is mostly field names, system URLs and identifiers. Two observations of different analytes look more alike to an embedding model than an observation and the clinic note that discusses it.
  • The patient is a boundary, not a feature. In document search a slightly wrong result is a relevance problem. Here, a result from the wrong patient is a patient-safety incident and a data breach at once.
  • Some facts must always be present. Allergies and current medication matter to almost any clinical answer, and they are rarely the nearest neighbours of the question asked.

The design that follows from this has two retrieval paths behind a router, a pinned set of safety facts, and a hard partition by patient.

Diagram of a retrieval design for FHIR data: a clinician question passes through a router to structured FHIR search or semantic search within one patient, with pinned allergies and medication, then to a model that cites resources. AWS and Azure services for each step are listed.
The retrieval design used in this article, and the services that provide each step on AWS and Azure.

Render statements, do not embed JSON

The first step turns each resource into one short sentence a clinician would recognise, with the unit, the date and the status in the text, and the resource reference kept alongside as the citation. Records that are not facts are excluded with a reason. Resource types the renderer does not understand are reported, never silently dropped, because an invisible gap in a clinical summary is worse than a visible one.

"""fhir_statements.py - FHIR R4 resources to short clinical statements with provenance."""
import base64
from dataclasses import dataclass, field

# Records that must never reach a prompt as if they were facts about the patient.
EXCLUDED_STATUS = {"entered-in-error", "cancelled", "unknown"}
EXCLUDED_VERIFICATION = {"entered-in-error", "refuted"}


@dataclass(frozen=True)
class Statement:
    patient_id: str
    resource: str            # "Observation/obs-2": the citation
    kind: str                # resource type
    date: str                # clinically relevant date, ISO 8601, may be ""
    text: str
    codes: tuple[str, ...] = ()
    pinned: bool = False     # always sent to the model, never left to similarity search


@dataclass
class RenderReport:
    statements: list[Statement] = field(default_factory=list)
    excluded: list[tuple[str, str]] = field(default_factory=list)     # (resource, reason)
    unsupported: list[str] = field(default_factory=list)              # resource types with no renderer


def _codes(concept: dict | None) -> tuple[str, ...]:
    return tuple(f"{c.get('system', '')}|{c.get('code', '')}" for c in (concept or {}).get("coding", []))


def _label(concept: dict | None) -> str:
    concept = concept or {}
    if concept.get("text"):
        return concept["text"]
    return next((c["display"] for c in concept.get("coding", []) if c.get("display")), "unspecified")


def _first_code(concept: dict | None) -> str:
    return next((c.get("code", "") for c in (concept or {}).get("coding", [])), "")


def _patient_id(resource: dict) -> str:
    ref = (resource.get("subject") or resource.get("patient") or {}).get("reference", "")
    return ref.split("/")[-1]


def _condition(r: dict):
    verification = _first_code(r.get("verificationStatus"))
    if verification in EXCLUDED_VERIFICATION:
        return None, f"verificationStatus={verification}"
    clinical = _first_code(r.get("clinicalStatus")) or "status not recorded"
    date = r.get("onsetDateTime") or r.get("recordedDate", "")
    return (date, f"Condition ({clinical}): {_label(r.get('code'))}. Onset {date or 'not recorded'}.",
            _codes(r.get("code")), False), None


def _observation(r: dict):
    if r.get("status") in EXCLUDED_STATUS:
        return None, f"status={r.get('status')}"
    date = r.get("effectiveDateTime", "")
    q = r.get("valueQuantity")
    if q:
        value = f"{q.get('value')} {q.get('unit') or q.get('code') or '(unit not recorded)'}"
    else:
        value = r.get("valueString") or _label(r.get("valueCodeableConcept"))
    flag = _label(r["interpretation"][0]) if r.get("interpretation") else ""
    text = f"Observation on {date or 'unknown date'}: {_label(r.get('code'))} = {value}"
    return (date, text + (f" ({flag})." if flag else "."), _codes(r.get("code")), False), None


def _medication_request(r: dict):
    status = r.get("status", "unknown")
    if status in EXCLUDED_STATUS:
        return None, f"status={status}"
    date = r.get("authoredOn", "")
    dose = (r.get("dosageInstruction") or [{}])[0].get("text", "dose not recorded")
    text = f"Medication ({status}): {_label(r.get('medicationCodeableConcept'))}, {dose}. Prescribed {date or 'date not recorded'}."
    return (date, text, _codes(r.get("medicationCodeableConcept")), status == "active"), None


def _allergy(r: dict):
    verification = _first_code(r.get("verificationStatus"))
    if verification in EXCLUDED_VERIFICATION:
        return None, f"verificationStatus={verification}"
    reactions = ", ".join(_label(m) for rx in r.get("reaction", []) for m in rx.get("manifestation", [])) or "not recorded"
    text = (f"Allergy or intolerance ({r.get('criticality', 'criticality not recorded')}): "
            f"{_label(r.get('code'))}. Reaction: {reactions}.")
    return (r.get("recordedDate", ""), text, _codes(r.get("code")), True), None


RENDERERS = {"Condition": _condition, "Observation": _observation,
             "MedicationRequest": _medication_request, "AllergyIntolerance": _allergy}


def _document_chunks(r: dict, patient_id: str, max_chars: int = 600) -> list[Statement]:
    """Free-text notes are the one place where semantic search earns its keep."""
    if r.get("status") in EXCLUDED_STATUS or r.get("docStatus") == "entered-in-error":
        return []
    out = []
    for content in r.get("content", []):
        att = content.get("attachment", {})
        if not att.get("contentType", "").startswith("text/plain") or "data" not in att:
            continue
        note = base64.b64decode(att["data"]).decode("utf-8")
        paragraphs, buf = [p.strip() for p in note.split("\n\n") if p.strip()], ""
        for para in paragraphs + [""]:
            if buf and (not para or len(buf) + len(para) > max_chars):
                out.append(Statement(patient_id, f"DocumentReference/{r['id']}", "DocumentReference",
                                     r.get("date", ""), f"Note ({_label(r.get('type'))}, {r.get('date', '')[:10]}): {buf}"))
                buf = ""
            buf = f"{buf}\n{para}".strip()
    return out


def render_bundle(bundle: dict) -> RenderReport:
    report = RenderReport()
    for entry in bundle.get("entry", []):
        r = entry["resource"]
        kind, ref = r["resourceType"], f"{r['resourceType']}/{r.get('id', '?')}"
        if kind == "Patient":
            continue                                   # demographics are not embedded
        patient_id = _patient_id(r)
        if not patient_id:
            report.excluded.append((ref, "no patient reference"))
            continue
        if kind == "DocumentReference":
            chunks = _document_chunks(r, patient_id)
            report.statements.extend(chunks) if chunks else report.excluded.append((ref, "no usable text"))
            continue
        renderer = RENDERERS.get(kind)
        if renderer is None:
            report.unsupported.append(kind)            # reported, never silently dropped
            continue
        rendered, reason = renderer(r)
        if rendered is None:
            report.excluded.append((ref, reason))
            continue
        date, text, codes, pinned = rendered
        report.statements.append(Statement(patient_id, ref, kind, date, text, codes, pinned))
    return report

Three choices in that file are deliberate. Patient demographics are not rendered at all, which keeps names and addresses out of the vector store. A stopped medication is still rendered, labelled as stopped, because “was this patient ever on gliclazide” is a fair question, but only active medication is pinned. And the exclusion lists are short constants at the top of the file, where a clinical reviewer can read and challenge them.

Two retrieval paths and a pinned set

Retrieval then takes one of two routes. A question that names a coded concept and asks for the latest value goes to coded data and returns exactly one statement. Everything else goes to similarity search over that patient’s statements. On both routes the patient’s allergies and active medication are added from structured data, whatever the question was.

"""fhir_retrieval.py - patient-scoped retrieval: a structured path, a semantic path, pinned safety facts."""
import hashlib
import math
import re
from typing import Protocol
from urllib.parse import urlencode

from fhir_statements import Statement

LOINC = "http://loinc.org"
# Questions with one right answer go to coded data. Extend from your own terminology service.
CODED_CONCEPTS = {
    "hba1c": (LOINC, "4548-4"), "glycated haemoglobin": (LOINC, "4548-4"), "a1c": (LOINC, "4548-4"),
    "egfr": (LOINC, "62238-1"), "creatinine": (LOINC, "2160-0"), "potassium": (LOINC, "2823-3"),
}
LATEST = re.compile(r"\b(latest|last|most recent|current)\b", re.I)


class Embedder(Protocol):
    def embed(self, text: str) -> list[float]: ...


class HashingEmbedder:
    """Deterministic stand-in for tests. Production uses a real embedding model behind the same method."""

    def __init__(self, dims: int = 256) -> None:
        self.dims = dims

    def embed(self, text: str) -> list[float]:
        vec = [0.0] * self.dims
        for token in re.findall(r"[a-z0-9]+", text.lower()):
            vec[int(hashlib.sha256(token.encode()).hexdigest(), 16) % self.dims] += 1.0
        norm = math.sqrt(sum(v * v for v in vec)) or 1.0
        return [v / norm for v in vec]


class PatientIndex:
    """One partition per patient. The patient id selects the partition; it is never a similarity signal."""

    def __init__(self, embedder: Embedder) -> None:
        self._embedder = embedder
        self._partitions: dict[str, list[tuple[Statement, list[float]]]] = {}

    def add(self, statements: list[Statement]) -> None:
        for s in statements:
            self._partitions.setdefault(s.patient_id, []).append((s, self._embedder.embed(s.text)))

    def statements(self, patient_id: str) -> list[Statement]:
        return [s for s, _ in self._partitions.get(patient_id, [])]

    def search(self, patient_id: str, question: str, k: int = 5) -> list[Statement]:
        q = self._embedder.embed(question)
        scored = [(sum(a * b for a, b in zip(q, v)), s) for s, v in self._partitions.get(patient_id, [])]
        return [s for score, s in sorted(scored, key=lambda t: t[0], reverse=True)[:k] if score > 0]

    def purge(self, patient_id: str) -> int:
        """Erasure: remove every derived record when the source record is erased."""
        return len(self._partitions.pop(patient_id, []))


def coded_concept(question: str) -> tuple[str, str] | None:
    lowered = question.lower()
    return next((code for term, code in CODED_CONCEPTS.items() if term in lowered), None)


def fhir_search_url(base_url: str, patient_id: str, system: str, code: str, count: int = 1) -> str:
    """The same question asked of the FHIR server directly. Works on HealthLake and the Azure FHIR service."""
    query = urlencode({"patient": patient_id, "code": f"{system}|{code}", "_sort": "-date", "_count": count})
    return f"{base_url.rstrip('/')}/Observation?{query}"


def retrieve(index: PatientIndex, patient_id: str, question: str, k: int = 5) -> dict:
    """Returns pinned safety facts, plus either an exact coded answer or semantic matches."""
    everything = index.statements(patient_id)
    pinned = [s for s in everything if s.pinned]
    concept = coded_concept(question)
    if concept and LATEST.search(question):
        token = f"{concept[0]}|{concept[1]}"
        matches = sorted((s for s in everything if token in s.codes), key=lambda s: s.date, reverse=True)
        return {"route": "structured", "pinned": pinned, "evidence": matches[:1]}
    evidence = [s for s in index.search(patient_id, question, k) if not s.pinned]
    return {"route": "semantic", "pinned": pinned, "evidence": evidence}


def build_context(result: dict) -> str:
    def lines(items):
        return "\n".join(f"- {s.text} [{s.resource}]" for s in items) or "- none recorded"
    return ("Answer only from the record extracts below. Cite the bracketed resource for every statement. "
            "If the extracts do not contain the answer, say that the record does not show it.\n\n"
            f"ALWAYS CONSIDER (allergies and active medication):\n{lines(result['pinned'])}\n\n"
            f"EVIDENCE FOR THIS QUESTION:\n{lines(result['evidence'])}")

The router here is a keyword table, which is enough to show the principle and far too little for production. The realistic version gives the model one tool that runs FHIR searches, and fhir_search_url shows the shape of the call: the same question, asked of the FHIR server, for the freshest answer available. The in-memory index stands in for a vector store with a per-patient filter or index. The vector store comparison covers where that boundary sits in each AWS option.

%%{init: {'theme':'base','themeVariables':{'actorBkg':'#FFF3E0','actorBorder':'#FF9900','actorTextColor':'#232F3E','signalColor':'#0073BB','signalTextColor':'#0F172A','noteBkgColor':'#FFF8E7','noteBorderColor':'#FF9900','noteTextColor':'#232F3E','labelBoxBkgColor':'#FFF3E0','labelBoxBorderColor':'#FF9900','labelTextColor':'#232F3E','loopTextColor':'#232F3E','activationBkgColor':'#EBF8FF','activationBorderColor':'#0073BB','lineColor':'#232F3E','textColor':'#232F3E'}}}%%
sequenceDiagram
    participant U as Clinician app
    participant R as Retrieval service
    participant F as FHIR server
    participant V as Vector store
    U->>R: Question + SMART launch context
    R->>F: Allergies and active medication for patient
    F-->>R: Pinned facts
    alt Coded question
        R->>F: Observation search by code, newest first
        F-->>R: Newest matching result
    else Free-text question
        R->>V: Similarity search within the patient partition
        V-->>R: Note chunks with resource references
    end
    R-->>U: Extracts with citations, ready for the model

What the tests assert

The test builds a synthetic bundle for two patients. The second patient is designed to be a better match for the test questions than the first: a higher HbA1c on a later date, and a note that mentions dizziness three times.

PropertyHow it is testedResult
Corrected results are excludedAn HbA1c of 71.0 % marked entered-in-error on the latest dateReported as excluded with its reason. The latest value returned is 7.2 %
Refuted diagnoses are excludedA myocardial infarction with verification status refutedReported as excluded. It never appears in a context
Gaps are visibleAn Immunization resource with no rendererListed under unsupported types
Coded questions get exact answers“What is the latest HbA1c?”Structured route, one statement, Observation/o2
Patients never mixThe same questions, with a better-matching second patient in the indexOnly the first patient’s statements are returned on both routes
Safety facts are always present“Has the patient mentioned dizziness?”The penicillin allergy and active metformin are in the context
Stopped drugs are not shown as currentA stopped gliclazide prescriptionAbsent from the pinned section
Everything is citableEvery rendered statementEach carries a patient id and a resource reference
Erasure reaches derived dataPurge of one patientNo statements remain for that patient

The context built for the dizziness question, exactly as the test printed it:

Answer only from the record extracts below. Cite the bracketed resource for every statement. If the extracts do not contain the answer, say that the record does not show it.

ALWAYS CONSIDER (allergies and active medication):
- Medication (active): Metformin 500 mg tablets, one tablet twice daily. Prescribed 2024-02-01. [MedicationRequest/m1]
- Allergy or intolerance (high): Penicillin. Reaction: anaphylaxis. [AllergyIntolerance/a1]

EVIDENCE FOR THIS QUESTION:
- Note (Clinic note, 2026-06-02): Review of type 2 diabetes. Patient reports good adherence to metformin.
Foot examination normal. Reports occasional dizziness on standing in the mornings.
Plan: continue current treatment, repeat HbA1c in three months. [DocumentReference/d1]
💡
HOW THIS WAS CHECKED

Both modules ran on Python 3.13 with no dependencies, against hand-written synthetic FHIR R4 resources. The embedder in the test is a deterministic hashing function, so the test proves the partitioning, exclusion, routing and pinning logic. It says nothing about the retrieval quality of a real embedding model, and nothing here was run against HealthLake or the Azure FHIR service.

Table of five failure modes of retrieval over FHIR data, what the clinician would see, and the control for each: patient partitioning, excluding entered-in-error records, FHIR search for coded questions, pinning allergies and medication, and rendering statements.
The hazards the tests above are written to catch.

Mapping the design to HealthLake and Azure Health Data Services

Both services are managed FHIR R4 servers with SMART on FHIR authorization, and the design needs nothing that only one of them has.

StepAWS HealthLakeAzure Health Data Services FHIR service
Pinned facts and coded questionsFHIR search on AllergyIntolerance, MedicationRequest, ObservationThe same FHIR searches
One patient’s whole recordPatient/$everything, available since February 2024Patient/$everything, with _type, _since, start and end. No _count, and RelatedPerson is not returned
Initial load of the indexBulk $export to Amazon S3. Filters on meta.security and meta.tag since April 2026Bulk $export to Azure storage
Keeping the index currentFHIR Subscriptions, since October 2025FHIR events delivered through Event Grid
PHI in free textAmazon Comprehend Medical PHI detectionDe-identification service: tag, redact or surrogate, covering the 18 HIPAA identifiers
Embeddings and generationAmazon BedrockAzure OpenAI
Vector storeS3 Vectors, OpenSearch Serverless or Aurora pgvectorAzure AI Search
Caller identitySMART on FHIR, with v2 scopes since January 2025, or IAMSMART on FHIR, or Microsoft Entra ID role-based access
Erasure at source$erase for one resource and its versions, $purge for a patient compartment, since August 2025Hard delete of resources and their history
EU data residencyDublin (Ireland) Region available since June 2025Check regional availability for your workspace
ℹ️
AZURE API FOR FHIR IS BEING RETIRED

Microsoft lists 30 September 2026 as the end date for Azure API for FHIR, the older standalone service. If your FHIR data still lives there, the migration to the FHIR service in Azure Health Data Services comes before any retrieval project, and every endpoint and identity setting in your design will change with it.

HealthLake’s integrated medical NLP, which extracts entities from notes into FHIR resources, has been off by default since February 2023 and needs a support request to enable. Do not design on the assumption that notes arrive pre-coded.

Keeping the index in step with the record

A vector index of clinical data is a copy, and copies go stale. Three events must reach it, and the third is the one usually forgotten.

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#FFF3E0','primaryTextColor':'#232F3E','primaryBorderColor':'#FF9900','lineColor':'#232F3E','clusterBkg':'#F8FAFC','clusterBorder':'#CBD5E1','edgeLabelBackground':'#FFFFFF','nodeTextColor':'#232F3E'}}}%%
flowchart TD
    E[Change event from the FHIR server] --> T{What changed?}
    T -- "Created or updated" --> R[Re-render the resource]
    R --> S{Still a fact?}
    S -- "Yes" --> U[Replace its statements
in the patient partition] S -- "No: entered-in-error,
refuted, cancelled" --> D[Delete its statements] T -- "Deleted" --> D T -- "Patient erased" --> P[Purge the whole partition
and confirm it is empty] U --> A[Write an audit record] D --> A P --> A class E,T,S edge class R,U compute class D,P alert class A store classDef compute fill:#FFF3E0,stroke:#FF9900,stroke-width:2px,color:#232F3E classDef edge fill:#EBF8FF,stroke:#0073BB,stroke-width:2px,color:#004C74 classDef store fill:#F0FFF4,stroke:#1D8102,stroke-width:2px,color:#145202 classDef alert fill:#FEF2F2,stroke:#D13212,stroke-width:2px,color:#991B1B classDef mesh fill:#F3E8FF,stroke:#7C3AED,stroke-width:2px,color:#4C1D95
  • Updates replace, they do not append. Key statements by resource reference so that a corrected value overwrites the old one. Two versions of the same result in an index is how a superseded value gets quoted.
  • A status change can be a deletion. When a result is marked entered-in-error the resource still exists and an update event fires. The indexer must treat it as a removal.
  • Erasure must reach every copy. When a patient compartment is purged at source, the statements, embeddings, caches and any stored prompts or transcripts go too. Verify the partition is empty and record that you did.
  • Measure the lag. The time between a write to the FHIR server and its appearance in the index is a clinical safety parameter. Publish it, alarm on it, and send coded questions to the FHIR server directly so that the most safety-critical answers do not depend on it.

Identity, consent and audit

  • The patient comes from the launch context. With SMART on FHIR, the patient in scope is established when the clinician opens the record. The retrieval service takes it from the token, never from the wording of the question, where a typed name or a prompt injection could change it.
  • The user’s access applies to retrieval. If a clinician may not read a category of data in the record system, the assistant must not surface it. Use security labels on resources, filter on them at indexing and at query time, and remember that a shared vector index flattens whatever access model the source had unless you rebuild it.
  • Record what was shown. For each answer, log who asked, for which patient, which resources were retrieved and what the model returned. That log is how a clinician’s later question, “why did it say that”, gets answered. It is also special-category data in its own right.
  • De-identify where identity is not needed. For evaluation sets, analytics and model comparison, run notes through PHI detection first. Treat the output as lower risk, not as anonymous: automated de-identification misses things, and both vendors say so.

Running it in production

  • Build an evaluation set with clinicians. Real question types, expected source resources, and cases designed to fail: the corrected result, the stopped drug, the similar patient. Run it on every change to prompts, models, renderers or index settings.
  • Extend the renderers deliberately. Each new resource type needs a clinical decision about which statuses count as facts. Track the unsupported list from the report and show users what the assistant cannot see.
  • Normalise dates and units. The sample sorts ISO 8601 strings. Real records mix precisions and time zones, and the same analyte arrives in different units from different laboratories.
  • Keep the model’s instructions narrow. Answer from extracts, cite every statement, say when the record is silent. Then test that it does, because an instruction is a request and not a guarantee.
  • Watch cost at the vector store, not only the model. One partition per patient suits stores that bill by index size or support cheap per-key filtering. Size it with your patient count before choosing.
  • Keep a human in the decision. Present answers with their citations as a reading aid. Nothing the assistant produces should write back to the record or trigger an action without a clinician’s review.
⚖️
SPECIAL-CATEGORY DATA, AND POSSIBLY A REGULATED PRODUCT

Health data is special-category data under GDPR. Processing it this way calls for a data protection impact assessment, a lawful basis under Articles 6 and 9, data residency decisions for the FHIR store, the vector store and the model endpoint, and contractual assurance that prompts are not retained or used for training. Embeddings and prompt logs derived from the record carry the same obligations as the record. Depending on its intended purpose, software that informs clinical decisions may also be a medical device, and may be a high-risk system under the EU AI Act. Get a regulatory assessment early. It changes the evidence you need to collect from the first prototype onward.

Key takeaways

  • Use FHIR search for questions with an exact answer, and similarity search for free-text notes. Most clinical questions are the first kind.
  • Partition by patient and take the patient from the authenticated launch context. Never let the patient be a ranking signal.
  • Exclude records that are not facts: entered-in-error, refuted, cancelled. Report what was excluded and what could not be read.
  • Pin allergies and active medication into every context from structured data.
  • Treat the index as a copy with a measured lag, and make corrections and erasure reach it.

If you have taken a retrieval system over FHIR data through clinical safety review, I would like to hear which hazards your reviewers raised that are missing here. Leave a comment below.

📝
UPDATE, NOVEMBER 2026

Two days after this article’s date, on 23 July 2026, AWS announced previews of a HealthLake Data Transformation Agent for converting C-CDA and CSV data to FHIR, and of resource matching for duplicate records. Azure API for FHIR reached its 30 September 2026 end date. Neither changes the retrieval design described here. Check the current release notes of both services before starting.

Glossary

FHIR
Fast Healthcare Interoperability Resources. The HL7 standard for representing and exchanging health data as resources over a REST API.
Resource
One unit of FHIR data, such as an Observation, Condition or MedicationRequest.
Patient compartment
The set of resources that belong to one patient. Operations such as $everything return it.
LOINC
The coding system most widely used to identify laboratory tests and clinical observations.
SNOMED CT
A clinical terminology used to code diagnoses, findings and procedures.
Entered-in-error
A FHIR status marking a record that should never have existed. It remains stored for audit.
Verification status
On a Condition or AllergyIntolerance, whether it is confirmed, provisional, refuted or entered in error.
SMART on FHIR
An OAuth 2.0 profile for launching apps against a FHIR server with a user, scopes and a patient in context.
Bulk export ($export)
A FHIR operation that writes large sets of resources to storage asynchronously.
RAG
Retrieval-augmented generation. Fetching relevant extracts and giving them to a model so that answers are grounded in them.
Pinned context
Facts added to every prompt from structured data, independent of similarity ranking.
Provenance
The link from a statement in an answer back to the resource it came from.
De-identification
Removing or replacing identifiers in data. Automated methods reduce risk and do not guarantee anonymity.
Hazard log
The clinical safety record of identified hazards, their causes, controls and residual risk.

References & Further Reading


Discover more from C4: Container, Code, Cloud & Context

Subscribe to get the latest posts sent to your email.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.