FIA 공식 규정집(2024·2026)을 벡터 DB로, 시즌 데이터를 Jolpica·OpenF1 API로, 진행 중인 세션을 F1 Live Timing(SignalR)으로 묶어 한국어로 답하는 LangGraph ReAct 에이전트입니다. "2026년 액티브 에어로 규정이 뭐야?" 같은 규정 질문부터 "노리스랑 피아스트리 커리어 비교해줘", 레이스 주말의 실시간 텔레메트리까지 하나의 챗 UI에서 처리합니다.
- 규정 RAG — FIA 규정 PDF(2024 통합본 + 2026 Section A~F)를 조항 단위로 임베딩, 연도·섹션을 인용해 답변. 2024↔2026 규정 비교 지원
- 시즌 데이터 조회 — 드라이버/컨스트럭터 순위, 레이스·예선 결과, 피트스톱, 일정, 드라이버 커리어 비교 (Jolpica — Ergast 호환 API)
- 라이브 세션 —
livetiming.formula1.comSignalR 피드(무인증)를 상시 수신해 세션 정보·타이밍·날씨·레이스 컨트롤을 인메모리 상태로 유지, 에이전트 컨텍스트와 텔레메트리 대시보드(/telemetry)에 공급 - 팀 라디오 전사 (선택) — F1 TV Premium 오디오를 streamlink/FFmpeg로 캡처해
Faster-Whisper로 실시간 전사, 에이전트가
get_team_radio도구로 조회 - 웹 검색 폴백 — Tavily 우선, 키가 없거나 실패하면 DuckDuckGo로 자동 전환
- 멀티턴 대화 — LangGraph
MemorySaver+thread_id로 스레드별 히스토리 유지 - SSE 스트리밍 —
/chat/stream으로 토큰 단위 응답, 정형 쿼리는 에이전트를 거치지 않는 직접 응답 경로로 지연 최소화
| 구성 요소 | 선택 | 비고 |
|---|---|---|
| LLM | Ollama qwen3.5:122b |
원격 Ollama 서버, OLLAMA_BASE_URL로 주입 |
| 에이전트 | LangGraph create_react_agent |
도구 11개, 시스템 프롬프트에 도구 사용 규칙 명시 |
| 임베딩 | Google gemini-embedding-001 |
무료 티어 (ingest는 분당 호출 제한 대응) |
| 벡터 DB | ChromaDB (로컬 ./chroma_db) |
ingest.py가 생성 |
| 시즌 데이터 | Jolpica F1 API (Ergast 호환) | 무인증 |
| 라이브 데이터 | F1 SignalR + OpenF1 API | SignalR은 무인증 |
| 음성 전사 | Faster-Whisper | CUDA/CPU 선택, F1 TV Premium 구독 필요 |
| 백엔드 | FastAPI + uvicorn | 챗 UI(/)·대시보드(/telemetry) 정적 서빙 포함 |
사용자 ──> FastAPI /chat(/stream) ──> 직접 응답 경로 (정형 쿼리)
│
└──> LangGraph ReAct 에이전트 (Ollama qwen3.5:122b)
├─ search_regulations ── ChromaDB (FIA PDF 임베딩)
├─ Jolpica 도구 7종 ──── 순위·결과·예선·피트스톱·일정·비교
├─ get_live_telemetry ── OpenF1
├─ get_team_radio ────── live_state ◀─ Whisper 전사 (선택)
└─ search ────────────── Tavily → DuckDuckGo 폴백
F1 SignalR 수신 루프 ──────────────────▶ live_state ──▶ /api/live/* · /telemetry
Python 3.11+ 권장.
pip install -r requirements.txt
cp .env.example .env # GOOGLE_API_KEY(필수) 등 채우기
# 1) 규정 PDF 준비 — FIA 저작권 문제로 저장소에 미포함, data/README.md의 안내대로 다운로드
# 2) 임베딩 (PDF → ChromaDB, 무료 티어 기준 수십 분 소요)
python ingest.py
# 3) 서버 실행
python main.py # http://localhost:8000 (챗 UI) · /telemetry (대시보드)동작 확인:
curl -s localhost:8000/health
curl -s -X POST localhost:8000/chat -H 'Content-Type: application/json' \
-d '{"message": "2026년 파워유닛 규정 뭐가 바뀌어?"}'| 변수 | 필수 | 설명 |
|---|---|---|
GOOGLE_API_KEY |
✅ | Gemini 임베딩용 (ingest·규정 검색) |
OLLAMA_BASE_URL |
✅ | Ollama 서버 주소 (기본 http://localhost:11434) |
OLLAMA_LLM_MODEL |
기본 qwen3.5:122b |
|
TAVILY_API_KEY |
없으면 DuckDuckGo 단독 검색 | |
F1TV_EMAIL / F1TV_PASSWORD |
팀 라디오 전사용 (F1 TV Premium) | |
WHISPER_MODEL / WHISPER_DEVICE / WHISPER_COMPUTE |
전사 모델 설정 (기본 medium/cuda/float16) | |
DEMO_MODE |
true 시 /api/live/demo 리플레이 활성화 (발표용) |
| 엔드포인트 | 설명 |
|---|---|
POST /chat |
채팅 (JSON: message, 선택 thread_id) |
POST /chat/stream |
SSE 스트리밍 채팅 |
GET /api/live/session·overview·race-control·weather·car-data/{n} |
라이브 세션 상태 |
GET /health |
헬스체크 |
GET / · GET /telemetry |
챗 UI · 텔레메트리 대시보드 |
main.py # FastAPI 앱 + 에이전트 + 도구 + SSE
f1_api.py # Jolpica/OpenF1 클라이언트 + @tool 8종
f1_signalr.py # F1 Live Timing SignalR 클라이언트 (무인증)
live_state.py # 라이브 세션 인메모리 상태
telemetry.py # /api/live/* 라우터 (+ 데모 리플레이)
radio_transcriber.py # F1 TV 오디오 → Faster-Whisper 전사 (선택)
ingest.py # FIA PDF → ChromaDB 임베딩 (체크포인트·레이트리밋 대응)
static/ # 챗 UI, 텔레메트리 대시보드
docs/ # 개발 기록 (아키텍처 마이그레이션 계획, 에이전트 전환 보고)
- 규정 PDF는 직접 내려받아야 함 (FIA 저작권 — data/README.md)
- 팀 라디오 전사는 F1 TV Premium 구독 + FFmpeg 필요
- 대화 히스토리는 인메모리(
MemorySaver) — 서버 재시작 시 초기화
MIT