본문 바로가기

AI 개발 실습

FastAPI로 AI 챗봇 백엔드 만들기 — Gemini 연동 완성

FastAPI로 AI 챗봇 백엔드 만들기 — Gemini 연동 완성

지난 글에서 FastAPI 기본 구조를 익혔으니까,
이번엔 실제로 Gemini API를 붙여서 동작하는 챗봇 백엔드를 만들어볼게요.

이 글 끝나면 Postman이나 브라우저에서 메시지를 보내면
AI가 답변을 돌려주는 서버가 완성돼요.


만들 것 미리보기

POST /chat
요청: { "message": "파이썬이 뭔가요?" }
응답: { "reply": "파이썬은 ...", "session_id": "abc123" }

단순하지만 이게 AI 챗봇 백엔드의 핵심이에요.


프로젝트 구조

chatbot/
├── main.py          # 서버 진입점
├── .env             # API 키
└── requirements.txt

처음엔 이 정도면 충분해요.


1단계 — 패키지 설치

pip install fastapi uvicorn google-generativeai python-dotenv

requirements.txt로 저장:

pip freeze > requirements.txt

2단계 — .env 파일 설정

GEMINI_API_KEY=여기에_발급받은_API_키

3단계 — main.py 작성

from fastapi import FastAPI
from pydantic import BaseModel
from dotenv import load_dotenv
import google.generativeai as genai
import os
import uuid

load_dotenv()

genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
model = genai.GenerativeModel(
    model_name="gemini-1.5-flash",
    system_instruction="당신은 친절한 AI 어시스턴트입니다. 한국어로 답변하세요."
)

app = FastAPI()

# 요청/응답 모델
class ChatRequest(BaseModel):
    message: str

class ChatResponse(BaseModel):
    reply: str
    session_id: str

# 채팅 엔드포인트
@app.post("/chat", response_model=ChatResponse)
def chat(request: ChatRequest):
    response = model.generate_content(request.message)
    return ChatResponse(
        reply=response.text,
        session_id=str(uuid.uuid4())
    )

# 서버 상태 확인용
@app.get("/health")
def health():
    return {"status": "ok"}

4단계 — 서버 실행

uvicorn main:app --reload

5단계 — 테스트

서버 실행 후 브라우저에서 http://127.0.0.1:8000/docs 접속하면
Swagger UI가 자동으로 열려요.

거기서 /chat 엔드포인트 클릭 → Try it out → 메시지 입력 → Execute

또는 터미널에서 curl로 테스트:

curl -X POST "http://127.0.0.1:8000/chat" \
  -H "Content-Type: application/json" \
  -d '{"message": "파이썬이 뭔가요?"}'

응답이 이렇게 돌아오면 성공이에요:

{
  "reply": "파이썬은 ...",
  "session_id": "a1b2c3d4-..."
}

대화 맥락 유지하기 (멀티턴)

위 코드는 매 요청이 독립적이라 이전 대화를 기억 못 해요.
대화 맥락을 유지하려면 세션별로 히스토리를 저장해야 해요.

from fastapi import FastAPI
from pydantic import BaseModel
from dotenv import load_dotenv
import google.generativeai as genai
import os
import uuid

load_dotenv()
genai.configure(api_key=os.getenv("GEMINI_API_KEY"))

model = genai.GenerativeModel(
    model_name="gemini-1.5-flash",
    system_instruction="당신은 친절한 AI 어시스턴트입니다. 한국어로 답변하세요."
)

app = FastAPI()

# 세션 저장소 (메모리)
sessions = {}

class ChatRequest(BaseModel):
    message: str
    session_id: str = None  # 없으면 새 세션 생성

class ChatResponse(BaseModel):
    reply: str
    session_id: str

@app.post("/chat", response_model=ChatResponse)
def chat(request: ChatRequest):
    # 세션 ID 결정
    session_id = request.session_id or str(uuid.uuid4())

    # 세션 없으면 새로 생성
    if session_id not in sessions:
        sessions[session_id] = model.start_chat(history=[])

    # 메시지 전송
    chat_session = sessions[session_id]
    response = chat_session.send_message(request.message)

    return ChatResponse(
        reply=response.text,
        session_id=session_id
    )

이제 첫 요청에서 받은 session_id를 다음 요청에 넣으면
이전 대화를 기억하는 챗봇이 돼요.


테스트 흐름

# 1번째 메시지 (session_id 없이)
curl -X POST "http://127.0.0.1:8000/chat" \
  -H "Content-Type: application/json" \
  -d '{"message": "내 이름은 잠탱이야"}'

# 응답에서 session_id 받음: "abc-123"

# 2번째 메시지 (session_id 포함)
curl -X POST "http://127.0.0.1:8000/chat" \
  -H "Content-Type: application/json" \
  -d '{"message": "내 이름이 뭐라고?", "session_id": "abc-123"}'

# 응답: "잠탱이라고 하셨습니다!"

주의할 점

  • sessions를 딕셔너리로 메모리에 저장하기 때문에 서버 재시작하면 초기화돼요
  • 실서비스라면 Redis나 DB에 저장해야 하지만, 지금은 이 정도로 충분해요
  • 세션이 쌓이면 메모리가 늘어날 수 있으니 주기적으로 정리하는 로직도 나중에 추가하면 좋아요

정리

단계 내용
패키지 설치 fastapi, uvicorn, google-generativeai
환경 변수 .env에 API 키 저장
기본 챗봇 generate_content() 단일 호출
멀티턴 챗봇 start_chat() + session_id 관리
테스트 /docs Swagger UI 또는 curl

다음 글에서는 FastAPI + uvicorn 개발하면서 자주 만나는 에러 모음을 정리해드릴게요.
저도 삽질 꽤 했거든요 😅


📌 이 글 시리즈