뉴스낵의 AI 콘텐츠 생성을 담당하는 FastAPI 서버입니다. LangGraph 기반 워크플로우로 뉴스툰(웹툰/카드뉴스)과 오늘의 뉴스낵(오디오 브리핑)을 자동 생성하며, 완성된 이미지와 오디오 파일은 S3에, 메타데이터는 PostgreSQL(RDS)에 저장합니다.
- 외부 파이프라인에서 API 호출로 뉴스툰/오늘의 뉴스낵 생성
- 이슈별 뉴스툰(웹툰 또는 카드뉴스) 생성
- 오늘의 뉴스낵(오디오 브리핑) 생성
- 이미지 리서치 에이전트: 도구를 활용해 기사 생성에 참조할 이미지(로고, 인물 등) 수집
- 멀티 프로바이더 지원: Google, OpenAI 사용 가능
- Redis 기반 분산 Circuit Breaker: 특정 이미지 모델 장애 시 Fallback 모델로 자동 라우팅
LangGraph StateGraph로 구현된 뉴스툰(웹툰/카드뉴스) 생성 워크플로우
주요 노드 설명:
analyze_article: 원본 기사 분석, 제목/요약 생성, 콘텐츠 타입(웹툰/카드뉴스) 결정image_researcher: 기사 맥락에 맞는 에셋(로고, 인물 등)을 판단하고, 스스로 검색 도구를 호출해 수집하는 에이전트 노드validate_image: 리서치된 이미지가 원본 기사에 적합한지 멀티모달 모델로 정밀 검증select_editor: 이슈의 카테고리와 일치하는 에디터 배정 (없으면 랜덤)draft_article: 에디터 페르소나 기반 본문 작성 및 이미지 프롬프트 4개 생성 (콘텐츠 타입에 따라 웹툰/카드뉴스 스타일 내부 분기)generate_images: 프로바이더 설정에 따라 최종 이미지 4장 생성- 컷 간 작화 유지를 위해 1장을 기준 이미지로 선 생성 후, 나머지 3장은 이를 '스타일'로 참조하여 병렬 생성
- 참고: 만약
image_researcher에서 찾은 이미지(실사, 로고 등)가 있다면, 1장(기준) 생성 단계에서 이를 '내용(Content)'으로 추가 참조하여 기사 맥락을 반영함
save_ai_article: ai_article 테이블 저장, reaction_count 초기화, 이슈 처리 상태 업데이트
외부에서 선정된 이슈 ID들을 받아 오늘의 뉴스낵(오디오 브리핑)으로 생성
주요 노드 설명:
fetch_articles: 요청받은 Issue ID 리스트에 해당하는 AI 기사들을 조회 (ID 순 정렬)assemble_briefing: 조회된 기사들을 구조화된 대본으로 변환 (기사 개수 유동적)generate_audio: 대본을 하나로 병합 후 TTS 생성, 오디오 길이 측정 및 타임라인 계산save_today_newsnack: S3 업로드 및 today_newsnack 테이블 저장
이 서버는 오케스트레이터(newsnack-orchestrator)의 호출을 받아 워크플로우를 실행합니다.
- 뉴스툰 생성 트리거:
POST /ai-articles - 오늘의 뉴스낵 생성 트리거:
POST /today-newsnack
상세 명세는 서버 실행 후 Swagger UI(http://localhost:8000/docs)에서 확인 가능합니다.
필수:
API_KEY: 요청 헤더X-API-KEY검증용DB_URL: PostgreSQL 연결 문자열REDIS_URL: Redis 연결 문자열AWS_REGION,AWS_S3_BUCKET,AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY
AI 프로바이더:
AI_PROVIDER:google(기본) 또는openaiGOOGLE_API_KEY(AI_PROVIDER=google일 때 필수)OPENAI_API_KEY(AI_PROVIDER=openai일 때 필수)
검색 도구 API (선택. 이미지 리서치 기능 사용 시):
LOGO_DEV_SECRET_KEY,LOGO_DEV_PUBLISHABLE_KEY: 기업 로고 검색용 (Logo.dev)KAKAO_REST_API_KEY: 기존 도구 실패 시 이미지 검색용 (Daum)
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
uvicorn app.main:app --reload- 프로바이더 전환:
AI_PROVIDER=openai

