Skip to content

AI 서비스 통합

truloop-ai-server가 연동하는 AI 서비스 프로바이더들을 설명합니다.


프로바이더 개요


프로바이더 상세

OpenRouter (이미지 분석/이미지 선택 LLM Gateway)

항목설명
역할이미지 분석, 이미지 선택, 텍스트 생성
지원 모델Anthropic Claude (주력), OpenAI GPT 등
인증OPENROUTER_API_KEY
용도이미지 설명/태깅, 최적 이미지 선택, post message 생성
구현call_claude_with_retry() in app/services/common/utils.py

OpenRouter는 다양한 LLM 프로바이더의 통합 게이트웨이 역할을 합니다. 단일 API Key로 여러 모델에 접근할 수 있어 프로바이더 전환이 용이합니다.

정보

OpenRouter 호출은 OpenAI Python SDK (AsyncOpenAI)를 사용하여 OpenRouter 엔드포인트(https://openrouter.ai/api/v1)로 요청합니다. 응답은 내부적으로 Anthropic 응답 형식(MockAnthropicResponse)으로 변환하여 기존 코드와 호환됩니다.

Junis AI (주력 콘텐츠 생성)

항목설명
역할하이라이트/포스터/스토리 콘텐츠 생성
인증JUNIS_API_KEY
도메인JUNIS_DOMAIN (기본: https://content.junis.ai)
통신 방식비동기 웹훅 기반 — 요청 후 결과는 webhook으로 전달
구현app/services/content_template/junis_content_generator.py
인터페이스ContentGeneratorInterface (ABC)

Junis AI는 실제 콘텐츠 생성(하이라이트 비디오, 포스터 이미지, 스토리 텍스트)을 수행하는 핵심 프로바이더입니다. 요청 시 webhook_url을 포함하여 비동기로 결과를 받습니다.

Replicate / FAL

항목설명
역할특수 이미지/비디오 모델 실행
상태의존성에 포함되어 있으나 현재 주요 콘텐츠 생성 흐름에서 직접 사용되지 않음
인증REPLICATE_API_TOKEN / FAL SDK
특징GPU 기반 추론, 비동기 처리

콘텐츠 생성 흐름

이미지 분석 흐름

콘텐츠 생성 흐름


프롬프트 관리

버전 관리 시스템

AI 프롬프트는 DB에서 버전 관리됩니다:

모델테이블역할
AIPromptTemplateai_prompt_templates프롬프트 템플릿 정의 (카테고리별)
AIPromptVersionai_prompt_versions프롬프트 버전 (모델명, 온도, 최대 토큰, 프롬프트 텍스트)
AIPromptTemplate (1) ──→ (N) AIPromptVersion
  • AIPromptTemplatePromptCategory 기반으로 분류 (image_description, image_tag, thumbnail_title, image_selection 등)
  • AIPromptVersionmodel_name, temperature, max_tokens, prompt_text 등을 포함
  • 활성 버전(is_active=True)의 최신 버전을 사용
  • 프롬프트 변경 시 새 버전을 생성하여 이력 유지
  • 관리자 UI (SQLAdmin)에서 프롬프트 편집 가능

다국어 지원

콘텐츠 생성 시 lang_code 파라미터로 생성 언어를 지정합니다:

언어 코드언어
ko한국어
en영어
ja일본어

최적 이미지 선택

BestImageSelector 서비스는 재귀적 토너먼트 방식으로 AI를 활용하여 룹의 이미지들 중 콘텐츠에 가장 적합한 이미지를 자동 선택합니다.

선택 방식

메서드선택 수설명
recursive_select()1개단일 최적 이미지 선택
recursive_select_with_selected_image_count()N개 (1, 3, 5)복수 최적 이미지 선택

토너먼트 흐름

단계설명
1. 이미지 로드병렬로 이미지를 base64로 변환 (thumbnail > optimized > original 우선순위)
2. 그룹 분할group_size (기본: 10)개씩 그룹으로 분할
3. 그룹별 AI 선택Claude를 통해 각 그룹에서 최적 이미지 선택
4. 승자 재귀각 그룹의 승자를 모아 다시 토너먼트 진행
5. 최종 선택최종 승자 반환

정보

AI 선택 실패 시 random.sample()로 fallback합니다. 이미지 캐싱(_image_cache)을 지원하여 같은 이미지의 중복 다운로드를 방지합니다.


에러 처리

상황처리
OpenRouter API 호출 실패call_claude_with_retry()에서 최대 3회 재시도
Junis API 타임아웃120초 전체 타임아웃, 30초 연결 타임아웃
Celery 태스크 실패재시도 없음 (max_retries=0), 에러 로깅
모델 할당량 초과ClaudeRateLimiter로 사전 제어 (동시 3개, 분당 50개)
잘못된 AI 응답 형식파싱 에러 로깅, 태스크 실패 기록 (ContentStatus.FAILED)
웹훅 에러Sentry에 상세 컨텍스트와 함께 보고, LoopGeneratedContent 상태를 FAILED로 업데이트
미디어 없음ValueError 발생, 콘텐츠 상태 FAILED로 업데이트
이미지 선택 실패random.sample()로 fallback 선택