hgzero/ai-python/API-DOCUMENTATION.md
2025-10-29 17:35:01 +09:00

7.9 KiB

AI Service API Documentation

서비스 정보

  • Base URL: http://localhost:8086
  • 프로덕션 URL: http://{AKS-IP}:8086 (배포 후)
  • 포트: 8086
  • 프로토콜: HTTP
  • CORS: 모든 origin 허용 (개발 환경)

API 엔드포인트

1. 실시간 AI 제안사항 스트리밍 (SSE)

엔드포인트: GET /api/ai/suggestions/meetings/{meeting_id}/stream

설명: 회의 중 실시간으로 AI 제안사항을 Server-Sent Events로 스트리밍합니다.

파라미터:

이름 위치 타입 필수 설명
meeting_id path string O 회의 ID

응답 형식: text/event-stream

SSE 이벤트 구조:

event: ai-suggestion
id: 15
data: {"suggestions":[{"id":"uuid","content":"제안 내용","timestamp":"14:23:45","confidence":0.92}]}

응답 데이터 스키마:

interface SimpleSuggestion {
  id: string;              // 제안 ID (UUID)
  content: string;         // 제안 내용 (1-2문장)
  timestamp: string;       // 타임스탬프 (HH:MM:SS)
  confidence: number;      // 신뢰도 (0.0 ~ 1.0)
}

interface RealtimeSuggestionsResponse {
  suggestions: SimpleSuggestion[];
}

프론트엔드 연동 예시 (JavaScript/TypeScript):

// EventSource 연결
const meetingId = 'meeting-123';
const eventSource = new EventSource(
  `http://localhost:8087/api/ai/suggestions/meetings/${meetingId}/stream`
);

// AI 제안사항 수신
eventSource.addEventListener('ai-suggestion', (event) => {
  const data = JSON.parse(event.data);

  data.suggestions.forEach(suggestion => {
    console.log('새 제안:', suggestion.content);
    console.log('신뢰도:', suggestion.confidence);
    console.log('시간:', suggestion.timestamp);

    // UI 업데이트
    addSuggestionToUI(suggestion);
  });
});

// 에러 핸들링
eventSource.onerror = (error) => {
  console.error('SSE 연결 오류:', error);
  eventSource.close();
};

// 연결 종료 (회의 종료 시)
function closeSuggestions() {
  eventSource.close();
}

React 예시:

import { useEffect, useState } from 'react';

interface Suggestion {
  id: string;
  content: string;
  timestamp: string;
  confidence: number;
}

function MeetingRoom({ meetingId }: { meetingId: string }) {
  const [suggestions, setSuggestions] = useState<Suggestion[]>([]);

  useEffect(() => {
    const eventSource = new EventSource(
      `http://localhost:8087/api/ai/suggestions/meetings/${meetingId}/stream`
    );

    eventSource.addEventListener('ai-suggestion', (event) => {
      const data = JSON.parse(event.data);
      setSuggestions(prev => [...prev, ...data.suggestions]);
    });

    eventSource.onerror = () => {
      console.error('SSE 연결 오류');
      eventSource.close();
    };

    return () => {
      eventSource.close();
    };
  }, [meetingId]);

  return (
    <div>
      <h2>AI 제안사항</h2>
      {suggestions.map(s => (
        <div key={s.id}>
          <span>{s.timestamp}</span>
          <p>{s.content}</p>
          <small>신뢰도: {(s.confidence * 100).toFixed(0)}%</small>
        </div>
      ))}
    </div>
  );
}

2. 헬스 체크

엔드포인트: GET /health

설명: 서비스 상태 확인 (Kubernetes probe용)

응답 예시:

{
  "status": "healthy",
  "service": "AI Service",
  "port": 8087
}

3. 서비스 정보

엔드포인트: GET /

설명: 서비스 기본 정보 조회

응답 예시:

{
  "service": "AI Service",
  "version": "1.0.0",
  "status": "running",
  "endpoints": {
    "test": "/api/ai/suggestions/test",
    "stream": "/api/ai/suggestions/meetings/{meeting_id}/stream"
  }
}

동작 흐름

1. 회의 시작
   └─> 프론트엔드가 SSE 연결 시작

2. 음성 녹음
   └─> STT 서비스가 텍스트 변환
       └─> Event Hub 발행
           └─> AI 서비스가 Redis에 축적

3. 실시간 분석 (5초마다)
   └─> Redis에서 텍스트 조회
       └─> 임계값(10개 세그먼트) 도달 시
           └─> Claude API 분석
               └─> SSE로 제안사항 전송
                   └─> 프론트엔드 UI 업데이트

4. 회의 종료
   └─> SSE 연결 종료

주의사항

  1. 연결 유지:

    • SSE 연결은 장시간 유지되므로 네트워크 타임아웃 설정 필요
    • 브라우저는 연결 끊김 시 자동 재연결 시도
  2. CORS:

    • 개발 환경: 모든 origin 허용
    • 프로덕션: 특정 도메인만 허용하도록 설정 필요
  3. 에러 처리:

    • SSE 연결 실패 시 재시도 로직 구현 권장
    • 네트워크 오류 시 사용자에게 알림
  4. 성능:

    • 한 회의당 하나의 SSE 연결만 유지
    • 불필요한 재연결 방지

테스트

curl 테스트:

# 헬스 체크
curl http://localhost:8087/health

# SSE 스트리밍 테스트
curl -N http://localhost:8087/api/ai/suggestions/meetings/test-meeting/stream

브라우저 테스트:

  1. 서비스 실행: python3 main.py
  2. Swagger UI 접속: http://localhost:8087/docs
  3. /api/ai/suggestions/meetings/{meeting_id}/stream 엔드포인트 테스트

환경 변수

프론트엔드에서 API URL을 환경 변수로 관리:

# .env.local
NEXT_PUBLIC_AI_SERVICE_URL=http://localhost:8087
const AI_SERVICE_URL = process.env.NEXT_PUBLIC_AI_SERVICE_URL || 'http://localhost:8087';

const eventSource = new EventSource(
  `${AI_SERVICE_URL}/api/ai/suggestions/meetings/${meetingId}/stream`
);

FAQ

Q: SSE vs WebSocket? A: SSE는 서버→클라이언트 단방향 통신에 최적화되어 있습니다. 이 서비스는 AI 제안사항을 프론트엔드로 전송만 하므로 SSE가 적합합니다.

Q: 재연결은 어떻게? A: 브라우저의 EventSource는 자동으로 재연결을 시도합니다. 추가 로직 불필요.

Q: 여러 클라이언트가 동시 연결 가능? A: 네, 각 클라이언트는 독립적으로 SSE 연결을 유지합니다.

Q: 제안사항이 오지 않으면? A: Redis에 충분한 텍스트(10개 세그먼트)가 축적되어야 분석이 시작됩니다. 5초마다 체크합니다.

3. AI 텍스트 요약 생성

엔드포인트: POST /api/v1/ai/summary/generate

설명: 텍스트를 AI로 요약하여 핵심 내용과 포인트를 추출합니다.

요청 본문:

{
  "text": "요약할 텍스트 내용",
  "language": "ko",  // ko: 한국어, en: 영어 (기본값: ko)
  "style": "bullet", // bullet: 불릿포인트, paragraph: 단락형 (기본값: bullet)
  "max_length": 100  // 최대 요약 길이 (단어 수) - 선택사항
}

응답 예시:

{
  "summary": "• 프로젝트 총 개발 기간 3개월 확정 (디자인 2주, 개발 8주, 테스트 2주)\n• 총 예산 5천만원 배정 (인건비 3천만원, 인프라 1천만원, 기타 1천만원)\n• 주간 회의 일정: 매주 화요일 오전 10시",
  "key_points": [
    "프로젝트 전체 일정 3개월로 확정",
    "개발 단계별 기간: 디자인 2주, 개발 8주, 테스트 2주",
    "총 예산 5천만원 책정",
    "예산 배분: 인건비 60%, 인프라 20%, 기타 20%",
    "정기 회의: 매주 화요일 오전 10시"
  ],
  "word_count": 32,
  "original_word_count": 46,
  "compression_ratio": 0.7,
  "generated_at": "2025-10-29T17:23:49.429982"
}

요청 예시 (curl):

curl -X POST "http://localhost:8086/api/v1/ai/summary/generate" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "오늘 회의에서는 프로젝트 일정과 예산에 대해 논의했습니다...",
    "language": "ko",
    "style": "bullet"
  }'

에러 응답:

  • 400 Bad Request: 텍스트가 비어있거나 너무 짧은 경우 (최소 20자)
  • 400 Bad Request: 텍스트가 너무 긴 경우 (최대 10,000자)
  • 500 Internal Server Error: AI 처리 중 오류 발생