The Agent Walks the Graph

One clinical fact is not a row — it’s a graph you have to traverse. FHIR references are pointers, never inlined data, so answering one question means fetching node after node, whole. Scroll and watch the walk: every single response fits the window. The conversation doesn’t. Nothing here autoplays and scroll is never captured — the scrubber in the figure replays any moment.

64% of benchmark questions overflow a 32k window · 53% of overflowing loops re-request a type they already had · 82 of 107 fit-but-wrong answers said “cannot find” measured in this benchmark

Illustrative patient journey · failure rates below are measured

Q: “What was this patient’s first abnormal HbA1c (≥ 6.5%)?”
Illustrative FHIR retrieval path that exceeds the context window A synthetic patient graph shows repeated retrieval and pagination accumulating context before the earliest value is reached. Observation.subject …page 12 Observation.encounter MedicationRequest.encounter medicationReference Encounter.diagnosis Patient pt-847a Observation ×100 · newest first HbA1c 6.8% 2124 · page 12 Encounter enc-3301 (+2) MedicationRequest ×34 Medication display not inlined Condition E11.9
0 tokens in context window: 32,000
agent call trace
  1. 1 GET Patient/pt-847a 1 resource +350
  2. 2 GET Observation?patient=pt-847a&category=laboratory&_count=100&_sort=-date 100 resources (page 1 of 12) +12,400
  3. 3 GET Encounter/enc-3301 (+2 more) 3 resources +1,900
  4. 4 GET MedicationRequest?patient=pt-847a 34 resources · displays not inlined +8,700
  5. 5 GET Observation?patient=pt-847a&category=laboratory&_count=100&page=2 100 resources — window exceeded mid-response +12,400
insufficiency_reason: "cannot find first abnormal HbA1c — earliest results not in retrieved data"
  1. 01

    One question, one graph

    A clinical fact is not a row — it’s a graph. The answer lives in an Observation, but FHIR references are pointers, never inlined data: the agent has to fetch every node it needs, whole. The context window is 32k tokens — the benchmark cap this record family overflows on 64% of questions.

  2. 02

    Fetch the labs

    The agent asks for lab Observations — newest first, 100 per page. The response fits comfortably. But the value the question needs is the earliest abnormal result, and newest-first puts it ~12 pages deep.

  3. 03

    Chase the references

    Meaning lives in the links. Each Observation points at an Encounter; the agent follows, and each fetched resource arrives fully serialized. Still fits. The gauge keeps climbing.

  4. 04

    The side quest

    Medications look relevant, so the agent pulls them too — 34 MedicationRequests. The drug names aren’t in them: they live behind medicationReference, in Medication resources that were never inlined. Another fetch would be needed for every name.

  5. 05

    The loop closes

    Needing older labs, the agent re-requests Observations — the same resource type it already holds. In the measured runs, 53% of overflowing conversations did exactly this. Every single response fit under the cap (max block: 24.8k). The conversation didn’t: 97 conversations overflowed by accumulation alone.

  6. 06

    The answer was on page 12

    The earliest abnormal HbA1c — 6.8% in 2124 — was never fetched. The agent answers honestly: “cannot find.” In the measured decomposition, 82 of 107 fit-but-wrong answers said exactly that. The record didn’t fail to exist; it failed to arrive.

What's real here (and what's illustrative)

The failure-mode statistics woven into the steps are measured: the overflow rate (262/409 questions at 32k), the multi-turn accumulation finding (97 residual overflows, none of them from a single over-budget payload; 53% re-requested a resource type already held), and the “cannot find” share (82 of 107 fit-but-wrong answers). The graph and its token costs are an illustrative synthetic patient shaped like the real ones — per-hop token counts use the codebase’s assumed per-resource defaults (its own words: rough defaults, not measured priors), scaled so the accumulation failure plays out exactly as the measured runs describe it.

The trap is structural, not a model quirk: newest-first pagination puts the earliest value — the one the question asks for — many pages deep, and reference-chasing burns the budget before the agent gets there. Widening the window doesn’t fix a record that is 1–2 orders of magnitude too big (see the Context Bomb); the lever that moved accuracy is deterministic, question-aware selection before the model reasons. See the benchmark →

The agent shouldn’t have to walk the graph at all.

Part two runs the same question through the same graph — and the agent lives: the data layer does the traversal, and the odometer barely moves.