How are you structuring system prompts in Claude Code / Cursor to force strict FHIR R4 JSON rather than conversational markdown?
· #agentic-workflows
We spent three weeks battling LLM hallucinations where Claude would return markdown wrappers around FHIR Bundles or drop required fields like meta.lastUpdated and subject.reference. Here is the exact two-tier prompt architecture that reached 99.4% schema compliance.
“Bundle.entry.resource of type transaction SHALL satisfy invariant bdl-3: every entry must have a fullUrl or resource, and Condition resources require verified SNOMED-CT clinical coding.”
// SYSTEM INSTRUCTION DIFF:
- "Please convert this clinical encounter note into a FHIR R4 JSON object."
+ "You are a deterministic clinical compiler.
+ Output ONLY a valid RFC 8259 JSON object conforming to HL7 FHIR R4 Resource 'Bundle'.
+ Schema constraints:
+ 1. Must include resourceType: 'Bundle', type: 'transaction'.
+ 2. Every Condition entry must contain verified SNOMED-CT code and subject.reference.
+ 3. Do NOT include markdown codeblocks (```json).
+ 4. Do NOT output conversational greetings, commentary, or trailers.
+ If clinical facts are insufficient, emit 'incomplete_clinical_context' in the issue array."This matches our findings exactly. The moment we stripped conversational prompt layers and used strict deterministic schema guards, hallucinated dosing dropped to zero.
We should extract this invariant boundary as a standardized KleranOS module. Other clinics will not need to rewrite the dosage validator from scratch.
The hardest lesson is that human lives cannot depend on temperature settings. Always reject downstream tool calls if pre-execution assertions fail.