Skip to content
Learn Agentic AI12 min read0 views

Building a Veterinary Practice Agent: Pet Health Inquiries and Appointment Scheduling

Build an AI agent for veterinary practices that handles pet health inquiries, manages vaccination reminders, performs emergency triage, and schedules appointments — while keeping pet owner communication warm and reassuring.

Why Veterinary Practices Need AI Agents

Veterinary clinics face a unique challenge: their clients are emotionally invested pet owners who call with everything from "my dog ate chocolate" (potentially urgent) to "when is Bella's next vaccine due?" (routine lookup). Front desk staff juggle these calls while checking in patients, processing payments, and calming anxious pet parents in the waiting room. An AI agent can triage incoming inquiries, answer routine questions from pet records, and schedule appointments — freeing the vet team to practice medicine.

Pet Record Data Model

Veterinary agents need access to pet and owner records to provide personalized responses. The data model captures the essential information a front desk would reference.

from dataclasses import dataclass, field
from datetime import datetime, date, timedelta
from enum import Enum
from typing import Optional


class Species(Enum):
    DOG = "dog"
    CAT = "cat"
    BIRD = "bird"
    RABBIT = "rabbit"
    OTHER = "other"


@dataclass
class Vaccination:
    name: str
    date_given: date
    next_due: date
    batch_number: str = ""


@dataclass
class PetRecord:
    id: str
    name: str
    species: Species
    breed: str
    age_years: float
    weight_kg: float
    owner_name: str
    owner_phone: str
    vaccinations: list[Vaccination] = field(default_factory=list)
    allergies: list[str] = field(default_factory=list)
    medications: list[str] = field(default_factory=list)
    notes: str = ""


@dataclass
class VetAppointment:
    pet_id: str
    reason: str
    vet_name: str
    date_time: datetime
    duration_minutes: int = 30
    is_emergency: bool = False

Emergency Triage System

Veterinary emergencies range from "ate something toxic" to "difficulty breathing." The triage system must quickly distinguish between situations that need immediate care, same-day appointments, and issues that can wait.

class VetTriageEngine:
    EMERGENCY_SYMPTOMS = [
        "not breathing", "difficulty breathing", "seizure",
        "unconscious", "hit by car", "heavy bleeding",
        "bloated stomach", "collapsed", "poisoned",
        "ate chocolate", "ate rat poison", "ate antifreeze",
        "choking", "cannot walk", "eye injury",
    ]

    URGENT_SYMPTOMS = [
        "vomiting blood", "not eating", "diarrhea",
        "limping", "swollen", "lethargic", "crying in pain",
        "blood in urine", "coughing", "excessive drooling",
    ]

    def triage(self, symptoms: str, species: str = "dog") -> dict:
        symptoms_lower = symptoms.lower()

        for emergency in self.EMERGENCY_SYMPTOMS:
            if emergency in symptoms_lower:
                return {
                    "level": "EMERGENCY",
                    "action": "Come in immediately or go to the nearest emergency vet.",
                    "advice": self._get_first_aid(emergency, species),
                    "call_vet": True,
                }

        for urgent in self.URGENT_SYMPTOMS:
            if urgent in symptoms_lower:
                return {
                    "level": "URGENT",
                    "action": "Schedule a same-day appointment.",
                    "advice": f"Monitor your {species} closely. If symptoms worsen, come in immediately.",
                    "call_vet": False,
                }

        return {
            "level": "ROUTINE",
            "action": "Schedule an appointment within the next few days.",
            "advice": "This does not appear to be an emergency, but a vet visit is recommended.",
            "call_vet": False,
        }

    def _get_first_aid(self, symptom: str, species: str) -> str:
        first_aid = {
            "ate chocolate": (
                f"Do NOT induce vomiting unless instructed by a vet. "
                f"Note the type of chocolate and how much your {species} ate."
            ),
            "choking": (
                f"Check your {species}'s mouth for visible obstructions. "
                f"Do not reach in blindly. Head to the clinic immediately."
            ),
            "heavy bleeding": (
                f"Apply gentle pressure with a clean cloth. "
                f"Keep your {species} calm and bring them in immediately."
            ),
            "seizure": (
                f"Do not restrain your {species}. Clear the area of objects "
                f"that could cause injury. Time the seizure. Come in immediately."
            ),
        }
        return first_aid.get(symptom, f"Keep your {species} calm and comfortable. Head to the clinic.")

Vaccination Reminder System

Pet owners frequently call to ask when their pet's next vaccine is due. The agent can look this up instantly from the pet record.

See AI Voice Agents Handle Real Calls

Book a free demo or calculate how much you can save with AI voice automation.

def check_vaccination_status(pet: PetRecord) -> list[dict]:
    """Check which vaccinations are due or overdue."""
    today = date.today()
    results = []
    for vax in pet.vaccinations:
        days_until_due = (vax.next_due - today).days
        if days_until_due < 0:
            results.append({
                "vaccine": vax.name,
                "status": "OVERDUE",
                "due_date": vax.next_due.isoformat(),
                "days_overdue": abs(days_until_due),
                "message": f"{vax.name} is {abs(days_until_due)} days overdue. Please schedule soon.",
            })
        elif days_until_due <= 30:
            results.append({
                "vaccine": vax.name,
                "status": "DUE_SOON",
                "due_date": vax.next_due.isoformat(),
                "days_until_due": days_until_due,
                "message": f"{vax.name} is due in {days_until_due} days.",
            })
        else:
            results.append({
                "vaccine": vax.name,
                "status": "UP_TO_DATE",
                "due_date": vax.next_due.isoformat(),
                "message": f"{vax.name} is current. Next due {vax.next_due.isoformat()}.",
            })
    return results

Agent Tools and Assembly

from agents import Agent, Runner, function_tool

triage_engine = VetTriageEngine()

# Sample pet records (in production these come from your practice management system)
PET_DB = {
    "bella-johnson": PetRecord(
        "p1", "Bella", Species.DOG, "Golden Retriever", 4.0, 30.0,
        "Sarah Johnson", "555-0101",
        vaccinations=[
            Vaccination("Rabies", date(2025, 6, 15), date(2026, 6, 15), "RB-2025-001"),
            Vaccination("DHPP", date(2025, 9, 1), date(2026, 3, 1), "DH-2025-042"),
        ],
        allergies=["chicken"],
    ),
}


@function_tool
def lookup_pet(owner_name: str, pet_name: str) -> str:
    """Look up a pet record by owner name and pet name."""
    key = f"{pet_name.lower()}-{owner_name.lower().split()[-1]}"
    pet = PET_DB.get(key)
    if not pet:
        return f"No record found for {pet_name} owned by {owner_name}."
    vax_status = check_vaccination_status(pet)
    vax_summary = "\n".join(f"  - {v['message']}" for v in vax_status)
    allergies = ", ".join(pet.allergies) if pet.allergies else "None recorded"
    meds = ", ".join(pet.medications) if pet.medications else "None"
    return (
        f"Pet: {pet.name} ({pet.breed}, {pet.age_years} years, {pet.weight_kg} kg)\n"
        f"Owner: {pet.owner_name} ({pet.owner_phone})\n"
        f"Allergies: {allergies}\n"
        f"Current medications: {meds}\n"
        f"Vaccination status:\n{vax_summary}"
    )


@function_tool
def triage_symptoms(symptoms: str, species: str = "dog") -> str:
    """Triage pet symptoms to determine urgency level."""
    result = triage_engine.triage(symptoms, species)
    return (
        f"Triage level: {result['level']}\n"
        f"Action: {result['action']}\n"
        f"Advice: {result['advice']}"
    )


@function_tool
def schedule_vet_appointment(
    pet_name: str, owner_name: str, reason: str,
    preferred_date: str, is_emergency: bool = False
) -> str:
    """Schedule a veterinary appointment."""
    appt_type = "EMERGENCY" if is_emergency else "Regular"
    return (
        f"{appt_type} appointment scheduled for {pet_name} ({owner_name})\n"
        f"Reason: {reason}\nDate: {preferred_date}\n"
        f"Please bring any recent test results and your pet's current medications."
    )


vet_agent = Agent(
    name="Vet Practice Assistant",
    instructions="""You are a warm, reassuring veterinary practice assistant.

1. When an owner calls about symptoms, use triage_symptoms first.
   For EMERGENCY results, give the first aid advice immediately
   and tell them to come in right away.
2. For routine inquiries, use lookup_pet to check their pet's record,
   vaccination status, and allergies.
3. When scheduling, use schedule_vet_appointment and remind owners
   to bring medications and recent test results.
4. Always use the pet's name in conversation — owners appreciate this.
5. Never diagnose conditions. Use phrases like "that should be
   evaluated by the doctor" instead of making medical claims.
6. For medication refill requests, confirm the medication from the
   pet record and schedule a pharmacy pickup.""",
    tools=[lookup_pet, triage_symptoms, schedule_vet_appointment],
)

FAQ

How does the agent handle after-hours emergency calls?

Configure the agent with your local emergency vet hospital's contact information. When triage returns EMERGENCY outside business hours, the agent provides first aid advice and directs the owner to the nearest 24-hour emergency vet clinic, including the address and phone number.

Can the agent send automated vaccination reminders proactively?

Yes. Run a daily batch job that queries all pet records, identifies vaccinations due within 30 days, and sends SMS or email reminders to the owners. The agent handles inbound inquiries while the batch job handles outbound reminders — they share the same pet database but operate independently.

How do I prevent the agent from giving medical advice?

The agent instructions explicitly state "never diagnose conditions." Reinforce this with output guardrails that scan agent responses for diagnostic language patterns (like "your pet has..." or "this is likely...") and replace them with referral language. Test with adversarial prompts where the caller pushes for a diagnosis to verify the guardrail holds.


#VeterinaryAI #PetHealth #EmergencyTriage #AppointmentScheduling #Python #AgenticAI #LearnAI #AIEngineering

Share this article
C

CallSphere Team

Expert insights on AI voice agents and customer communication automation.

Try CallSphere AI Voice Agents

See how AI voice agents work for your industry. Live demo available -- no signup required.