# Keep (이번 주에 잘한 일)
- 1. daily scrum을 진행하여 전날 / 오늘 할 작업에 대해서 공유함
- 2. exception_handler을 사용하여 에러메세지 기본 형식을 통일함
- 3. swagger에 기획서와 작업물 2가지를 추가하여 프론트에게 제공함
- 4. 구현 완료된 기능은 기능의 결과값을 기반으로 api명세를 수정함
- 5. 내가 맡은 파트에서 프론트구현에 대해서 궁금한 점은 직접 물어봤음
# Problem (고쳐야 할 점)
- 1. 프론트와 현재 진행상황은 지속적으로 공유하지 않았음
# Try (Keep과 Problem을 기반으로 시도해볼 것)
- 1. 기능개발은 지금처럼 진행하되 프론트와 소통을 좀 늘려야 할 듯
AI
AI 모델(OpenAI API 등)을 연동
- APIView의 post 또는 get 메서드 내에서 AI 모델을 호출하고 응답을 반환하는 구조
- pip install djangorestframework openai python-dotenv 설치 필요
views.py
import os
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from openai import OpenAI
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
class AICompletionView(APIView):
def post(self, request):
user_prompt = request.data.get('prompt')
if not user_prompt:
return Response({"error": "Prompt is required"}, status=status.HTTP_400_BAD_REQUEST)
try:
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": user_prompt}]
)
ai_message = response.choices[0].message.content
return Response({"result": ai_message}, status=status.HTTP_200_OK)
except Exception as e:
return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
from django.urls import path
from .views import AICompletionView
urlpatterns = [
path('ai/generate/', AICompletionView.as_view(), name='ai-generate'),
]
작동 방식 요약
- POST 요
- 클라이언트가 {"prompt": "안녕?"}과 같은 JSON 데이터를 보냄
- APIView 처리
- view(ex. AICompletionView)가 이를 받아 OpenAI API에 데이터를 전달
- AI 응답
- JSON 응답
- APIView가 최종적으로 {"result": "안녕하세요!..."} 형식으로 클라이언트에게 응답함
추가 고민
- 비동기 처리
- AI 모델 응답이 길어질 경우, APIView 대신 Celery 같은 백그라운드 작업을 활용하는 것 고민
- 랑체인(LangChain) 연동
- 복잡한 AI 워크플로우가 필요하면, APIView 내부에서 LangChain을 연동하여 사용
제미나이
- 1. 라이브러리
pip install google-generativeai python-dotenv djangorestframework
- 2. 제미나이 API Key 설정
- Google AI Studio에서 API Key를 발급받고
- Django 프로젝트 루트 디렉토리에 .env 파일을 생성하여 Key를 저장
GOOGLE_API_KEY=your_gemini_api_key_here
- 3. Django 프로젝트 설정 (Settings)
- settings.py에서 .env 파일을 로드하고 제미나이 API Key를 설정
import os
from dotenv import load_dotenv
load_dotenv()
GEMINI_API_KEY = os.getenv("GOOGLE_API_KEY")
INSTALLED_APPS = [
'rest_framework',
'your_app_name',
]
- 4. APIView 구현 및 URL 매핑
- APIView를 상속받아 POST 요청을 처리하는 뷰를 생성하고, URL 패턴에 연결
- 5. 테스트 (Postman/cURL)
- 서버 실행 후, http://127.0.0.1 엔드포인트로 POST 요청을 보내며,
- 요청 본문에는 "prompt" 필드를 포함하여 보내야 함
-
코드 대기
from django.conf import settings
from apps.community.models.reviews import Review
import openai
def get_review_summary(game_id: int) -> str:
"""
특정 게임의 리뷰들을 조회하여 AI를 통해 요약본을 생성합니다.
"""
reviews = Review.objects.filter(game_id=game_id, is_deleted=False).order_by("-created_at")[:30]
if not reviews:
return "작성된 리뷰가 없습니다."
reviews_text = "\n".join([f"- {r.content}" for r in reviews])
prompt = f"""
아래는 특정 게임에 대한 유저들의 리뷰 모음입니다.
이 게임에 대한 유저들의 전반적인 평가를 3줄로 요약해주세요.
[리뷰 목록]
{reviews_text}
"""
try:
client = openai.OpenAI(api_key=settings.OPENAI_API_KEY)
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "당신은 게임 리뷰 요약 전문가입니다."},
{"role": "user", "content": prompt}
]
)
summary = response.choices[0].message.content
return summary
except Exception as e:
return "요약 서비스를 일시적으로 사용할 수 없습니다."
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from drf_spectacular.utils import extend_schema, inline_serializer
from rest_framework import serializers
from apps.community.services.review.review_summary_service import get_review_summary
class ReviewSummaryAPIView(APIView):
permission_classes = [IsAuthenticatedOrReadOnly]
@extend_schema(
tags=["리뷰"],
summary="리뷰 AI 요약 API",
responses={
200: inline_serializer(
name="ReviewSummaryResponse",
fields={
"game_id": serializers.IntegerField(),
"summary": serializers.CharField(),
},
),
},
)
def post(self, request, game_id: int):
"""
특정 게임의 리뷰 요약을 요청합니다.
(요약 비용 등을 고려하여 POST 요청으로 설계하거나, 캐싱을 적용한 GET으로 설계할 수 있습니다.)
"""
summary_text = get_review_summary(game_id=game_id)
return Response(
{
"game_id": game_id,
"summary": summary_text
},
status=status.HTTP_200_OK
)
from django.urls import path
from apps.community.views.review_api import ReviewAPIView
from apps.community.views.review_like_api import ReviewLikeAPIView
from apps.community.views.review_update_api import ReviewUpdateAPIView
from apps.community.views.review_summary_api import ReviewSummaryAPIView
urlpatterns = [
path("<int:game_id>/reviews", ReviewAPIView.as_view(), name="game_review_create"),
path(
"reviews/<int:review_id>/like", ReviewLikeAPIView.as_view(), name="review_like"
),
path(
"reviews/<int:review_id>", ReviewUpdateAPIView.as_view(), name="review_update"
),
path(
"<int:game_id>/reviews/summary", ReviewSummaryAPIView.as_view(), name="game_review_summary"
),
]
chatGPT
Gemini
기초세팅
- API 키 발급
- 라이브러리 설치
poetry add google-generativeai
참고