Skip to content

🎣 포항 ꡬ룑포 λ‚šμ‹œ 관광객을 μœ„ν•œ AI μ „ν™” μ˜ˆμ•½ μ—μ΄μ „νŠΈ

Notifications You must be signed in to change notification settings

sjin4861/deepcatch-agent

Repository files navigation

Deepcatch Agent

Deepcatch AgentλŠ” 포항 ꡬ룑포 λ‚šμ‹œ 관광객을 μœ„ν•΄ μ„€κ³„λœ AI 기반 μ „ν™” μ˜ˆμ•½ μ–΄μ‹œμŠ€ν„΄νŠΈμž…λ‹ˆλ‹€. LangGraph둜 κ΅¬μ„±λœ μ—μ΄μ „νŠΈκ°€ 기상/μ–΄νš 데이터λ₯Ό μˆ˜μ§‘ν•΄ 맞좀 ν”Œλžœμ„ μ œμ•ˆν•˜κ³ , Twilio μŒμ„± 톡화λ₯Ό 톡해 λ‚šμ‹œμ  μ˜ˆμ•½κΉŒμ§€ λ•μŠ΅λ‹ˆλ‹€. Next.js λŒ€μ‹œλ³΄λ“œμ—μ„œλŠ” λŒ€ν™” νžˆμŠ€ν† λ¦¬, μ‹€μ‹œκ°„ 전사, 뢄석 μΈμ‚¬μ΄νŠΈλ₯Ό ν•œλˆˆμ— 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

image

πŸ“š Table of Contents


ν”„λ‘œμ νŠΈ κ°œμš”

  • λͺ©ν‘œ: μ‚¬μš©μžμ˜ λ‚šμ‹œ 일정 μš”κ΅¬μ‚¬ν•­μ„ μ΄ν•΄ν•˜κ³ , 기상/μ–΄νš 정보λ₯Ό λ°”νƒ•μœΌλ‘œ 맞좀 ν”Œλžœμ„ μ œμ•ˆν•˜λ©°, ν•„μš” μ‹œ μ „ν™” μ˜ˆμ•½μ„ λŒ€ν–‰ν•©λ‹ˆλ‹€.
  • ꡬ성:
    • LangGraph μ—μ΄μ „νŠΈ: λŒ€ν™”, ν”Œλž˜λ„ˆ, μ „ν™” λ…Έλ“œλ‘œ κ΅¬μ„±λœ λ©€ν‹°νˆ΄ νŒŒμ΄ν”„λΌμΈ
    • FastAPI λ°±μ—”λ“œ: μˆ˜μ‚°λ¬Ό/기상 API λž˜ν•‘, Twilio μ›Ήν›…, LangGraph μ‹€ν–‰, SQLite μƒνƒœ 관리
    • Next.js ν”„λŸ°νŠΈμ—”λ“œ: μ‹€μ‹œκ°„ 전사, 도ꡬ κ²°κ³Ό, μΆ”μ²œ ν”Œλžœμ„ μ‹œκ°ν™”ν•˜λŠ” λŒ€μ‹œλ³΄λ“œ
    • Socket.IO λΈŒλ¦¬μ§€: OpenAI Realtime 및 Twilio λ―Έλ””μ–΄ 이벀트λ₯Ό 톡합

λ ˆν¬μ§€ν† λ¦¬ ꡬ쑰

deepcatch-agent/
β”œβ”€β”€ front-end/                # Next.js 15 + Tailwind λŒ€μ‹œλ³΄λ“œ
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ app/              # App Router νŽ˜μ΄μ§€ 및 API 라우트
β”‚   β”‚   β”œβ”€β”€ components/       # λŒ€μ‹œλ³΄λ“œ, UI, 차트 μ»΄ν¬λ„ŒνŠΈ
β”‚   β”‚   β”œβ”€β”€ ai/flows/         # Genkit 기반 μš”μ•½ ν”Œλ‘œμš°
β”‚   β”‚   └── lib/              # μ„€μ •, μ‹€μ‹œκ°„ μ†ŒμΌ“ ν΄λΌμ΄μ–ΈνŠΈ λ“±
β”‚   β”œβ”€β”€ package.json
β”‚   └── README.md
β”œβ”€β”€ server/                   # FastAPI + LangGraph + Twilio λ°±μ—”λ“œ
β”‚   β”œβ”€β”€ src/                  # API, μ—μ΄μ „νŠΈ, μ„œλΉ„μŠ€ λ ˆμ΄μ–΄
β”‚   β”œβ”€β”€ app/                  # (λ ˆκ±°μ‹œ) Flask μ‹€ν—˜μš© μ½”λ“œ
β”‚   β”œβ”€β”€ data/                 # μƒ˜ν”Œ DB/CSV
β”‚   β”œβ”€β”€ pyproject.toml
β”‚   └── README.md
β”œβ”€β”€ data/                     # SQLite DB (μ‹€ν—˜μš©)
└── README.md                 # ← μ§€κΈˆ 보고 μžˆλŠ” 파일

μ£Όμš” κΈ°λŠ₯

image image image image
  • λŒ€ν™”ν˜• 일정 μˆ˜μ§‘: LangGraph ν”Œλž˜λ„ˆκ°€ λ‚ μ§œ, 인원, μ˜ˆμ‚° λ“± 핡심 μŠ¬λ‘―μ„ μ§ˆμ˜Β·λ³΄κ΄€
  • 기상/λ¬Όλ•Œ μΈμ‚¬μ΄νŠΈ: ꡬ룑포 좔석 μ—°νœ΄(10/5~10/8) 맞좀 예보, 풍속/파고 차트, μΆ”μ²œ 일정 제곡
  • μ–΄νš 데이터 뢄석: 졜근 μ–΄νšλŸ‰ μΆ”μ„Έ, μ£Όμš” μ–΄μ’… 차트, μž…ν•­ μ„ λ°• 정보
  • μ‹€μ‹œκ°„ 톡화 슀트리밍: Socket.IOλ₯Ό ν†΅ν•œ Twilio/OpenAI μŒμ„± 이벀트 μ „νŒŒ, λŒ€μ‹œλ³΄λ“œ 전사 λ Œλ”λ§
  • μ „ν™” μ˜ˆμ•½ μžλ™ν™”: Twilio API둜 μ‹€μ œ μ „ν™” λ°œμ‹  및 κ²°κ³Ό μš”μ•½
  • λ§΅ 경둜 μ‹œκ°ν™”: Kakao 지도 기반 μΆ”μ²œ λ‚šμ‹œμ  경둜/μœ„μΉ˜ ν‘œμ‹œ

μ‹œμŠ€ν…œ μ•„ν‚€ν…μ²˜

μ‚¬μš©μž ↔ Next.js λŒ€μ‹œλ³΄λ“œ ↔ FastAPI (LangGraph) ↔ μ™ΈλΆ€ API (기상청, DPG)
                                      β†˜ Twilio ↔ μŒμ„± 톡화
Socket.IO λΈŒλ¦¬μ§€ ↔ OpenAI Realtime ↔ μ‹€μ‹œκ°„ 전사/응닡 슀트리밍
  • λŒ€ν™” 흐름: ν”„λŸ°νŠΈ β†’ /chat β†’ LangGraph β†’ Weather/Fish Tool 호좜 β†’ 응닡/도ꡬ 메타데이터 β†’ λŒ€μ‹œλ³΄λ“œ μΉ΄λ“œ 반영
  • 톡화 흐름: ν”„λŸ°νŠΈ β†’ Socket.IO start_call β†’ OpenAI/Twilio μ—°κ²° β†’ μ‹€μ‹œκ°„ 이벀트 β†’ RealtimeTranscription μ»΄ν¬λ„ŒνŠΈ μ—…λ°μ΄νŠΈ

사전 μ€€λΉ„ 사항

ν•­λͺ© 버전 λΉ„κ³ 
Node.js β‰₯ 18 Next.js 15 λŒ€μ‘ (npm λ˜λŠ” pnpm μ‚¬μš© κ°€λŠ₯)
Python 3.10–3.11 uv ꢌμž₯
uv μ΅œμ‹  λ°±μ—”λ“œ 쒅속성/λͺ…λ Ή μ‹€ν–‰
SQLite κΈ°λ³Έ λ‚΄μž₯ ν…ŒμŠ€νŠΈ 데이터 data/fishing.db 포함
ngrok (선택) μ΅œμ‹  Twilio μ›Ήν›… 둜컬 μ—°λ™μš©
Twilio 계정 (선택) - μ‹€μ œ μ „ν™” λ°œμ‹  μ‹œ ν•„μš”

λΉ λ₯Έ μ‹œμž‘

곡톡

git clone https://github.com/sjin4861/deepcatch-agent.git
cd deepcatch-agent

λ°±μ—”λ“œ (FastAPI)

cd server
uv sync                    # μ˜μ‘΄μ„± μ„€μΉ˜ (pyproject.toml 기반)
cp .env.example .env       # ν•„μš” μ‹œ ν™˜κ²½ λ³€μˆ˜ μˆ˜μ •
uv run uvicorn src.main:app --reload --port 8000
  • 기본적으둜 http://localhost:8000μ—μ„œ API 제곡
  • USE_SSL=true μ„€μ • ν›„ python run_https.py둜 HTTPS μ‹€ν–‰ κ°€λŠ₯
  • LangGraph/Socket.IO μ„œλ²„λ„ FastAPI 앱에 ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

ν”„λŸ°νŠΈμ—”λ“œ (Next.js)

cd front-end
npm install               # pnpm / yarn μ‚¬μš© κ°€λŠ₯
npm run dev               # http://localhost:9002 (package.json의 dev 슀크립트)

ν•„μš” μ‹œ λ‹€μŒ ν™˜κ²½ λ³€μˆ˜(.env.local) μ„€μ •:

NEXT_PUBLIC_API_BASE_URL=http://localhost:8000
NEXT_PUBLIC_SOCKET_URL=http://localhost:8000
NEXT_PUBLIC_KAKAO_MAP_KEY=카카였_지도_Javascript_ν‚€

μ‹€μ‹œκ°„ 쀑계 μ„œλ²„

  • FastAPI 앱이 Socket.IO ASGI μ„œλ²„(/socket.io)λ₯Ό ν•¨κ»˜ μ œκ³΅ν•˜λ―€λ‘œ μΆ”κ°€ μ‹€ν–‰ 없이 μž‘λ™
  • OpenAI Realtime을 μ‚¬μš©ν•  경우 .env에 OPENAI_API_KEYλ₯Ό μΆ”κ°€ν•˜κ³  λΈŒλΌμš°μ €μ—μ„œ 톡화λ₯Ό μ‹œμž‘ν•˜μ„Έμš”.

ν™˜κ²½ λ³€μˆ˜

λ°±μ—”λ“œ (.env)

# Twilio (선택)
TWILIO_ACCOUNT_SID=
TWILIO_AUTH_TOKEN=
TWILIO_NUMBER=

# DPG μ„ λ°•/μ–΄νš API
DPG_SERVICE_KEY=...
FISHERY_API_DEV_MODE=true      # trueλ©΄ mock 데이터 μ‚¬μš©

# 기상청 API
WEATHER_AUTH_KEY=...
WEATHER_URL=https://apihub.kma.go.kr/api/typ01/url/fct_shrt_reg.php
WEATHER_CODE_URL=...

# OpenAI Realtime
OPENAI_API_KEY=sk-...

# 기타
USE_SSL=false

ν”„λŸ°νŠΈμ—”λ“œ (.env.local)

NEXT_PUBLIC_API_BASE_URL=http://localhost:8000
NEXT_PUBLIC_SOCKET_URL=http://localhost:8000
NEXT_PUBLIC_KAKAO_MAP_KEY=...

μ£Όμš” μ›Œν¬ν”Œλ‘œ

  1. λŒ€ν™” ν”Œλ‘œμš°

    • μ‚¬μš©μžκ°€ ν”„λŸ°νŠΈ λŒ€ν™”μ°½μ—μ„œ 문의 β†’ FastAPI /chat
    • LangGraph FishingPlannerGraphκ°€ 도ꡬ 호좜/응닡 κ²°μ •
    • Weather/Fish Tool κ²°κ³ΌλŠ” toolResults둜 ν”„λŸ°νŠΈμ— μŠ€νŠΈλ¦¬λ°λ˜μ–΄ 인포 μΉ΄λ“œ 및 μ°¨νŠΈμ— 반영
  2. 기상 데이터 νŒŒμ΄ν”„λΌμΈ

    • /api/v1/ship-safe/holiday/forecastμ—μ„œ 좔석 μ—°νœ΄ 4일치 풍속/파고/λ¬Όλ•Œ 제곡
    • WeatherTool이 Holiday Forecastλ₯Ό 병합해 졜적 일정, 차트 메타데이터 생성
    • HolidayWeatherWidgetμ—μ„œ 차트 및 ν•˜μ΄λΌμ΄νŠΈ λ Œλ”λ§
  3. μ‹€μ‹œκ°„ 톡화

    • RealtimeTranscription μ»΄ν¬λ„ŒνŠΈκ°€ Socket.IO 이벀트(call_status, transcription_update, ai_response_*) μˆ˜μ‹ 
    • 톡화 μƒνƒœ/κ²½κ³Ό μ‹œκ°„μ„ μ¦‰μ‹œ μ—…λ°μ΄νŠΈ, 슀트리밍 ν…μŠ€νŠΈλ₯Ό νƒ€μž 효과둜 ν‘œν˜„
    • Twilio webhook(/voice/status) β†’ μ„œλ²„ β†’ Socket.IO call_status_update

ν…ŒμŠ€νŠΈ & ν’ˆμ§ˆ 체크

μ˜μ—­ λͺ…λ Ή λΉ„κ³ 
λ°±μ—”λ“œ Lint/Test uv run pytest app/tests/test_api.py λ“±
λ°±μ—”λ“œ νƒ€μž… 검사 uv run python -m compileall src λΉ λ₯Έ 문법 체크
ν”„λŸ°νŠΈμ—”λ“œ Lint npm run lint ESLint + Next.js μ„€μ •
ν”„λŸ°νŠΈμ—”λ“œ νƒ€μž… 체크 npm run typecheck TypeScript --noEmit

문제 ν•΄κ²°

  • 톡화 μƒνƒœκ°€ κ°±μ‹ λ˜μ§€ μ•Šμ„ λ•Œ: ν”„λŸ°νŠΈ .env.local의 NEXT_PUBLIC_SOCKET_URL이 FastAPI ν˜ΈμŠ€νŠΈμ™€ μΌμΉ˜ν•˜λŠ”μ§€ ν™•μΈν•˜μ„Έμš”.
  • 기상/μ–΄νš API μ—λŸ¬: FISHERY_API_DEV_MODE=true μƒνƒœμ—μ„œ mock 데이터가 μ œκ³΅λ©λ‹ˆλ‹€. μ‹€μ œ API 인증킀가 μœ νš¨ν•œμ§€ μ κ²€ν•˜μ„Έμš”.
  • Kakao 지도 λ―Έν‘œμ‹œ: λΈŒλΌμš°μ € μ½˜μ†”μ˜ appkey μ—λŸ¬λ₯Ό ν™•μΈν•˜κ³  NEXT_PUBLIC_KAKAO_MAP_KEYλ₯Ό μž¬ν™•μΈν•˜μ„Έμš”.
  • OpenAI Realtime μ—°κ²° μ‹€νŒ¨: OPENAI_API_KEY와 λ„€νŠΈμ›Œν¬ κΆŒν•œ(λ°©ν™”λ²½ λ“±)을 ν™•μΈν•©λ‹ˆλ‹€.

λΌμ΄μ„ μŠ€

λ³Έ ν”„λ‘œμ νŠΈλŠ” LICENSE에 λͺ…μ‹œλœ 쑰건을 λ”°λ¦…λ‹ˆλ‹€. λ‚΄λΆ€ 데이터(data/ ν•˜μœ„ SQLite/CSV)λŠ” 데λͺ¨ λͺ©μ μ˜ μ˜ˆμ‹œμ΄λ©°, μ‹€μ œ μ„œλΉ„μŠ€ 배포 μ‹œ ꡐ체가 ν•„μš”ν•©λ‹ˆλ‹€.


About

🎣 포항 ꡬ룑포 λ‚šμ‹œ 관광객을 μœ„ν•œ AI μ „ν™” μ˜ˆμ•½ μ—μ΄μ „νŠΈ

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •