Clinical, Literature, Safety, and Critic agents in detail
ClinicalPilot uses four specialized agents that work together through multi-round debate. Each agent has a distinct role, model configuration, and output schema.
Purpose: Search medical literature for evidence to support/refute clinical claimsModel: GPT-4o-mini (faster, cheaper for search tasks)Source: backend/agents/literature.py:20
# backend/agents/literature.py:76-121async def _search_pubmed( patient: PatientContext, clinical_output: ClinicalAgentOutput | None,) -> str: from backend.external.pubmed import search_pubmed # Build queries from top differentials queries = [] if clinical_output and clinical_output.differentials: for d in clinical_output.differentials[:3]: queries.append(d.diagnosis) # Also search primary condition if patient.conditions: queries.extend(c.display for c in patient.conditions[:2]) if not queries: queries = [patient.current_prompt[:100]] results = [] # Run all PubMed searches in PARALLEL tasks = [search_pubmed(q, max_results=3) for q in queries[:3]] all_hits = await asyncio.gather(*tasks, return_exceptions=True) for hits in all_hits: if isinstance(hits, list): results.extend(hits) # Format results formatted = [] for r in results[:8]: # Max 8 results formatted.append( f"- [{r.get('title', 'No title')}] " f"({r.get('journal', '')}, {r.get('year', '')}). " f"PMID: {r.get('pmid', 'N/A')}. " f"{r.get('abstract', '')[:200]}..." ) return "\n".join(formatted)
Optimization: PubMed searches run 3 queries in parallel via asyncio.gather, reducing latency from ~9s to ~3s.
# backend/agents/safety.py:65-94async def _get_external_safety_data(patient: PatientContext) -> str: if not patient.medications: return "" results = [] drug_names = [m.name for m in patient.medications] # Query FDA and DrugBank in PARALLEL try: from backend.external.fda import check_drug_interactions from backend.external.drugbank import lookup_interactions fda_results, db_results = await asyncio.gather( check_drug_interactions(drug_names), lookup_interactions(drug_names), return_exceptions=True, ) if isinstance(fda_results, str) and fda_results: results.append(f"FDA Data:\n{fda_results}") if isinstance(db_results, str) and db_results: results.append(f"DrugBank Data:\n{db_results}") except Exception as e: logger.debug(f"External lookup failed: {e}") return "\n\n".join(results)
# backend/agents/critic.py:22-85async def run_critic_agent( patient: PatientContext, clinical: ClinicalAgentOutput, literature: LiteratureAgentOutput, safety: SafetyAgentOutput,) -> CriticOutput: system_prompt = load_prompt("critic_system.txt") # Format all agent outputs for review ddx_text = "\n".join( f" {i+1}. {d.diagnosis} ({d.likelihood}, {d.confidence.value} confidence): {d.reasoning}" for i, d in enumerate(clinical.differentials) ) evidence_text = "\n".join( f" - {e.title} ({e.journal}, {e.year}): {e.snippet}" for e in literature.evidence[:5] ) safety_text = "\n".join( f" - [{f.severity.upper()}] {f.description} → {f.recommendation}" for f in safety.flags ) user_message = f"""## Original Patient Context{patient.to_clinical_summary()}## Clinical Agent OutputDifferentials:{ddx_text or " (none provided)"}Risk Scores: {clinical.risk_scores or "None calculated"}SOAP Draft:{clinical.soap_draft or "(none)"}## Literature Agent OutputEvidence:{evidence_text or " (no evidence found)"}Summary: {literature.summary}Contradictions: {literature.contradictions or "None"}## Safety Agent OutputFlags:{safety_text or " (no flags)"}Medication Review: {safety.medication_review}""" result = await llm_call( system_prompt=system_prompt, user_message=user_message, json_mode=True, ) return _parse_output(result["content"])
You are a clinical QA reviewer. Your job is to critically evaluate outputs fromthree agents (Clinical, Literature, Safety) and determine if they form a coherent,evidence-backed, safe clinical assessment.Check for:1. EHR Contradictions - Does the DDx conflict with patient data?2. Evidence Gaps - Are clinical claims unsupported by literature?3. Safety Misses - Were all drug interactions caught?4. Logical Coherence - Do the agents agree?Set consensus_reached = true ONLY if:- No EHR contradictions- No major evidence gaps- No missed safety issues- No significant dissent between agentsIf consensus is NOT reached, provide specific, actionable feedback for each agent.
{ "ehr_contradictions": [ "DDx includes 'CKD' but patient creatinine is normal (0.9 mg/dL, eGFR >60)" ], "evidence_gaps": [ "Claim that 'orthostatic hypotension is common in elderly' lacks citation" ], "safety_misses": [ "Lisinopril + Potassium interaction not flagged by Safety Agent" ], "overall_assessment": "Strong clinical reasoning but needs better lab integration. Safety review incomplete.", "consensus_reached": false, "dissent_log": [ "Clinical agent suggests CKD but labs contradict", "Safety agent did not check all medication pairs" ]}