스마트한 운동 만들기: LangGraph와 바이오피드백을 활용한 스스로 조정되는 AI 코치 만들기 🏃‍♂️🤖

발행: (2026년 2월 13일 오전 10:10 GMT+9)
7 분 소요
원문: Dev.to

Source: Dev.to

우리는 모두 경험해봤습니다: 피트니스 앱이 **“다리 운동일”**이라고 알려주지만, 실제로는 휴식 심박수가 80이고 수면 점수가 낙제점처럼 보이는 경우 말이죠. 대부분의 트레이닝 플랜은 정적이지만, 우리의 몸은 동적입니다. 바로 이 지점에서 LLM AgentsLangGraph가 빛을 발합니다.

이 튜토리얼에서는 Self‑Adjusting AI Coach Agent를 구축합니다. 이것은 단순한 챗봇이 아니라, 다음과 같은 폐쇄‑루프 시스템입니다:

  1. Oura API를 통해 실시간 건강 데이터(HRV, Sleep)를 가져옵니다.
  2. 회복 상태에 대해 추론합니다.
  3. Tavily를 사용해 최적화된 저강도 운동을 검색합니다.
  4. Google Calendar동적으로 재조정합니다.

LangGraph를 활용함으로써 “건강 확인 → 결정 → 업데이트 → 검증”이라는 순환적 과정을 선형 체인보다 훨씬 효율적으로 처리할 수 있습니다.

아키텍처: 폐쇄‑루프 피트니스 에이전트

단순한 RAG 파이프라인과 달리, 우리 에이전트는 상태를 유지해야 하며 일정 충돌이 발생할 경우 다시 루프백할 수 있어야 합니다. 아래는 데이터 흐름도입니다.

graph TD
    A[Start: Morning Sync] --> B{Fetch Oura Metrics}
    B --> C[Analyze Readiness Score]
    C -->|High Readiness| D[Keep Original Workout]
    C -->|Low Readiness| E[Consult Tavily for Active Recovery]
    E --> F[Find Low‑Intensity Alternative]
    D --> G[Sync with Google Calendar]
    F --> G
    G --> H{Conflict?}
    H -->|Yes| I[Reschedule Logic]
    I --> G
    H -->|No| J[Finalize Schedule & Notify User]
    J --> K[End]

필수 조건 🛠️

따라 하려면 다음이 필요합니다:

  • Python 3.10+
  • LangGraph & LangChain – 에이전트 오케스트레이션을 위해
  • Oura Personal Access Token – 생체 데이터 조회를 위해
  • Google Cloud Console Access – Calendar API가 활성화된 상태
  • Tavily API Key – 회복 중심 운동 검색을 위해

Step 1: 에이전트 상태 정의

LangGraph에서 State는 노드 간에 전달되는 진실의 원천입니다. 우리는 건강 지표와 현재 일정을 추적해야 합니다.

from typing import TypedDict, List
from langgraph.graph import StateGraph, END

class AgentState(TypedDict):
    health_metrics: dict
    current_schedule: List[str]
    readiness_score: int
    suggested_workout: str
    calendar_updated: bool
    recovery_mode: bool

Step 2: 실시간 바이오피드백 가져오기

Oura API와 통신하는 노드를 생성합니다 (여기서는 시연을 위해 호출을 모의합니다).

import requests

def fetch_health_data(state: AgentState):
    # Mocking the Oura API call for demonstration
    # In production, use:
    #   requests.get(f"{OURA_URL}/usercollection/daily_readiness", headers=headers)
    print("🚀 Fetching biometric data from Oura...")

    # Example response data
    metrics = {
        "readiness_score": 62,   # Low score
        "hrv": 35,
        "sleep_duration": "5h 20m"
    }

    return {
        "health_metrics": metrics,
        "readiness_score": metrics["readiness_score"],
        "recovery_mode": metrics["readiness_score"] < 70
    }

Step 3: 추론 엔진 (코치)

회복이 낮으면, 에이전트는 Tavily Search를 사용하여 능동 회복 루틴으로 전환합니다.

from langchain_community.tools.tavily_search import TavilySearchResults

def plan_workout_node(state: AgentState):
    if state["recovery_mode"]:
        search = TavilySearchResults(k=1)
        query = "best 30 minute active recovery mobility flow for low HRV"
        result = search.run(query)
        suggestion = f"Recovery Flow: {result}"
    else:
        suggestion = "Proceed with scheduled Heavy Strength Training."

    return {"suggested_workout": suggestion}

단계 4: Google 캘린더와 동기화

Google 캘린더의 “Gym” 블록을 새로운 suggested_workout으로 업데이트합니다.

def update_calendar_node(state: AgentState):
    workout = state["suggested_workout"]
    print(f"📅 Updating Google Calendar with: {workout}")

    # Logic to interface with google-api-python-client
    # service.events().patch(
    #     calendarId='primary',
    #     eventId=event_id,
    #     body=updated_event
    # ).execute()

    return {"calendar_updated": True}

고급 패턴 및 프로덕션 준비 🥑

이 데모는 기본 사항만 다루지만, 프로덕션 수준의 AI 에이전트는 다음을 처리해야 합니다:

  • API 호출 제한
  • OAuth 토큰 갱신
  • LLM 추론에 대한 “환각 방지 검사”

고급 에이전트 패턴, 다중 에이전트 협업, 그리고 프로덕션에 적합한 구현에 대해 더 깊이 알아보려면 **WellAlly Blog**의 기술 기사들을 확인하세요.

5단계: 그래프 연결

노드를 연결하고 흐름 로직을 정의합니다.

workflow = StateGraph(AgentState)

# Add Nodes
workflow.add_node("fetch_health", fetch_health_data)
workflow.add_node("plan_workout", plan_workout_node)
workflow.add_node("sync_calendar", update_calendar_node)

# Define Edges
workflow.set_entry_point("fetch_health")
workflow.add_edge("fetch_health", "plan_workout")
workflow.add_edge("plan_workout", "sync_calendar")
workflow.add_edge("sync_calendar", END)

# Compile the graph
graph = workflow.compile()

이제 실시간 바이오메트릭 피드백을 기반으로 워크아웃 계획을 지속적으로 조정하는 완전한 기능을 갖춘 자체 조정 AI 코치를 보유하게 됩니다. 즐거운 코딩—그리고 더욱 행복한 회복을 기원합니다!

# Run the workflow
app = graph  # The compiled graph
inputs = {"current_schedule": ["08:00 - Weightlifting"]}

for output in app.stream(inputs):
    print(output)

결론: 개인화된 에이전트 시대 🚀

LangGraph와 실제 건강 텔레메트리를 결합함으로써, 우리는 정적인 자동화를 넘어 맥락 인식 AI 영역으로 나아갔습니다. 이제 AI 코치는 눈을 뜨기도 전에 당신이 번아웃 상태인지 알 수 있습니다.

에이전트를 위해 다음에 할 일은?

  • Twilio 노드를 추가하여 업데이트를 SMS로 받아보기.
  • Garmin의 “Body Battery”를 통합해 더 세밀한 데이터를 얻기.
  • Slack을 통해 코치의 제안을 “거부”할 수 있는 피드백 루프 추가하기.

이 빌드가 마음에 들었다면 아래에 댓글을 남겨 주세요! 그리고 WellAlly 를 방문해 AI 기반 웰니스와 에이전시 워크플로우의 미래에 대한 더 많은 인사이트를 확인하세요. 즐거운 코딩 되세요! 💻🔥

0 조회
Back to Blog

관련 글

더 보기 »