딸기 스마트팜 관제 시스템, 한 세션에 풀스택으로 만든 이야기

소개 - claude 채팅+claude code 결합

딸기 스마트팜을 수동으로 관리하고 있었습니다. 매번 농장에 직접 가서 온도, 습도를 확인하고, 관수와 환기도 사람이 직접 조작해야 했습니다. 기록은 엑셀이나 수기로 관리하다 보니 이상 상황을 놓칠 때가 많았고, 체계적인 관리가 어려웠습니다.

(스마트 딸기 팜 관제 시스템)

많은 정보가 포함된 대시보드의 스크린샷
한국 앱 스크린샷

진행 방법

Claude Code에게 "스마트팜 관제 시스템을 만들고 싶다"고 말한 것에서 시작했습니다.

Tip: 사용한 프롬프트 전문을 꼭 포함하고, 내용을 짧게 소개해 주세요.

Tip: 활용 이미지나 캡처 화면을 꼭 남겨주세요.

Tip: 코드 전문은 코드블록에 감싸서 작성해주세요. ( / 을 눌러 '코드 블록'을 선택)

Claude Code에게 "스마트팜 관제 시스템을 만들고 싶다"고 말한 것에서 시작했습니다.

### Phase 1 — 기반 시스템 구축

- 프로젝트 정의서부터 기술 스택 선정까지 대화형으로 결정
- FastAPI 백엔드 + React 프론트엔드 풀스택 구성
- 센서 시뮬레이터: 정현파+노이즈 기반으로 현실적인 딸기 재배 환경 데이터 생성 (3구역, 7개 센서, 1초 주기)
- WebSocket 실시간 스트리밍 + 알림 시스템
- 장비 제어 패널 (관수/환기/난방/차광)

### Phase 2 — AI 기능 추가

- IsolationForest로 이상 감지 (30분 윈도우, 자동 재학습)
- XGBoost로 수확 예측 (GDD 기반, 수확일/수확량)
- Claude Vision으로 병해충 이미지 진단
- AI 일일 생육 리포트 자동 생성

### 시행착오

- Python 버전이 여러 개라 패키지가 다른 버전에 설치되는 문제 발생 → Claude Code가 환경 확인 후 올바른 경로로 재설치
- 포트 충돌로 서버 재시작 실패 → 프로세스 확인/종료 후 해결
- 이런 문제들을 직접 해결하려면 한참 걸렸을 텐데, Claude Code가 에러를 보고 바로 대응해줘서 금방 해결됨

## 결과

| Before | After |
|--------|-------|
| 농장 직접 방문 확인 | 웹 대시보드에서 실시간 모니터링 |
| 수동 관수/환기 조작 | 자동/수동 토글 + AI 자동 제어 |
| 이상 상황 뒤늦게 발견 | IsolationForest 이상 감지 + 즉시 알림 |
| 수확 시기 감으로 판단 | XGBoost 기반 GDD 수확 예측 |
| 병해충 진단 경험 부족 | Claude Vision 이미지 진단 |
| 기록 없음 | AI 일일 생육 리포트 자동 생성 |

**구축 시간**: 한 세션 (약 1시간)
**만들어진 파일**: 백엔드 15개 + 프론트엔드 18개 = 33개 파일
**기술 스택**: FastAPI, React, TypeScript, Tailwind CSS, Recharts, Zustand, scikit-learn, XGBoost, Claude Vision API

## 배운 점

1. **일단 말로 시작하면 된다**: "스마트팜 관제 시스템 만들고 싶어" 한 마디에서 프로젝트 정의서 → 기술 선택 → 구현까지 이어졌다
2. **에러도 AI가 잡는다**: Python 환경 문제, 포트 충돌 등 삽질할 만한 부분을 Claude Code가 바로 해결해줬다
3. **Phase별 접근이 효과적**: 기반 먼저, AI 나중에 — 단계를 나눠서 진행하니 복잡한 시스템도 한 세션에 완성 가능
4. **목업 데이터의 힘**: 실제 센서 없이도 시뮬레이터로 시스템을 완성하고 검증할 수 있었다

(세부 내용)

## 과정

### 1단계: 첫 프롬프트 — 아이디어 던지기

Claude Code에 딱 한 마디만 했습니다:

```
스마트팜 관리하는 관제 시스템을 만들고 싶어
```

이것만으로 Claude Code가 `/gpters-thinking-partner` 스킬을 실행해서 3번의 질문으로 프로젝트를 구체화해줬습니다:
- "핵심 기능은?" → 전체 통합 관제
- "현재 상태는?" → 수동 관리, 시간 많이 걸림
- "기술 스택은?" → React 선택

> ![여기에 첫 프롬프트 입력 화면 캡처를 넣어주세요]

### 2단계: CLAUDE.md 스펙 문서 작성

프로젝트의 전체 설계를 CLAUDE.md에 상세하게 작성해서 전달했습니다. 핵심 내용:

```markdown
## 기술 스택
| 레이어 | 기술 | 용도 |
|--------|------|------|
| Backend | FastAPI | REST API + WebSocket |
| DB | PostgreSQL + TimescaleDB | 시계열 센서 데이터 |
| ML | scikit-learn, XGBoost | 수확 예측, 이상 감지 |
| AI Vision | Claude Sonnet API | 병해충 이미지 진단 |
| Frontend | React + Vite | 대시보드 UI |
| Realtime | WebSocket | 1초 주기 센서 스트리밍 |
```

딸기 재배 환경 임계값(농진청 기준)도 포함시켰습니다:

```python
STRAWBERRY_THRESHOLDS = {
    "temperature": {
        "optimal_min": 18.0,   # °C
        "optimal_max": 25.0,
        "warn_low":    13.0,
        "warn_high":   28.0,
        "critical_low": 5.0,
        "critical_high": 32.0,
    },
    "humidity": {
        "optimal_min": 60.0,   # %RH
        "optimal_max": 80.0,
        "warn_low":    45.0,
        "warn_high":   88.0,
    },
    # ... 토양수분, CO2, EC, pH, 조도 등 7개 센서
}
```

> Tip: CLAUDE.md에 임계값, API 명세, 디렉토리 구조까지 상세하게 적어주니 Claude Code가 정확하게 구현했습니다.

### Phase 1 — 기반 시스템 구축

스펙 문서 전달 후 plan mode로 8단계 구현 계획을 세우고 순서대로 진행했습니다.

**센서 시뮬레이터** — 정현파+노이즈 기반으로 현실적인 데이터 생성:

```python
def _sinusoidal(self, profile: SensorProfile, t: float) -> float:
    """정현파 기반 값 생성 (24시간 주기)"""
    day_progress = (t % 86400) / 86400 * 2 * math.pi
    base_value = profile.base + profile.amplitude * math.sin(
        day_progress + profile.phase_shift
    )
    noise = random.gauss(0, profile.noise_std)
    return round(base_value + noise, 2)
```

- 3구역(A: 100평, B: 80평, C: 60평) 독립 시뮬레이션
- 7개 센서(온도/습도/토양수분/CO2/EC/pH/조도) 1초 주기 생성
- 5% 확률로 이상 이벤트 발생 (5~15초 지속)

**WebSocket 실시간 스트리밍** — 1초마다 전 구역 데이터 브로드캐스트:

```python
async def sensor_stream_loop():
    while True:
        readings = farm_simulator.generate_all()
        new_alerts = check_alerts(readings)
        payload = {
            "type": "sensor_update",
            "zones": readings,
            "alerts": new_alerts,
            "anomalies": anomaly_results,
        }
        await manager.broadcast(payload)
        await asyncio.sleep(1)
```

**프론트엔드** — React + TypeScript + Tailwind CSS + Recharts:

```tsx
// WebSocket 훅 (exponential backoff 재연결)
export function useSensorStream() {
  ws.onclose = () => {
    setTimeout(connect, retryRef.current);
    retryRef.current = Math.min(retryRef.current * 2, 30000);
    // 1s → 2s → 4s → ... → max 30s
  };
}
```

> ![여기에 대시보드 전체 화면 캡처를 넣어주세요]
> 센서 카드 7종 + 시계열 차트 + 구역별 히트맵 + 장비 제어 + 알림 목록

### Phase 2 — AI 기능 추가

Phase 1 완성 후 "다음 단계 해줘" 한 마디로 AI 기능 4종을 추가했습니다.

**IsolationForest 이상 감지:**

```python
class AnomalyDetector:
    def detect(self, zone_id: str) -> dict | None:
        model = IsolationForest(n_estimators=100, contamination=0.05)
        # 최근 30분(1800개) 슬라이딩 윈도우
        # 30초마다 자동 실행, 이상 시 WebSocket 푸시
        # 상위 3개 이상 원인 피처 + z-score 반환
```

**XGBoost 수확 예측:**

```python
# GDD(Growing Degree Days) 기반
# base temp = 5°C, 목표 GDD = 550
# → 예상 수확일, 수확량(kg), 신뢰구간 반환
harvest_predictor.predict("A")
# {"predicted_harvest_date": "2026-03-20",
#  "predicted_yield_kg": 251.4,
#  "yield_per_pyeong": 2.51}
```

**Claude Vision 병해충 진단:**

```python
DIAGNOSIS_PROMPT = """
당신은 딸기 병해충 전문가입니다.
업로드된 이미지를 분석하여 다음을 JSON으로 답하세요:
- disease_name, confidence, severity
- symptoms, treatment, prevention
딸기 주요 병해충: 잿빛곰팡이병, 흰가루병, 탄저병,
점박이응애, 진딧물, 총채벌레
"""
# API 키 없으면 목업 응답 반환 (개발 편의)
```

> ![여기에 AI 분석 섹션 캡처를 넣어주세요]
> 수확 예측 위젯 + 병해충 진단 패널 + 일일 생육 리포트

### 시행착오

**Python 버전 충돌:**
```
ModuleNotFoundError: No module named 'sklearn'
# pip가 Python 3.11에 설치했는데 실행은 3.12로 됨
# → Claude Code가 `which python`으로 확인 후 올바른 경로로 재설치
```

**포트 충돌:**
```
ERROR: [Errno 10048] error while attempting to bind on address ('0.0.0.0', 8000)
# 이전 프로세스가 살아있음
# → netstat로 PID 확인 → taskkill로 종료 → 재시작 성공
```

> Tip: 이런 환경 문제는 직접 해결하면 30분은 걸리는데, Claude Code가 에러 로그를 보고 바로 원인을 파악해서 해결해줍니다.

## 결과

| Before | After |
|--------|-------|
| 농장 직접 방문 확인 | 웹 대시보드에서 실시간 모니터링 |
| 수동 관수/환기 조작 | 자동/수동 토글 + AI 자동 제어 |
| 이상 상황 뒤늦게 발견 | IsolationForest 이상 감지 + 즉시 알림 |
| 수확 시기 감으로 판단 | XGBoost 기반 GDD 수확 예측 |
| 병해충 진단 경험 부족 | Claude Vision 이미지 진단 |
| 기록 없음 | AI 일일 생육 리포트 자동 생성 |

**구축 시간**: 한 세션 (약 1시간)
**만들어진 파일**: 백엔드 15개 + 프론트엔드 18개 = 33개 파일
**기술 스택**: FastAPI, React, TypeScript, Tailwind CSS, Recharts, Zustand, scikit-learn, XGBoost, Claude Vision API

### 최종 프로젝트 구조

```
smart-farm-strawberry/
├── backend/
│   ├── main.py                  # FastAPI 진입점
│   ├── config.py                # 딸기 재배 임계값
│   ├── simulation/
│   │   └── sensor_simulator.py  # 정현파+노이즈 시뮬레이터
│   ├── websocket/
│   │   └── sensor_stream.py     # 1초 주기 브로드캐스트
│   ├── ai/
│   │   ├── anomaly_detector.py  # IsolationForest 이상 감지
│   │   ├── harvest_predictor.py # XGBoost 수확 예측
│   │   └── vision_client.py     # Claude Vision 진단
│   └── api/                     # REST 엔드포인트 6개
│
└── frontend/
    └── src/
        ├── components/
        │   ├── Dashboard/       # 센서카드, 차트, 히트맵
        │   ├── Controls/        # 장비 제어 패널
        │   ├── Alerts/          # 알림 목록, 뱃지
        │   └── AI/              # 진단, 예측, 리포트
        ├── hooks/               # WebSocket, API 훅
        └── store/               # Zustand 전역 상태
```

> ![여기에 전체 시스템 구성도 또는 대시보드 전체 화면 캡처를 넣어주세요]

## 배운 점

1. **일단 말로 시작하면 된다**: "스마트팜 관제 시스템 만들고 싶어" 한 마디에서 프로젝트 정의서 → 기술 선택 → 구현까지 이어졌다
2. **에러도 AI가 잡는다**: Python 환경 문제, 포트 충돌 등 삽질할 만한 부분을 Claude Code가 바로 해결해줬다
3. **Phase별 접근이 효과적**: 기반 먼저, AI 나중에 — 단계를 나눠서 진행하니 복잡한 시스템도 한 세션에 완성 가능
4. **목업 데이터의 힘**: 실제 센서 없이도 시뮬레이터로 시스템을 완성하고 검증할 수 있었다
5. **CLAUDE.md가 핵심**: 임계값, API 명세, 디렉토리 구조를 상세하게 적어주니 Claude Code가 한 번에 정확하게 구현했다

## 사용한 프롬프트 요약

| 순서 | 프롬프트 | 결과 |
|------|---------|------|
| 1 | `스마트팜 관리하는 관제 시스템을 만들고 싶어` | 프로젝트 정의서 생성 |
| 2 | `스마트 품목은 딸기` | 딸기 특화 설정 반영 |
| 3 | (CLAUDE.md 스펙 문서 전체 전달) | Phase 1 풀스택 구현 |
| 4 | `다음 단계 해줘` | Phase 2 AI 기능 4종 추가 |

결과와 배운 점

배운 점과 나만의 꿀팁을 알려주세요.

과정 중에 어떤 시행착오를 겪었나요?

도움이 필요한 부분이 있나요?

앞으로의 계획이 있다면 들려주세요.

(내용 입력)

도움 받은 글 (옵션)

참고한 지피터스 글이나 외부 사례를 알려주세요.

(내용 입력)

뉴스레터 무료 구독

👉 이 게시글도 읽어보세요