🐨CoalaCoding
Docs▾
JavaScriptReactHTML & CSSBackendAI & LLMDev ToolsCreative
B반1
👾숏츠
🙉B반2
게시판
🐨CoalaCoding

디지털 크리에이터를 위한 한국어 기술 문서

문서

  • JavaScript
  • React
  • HTML & CSS
  • Backend
  • AI & LLM
  • Dev Tools
  • Creative

커뮤니티

  • 게시판
  • 예제 모음

기타

  • 관리자

정책

  • 소개
  • 개인정보처리방침
  • 이용약관
  • 연락처
© 2026 CoalaCoding. All rights reserved.
  • 1. 허깅페이스 무료 Inference API - OTT 앱 활용 가이드
  • 1. 사진수집
  • 2. 네이버 영화 리뷰 크롤링
  • 3. PPT작성
  • 4. 이메일전송
  • 5. 파이썬 챗봇 만들기
  • 6. 주식분석보고서
  • 99. 구인업체 데이터 수집 크롤러 만들기 (바이브 코딩)
  1. 홈
  2. 문서
  3. Backend
  4. Python 프로젝트
  5. 5. 파이썬 챗봇 만들기

5. 파이썬 챗봇 만들기

목차

  • 1. 전체 구조 이해하기
  • 2. 1단계. 개발 환경 준비
  • 2.1. 프로젝트 폴더 만들기
  • 2.2. HuggingFace(허깅페이스) API(에이피아이) 키 발급
  • 3. 2단계. 파이썬 백엔드(back-end) 만들기
  • 3.1. 가상환경 설정
  • 3.2. 라이브러리(library) 설치
  • 3.3. 환경변수(environment variable) 파일 만들기
  • 3.4. 메인 서버 파일 작성
  • 3.5. 서버 실행 테스트
  • 3.6. requirements.txt 작성
  • 4. 3단계. 리액트 프론트엔드(front-end) 만들기
  • 4.1. 리액트 프로젝트 생성
  • 4.2. 채팅 화면 만들기
  • 4.3. CSS(씨에스에스) 스타일 작성
  • 4.4. 프론트엔드 실행 테스트
  • 5. 4단계. Render(렌더)에 배포하기
  • 5.1. GitHub(깃허브)에 코드 올리기
  • 5.2. 파이썬 백엔드 배포
  • 5.3. 리액트 프론트엔드 배포 전 수정
  • 5.4. 리액트 프론트엔드 배포
  • 6. 5단계. 응용하기
  • 6.1. 다른 AI 모델로 바꾸기
  • 6.2. 캐릭터 챗봇으로 만들기
  • 7. 전체 흐름 요약

구현화면

1. 전체 구조 이해하기

이 교안은 아래의 기술을 사용하여 AI 챗봇을 만드는 방법을 단계별로 설명한다.

역할기술설명
프론트엔드(front-end)React(리액트) + Vanilla CSS사용자 화면
백엔드(back-end)Python(파이썬) + FastAPI(패스트에이피아이)서버 로직
AI 모델HuggingFace(허깅페이스)무료 AI API
배포Render(렌더)무료 호스팅

Info: HuggingFace(허깅페이스) 란? AI 모델을 누구나 무료로 사용할 수 있도록 제공하는 플랫폼이다. 회원가입만 하면 API(에이피아이) 키를 무료로 받을 수 있다.


2. 1단계. 개발 환경 준비

2.1. 프로젝트 폴더 만들기

폴더 구조

my-chatbot/
├── backend/        ← 파이썬 서버
│   ├── main.py
│   └── requirements.txt
└── frontend/       ← 리액트 화면
    ├── src/
    │   ├── App.jsx
    │   └── App.css
    └── package.json
  • backend/ : 파이썬 코드가 들어가는 폴더이다.
  • frontend/ : 리액트 코드가 들어가는 폴더이다.
  • 두 폴더는 서로 다른 역할을 하며, 나중에 각각 배포한다.

Terminal(터미널)

mkdir my-chatbot
cd my-chatbot
mkdir backend
mkdir frontend
  • mkdir (메이크 디렉토리): 폴더를 만드는 명령어이다.
  • cd (체인지 디렉토리): 폴더 안으로 이동하는 명령어이다.

2.2. HuggingFace(허깅페이스) API(에이피아이) 키 발급

Tip: API(에이피아이) 키란? 내 신분증처럼, 허깅페이스 서버에 "나는 회원이에요"라고 증명하는 비밀 문자열이다.

  1. https://huggingface.co 에 접속하여 회원가입을 한다.
  2. 우측 상단 프로필 → Settings(설팅스) → Access Tokens(액세스 토큰스) 를 클릭한다.
  3. New token(뉴 토큰) 버튼을 클릭하고 이름을 입력한 뒤 Read 권한으로 생성한다.
  4. 생성된 키(예: hf_xxxxxxxxxxxxxxxx)를 복사하여 안전한 곳에 저장한다.

Warning: API(에이피아이) 키는 절대로 GitHub(깃허브)에 올리면 안 된다. 타인이 내 키를 무단으로 사용할 수 있다.


3. 2단계. 파이썬 백엔드(back-end) 만들기

3.1. 가상환경 설정

Windows(윈도우)

cd backend
python -m venv .venv
.venv\Scripts\activate
  • python -m venv .venv : 가상환경 폴더를 만든다.
  • .venv\Scripts\activate : 가상환경을 실행(활성화)한다.
  • 활성화되면 터미널 앞에 (.venv) 표시가 나타난다.

Mac/Linux(맥/리눅스)

cd backend
python3 -m venv .venv
source .venv/bin/activate
  • source .venv/bin/activate : Mac/Linux에서 가상환경을 활성화하는 명령어이다.

3.2. 라이브러리(library) 설치

pip install fastapi uvicorn requests python-dotenv
라이브러리발음역할
fastapi패스트에이피아이파이썬 웹 서버 프레임워크
uvicorn유비콘서버 실행기
requests리퀘스츠외부 API 호출 도구
python-dotenv파이썬 닷엔브환경변수 관리

3.3. 환경변수(environment variable) 파일 만들기

backend/ 폴더 안에 .env 파일을 만들고 아래 내용을 입력한다.

HF_TOKEN=hf_여기에_내_키를_붙여넣기

Note: .env (닷엔브) 파일이란? 비밀 정보를 코드 밖에 보관하는 파일이다. 코드에 직접 키를 쓰지 않아도 되므로 안전하다.


3.4. 메인 서버 파일 작성

backend/main.py 파일을 만들고 아래 코드를 작성한다.

from fastapi import FastAPI                         # 01
from fastapi.middleware.cors import CORSMiddleware  # 02
from pydantic import BaseModel                      # 03
import requests, os                                 # 04
from dotenv import load_dotenv                      # 05

load_dotenv()                                       # 06
app = FastAPI()                                     # 07

app.add_middleware(                                 # 08
    CORSMiddleware,                                 # 09
    allow_origins=["*"],                            # 10
    allow_methods=["*"],                            # 11
    allow_headers=["*"],                            # 12
)                                                   # 13

class Msg(BaseModel):                               # 14
    text: str                                       # 15

HF_URL = "https://router.huggingface.co/v1/chat/completions" # 16
HF_MODEL = "Qwen/Qwen2.5-72B-Instruct"             # 17

def ask_ai(q: str) -> str:                          # 18
    token = os.getenv("HF_TOKEN")                   # 19
    headers = {"Authorization": f"Bearer {token}"}  # 20
    payload = {                                     # 21
        "model": HF_MODEL,                          # 22
        "messages": [{"role": "user", "content": q}], # 23
        "max_tokens": 300                           # 24
    }                                               # 25
    res = requests.post(HF_URL, headers=headers, json=payload) # 26
    data = res.json()                               # 27
    return data["choices"][0]["message"]["content"] # 28

@app.post("/chat")                                  # 27
def chat(msg: Msg):                                 # 28
    reply = ask_ai(msg.text)                        # 29
    return {"reply": reply}                         # 30

3.5. 서버 실행 테스트

uvicorn main:app --reload
  • uvicorn (유비콘): 파이썬 서버 실행 도구이다.
  • main:app : main.py 파일의 app 객체를 실행한다는 뜻이다.
  • --reload : 코드 수정 시 자동으로 서버를 재시작한다.

브라우저에서 http://localhost:8000/docs 에 접속하면 자동 생성된 API(에이피아이) 문서를 확인할 수 있다.

Tip: /docs (닥스) 페이지에서 /chat 엔드포인트를 직접 테스트해볼 수 있다. Try it out(트라이 잇 아웃) 버튼을 클릭하여 {"text": "안녕?"} 을 입력해 보자.


3.6. requirements.txt 작성

배포 시 필요한 파일이다. backend/requirements.txt 를 만들고 아래 내용을 입력한다.

fastapi
uvicorn
requests
python-dotenv

4. 3단계. 리액트 프론트엔드(front-end) 만들기

4.1. 리액트 프로젝트 생성

cd ../frontend
npm create vite@latest . -- --template react
npm install
  • cd ../frontend : 백엔드 폴더에서 나와 프론트엔드 폴더로 이동한다.
  • npm create vite@latest . : 현재 폴더에 Vite(비트) 프로젝트를 생성한다.
  • -- --template react : 리액트 템플릿(template)으로 생성한다.
  • npm install : 필요한 패키지(package)들을 설치한다.

4.2. 채팅 화면 만들기

frontend/src/App.jsx 파일을 아래 코드로 교체한다.

import { useState } from "react";          // 01
import "./App.css";                         // 02

const API = "http://localhost:8000/chat";  // 03

export default function App() {            // 04
  const [msgs, setMsgs] = useState([]);   // 05
  const [input, setInput] = useState(""); // 06
  const [loading, setLoading] = useState(false); // 07

  const send = async () => {              // 08
    if (!input.trim()) return;            // 09
    const userMsg = { role: "user", text: input }; // 10
    setMsgs(prev => [...prev, userMsg]);  // 11
    setInput("");                         // 12
    setLoading(true);                     // 13

    const res = await fetch(API, {        // 14
      method: "POST",                     // 15
      headers: { "Content-Type": "application/json" }, // 16
      body: JSON.stringify({ text: input }) // 17
    });                                   // 18
    const data = await res.json();        // 19
    const botMsg = { role: "bot", text: data.reply }; // 20
    setMsgs(prev => [...prev, botMsg]);   // 21
    setLoading(false);                    // 22
  };                                      // 23

  const onKey = (e) => {                  // 24
    if (e.key === "Enter") send();        // 25
  };                                      // 26

  return (                                // 27
    <div className="wrap">               // 28
      <h1>🤖 AI 챗봇</h1>               // 29
      <div className="box">              // 30
        {msgs.map((m, i) => (            // 31
          <div key={i} className={m.role}> // 32
            <span>{m.role === "user" ? "🧑" : "🤖"}</span> // 33
            <p>{m.text}</p>              // 34
          </div>                         // 35
        ))}                              // 36
        {loading && <p className="loading">생각 중...</p>} // 37
      </div>                             // 38
      <div className="input-row">        // 39
        <input                           // 40
          value={input}                  // 41
          onChange={e => setInput(e.target.value)} // 42
          onKeyDown={onKey}              // 43
          placeholder="메시지를 입력하세요" // 44
        />                               // 45
        <button onClick={send}>전송</button> // 46
      </div>                             // 47
    </div>                               // 48
  );                                     // 49
}                                        // 50

4.3. CSS(씨에스에스) 스타일 작성

frontend/src/App.css 파일을 아래 코드로 교체한다.

.wrap { max-width: 600px; margin: 40px auto; font-family: sans-serif; }
.box  { border: 1px solid #ccc; height: 400px; overflow-y: auto; padding: 16px; }
.user { text-align: right; margin: 8px 0; }
.bot  { text-align: left;  margin: 8px 0; }
.user p, .bot p { display: inline-block; padding: 8px 12px; border-radius: 8px; }
.user p  { background: #d1e7ff; }
.bot  p  { background: #f0f0f0; }
.loading { color: #888; font-style: italic; }
.input-row { display: flex; gap: 8px; margin-top: 8px; }
.input-row input  { flex: 1; padding: 8px; }
.input-row button { padding: 8px 16px; cursor: pointer; }
  • 최소한의 스타일만 적용하여 채팅 레이아웃을 구성한다.
  • .user와 .bot으로 사용자와 봇 메시지를 좌우로 구분한다.

4.4. 프론트엔드 실행 테스트

npm run dev

브라우저에서 http://localhost:5173 에 접속하여 챗봇이 동작하는지 확인한다.

Tip: 파이썬 서버(uvicorn)와 리액트 개발 서버(npm run dev)를 동시에 실행해야 한다. 터미널 창을 두 개 열어서 각각 실행한다.


5. 4단계. Render(렌더)에 배포하기

5.1. GitHub(깃허브)에 코드 올리기

Note: GitHub(깃허브)란? 코드를 온라인에 저장하고 공유하는 서비스이다. Render(렌더)는 깃허브 저장소를 연결하여 자동으로 배포한다.

  1. https://github.com 에서 새 저장소(repository, 리포지토리)를 만든다.
  2. 프로젝트 루트(my-chatbot/)에 .gitignore 파일을 만들고 아래 내용을 입력한다.
backend/.env
backend/.venv/
frontend/node_modules/
  1. 터미널에서 아래 명령어를 실행하여 코드를 깃허브에 올린다.
git init
git add .
git commit -m "first commit"
git remote add origin https://github.com/내아이디/my-chatbot.git
git push -u origin main

5.2. 파이썬 백엔드 배포

  1. https://render.com 에 접속하여 GitHub(깃허브) 계정으로 로그인한다.
  2. New(뉴) → Web Service(웹 서비스) 를 클릭한다.
  3. 깃허브 저장소를 연결하고 아래와 같이 설정한다.
항목입력값
Root Directory(루트 디렉토리)backend
Runtime(런타임)Python 3
Build Command(빌드 커맨드)pip install -r requirements.txt
Start Command(스타트 커맨드)uvicorn main:app --host 0.0.0.0 --port 10000
  1. Environment(환경변수) 탭에서 아래 값을 입력한다.
Key(키)Value(값)
HF_TOKEN허깅페이스에서 발급받은 API(에이피아이) 키
  1. Create Web Service(크리에이트 웹 서비스) 버튼을 클릭하면 배포가 시작된다.
  2. 배포 완료 후 https://my-chatbot-xxxx.onrender.com 형태의 주소가 생성된다.

5.3. 리액트 프론트엔드 배포 전 수정

frontend/src/App.jsx 의 API 상수를 Render(렌더) 주소로 변경한다.

const API = "https://my-chatbot-xxxx.onrender.com/chat";
  • localhost:8000 을 배포된 파이썬 서버 주소로 바꾼다.
  • 이 작업 후 깃허브에 다시 push(푸시)한다.

5.4. 리액트 프론트엔드 배포

  1. Render(렌더)에서 New(뉴) → Static Site(스태틱 사이트) 를 클릭한다.
  2. 같은 저장소를 연결하고 아래와 같이 설정한다.
항목입력값
Root Directory(루트 디렉토리)frontend
Build Command(빌드 커맨드)npm install && npm run build
Publish Directory(퍼블리시 디렉토리)dist
  1. Create Static Site(크리에이트 스태틱 사이트) 버튼을 클릭한다.
  2. 배포 완료 후 생성된 주소로 접속하면 챗봇을 사용할 수 있다.

Tip: Render(렌더) 무료 플랜은 15분간 요청이 없으면 서버가 절전 모드로 전환된다. 처음 요청 시 30초~1분 정도 응답이 느릴 수 있다. 이는 정상 동작이다.


5.4.1. 배포 오류 해결

5.4.1.1. Conflicting peer dependency
  1. 배포중 아래와 같이 오류 발생시 alt
  2. 에러 로그에 npm error ..., Conflicting peer dependency 가 포함되어 있을 경우 의존성 버전이 안맞아 실패한 것이다.
  3. 배포 프로젝트의 루트 폴더에 .npmrc 파일을 생성하고 아래의 코드를 추가한다.
  legacy-peer-deps=true

alt 4. 깃허브에 푸쉬한다. 5. 렌더에 재배포 한다. alt

6. 5단계. 응용하기

6.1. 다른 AI 모델로 바꾸기

main.py의 HF_URL 을 변경하면 다른 AI 모델을 사용할 수 있다.

추천 모델 목록

모델명특징
Qwen/Qwen2.5-72B-Instruct✅ 기본 추천, 한국어 응답 우수
meta-llama/Llama-3.1-8B-Instruct가볍고 빠른 응답
mistralai/Mistral-Nemo-Instruct-2407균형 잡힌 성능

Warning: 2025년 기준 api-inference.huggingface.co 엔드포인트는 폐지되었다. 반드시 router.huggingface.co/v1 을 사용해야 한다.

변경 방법

# HF_MODEL 변수의 모델명만 교체한다
HF_MODEL = "meta-llama/Llama-3.1-8B-Instruct"
  • HF_MODEL 변수의 값만 바꾸면 된다.
  • 모든 모델이 동일한 OpenAI(오픈에이아이) 호환 형식을 사용하므로 다른 코드는 수정하지 않아도 된다.

6.2. 캐릭터 챗봇으로 만들기

AI에게 역할을 부여하면 특정 캐릭터처럼 대화할 수 있다. ask_ai 함수의 messages 부분을 수정한다.

def ask_ai(q: str) -> str:
    token = os.getenv("HF_TOKEN")
    headers = {"Authorization": f"Bearer {token}"}

    # 캐릭터 역할 설정 (system 메시지로 전달)
    system = "You are a helpful Korean cooking teacher. Answer only about Korean food."

    payload = {
        "model": HF_MODEL,
        "messages": [
            {"role": "system", "content": system}, # 역할 설정
            {"role": "user",   "content": q}        # 사용자 질문
        ],
        "max_tokens": 300
    }
    res = requests.post(HF_URL, headers=headers, json=payload)
    data = res.json()
    return data["choices"][0]["message"]["content"]
  • system 역할의 메시지를 messages 배열 맨 앞에 추가하면 AI가 해당 캐릭터처럼 행동한다.
  • system 내용을 바꾸면 요리 선생님, 영어 튜터, 게임 캐릭터 등 다양한 챗봇을 만들 수 있다.

Note: system 역할 메시지는 영어로 작성할 때 더 정확하게 동작한다. 한국어 지시도 가능하지만 영어를 권장한다.


7. 전체 흐름 요약

사용자 입력
    ↓
리액트 (fetch POST /chat)
    ↓
파이썬 FastAPI (/chat 엔드포인트)
    ↓
허깅페이스 API (AI 모델 호출)
    ↓
AI 응답 반환
    ↓
리액트 화면에 메시지 출력

Tip: 막히는 부분이 있으면 각 단계의 console.log(리액트) 또는 print(파이썬)로 데이터 흐름을 확인하는 것이 디버깅(debugging, 디버깅)의 기본이다.