AI Service: Flask VS FastAPI
AI Service를 구축하기 위해 Flask와 FastAPI의 비교
Flask
장점
- 간단하고 가벼움: 초보자도 쉽게 시작할 수 있는 단순한 구조
- 유연성: 개발자가 원하는 대로 구조를 설계할 수 있음
- 광범위한 커뮤니티와 풍부한 확장 기능
단점
- 비동기 처리가 기본적으로 지원되지 않음
- 대규모 애플리케이션에서는 구조화에 더 많은 노력이 필요
- 타입 힌팅이 기본적으로 제공되지 않음
FastAPI
장점
- 빠른 성능: 비동기 처리를 기본적으로 지원
- 자동 문서화: Swagger UI와 ReDoc을 통한 API 문서 자동 생성
- 타입 힌팅과 데이터 검증: Pydantic을 이용한 강력한 타입 체크와 데이터 검증
- 현대적인 Python 기능 활용: 비동기 프로그래밍, 타입 힌팅 등
단점
- 학습 곡선: 비동기 프로그래밍과 타입 시스템에 대한 이해가 필요
- 상대적으로 새로운 프레임워크: Flask에 비해 커뮤니티와 리소스가 적음
- 일부 레거시 시스템과의 통합이 어려울 수 있음
AI 서비스 구축 관점에서
- Flask는 간단한 AI 모델 서빙이나 프로토타이핑에 적합할 수 있습니다.
- FastAPI는 대규모 AI 서비스, 실시간 처리가 필요한 경우, 또는 복잡한 데이터 구조를 다루는 경우에 더 적합할 수 있습니다.
Flask
기본 - Flask
디렉토리 구조
project_folder/
├── .env
├── app.py
└── templates/
└── index.html
.env
OPENAI_API_KEY=your_openai_api_key
index.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI 챗봇</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<style>
body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
#chat-container { border: 1px solid #ccc; height: 400px; overflow-y: scroll; padding: 10px; margin-bottom: 10px; }
#user-input { width: 100%; padding: 5px; margin-bottom: 10px; }
#send-button { padding: 5px 10px; }
</style>
</head>
<body>
<h1>AI 챗봇</h1>
<div id="chat-container"></div>
<input type="text" id="user-input" placeholder="메시지를 입력하세요...">
<button id="send-button">전송</button>
<script>
$(document).ready(function() {
function sendMessage() {
var message = $("#user-input").val();
if (message.trim() === "") return;
$("#chat-container").append("<p><strong>사용자:</strong> " + message + "</p>");
$("#user-input").val("");
$.ajax({
url: "/chat",
type: "POST",
contentType: "application/json",
data: JSON.stringify({message: message}),
success: function(response) {
$("#chat-container").append("<p><strong>AI:</strong> " + response.response + "</p>");
$("#chat-container").scrollTop($("#chat-container")[0].scrollHeight);
}
});
}
$("#send-button").click(sendMessage);
$("#user-input").keypress(function(e) {
if (e.which == 13) sendMessage();
});
});
</script>
</body>
</html>
app.py
from dotenv import load_dotenv
load_dotenv()
from flask import Flask, render_template, request, jsonify
from openai import OpenAI
app = Flask(__name__)
@app.route("/")
def index():
return render_template("index.html")
@app.route("/chat", methods=["POST"])
def chat():
user_message = request.json["message"]
client = OpenAI()
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": user_message}
]
)
ai_message = response.choices[0].message.content
return jsonify({"response": ai_message})
if __name__ == "__main__":
app.run(debug=True)
# 실행
python app.py
# 브라우저에서 접속
http://localhost:5000
이전 대화 기억
app.py
from dotenv import load_dotenv
load_dotenv()
from flask import Flask, render_template, request, jsonify
from openai import OpenAI
import time
app = Flask(__name__)
client = OpenAI()
# 대화 기록을 저장할 리스트
conversation_history = []
@app.route("/")
def index():
return render_template("index.html")
@app.route("/chat", methods=["POST"])
def chat():
time.sleep(5)
user_message = request.json["message"]
# 사용자 메시지를 대화 기록에 추가
conversation_history.append({"role": "user", "content": user_message})
# OpenAI API 호출
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
] + conversation_history # 시스템 메시지와 대화 기록을 합침
)
ai_message = response.choices[0].message.content
# AI 응답을 대화 기록에 추가
conversation_history.append({"role": "assistant", "content": ai_message})
# 대화 기록이 너무 길어지지 않도록 제한 (선택사항)
if len(conversation_history) > 10: # 최근 10개의 메시지만 유지
conversation_history.pop(0)
return jsonify({"response": ai_message})
@app.route("/history", methods=["GET"])
def get_history():
return jsonify(conversation_history)
if __name__ == "__main__":
app.run(debug=True)
FastAPI
기본 - FastAPI
디렉토리 구조
project_folder/
├── .env
├── main.py
└── chat.py
.env
OPENAI_API_KEY=your_openai_api_key
main.py
from dotenv import load_dotenv
load_dotenv()
from fastapi import FastAPI
from pydantic import BaseModel
from openai import OpenAI
app = FastAPI()
# Pydantic 모델 정의
class ChatRequest(BaseModel):
message: str
class ChatResponse(BaseModel):
response: str
@app.post("/chat", response_model=ChatResponse)
async def chat(chat_request: ChatRequest):
client = OpenAI()
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": chat_request.message}
]
)
ai_message = response.choices[0].message.content
return ChatResponse(response=ai_message)
# 실행
uvicorn main:app --reload
# 브라우저에서 접속
http://localhost:8000/docs
chat.py
import requests
# FastAPI 서버 URL
url = "http://localhost:8000/chat"
def chat_with_ai():
print("AI 어시스턴트와의 대화를 시작합니다. 종료하려면 '/q'를 입력하세요.")
while True:
# 사용자 입력 받기
user_message = input("You: ")
# 종료 조건 확인
if user_message.lower() == '/q':
print("대화를 종료합니다.")
break
# 요청 데이터 준비
data = {"message": user_message}
try:
# HTTP POST 요청 보내기
response = requests.post(url, json=data)
# 응답 확인
if response.status_code == 200:
result = response.json()
ai_response = result["response"]
print("AI:", ai_response)
else:
print(f"오류 발생: HTTP {response.status_code}")
print("응답:", response.text)
except requests.RequestException as e:
print(f"요청 중 오류 발생: {e}")
if __name__ == "__main__":
chat_with_ai()
# 실행
python chat.py
# /q 입력하면 종료
이전 대화 기억 - FastAPI
main.py
수정
from dotenv import load_dotenv
load_dotenv()
from fastapi import FastAPI
from pydantic import BaseModel
from openai import OpenAI
from typing import List, Dict
app = FastAPI()
# 대화 기록을 저장할 전역 리스트
conversation_history: List[Dict[str, str]] = []
# Pydantic 모델 정의
class ChatRequest(BaseModel):
message: str
class ChatResponse(BaseModel):
response: str
@app.post("/chat", response_model=ChatResponse)
async def chat(chat_request: ChatRequest):
global conversation_history
# 사용자 메시지를 대화 기록에 추가
conversation_history.append({"role": "user", "content": chat_request.message})
# OpenAI API 호출 준비
client = OpenAI()
messages = [
{"role": "system", "content": "You are a helpful assistant."},
] + conversation_history # 시스템 메시지와 대화 기록을 합침
# OpenAI API 호출
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=messages
)
ai_message = response.choices[0].message.content
# AI 응답을 대화 기록에 추가
conversation_history.append({"role": "assistant", "content": ai_message})
# 대화 기록이 너무 길어지지 않도록 제한 (선택사항)
if len(conversation_history) > 10: # 최근 10개의 메시지만 유지
conversation_history = conversation_history[-10:]
return ChatResponse(response=ai_message)
@app.get("/reset")
async def reset_conversation():
global conversation_history
conversation_history = []
return {"message": "Conversation history has been reset."}
# 서버 실행
uvicorn main:app --reload
# 클라이언트 실행
python chat.py
# /q 입력하면 종료
사용자별로 대화 기록 저장 - FastAPI
main.py
수정
from dotenv import load_dotenv
load_dotenv()
from fastapi import FastAPI, Depends
from pydantic import BaseModel
from openai import OpenAI
from typing import List, Dict
app = FastAPI()
# 대화 기록을 저장할 전역 딕셔너리
conversation_history: Dict[str, List[Dict[str, str]]] = {}
# Pydantic 모델 정의
class ChatRequest(BaseModel):
message: str
conversation_id: str
class ChatResponse(BaseModel):
response: str
def get_conversation(conversation_id: str) -> List[Dict[str, str]]:
if conversation_id not in conversation_history:
conversation_history[conversation_id] = []
return conversation_history[conversation_id]
@app.post("/chat", response_model=ChatResponse)
async def chat(chat_request: ChatRequest):
conversation = get_conversation(chat_request.conversation_id)
# 사용자 메시지를 대화 기록에 추가
conversation.append({"role": "user", "content": chat_request.message})
# OpenAI API 호출 준비
client = OpenAI()
messages = [
{"role": "system", "content": "You are a helpful assistant."},
] + conversation # 시스템 메시지와 대화 기록을 합침
# OpenAI API 호출
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=messages
)
ai_message = response.choices[0].message.content
# AI 응답을 대화 기록에 추가
conversation.append({"role": "assistant", "content": ai_message})
# 대화 기록이 너무 길어지지 않도록 제한 (선택사항)
if len(conversation) > 10: # 최근 10개의 메시지만 유지
conversation = conversation[-10:]
return ChatResponse(response=ai_message)
chat.py
수정
import requests
import uuid
# FastAPI 서버 URL
url = "http://localhost:8000/chat"
def chat_with_ai():
print("AI 어시스턴트와의 대화를 시작합니다. 종료하려면 '/q'를 입력하세요.")
# 사용자별 고유 conversation_id 생성
conversation_id = str(uuid.uuid4())
print(f"Your conversation ID: {conversation_id}")
while True:
# 사용자 입력 받기
user_message = input("You: ")
# 종료 조건 확인
if user_message.lower() == '/q':
print("대화를 종료합니다.")
break
# 요청 데이터 준비
data = {
"message": user_message,
"conversation_id": conversation_id
}
try:
# HTTP POST 요청 보내기
response = requests.post(url, json=data)
# 응답 확인
if response.status_code == 200:
result = response.json()
ai_response = result["response"]
print("AI:", ai_response)
else:
print(f"오류 발생: HTTP {response.status_code}")
print("응답:", response.text)
except requests.RequestException as e:
print(f"요청 중 오류 발생: {e}")
if __name__ == "__main__":
chat_with_ai()
# 서버 실행
uvicorn main:app --reload
### 2개의 클라이언트 실행하여 대화가 구분되어 저장되는지 확인
# A 클라이언트 실행
python chat.py
# B 클라이언트 실행
python chat.py
# /q 입력하면 종료
'인공지능 > 챗봇' 카테고리의 다른 글
Telegram - ChatBot (OpenAI API) (0) | 2024.04.30 |
---|