DEV Community

Beck_Moulton
Beck_Moulton

Posted on

From Heartbeat to Hospital: Building a Closed-Loop Health Agent with LangGraph

We live in an era where our watches know more about our hearts than we do. But there’s a massive gap between receiving a "High Heart Rate" notification and actually sitting in a doctor's office. Most health apps just give you data; they don't give you a solution. Today, we are bridging that gap by building a closed-loop health assistant using LangGraph, LangChain, and the HealthKit API.

By leveraging AI Agents and advanced LLM healthcare automation, we can create a system that doesn't just monitor—it acts. We’ll be using a LangGraph state machine to orchestrate a complex workflow: detecting anomalies, verifying symptoms with the user, and automatically interacting with hospital booking APIs. 🏥💻

The Architecture: A State-Driven Health Journey

Unlike simple linear chains, health interventions require loops and state persistence. If a user is feeling fine despite a high heart rate, we might just log it. If they feel dizzy, we book an appointment.

Here is how the data flows through our LangGraph agent:

graph TD
    A[Start: HealthKit Alert] --> B{Analyze Heart Data}
    B -- Normal --> C[Log & End]
    B -- Anomaly Detected --> D[Ask User for Symptoms]
    D --> E{User Response}
    E -- "I'm fine" --> F[Log Observation]
    E -- "I feel dizzy/pain" --> G[Search Available Doctors]
    G --> H[Confirm Appointment Time]
    H --> I[Execute Booking API]
    I --> J[Notify User & Send Calendar Invite]
    F --> K[End]
    J --> K
Enter fullscreen mode Exit fullscreen mode

Prerequisites

To follow this advanced tutorial, you'll need:

  • Python 3.10+
  • LangGraph & LangChain: For agent orchestration.
  • OpenAI GPT-4o: Our reasoning engine.
  • HealthKit (Simulated): We will mock the HealthKit API for this demonstration.

Step 1: Defining the Agent State

In LangGraph, the State object is the single source of truth. It tracks the conversation history, health metrics, and whether a booking is required.

from typing import Annotated, TypedDict, List, Union
from langgraph.graph.message import add_messages

class AgentState(TypedDict):
    # Tracks the conversation history
    messages: Annotated[list, add_messages]
    # Current health vitals
    vitals: dict
    # Booking status
    booking_confirmed: bool
    # User symptoms
    symptoms: List[str]
Enter fullscreen mode Exit fullscreen mode

Step 2: Crafting Custom Tools

Our agent needs to interact with the real world. We’ll define two tools: one to fetch health data and one to book appointments.

from langchain_core.tools import tool

@tool
def fetch_health_metrics():
    """Fetches the latest heart rate data from HealthKit."""
    # In a real app, this calls the iOS Bridge
    return {"heart_rate": 115, "status": "Tachycardia Detected", "timestamp": "2023-10-27T10:30:00"}

@tool
def book_doctor_appointment(specialty: str, preferred_time: str):
    """Books an appointment via the hospital API."""
    print(f"CONFIRMED: Booking {specialty} for {preferred_time}")
    return {"status": "Success", "appointment_id": "REF-9921", "doctor": "Dr. Smith"}
Enter fullscreen mode Exit fullscreen mode

Step 3: Building the LangGraph Logic

Now, we define the nodes and the logic that governs the transitions. We use a ToolNode to handle the execution of our Python functions.

from langgraph.prebuilt import ToolNode
from langgraph.graph import StateGraph, END

# Define the Logic Node
def analyze_data(state: AgentState):
    # Logic to decide if we need to escalate to a doctor
    vitals = state.get("vitals", {})
    if vitals.get("heart_rate", 0) > 100:
        return {"messages": [("system", "Heart rate is high. I must ask the user about symptoms.")]}
    return {"messages": [("system", "Everything looks normal.")]}

# Build the Graph
workflow = StateGraph(AgentState)

workflow.add_node("monitor", analyze_data)
workflow.add_node("tools", ToolNode([fetch_health_metrics, book_doctor_appointment]))

workflow.set_entry_point("monitor")
# ... (Additional edges and logic would go here)
Enter fullscreen mode Exit fullscreen mode

Step 4: Adding the "Human-in-the-Loop"

A critical aspect of healthcare agents is safety. We don't want the AI booking surgery without a "Yes" from the human. LangGraph's interrupt feature allows us to pause execution until the user provides input. 🛑

# In a real implementation, we use a breakpoint before the booking tool
# to ensure the user has explicitly agreed to the time and date.
Enter fullscreen mode Exit fullscreen mode

The "Official" Way: Production Patterns 🥑

Building a toy agent is easy; building a HIPAA-compliant, production-grade health system is a different beast. For deep dives into advanced state-management patterns and enterprise AI deployment, I highly recommend checking out the WellAlly Tech Blog.

They provide excellent resources on:

  • LLM Security: Ensuring patient data privacy.
  • Reliable Tool-Calling: Handling API failures gracefully in mission-critical environments.
  • Multi-Agent Systems: How to separate the "Diagnosis Agent" from the "Booking Agent."

It’s been a massive source of inspiration for how I structure my production LangGraph instances!


Conclusion: The Future of Proactive Health

By moving from a "reactive" dashboard to a "proactive" agent, we change the user experience from anxiety-inducing alerts to seamless care coordination. LangGraph provides the perfect framework for this because it treats "loops" and "state" as first-class citizens.

What do you think? Would you trust an AI agent to book your doctor's appointment? Let's discuss in the comments below! 👇


If you enjoyed this tutorial, don't forget to **Follow* for more "Learning in Public" AI content!* 🚀

Top comments (0)