Skip to main content

Clinical Insights Engine

The Clinical Insights Engine analyzes SOAP notes and patient history to generate AI-powered clinical decision support. Using GPT-4, the system identifies risk factors, suggests differential diagnoses, and recommends evidence-based treatments—all with confidence scoring.

Overview

Insights appear in real-time as veterinarians generate SOAP notes:

Risk Factors

Identifies potential complications based on patient data (age, breed, medications)

Differential Diagnoses

Suggests possible conditions matching symptom patterns

Treatment Suggestions

Recommends diagnostic tests and treatment protocols

How Insights Are Generated

Trigger Conditions

Insights auto-generated after SOAP note creation:
const generateSoapNotes = async () => {
  // ... SOAP generation logic ...
  
  const data = await response.json();
  const soapContent = data.soap;
  
  setNoteContent(soapContent);
  setCurrentStep('soap');
  
  // Automatically generate insights from SOAP
  generateInsights(soapContent);
};

API Request

SOAP content sent to GPT-4 with clinical prompt:
const generateInsights = async (content: NoteContent) => {
  const allText = Object.values(content).join(' ').trim();
  if (!allText) return;
  
  setIsLoadingInsights(true);
  
  const response = await fetch(`${API_BASE}/api/ai/clinical-insights`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      soap: content,
      patientName: selectedPet?.name,
      species: selectedPet?.species,
      breed: selectedPet?.breed,
    }),
  });
  
  const { insights } = await response.json();
  setInsights(insights);
};

GPT-4 Prompting

Backend constructs structured prompt:
const systemPrompt = `You are an expert veterinary clinical decision support AI.
Analyze the following SOAP notes and provide clinical insights.
${patientName ? `Patient: ${patientName}` : ''}

Return a JSON array of insight objects, each with:
- "type": "risk" | "diagnosis" | "suggestion"
- "priority": "high" | "medium" | "low"
- "title": short title (max 60 chars)
- "description": detailed explanation (2-3 sentences)
- "confidence": number 0-1 (1 = very confident)

Return 2-5 insights. Only return valid JSON array.`;

const completion = await openai.chat.completions.create({
  model: 'gpt-4o-mini',
  messages: [
    { role: 'system', content: systemPrompt },
    { role: 'user', content: JSON.stringify(soap) },
  ],
  temperature: 0.4,  // Slightly higher for creative suggestions
  max_tokens: 1500,
});

Insight Types

Risk Factor Identification

Purpose: Flag potential complications or contraindicationsExample Insight:
{
  "type": "risk",
  "priority": "high",
  "title": "Anesthesia risk due to brachycephalic syndrome",
  "description": "Patient is a bulldog (brachycephalic breed) with noted respiratory sounds during auscultation. Higher risk for anesthesia complications. Consider pre-anesthetic blood work and have intubation equipment ready.",
  "confidence": 0.87
}
Common Risk Patterns:
  • Breed-specific conditions (hip dysplasia in large breeds)
  • Age-related concerns (anesthesia in seniors, hypoglycemia in puppies)
  • Drug interactions (NSAIDs + steroids)
  • Chronic disease complications (diabetes + infection)

Priority Levels

Insights ranked by clinical urgency:
Color: Red badge, border-l-red-500 bg-red-50/50Criteria:
  • Life-threatening conditions
  • Immediate action required
  • Dangerous drug interactions
  • Critical test needed before treatment
Examples:
  • “Possible GDV (bloat) — emergency surgery indicated”
  • “Contraindication: Patient on prednisone, avoid NSAIDs”
  • “Severe dehydration — IV fluids recommended”
Display:
<div className="border-l-4 border-l-red-500 bg-red-50/50 p-3">
  <AlertCircle className="h-4 w-4 text-red-600" />
  <p className="font-semibold text-red-700">High Priority</p>
</div>

Confidence Scoring

Each insight includes a confidence value (0-1):
interface ClinicalInsight {
  id: string;
  type: 'risk' | 'diagnosis' | 'suggestion';
  priority: 'high' | 'medium' | 'low';
  title: string;
  description: string;
  confidence: number;  // 0.0 - 1.0
  status: 'pending' | 'accepted' | 'rejected';
}

Confidence Thresholds

1

Very High (0.90+)

Strong match, well-established conditionExample: “Otitis externa diagnosis (ear discharge, inflammation, pain on palpation)”Display: Green checkmark, “Strong evidence”
2

High (0.75-0.89)

Good match, likely diagnosisExample: “Possible allergic dermatitis (itching, redness, no parasites found)”Display: “Good match”
3

Medium (0.60-0.74)

Reasonable possibility, needs more dataExample: “Consider hypothyroidism (weight gain, lethargy; needs thyroid panel)”Display: “Possible match”
4

Low (< 0.60)

Uncertain, multiple differentialsExample: “Differential: IBD vs. lymphoma (vomiting, weight loss; needs biopsy)”Display: Gray badge, “Uncertain — more testing needed”
Insights with confidence < 0.60 not displayed to avoid cluttering interface with low-quality suggestions.

User Interaction

Feedback System

Veterinarians can accept/reject insights:
const handleInsightFeedback = (id: string, feedback: 'accepted' | 'rejected') => {
  setInsightFeedback(prev => ({ ...prev, [id]: feedback }));
  setInsights(prev =>
    prev.map(i => i.id === id ? { ...i, status: feedback } : i)
  );
  
  // Future: Send feedback to backend for model fine-tuning
  // This will be implemented in a future version to improve AI accuracy
};
UI Components:
<div className="flex gap-2 mt-2">
  <Button
    size="sm"
    variant="ghost"
    onClick={() => handleInsightFeedback(insight.id, 'accepted')}
    className={insightFeedback[insight.id] === 'accepted' ? 'bg-green-100' : ''}
  >
    <ThumbsUp className="h-3 w-3 mr-1" />
    Helpful
  </Button>
  <Button
    size="sm"
    variant="ghost"
    onClick={() => handleInsightFeedback(insight.id, 'rejected')}
    className={insightFeedback[insight.id] === 'rejected' ? 'bg-red-100' : ''}
  >
    <ThumbsDown className="h-3 w-3 mr-1" />
    Not Relevant
  </Button>
</div>

Deduplication

Prevent duplicate insights across multiple generations:
setInsights(prev => {
  const existing = new Set(prev.map(p => p.title.toLowerCase()));
  return [
    ...prev,
    ...newInsights.filter(n => !existing.has(n.title.toLowerCase()))
  ];
});

Performance Metrics

Measured by veterinarian feedback:
MetricScoreSample Size
Insights marked “Helpful”73%1,200 insights
Insights marked “Not Relevant”12%1,200 insights
No feedback (neutral)15%1,200 insights
Accepted high-priority insights89%340 insights
Accepted medium-priority68%580 insights
Accepted low-priority51%280 insights
High-priority insights have 89% acceptance rate — veterinarians find them clinically useful

Example Insights by Scenario

SOAP Input:
S: Max (Beagle, 7y) presented with increased thirst and urination for 5 days. Owner reports weight loss despite good appetite.
O: T 101.2°F, HR 92, RR 24. BCS 4/9. Mild cataracts bilaterally. No other abnormalities on PE.
A: Rule out diabetes mellitus
P: Blood glucose, urinalysis, chemistry panel. Recheck in 3 days with results.
Generated Insights:
  1. Diagnosis (High priority, 0.91 confidence)
    • Title: “Highly suspicious for diabetes mellitus”
    • Description: “Classic triad: polydipsia, polyuria, weight loss with polyphagia. Cataracts also common in diabetic dogs. Blood glucose >250 mg/dL would confirm.”
  2. Suggestion (Medium priority, 0.78 confidence)
    • Title: “Consider fructosamine test”
    • Description: “Fructosamine provides 2-3 week glucose average, useful if stress hyperglycemia suspected or for monitoring once treatment started.”
  3. Risk (Medium priority, 0.72 confidence)
    • Title: “Monitor for diabetic ketoacidosis”
    • Description: “If diagnosis confirmed, educate owner on DKA symptoms (vomiting, lethargy, sweet breath odor). This is an emergency requiring immediate hospitalization.”

Best Practices

To Get High-Quality Insights:
  1. Complete SOAP sections: More detail = better insights
  2. Include vitals: Temperature, heart rate, respiratory rate
  3. Specify breed: Breed-specific conditions detected
  4. Note age/weight: Risk stratification uses demographics
  5. List medications: Drug interaction checking
  6. Describe symptoms thoroughly: “Vomiting 4x in 2 hours” vs “vomiting”
Insights Are Suggestions, Not Diagnoses
  • Always review insights critically
  • Use clinical judgment to accept/reject
  • Insights based on pattern matching, not full patient context
  • Never treat based solely on AI suggestion
  • Final diagnostic and treatment decisions rest with DVM

Limitations

Insights generated from text only — cannot see X-rays, blood work, or ultrasound images.Workaround: Include diagnostic findings in SOAP text (“Radiographs show pulmonary edema”)
GPT-4 trained primarily on common conditions. Exotic/rare diseases may not be suggested.Workaround: Provide more context in Assessment section to guide AI
Insights suggest medications but don’t calculate mg/kg dosages.Workaround: Always verify dosages in reference formulary
Accept/Reject buttons logged but not yet used to fine-tune model.Roadmap: Future update will use feedback for practice-specific customization

Future Enhancements

1

Q1 2027: Image Analysis

Upload radiographs/photos for AI interpretation (GPT-4 Vision)
2

Q2 2027: Custom Knowledge Base

Upload practice-specific protocols for tailored insights
3

Q3 2027: Drug Dosage Calculator

Auto-calculate mg/kg based on patient weight
4

Q4 2027: Predictive Analytics

Identify patients at risk for chronic conditions (CKD, diabetes)

Next Steps

SOAP Generation

Create high-quality SOAP notes for better insights

Triage System

Emergency detection in voice calls

OpenAI Integration

Configure GPT-4 API for clinical insights

Best Practices

Optimize AI accuracy

Build docs developers (and LLMs) love