Your CGM Should Order Your Lunch: Building an Autonomous Health Agent with LangGraph 🥗🤖

Published: (January 30, 2026 at 08:30 PM EST)
3 min read
Source: Dev.to

Source: Dev.to

Introduction

We’ve all been there: your Continuous Glucose Monitor (CGM) pings you with a “High Glucose” alert, and your brain immediately enters panic mode. Should you eat? What should you eat? In the heat of a glucose spike, making a rational, low‑glycemic decision is hard.

What if your health data didn’t just notify you, but acted for you? In this tutorial we build a Health Butler using LangGraph, OpenAI function calling, and the Dexcom API. The AI agent monitors real‑time glucose levels and, upon detecting a spike or a crash, autonomously interacts with food‑delivery APIs (e.g., Meituan or Ele.me) to suggest and place a low‑GI meal order.

Architecture Diagram

graph TD
    A[Start: Dexcom Monitor] --> B{Glucose Stable?}
    B -- Yes --> C[Wait 5 Mins]
    C --> A
    B -- No: Spike/Crash --> D[Analyze Nutritional Needs]
    D --> E[OpenAI Function Calling: Search Low‑GI Meals]
    E --> F[Fetch Meituan/Ele.me Options]
    F --> G[Propose Order to User]
    G -- Approved --> H[Execute Delivery API]
    G -- Denied --> A
    H --> I[Log Event & Monitor Recovery]
    I --> A

Prerequisites

  • Node.js (v18+)
  • LangChain & LangGraph SDKs (@langchain/langgraph, @langchain/openai)
  • Dexcom Developer Account (sandbox API access)
  • OpenAI API Key (using GPT‑4o for best reasoning)

Defining the Agent State

import { StateGraph, Annotation } from "@langchain/langgraph";

// Define our state schema
const AgentState = Annotation.Root({
  glucoseLevel: Annotation(),
  trend: Annotation(), // 'rising', 'falling', 'stable'
  recommendations: Annotation(),
  orderPlaced: Annotation(),
  userAlerted: Annotation(),
});

The state is the source of truth: it tracks the current glucose value, its trend, and any recommended food items.

Dexcom Fetch Node

async function checkGlucoseNode(state) {
  console.log("Checking CGM data... 🩸");

  // Real-world: const response = await fetch('https://api.dexcom.com/v3/users/self/egvs/...');
  // Mocking a "Spike" scenario:
  const mockGlucose = 185;
  const mockTrend = "risingFast";

  return {
    glucoseLevel: mockGlucose,
    trend: mockTrend,
  };
}

This node simulates the OAuth flow and returns a glucose reading and trend.

Food‑Search Tool (OpenAI Function Calling)

import { ChatOpenAI } from "@langchain/openai";
import { tool } from "@langchain/core/tools";
import { z } from "zod";

const foodSearchTool = tool(
  async ({ query, maxCalories }) => {
    // Logic to call Meituan/Ele.me/UberEats API
    return `Found: Grilled Chicken Salad, Quinoa Bowl (Max ${maxCalories} kcal)`;
  },
  {
    name: "search_delivery_food",
    description: "Searches for healthy food options based on nutritional needs.",
    schema: z.object({
      query: z.string(),
      maxCalories: z.number(),
    }),
  }
);

const model = new ChatOpenAI({ modelName: "gpt-4o" }).bindTools([foodSearchTool]);

The tool enables the LLM to request low‑GI meal options from a delivery service.

Building the Workflow

const workflow = new StateGraph(AgentState)
  .addNode("monitor", checkGlucoseNode)
  .addNode("analyzer", async (state) => {
    const response = await model.invoke([
      ["system", "You are a medical nutrition assistant. Suggest a low-GI meal."],
      ["user", `My glucose is ${state.glucoseLevel} and ${state.trend}. Find me a meal.`],
    ]);
    return { recommendations: [response] };
  })
  .addEdge("__start__", "monitor")
  .addConditionalEdges("monitor", (state) => {
    if (state.glucoseLevel > 160 || state.glucoseLevel < 70) return "analyzer";
    return "monitor";
  })
  .addEdge("analyzer", "monitor"); // Simplified loop

const app = workflow.compile();

The graph starts with the monitor node, conditionally routes to analyzer when glucose is out of range, and then loops back.

Production Considerations

While this proof‑of‑concept demonstrates the core idea, a production‑grade health agent must address:

  • Robust error handling and retries
  • HIPAA‑compliant data processing and storage
  • Retrieval‑Augmented Generation (RAG) for personalized nutrition advice
  • Secure tool‑calling with human‑in‑the‑loop (HITL) patterns
  • Low‑latency edge deployment for real‑time responsiveness

For an in‑depth discussion of these topics, see the engineering guides on the WellAlly Tech Blog (search for “stateful AI agents in healthcare”).

Next Steps

  • Add a Human‑in‑the‑Loop node that requires biometric confirmation before invoking the payment API.
  • Implement a feedback loop where the agent learns which meals most effectively stabilize glucose levels.
  • Expand the data sources to include multi‑modal health inputs (e.g., vision + CGM).

Happy coding, and stay healthy! 🥑💻

Back to Blog

Related posts

Read more »