이미지 로딩 중...

바닥부터 만드는 ChatGPT 1편 프로젝트 개요 및 환경 설정 - 슬라이드 1/9
A

AI Generated

2025. 11. 11. · 3 Views

바닥부터 만드는 ChatGPT 1편 프로젝트 개요 및 환경 설정

ChatGPT와 같은 대화형 AI를 직접 구축하는 여정의 시작입니다. 프로젝트의 전체 구조를 파악하고, 개발 환경을 단계별로 설정하는 방법을 배웁니다. 실무에서 바로 적용할 수 있는 환경 설정 노하우와 함께 AI 프로젝트의 기초를 탄탄히 다집니다.


목차

  1. 프로젝트_전체_구조_이해
  2. Python_개발_환경_설정
  3. OpenAI_API_키_설정
  4. 필수_라이브러리_설치
  5. 프로젝트_폴더_구조_생성
  6. 환경_변수_관리
  7. Git_저장소_초기화
  8. 기본_설정_파일_작성

1. 프로젝트_전체_구조_이해

시작하며

여러분이 ChatGPT 같은 대화형 AI를 만들고 싶다고 생각해본 적 있나요? 막상 시작하려고 하면 "어디서부터 어떻게 시작해야 하지?"라는 막막함에 부딪히게 됩니다.

많은 개발자들이 AI 프로젝트를 시작할 때 전체 구조를 파악하지 않고 코딩부터 시작하다가 나중에 코드를 전부 다시 작성하는 경우가 많습니다. 특히 대화 히스토리 관리, API 호출 최적화, 에러 핸들링 등을 고려하지 않으면 프로젝트가 금방 복잡해집니다.

바로 이럴 때 필요한 것이 명확한 프로젝트 아키텍처입니다. 시작 전에 전체 구조를 이해하면 각 컴포넌트의 역할이 명확해지고, 확장 가능한 코드를 작성할 수 있습니다.

개요

간단히 말해서, ChatGPT 프로젝트는 사용자 인터페이스, API 통신 레이어, 대화 관리 시스템, 그리고 설정 관리 모듈로 구성됩니다. 실무에서 AI 챗봇을 만들 때는 단순히 API를 호출하는 것만으로는 부족합니다.

대화 컨텍스트를 유지하고, 토큰 사용량을 관리하며, 에러 발생 시 적절히 대응해야 합니다. 예를 들어, 사용자가 긴 대화를 이어갈 때 이전 맥락을 기억하면서도 토큰 한도를 초과하지 않도록 관리하는 것이 중요합니다.

기존에는 모든 코드를 한 파일에 작성했다면, 이제는 기능별로 모듈을 분리하여 유지보수가 쉬운 구조를 만들 수 있습니다. 핵심 구조는 다음과 같습니다: (1) main.py - 애플리케이션 진입점, (2) chat_manager.py - 대화 로직 관리, (3) api_client.py - OpenAI API 통신, (4) config.py - 설정 관리, (5) utils.py - 유틸리티 함수들.

이러한 분리는 각 컴포넌트를 독립적으로 테스트하고 개선할 수 있게 해줍니다.

코드 예제

# 프로젝트 구조 예시
chatgpt-from-scratch/
├── src/
│   ├── __init__.py           # 패키지 초기화
│   ├── main.py              # 애플리케이션 진입점
│   ├── chat_manager.py      # 대화 관리 클래스
│   ├── api_client.py        # OpenAI API 통신
│   ├── config.py            # 설정 관리
│   └── utils.py             # 유틸리티 함수
├── tests/                   # 테스트 코드
├── .env                     # 환경 변수 (API 키 등)
├── .gitignore              # Git 제외 파일 목록
├── requirements.txt        # 의존성 패키지
└── README.md              # 프로젝트 문서

설명

이것이 하는 일: 프로젝트를 기능별 모듈로 분리하여 각 컴포넌트의 책임을 명확히 하고, 확장 가능하며 유지보수하기 쉬운 구조를 제공합니다. 첫 번째로, src/ 디렉토리는 모든 소스 코드를 담는 메인 패키지입니다.

이렇게 분리하는 이유는 프로덕션 코드와 테스트 코드, 설정 파일 등을 명확히 구분하기 위함입니다. main.py는 애플리케이션의 시작점으로, 사용자와의 상호작용을 담당합니다.

그 다음으로, chat_manager.py와 api_client.py는 핵심 비즈니스 로직을 담당합니다. chat_manager는 대화 히스토리를 관리하고, 컨텍스트 윈도우를 조절하며, 사용자 입력을 처리합니다.

api_client는 OpenAI API와의 통신을 전담하여, API 호출 로직을 다른 코드에서 분리합니다. 이렇게 분리하면 나중에 다른 AI 모델로 교체하거나 여러 모델을 동시에 지원하기 쉬워집니다.

마지막으로, config.py와 .env 파일이 설정 관리를 담당합니다. API 키 같은 민감한 정보는 .env 파일에 저장하고, .gitignore에 추가하여 Git에 커밋되지 않도록 합니다.

config.py는 이러한 환경 변수를 읽어와 애플리케이션 전체에서 사용할 수 있도록 중앙화합니다. 여러분이 이 구조를 사용하면 코드 수정 시 영향 범위를 최소화할 수 있고, 새로운 기능 추가가 훨씬 쉬워집니다.

또한 각 모듈을 독립적으로 테스트할 수 있어 버그를 조기에 발견할 수 있습니다. 팀 프로젝트에서는 여러 개발자가 동시에 다른 모듈을 작업할 수 있어 협업 효율이 크게 향상됩니다.

실전 팁

💡 프로젝트 시작 전에 항상 폴더 구조를 먼저 설계하세요. 나중에 리팩토링하는 것보다 처음부터 잘 설계하는 것이 10배 빠릅니다.

💡 init.py 파일을 각 디렉토리에 추가하여 Python 패키지로 인식되게 하세요. 이것이 없으면 import 에러가 발생합니다.

💡 tests/ 폴더의 구조는 src/ 폴더와 동일하게 유지하세요. 예를 들어 src/chat_manager.py에 대한 테스트는 tests/test_chat_manager.py로 작성합니다.

💡 README.md에는 프로젝트 설명뿐만 아니라 설치 방법, 실행 방법, 환경 변수 설정 예시를 반드시 포함하세요. 6개월 후 본인도 이것을 보고 실행하게 됩니다.

💡 .gitignore에는 .env, pycache/, *.pyc, venv/ 등을 반드시 추가하세요. 민감한 정보나 불필요한 파일이 Git에 올라가는 것을 방지합니다.


2. Python_개발_환경_설정

시작하며

여러분이 새로운 Python 프로젝트를 시작할 때마다 라이브러리 버전 충돌로 고생한 경험이 있나요? "내 컴퓨터에서는 잘 되는데"라는 말을 들어본 적이 있다면, 바로 환경 설정 문제입니다.

실무에서는 여러 프로젝트를 동시에 진행하는 경우가 많습니다. A 프로젝트는 Django 3.2를 사용하는데, B 프로젝트는 Django 4.0을 사용한다면 어떻게 해야 할까요?

전역 환경에 설치하면 둘 중 하나는 반드시 문제가 생깁니다. 바로 이럴 때 필요한 것이 Python 가상환경입니다.

각 프로젝트마다 독립된 환경을 만들어 라이브러리 충돌을 완벽하게 방지하고, 다른 개발자와 정확히 동일한 환경을 공유할 수 있습니다.

개요

간단히 말해서, Python 가상환경(venv)은 프로젝트별로 독립된 Python 실행 환경을 만들어주는 도구입니다. 실무에서 가상환경 없이 개발하는 것은 재앙을 초래합니다.

특히 AI/ML 프로젝트는 tensorflow, pytorch, numpy 등 수많은 의존성 라이브러리가 있고, 각 라이브러리마다 특정 버전을 요구하는 경우가 많습니다. 예를 들어, OpenAI SDK 1.0과 0.28은 API가 완전히 다르기 때문에 버전 관리가 필수입니다.

기존에는 시스템 전체에 패키지를 설치했다면, 이제는 프로젝트별로 격리된 환경을 만들어 관리할 수 있습니다. 가상환경의 핵심 장점은 다음과 같습니다: (1) 프로젝트 간 의존성 격리, (2) 정확한 버전 관리, (3) requirements.txt를 통한 환경 재현, (4) 시스템 Python 보호.

이러한 특징들이 팀 협업과 배포 과정에서 발생할 수 있는 수많은 문제를 사전에 방지합니다.

코드 예제

# Windows에서 가상환경 생성 및 활성화
python -m venv venv
venv\Scripts\activate

# macOS/Linux에서 가상환경 생성 및 활성화
python3 -m venv venv
source venv/bin/activate

# 가상환경 활성화 확인 (프롬프트에 (venv) 표시됨)
# (venv) C:\project> 또는 (venv) user@computer:~/project$

# 가상환경 비활성화
deactivate

# Python 버전 확인
python --version

설명

이것이 하는 일: python -m venv 명령어로 프로젝트 전용 Python 환경을 생성하고, activate 스크립트로 해당 환경을 활성화하여 모든 패키지 설치가 이 환경 내에서만 이루어지도록 격리합니다. 첫 번째로, python -m venv venv 명령은 현재 디렉토리에 'venv'라는 이름의 폴더를 만들고, 그 안에 독립된 Python 인터프리터와 pip를 복사합니다.

이 폴더 안에는 Python 실행 파일, 표준 라이브러리, pip, 그리고 앞으로 설치할 모든 서드파티 라이브러리가 저장됩니다. 왜 이렇게 하냐면, 이 프로젝트에서 설치하는 패키지가 시스템의 다른 Python 프로젝트에 전혀 영향을 주지 않도록 하기 위함입니다.

그 다음으로, activate 스크립트를 실행하면 현재 셸의 환경 변수가 변경됩니다. 구체적으로는 PATH 환경 변수의 맨 앞에 venv/bin (또는 venv\Scripts)이 추가되어, python이나 pip 명령을 실행할 때 시스템의 Python이 아닌 가상환경의 Python이 실행됩니다.

터미널 프롬프트 앞에 (venv)가 표시되는 것으로 활성화 상태를 확인할 수 있습니다. 마지막으로, 가상환경이 활성화된 상태에서 pip install 명령을 실행하면 모든 패키지가 venv/lib/python3.x/site-packages 폴더에 설치됩니다.

이렇게 하면 나중에 venv 폴더만 삭제하면 이 프로젝트와 관련된 모든 패키지를 깔끔하게 제거할 수 있습니다. 여러분이 이 방법을 사용하면 프로젝트 시작 시 환경 설정으로 고생하는 시간을 극적으로 줄일 수 있습니다.

새로운 팀원이 합류하거나 다른 컴퓨터에서 작업할 때도 동일한 환경을 몇 분 만에 재현할 수 있습니다. 또한 프로덕션 배포 시 개발 환경과 동일한 패키지 버전을 사용할 수 있어 "내 컴퓨터에서는 되는데" 문제를 완전히 없앨 수 있습니다.

실전 팁

💡 가상환경 폴더(venv/)는 반드시 .gitignore에 추가하세요. 수백 MB의 라이브러리 파일을 Git에 올릴 필요가 없고, 각자 로컬에서 생성하면 됩니다.

💡 프로젝트를 처음 열 때마다 가상환경 활성화를 깜빡하는 실수가 많습니다. 터미널에 (venv)가 표시되는지 항상 확인하세요.

💡 VSCode를 사용한다면 Python 인터프리터를 가상환경의 python으로 선택하세요 (Ctrl+Shift+P → "Python: Select Interpreter"). 그러면 터미널을 열 때 자동으로 활성화됩니다.

💡 여러 Python 버전을 테스트해야 한다면 pyenv를 사용하세요. Python 3.8, 3.9, 3.10을 동시에 관리할 수 있습니다.

💡 conda를 사용하는 것도 좋지만, 가벼운 프로젝트에서는 venv가 더 빠르고 간단합니다. 데이터 과학 프로젝트가 아니라면 venv를 추천합니다.


3. OpenAI_API_키_설정

시작하며

여러분이 OpenAI API를 사용하려고 하는데, API 키를 코드에 직접 넣어야 할지 고민한 적 있나요? 혹시 API 키가 포함된 코드를 실수로 GitHub에 올린 적이 있다면, 그것은 매우 위험한 실수입니다.

실무에서는 API 키, 데이터베이스 비밀번호, AWS 자격 증명 등 수많은 민감한 정보를 다룹니다. 이러한 정보가 코드에 하드코딩되어 있으면 보안 사고로 이어지고, 최악의 경우 수백만 원의 요금 폭탄이나 데이터 유출이 발생할 수 있습니다.

실제로 GitHub에 올라간 AWS 키로 비트코인 채굴에 악용되어 엄청난 요금이 청구된 사례가 많습니다. 바로 이럴 때 필요한 것이 환경 변수를 통한 API 키 관리입니다.

코드와 설정을 완전히 분리하여 보안을 강화하고, 개발/스테이징/프로덕션 환경별로 다른 키를 쉽게 사용할 수 있습니다.

개요

간단히 말해서, 환경 변수는 운영체제 수준에서 관리되는 키-값 쌍으로, 코드 외부에서 설정 정보를 주입하는 안전한 방법입니다. Python에서 환경 변수를 관리하는 가장 일반적인 방법은 .env 파일과 python-dotenv 라이브러리를 사용하는 것입니다.

OpenAI API 키를 안전하게 관리하려면 절대 코드에 직접 작성하지 말고, .env 파일에 저장한 후 .gitignore에 추가해야 합니다. 예를 들어, 팀원들은 각자의 API 키를 자신의 .env 파일에 저장하여 사용하고, 코드는 공유하되 키는 공유하지 않는 방식입니다.

기존에는 API 키를 코드에 직접 문자열로 작성했다면, 이제는 환경 변수로 관리하여 보안과 유연성을 동시에 확보할 수 있습니다. 핵심 단계는 다음과 같습니다: (1) OpenAI 웹사이트에서 API 키 발급, (2) .env 파일에 키 저장, (3) .gitignore에 .env 추가, (4) python-dotenv로 키 로드, (5) 환경 변수로 API 클라이언트 초기화.

이러한 과정을 통해 코드는 공개하면서도 API 키는 안전하게 보호할 수 있습니다.

코드 예제

# .env 파일 내용
OPENAI_API_KEY=sk-proj-abc123def456ghi789jkl...
OPENAI_MODEL=gpt-4
MAX_TOKENS=2000
TEMPERATURE=0.7

# Python 코드에서 환경 변수 로드
import os
from dotenv import load_dotenv

# .env 파일 로드
load_dotenv()

# 환경 변수 읽기
api_key = os.getenv('OPENAI_API_KEY')
if not api_key:
    raise ValueError("OPENAI_API_KEY가 설정되지 않았습니다")

설명

이것이 하는 일: .env 파일에 API 키를 저장하고, python-dotenv 라이브러리가 이 파일을 읽어서 운영체제의 환경 변수로 로드한 후, Python 코드에서 os.getenv()로 안전하게 접근합니다. 첫 번째로, .env 파일은 단순한 텍스트 파일로 키=값 형식으로 설정을 저장합니다.

OPENAI_API_KEY에는 OpenAI 대시보드에서 생성한 실제 API 키를 입력합니다. 이 키는 "sk-"로 시작하는 긴 문자열입니다.

다른 설정들(MODEL, MAX_TOKENS 등)도 함께 관리하면 코드 수정 없이 동작을 변경할 수 있습니다. 중요한 것은 이 파일을 절대 Git에 커밋하지 않는 것입니다.

그 다음으로, load_dotenv() 함수를 호출하면 .env 파일을 찾아서 읽고, 각 줄을 파싱하여 운영체제의 환경 변수로 설정합니다. 이 과정은 프로그램 시작 시 단 한 번만 실행하면 되고, 보통 main.py나 config.py의 최상단에 위치합니다.

만약 .env 파일이 없어도 에러가 발생하지 않고 조용히 넘어가므로, 프로덕션 환경에서는 실제 환경 변수를 사용하고 개발 환경에서만 .env를 사용하는 패턴이 가능합니다. 마지막으로, os.getenv('OPENAI_API_KEY')는 환경 변수에서 값을 읽어옵니다.

만약 키가 설정되지 않았다면 None을 반환하므로, 반드시 검증 로직을 추가해야 합니다. 위 코드처럼 키가 없으면 ValueError를 발생시키는 것이 좋습니다.

그래야 API 호출 시점이 아닌 프로그램 시작 시점에 문제를 발견할 수 있습니다. 여러분이 이 패턴을 사용하면 실수로 API 키를 GitHub에 올리는 사고를 완벽하게 방지할 수 있습니다.

또한 개발 환경과 프로덕션 환경에서 다른 API 키를 사용할 수 있어 테스트 중에 실제 사용자에게 영향을 주지 않습니다. CI/CD 파이프라인에서도 환경 변수로 키를 주입하면 안전하게 자동 배포가 가능합니다.

실전 팁

💡 .env 파일과 함께 .env.example 파일을 만들어 Git에 커밋하세요. API 키는 제외하고 필요한 변수 목록만 작성하여 다른 개발자가 무엇을 설정해야 하는지 알 수 있게 합니다.

💡 API 키는 절대 print문으로 출력하거나 로그에 남기지 마세요. 디버깅 중에도 키의 앞 4자리만 표시하는 것이 안전합니다 (예: "sk-proj-abc1...").

💡 OpenAI API 키는 사용량 제한과 요금 한도를 설정하세요. OpenAI 대시보드에서 월 사용 한도를 설정하면 예상치 못한 요금 폭탄을 방지할 수 있습니다.

💡 프로덕션 환경에서는 .env 파일 대신 AWS Secrets Manager나 환경 변수 설정 기능을 사용하세요. 서버에 .env 파일을 업로드하는 것보다 더 안전합니다.

💡 python-dotenv 설치 명령어: pip install python-dotenv. requirements.txt에도 반드시 추가하여 다른 개발자가 놓치지 않도록 하세요.


4. 필수_라이브러리_설치

시작하며

여러분이 동료 개발자의 프로젝트를 받아서 실행하려고 하는데, "ModuleNotFoundError: No module named 'openai'" 같은 에러가 수십 개 나타난 경험이 있나요? 어떤 라이브러리를 어떤 버전으로 설치해야 하는지 하나하나 물어보느라 시간을 낭비한 적이 있을 것입니다.

실무에서는 프로젝트가 의존하는 라이브러리가 수십, 수백 개에 달합니다. 각 라이브러리는 또 다른 라이브러리에 의존하고, 버전 호환성 문제도 복잡합니다.

더 큰 문제는 시간이 지나면서 라이브러리 버전이 업데이트되어 3개월 전에는 작동하던 코드가 지금은 동작하지 않는 경우도 있습니다. 바로 이럴 때 필요한 것이 requirements.txt 파일입니다.

프로젝트에 필요한 모든 라이브러리와 정확한 버전을 한 곳에 명시하여, 누구든 단 한 줄의 명령어로 동일한 환경을 재현할 수 있습니다.

개요

간단히 말해서, requirements.txt는 Python 프로젝트가 의존하는 모든 패키지와 버전을 나열한 텍스트 파일로, pip가 이를 읽어서 일괄 설치합니다. ChatGPT 프로젝트에서는 OpenAI 공식 SDK, 환경 변수 관리를 위한 python-dotenv, 그리고 추가 기능에 따라 requests, rich(터미널 UI), tiktoken(토큰 계산) 등이 필요합니다.

버전 명시가 중요한 이유는 OpenAI SDK 1.0 이전과 이후가 완전히 다른 API를 사용하기 때문입니다. 예를 들어, openai==0.28.0과 openai>=1.0.0은 코드 작성 방식이 전혀 다릅니다.

기존에는 "README에 필요한 라이브러리를 나열"했다면, 이제는 requirements.txt로 자동화하여 사람의 실수를 완전히 제거할 수 있습니다. 핵심 원칙은 다음과 같습니다: (1) 직접 사용하는 라이브러리만 명시 (의존성은 자동 설치), (2) 버전 지정 방식 이해 (==, >=, ~=), (3) 정기적 업데이트와 테스트, (4) pip freeze로 정확한 버전 고정.

이렇게 관리하면 6개월 후에도, 다른 컴퓨터에서도, 새로운 팀원도 문제없이 프로젝트를 실행할 수 있습니다.

코드 예제

# requirements.txt 파일 내용
openai>=1.0.0
python-dotenv>=1.0.0
requests>=2.31.0
rich>=13.0.0
tiktoken>=0.5.0

# requirements.txt 설치 명령어
pip install -r requirements.txt

# 현재 설치된 패키지로 requirements.txt 생성
pip freeze > requirements.txt

# 특정 패키지만 업그레이드
pip install --upgrade openai

# 설치된 패키지 확인
pip list

설명

이것이 하는 일: requirements.txt에 패키지 이름과 버전을 나열하면, pip install -r requirements.txt 명령어가 이 파일을 읽어서 모든 패키지를 자동으로 다운로드하고 설치합니다. 첫 번째로, requirements.txt의 각 줄은 하나의 패키지를 나타냅니다.

openai>=1.0.0은 "openai 패키지의 1.0.0 이상 버전을 설치하라"는 의미입니다. >=는 "이상", ==는 "정확히 이 버전", ~=1.0.0은 "1.0.x 범위 내에서 최신 버전"을 의미합니다.

너무 엄격하게 버전을 고정하면 보안 업데이트를 받지 못하고, 너무 느슨하게 하면 호환성 문제가 생길 수 있으므로 적절한 균형이 필요합니다. 그 다음으로, pip install -r requirements.txt를 실행하면 pip는 파일을 한 줄씩 읽으면서 PyPI(Python Package Index)에서 각 패키지를 다운로드합니다.

이때 각 패키지의 의존성도 자동으로 분석하여 필요한 다른 패키지들까지 함께 설치합니다. 예를 들어 openai를 설치하면 내부적으로 사용하는 httpx, pydantic 등도 자동으로 설치됩니다.

마지막으로, pip freeze는 현재 가상환경에 설치된 모든 패키지와 정확한 버전을 출력합니다. 이것을 requirements.txt에 저장하면 의존성까지 포함한 완전한 스냅샷이 만들어집니다.

하지만 이 방법은 너무 많은 패키지가 포함되므로, 보통 직접 사용하는 패키지만 수동으로 작성하는 것을 추천합니다. 여러분이 이 방식을 사용하면 새로운 팀원이 합류했을 때 환경 설정 시간이 1시간에서 5분으로 단축됩니다.

코드 리뷰 시 "내 환경에서는 되는데" 같은 문제를 완전히 제거할 수 있습니다. CI/CD 파이프라인에서도 정확히 동일한 의존성으로 테스트와 배포가 가능해져 안정성이 크게 향상됩니다.

실전 팁

💡 requirements.txt와 requirements-dev.txt를 분리하세요. 프로덕션에서는 필요 없는 pytest, black, flake8 같은 개발 도구는 requirements-dev.txt에 작성합니다.

💡 정기적으로 pip list --outdated를 실행하여 업데이트 가능한 패키지를 확인하세요. 보안 패치는 즉시 적용하는 것이 좋습니다.

💡 pip install -r requirements.txt 후 의존성 충돌이 발생하면 pip-tools의 pip-compile을 사용하세요. 자동으로 호환되는 버전을 찾아줍니다.

💡 대규모 프로젝트에서는 poetry나 pipenv 같은 의존성 관리 도구를 고려하세요. lock 파일로 더 정확한 버전 관리가 가능합니다.

💡 설치 시간을 줄이려면 pip install -r requirements.txt --no-cache-dir를 사용하거나, 자주 사용하는 패키지는 미리 설치된 Docker 이미지를 만드세요.


5. 프로젝트_폴더_구조_생성

시작하며

여러분이 코드를 작성하다 보니 어느새 main.py가 500줄, 1000줄로 늘어나서 어디에 무엇이 있는지 찾기 어려워진 경험이 있나요? 함수 하나를 수정하려고 해도 관련 코드가 파일 전체에 흩어져 있어서 수정 범위를 파악하기 어렵습니다.

실무에서는 처음에는 작은 프로젝트로 시작했다가 점점 기능이 추가되면서 코드가 스파게티처럼 얽히는 경우가 많습니다. 특히 여러 명이 협업할 때 명확한 구조 없이 개발하면 같은 파일을 동시에 수정하다가 Git 충돌이 끊임없이 발생합니다.

바로 이럴 때 필요한 것이 모듈화된 폴더 구조입니다. 기능별로 파일을 분리하고, 책임을 명확히 하며, 계층 구조를 만들어 코드의 가독성과 유지보수성을 극대화합니다.

개요

간단히 말해서, 모듈화된 폴더 구조는 관련 기능을 논리적으로 그룹화하여 각 파일과 폴더의 역할을 명확히 하는 조직 방식입니다. ChatGPT 프로젝트에서는 사용자 인터페이스(main.py), API 통신(api_client.py), 대화 관리(chat_manager.py), 설정 관리(config.py), 유틸리티(utils.py)를 분리합니다.

왜 이렇게 분리하느냐면, 예를 들어 OpenAI에서 Azure OpenAI로 변경하려면 api_client.py만 수정하면 되고, 나머지 코드는 전혀 건드리지 않아도 됩니다. 이것이 바로 느슨한 결합(loose coupling)의 힘입니다.

기존에는 "모든 코드를 한 파일에"라는 접근이었다면, 이제는 "단일 책임 원칙"에 따라 각 모듈이 하나의 명확한 역할만 담당하도록 설계합니다. 핵심 설계 원칙은 다음과 같습니다: (1) 단일 책임 원칙 - 각 모듈은 하나의 역할만, (2) 의존성 방향 - 상위 모듈이 하위 모듈을 사용, (3) 인터페이스 분리 - 필요한 것만 import, (4) 확장 가능성 - 새 기능 추가 시 기존 코드 최소 수정.

이러한 원칙을 따르면 6개월 후에도 코드를 쉽게 이해하고 수정할 수 있습니다.

코드 예제

# 터미널에서 폴더 구조 생성 (Windows)
mkdir chatgpt-from-scratch
cd chatgpt-from-scratch
mkdir src tests
cd src
type nul > __init__.py
type nul > main.py
type nul > chat_manager.py
type nul > api_client.py
type nul > config.py
type nul > utils.py

# 터미널에서 폴더 구조 생성 (macOS/Linux)
mkdir -p chatgpt-from-scratch/src chatgpt-from-scratch/tests
cd chatgpt-from-scratch/src
touch __init__.py main.py chat_manager.py api_client.py config.py utils.py

설명

이것이 하는 일: 프로젝트를 src/, tests/ 등의 폴더로 나누고, src/ 내부를 기능별 모듈(main, chat_manager, api_client 등)로 세분화하여 각 파일이 명확한 책임을 갖도록 조직합니다. 첫 번째로, 최상위 폴더 구조를 보면 src/는 실제 애플리케이션 코드를, tests/는 테스트 코드를 담습니다.

이렇게 분리하는 이유는 배포 시 src/만 패키징하고 tests/는 제외할 수 있기 때문입니다. 또한 코드와 테스트가 섞이지 않아 프로젝트 구조가 깔끔해집니다.

init.py 파일은 해당 디렉토리를 Python 패키지로 인식하게 만들어, from src.chat_manager import ChatManager 같은 import가 가능해집니다. 그 다음으로, main.py는 애플리케이션의 진입점으로 사용자 입력을 받고 전체 흐름을 제어합니다.

chat_manager.py는 대화 히스토리 관리, 컨텍스트 윈도우 조절, 프롬프트 생성 등 대화 관련 로직을 담당합니다. api_client.py는 OpenAI API 호출, 재시도 로직, 에러 핸들링 등 외부 API와의 통신만 책임집니다.

이렇게 분리하면 나중에 Claude AI나 Gemini를 추가로 지원하고 싶을 때 새로운 클라이언트 모듈만 추가하면 됩니다. 마지막으로, config.py는 환경 변수 로딩, 설정 검증, 기본값 제공 등을 담당합니다.

utils.py에는 여러 모듈에서 공통으로 사용하는 헬퍼 함수들(토큰 계산, 텍스트 포맷팅, 로깅 등)을 모읍니다. 이런 식으로 기능별로 명확히 분리하면 각 모듈을 독립적으로 테스트할 수 있고, 한 모듈의 변경이 다른 모듈에 미치는 영향을 최소화할 수 있습니다.

여러분이 이 구조를 사용하면 버그를 찾을 때 어느 파일을 봐야 할지 즉시 알 수 있습니다. API 관련 문제면 api_client.py만 보면 되고, 대화 로직 문제면 chat_manager.py만 보면 됩니다.

새로운 기능을 추가할 때도 적절한 모듈에 코드를 추가하거나 새 모듈을 만들면 되므로 확장이 매우 쉽습니다. 코드 리뷰 시에도 변경 범위가 명확하여 리뷰어가 빠르게 이해할 수 있습니다.

실전 팁

💡 모듈 간 순환 참조를 절대 만들지 마세요. A가 B를 import하고 B가 A를 import하면 ImportError가 발생합니다. 의존성은 항상 한 방향으로만 흘러야 합니다.

💡 각 모듈 상단에 docstring으로 모듈의 역할을 명시하세요. 6개월 후 본인도 이것을 보고 이해하게 됩니다.

💡 utils.py가 너무 커지면 utils/ 폴더로 변경하고 text_utils.py, token_utils.py 등으로 세분화하세요.

💡 Python 3.3+ 이상이라면 init.py를 생략해도 패키지로 인식되지만, 명시적으로 만드는 것을 추천합니다. 패키지 초기화 코드를 추가할 수 있기 때문입니다.

💡 프로젝트가 커지면 src/ 내부에도 계층을 만드세요. src/api/, src/models/, src/services/ 같은 하위 폴더로 더 세분화할 수 있습니다.


6. 환경_변수_관리

시작하며

여러분이 개발 환경에서는 GPT-3.5를 사용하고, 프로덕션에서는 GPT-4를 사용하고 싶다면 어떻게 해야 할까요? 코드에 하드코딩된 설정값을 매번 수정해서 배포하는 것은 비효율적이고 실수하기 쉽습니다.

실무에서는 환경마다 다른 설정이 필요합니다. 개발 환경에서는 디버그 모드를 켜고, 로컬 데이터베이스를 사용하며, 낮은 비용의 모델을 사용합니다.

반면 프로덕션에서는 디버그를 끄고, 실제 데이터베이스에 연결하며, 최고 성능의 모델을 사용합니다. 이러한 설정을 코드에 섞어 놓으면 배포 시 실수로 개발용 설정이 프로덕션에 배포되는 사고가 발생할 수 있습니다.

바로 이럴 때 필요한 것이 python-dotenv를 활용한 환경 변수 관리입니다. 설정과 코드를 완전히 분리하여 환경별로 다른 .env 파일만 교체하면 코드 수정 없이 동작이 바뀝니다.

개요

간단히 말해서, python-dotenv는 .env 파일에서 키-값 쌍을 읽어와 Python의 os.environ에 로드하여, 환경별 설정을 코드 외부에서 관리할 수 있게 해주는 라이브러리입니다. 이 라이브러리의 핵심 가치는 12 Factor App의 "Config" 원칙을 구현하는 것입니다.

즉, 환경에 따라 달라지는 모든 것(API 키, 데이터베이스 URL, 모델 선택 등)을 환경 변수로 분리하는 것입니다. 예를 들어, 같은 코드가 .env.development에서는 gpt-3.5-turbo를 사용하고, .env.production에서는 gpt-4를 사용하도록 할 수 있습니다.

배포 시 환경 변수만 바꾸면 되므로 코드는 한 번 작성하고 어디서나 실행됩니다. 기존에는 "config_dev.py, config_prod.py를 만들고 import를 바꾸는" 방식이었다면, 이제는 "환경 변수로 통일"하여 코드는 하나, 설정만 바뀌는 방식입니다.

핵심 패턴은 다음과 같습니다: (1) .env 파일에 모든 설정 저장, (2) config.py에서 중앙 집중식 로딩, (3) 타입 변환과 검증 추가, (4) 기본값 제공으로 견고성 확보. 이렇게 하면 환경 변수가 누락되어도 적절한 에러 메시지를 보여주고, 개발자가 무엇을 설정해야 하는지 명확히 알 수 있습니다.

코드 예제

# config.py - 환경 변수 중앙 관리
import os
from dotenv import load_dotenv

# .env 파일 로드
load_dotenv()

class Config:
    """애플리케이션 설정 관리"""

    # OpenAI 설정
    OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
    OPENAI_MODEL = os.getenv('OPENAI_MODEL', 'gpt-3.5-turbo')

    # 모델 파라미터
    MAX_TOKENS = int(os.getenv('MAX_TOKENS', '2000'))
    TEMPERATURE = float(os.getenv('TEMPERATURE', '0.7'))

    # 애플리케이션 설정
    DEBUG = os.getenv('DEBUG', 'False').lower() == 'true'

    @classmethod
    def validate(cls):
        """필수 설정 검증"""
        if not cls.OPENAI_API_KEY:
            raise ValueError("OPENAI_API_KEY 환경 변수가 설정되지 않았습니다")

설명

이것이 하는 일: load_dotenv()가 .env 파일을 읽어서 환경 변수로 로드하고, Config 클래스가 이를 중앙에서 관리하며 타입 변환과 기본값 제공, 검증까지 수행합니다. 첫 번째로, Config 클래스는 모든 설정을 한곳에 모아 관리합니다.

클래스 변수로 선언하면 애플리케이션 어디서든 from config import Config로 import하여 Config.OPENAI_MODEL처럼 접근할 수 있습니다. 이렇게 중앙화하는 이유는 설정이 여러 파일에 흩어지면 어디서 무엇을 사용하는지 추적하기 어렵기 때문입니다.

한 곳만 보면 전체 설정을 파악할 수 있습니다. 그 다음으로, os.getenv()의 두 번째 인자는 기본값입니다.

예를 들어 os.getenv('OPENAI_MODEL', 'gpt-3.5-turbo')는 OPENAI_MODEL 환경 변수가 없으면 'gpt-3.5-turbo'를 사용합니다. 이렇게 하면 개발자가 모든 환경 변수를 설정하지 않아도 합리적인 기본값으로 동작합니다.

하지만 API 키 같은 필수 값은 기본값을 제공하지 않고, validate() 메서드에서 검증하여 명확한 에러를 발생시킵니다. 마지막으로, 타입 변환이 중요합니다.

환경 변수는 항상 문자열이므로, MAX_TOKENS는 int()로, TEMPERATURE는 float()로, DEBUG는 문자열을 불리언으로 변환합니다. DEBUG 같은 경우 'true', 'True', 'TRUE' 모두 처리하기 위해 .lower()를 사용합니다.

이런 세심한 처리가 없으면 'False' 문자열이 True로 평가되는 버그가 발생할 수 있습니다. 여러분이 이 패턴을 사용하면 환경별 배포가 매우 간단해집니다.

Docker 컨테이너에 환경 변수만 주입하면 되고, Kubernetes에서는 ConfigMap이나 Secret으로 관리할 수 있습니다. 로컬 개발 시에는 .env 파일을 사용하고, 클라우드 배포 시에는 플랫폼의 환경 변수 기능을 사용하면 됩니다.

설정 변경을 위해 코드를 수정하고 재배포할 필요가 없어 배포 주기가 짧아지고 안정성이 높아집니다.

실전 팁

💡 .env.example 파일을 만들어 필요한 변수 목록을 문서화하세요. 실제 값은 제거하고 키 이름과 설명만 남깁니다: OPENAI_API_KEY=your_api_key_here

💡 validate() 메서드를 main.py의 최상단에서 호출하세요. 프로그램이 실행되자마자 설정 문제를 발견할 수 있습니다: Config.validate()

💡 민감한 정보는 로그에 출력하지 마세요. DEBUG 모드에서도 API 키는 마스킹 처리해야 합니다.

💡 환경 변수 이름은 대문자와 언더스코어를 사용하는 것이 Python 컨벤션입니다: OPENAI_API_KEY (O), openai_api_key (X)

💡 복잡한 설정(JSON, 리스트 등)이 필요하면 pydantic-settings를 사용하세요. 타입 검증과 자동 변환을 제공합니다.


7. Git_저장소_초기화

시작하며

여러분이 코드를 열심히 작성하다가 실수로 중요한 파일을 삭제하거나, 어제까지 잘 되던 기능이 오늘 갑자기 안 되는 상황을 겪어본 적 있나요? "5분 전으로 돌아가고 싶다"는 생각이 간절했을 것입니다.

실무에서는 코드 변경 이력을 추적하는 것이 필수입니다. 누가, 언제, 왜 이 코드를 변경했는지 알아야 버그의 원인을 찾을 수 있고, 문제가 생겼을 때 이전 상태로 되돌릴 수 있습니다.

특히 팀 프로젝트에서는 여러 명이 동시에 작업하므로 버전 관리 시스템 없이는 서로의 코드를 덮어쓰는 재앙이 발생합니다. 바로 이럴 때 필요한 것이 Git 버전 관리입니다.

모든 변경 사항을 추적하고, 원하는 시점으로 돌아갈 수 있으며, 여러 개발자가 안전하게 협업할 수 있는 환경을 제공합니다.

개요

간단히 말해서, Git은 프로젝트의 모든 변경 사항을 스냅샷으로 저장하는 분산 버전 관리 시스템으로, 파일의 이력을 추적하고 협업을 가능하게 합니다. 프로젝트 시작 시 Git 저장소를 초기화하면 .git 폴더가 생성되고, 이후 모든 커밋(변경 사항 저장)이 이 폴더에 기록됩니다.

.gitignore 파일로 버전 관리에서 제외할 파일(가상환경, API 키, 캐시 등)을 지정하는 것이 중요합니다. 예를 들어, venv/ 폴더는 수백 MB의 라이브러리 파일이므로 Git에 올리면 저장소가 무거워지고, .env 파일은 민감한 정보가 포함되어 있어 보안 위험이 있습니다.

기존에는 "파일명에 날짜를 붙여 백업"하는 방식이었다면, 이제는 "Git의 커밋 히스토리"로 모든 변경을 체계적으로 관리할 수 있습니다. 핵심 워크플로우는 다음과 같습니다: (1) git init으로 저장소 초기화, (2) .gitignore 작성으로 제외 파일 지정, (3) git add로 스테이징, (4) git commit으로 변경 저장, (5) git log로 이력 확인.

이 과정을 습관화하면 코드 손실 걱정 없이 자유롭게 실험할 수 있습니다.

코드 예제

# Git 저장소 초기화
git init

# .gitignore 파일 생성 (중요!)
echo "venv/" > .gitignore
echo ".env" >> .gitignore
echo "__pycache__/" >> .gitignore
echo "*.pyc" >> .gitignore
echo ".DS_Store" >> .gitignore

# 현재 상태 확인
git status

# 모든 파일 스테이징
git add .

# 첫 커밋 생성
git commit -m "Initial commit: Project setup"

# 커밋 히스토리 확인
git log --oneline

설명

이것이 하는 일: git init이 현재 폴더를 Git 저장소로 만들고, .gitignore가 추적하지 않을 파일을 지정하며, git add와 git commit이 변경 사항을 기록하여 이력을 남깁니다. 첫 번째로, git init 명령은 현재 디렉토리에 .git 숨김 폴더를 생성합니다.

이 폴더 안에 모든 커밋 데이터, 브랜치 정보, 설정 등이 저장됩니다. 이 명령을 실행하는 순간부터 해당 폴더는 Git 저장소가 되고, 파일 변경을 추적할 수 있게 됩니다.

프로젝트 루트 디렉토리에서 단 한 번만 실행하면 됩니다. 그 다음으로, .gitignore 파일은 Git이 무시할 파일과 폴더를 지정합니다.

venv/는 가상환경 폴더로 용량이 크고 재생성 가능하므로 제외합니다. .env는 API 키 등 민감한 정보가 있어 절대 커밋하면 안 됩니다.

pycache/와 *.pyc는 Python이 자동 생성하는 캐시 파일로 불필요합니다. 각 줄에 하나의 패턴을 작성하며, *는 와일드카드로 모든 파일을 의미합니다.

마지막으로, git add .은 현재 디렉토리의 모든 변경 사항을 스테이징 영역에 추가합니다. 스테이징은 "다음 커밋에 포함할 변경 사항"을 선택하는 단계입니다.

그 다음 git commit -m "메시지"는 스테이징된 변경 사항을 하나의 커밋(스냅샷)으로 저장합니다. 커밋 메시지는 무엇을 변경했는지 명확히 작성해야 나중에 이력을 볼 때 이해할 수 있습니다.

여러분이 Git을 사용하면 실험적인 기능을 마음껏 시도할 수 있습니다. 실패하면 이전 커밋으로 되돌리면 되기 때문입니다.

버그가 발생했을 때 git log로 이력을 보고 "이 커밋에서 버그가 시작됐구나"를 찾을 수 있습니다. GitHub 같은 원격 저장소에 push하면 코드 백업과 협업까지 가능해져 팀 프로젝트의 필수 도구가 됩니다.

실전 팁

💡 커밋 메시지는 명령형으로 작성하세요: "Add chat history feature" (O), "Added chat history feature" (X). 이것이 Git 커뮤니티의 컨벤션입니다.

💡 .gitignore는 프로젝트 최상위에 위치해야 하며, 언어별 템플릿을 github.com/github/gitignore에서 찾을 수 있습니다. Python용 템플릿을 사용하세요.

💡 실수로 .env를 커밋했다면 즉시 git rm --cached .env로 제거하고, API 키를 재발급받으세요. 이미 푸시된 커밋에는 영구적으로 남기 때문입니다.

💡 작은 단위로 자주 커밋하세요. "하루 종일 작업한 내용을 한 번에 커밋"하면 나중에 특정 변경 사항을 되돌리기 어렵습니다.

💡 git status를 습관화하세요. 커밋 전에 항상 확인하여 의도하지 않은 파일이 포함되지 않았는지 체크합니다.


8. 기본_설정_파일_작성

시작하며

여러분이 프로젝트의 여러 파일에서 같은 설정값(API 키, 모델 이름, 토큰 한도 등)을 반복해서 사용하고 있다면, 나중에 값을 변경할 때 모든 파일을 찾아다니며 수정해야 하는 번거로움을 겪게 됩니다. 실무에서는 설정이 코드 전체에 흩어져 있으면 유지보수가 악몽이 됩니다.

예를 들어 OpenAI 모델을 gpt-3.5-turbo에서 gpt-4로 변경하려면 10개 파일을 수정해야 한다면? 하나라도 놓치면 버그가 발생합니다.

더 큰 문제는 설정 변경을 위해 비즈니스 로직이 들어있는 코드를 열어서 수정해야 한다는 점입니다. 바로 이럴 때 필요한 것이 중앙 집중식 설정 관리 파일입니다.

config.py 한 곳에서 모든 설정을 관리하고, 타입 안전성과 검증 로직까지 포함하여 설정 관련 버그를 사전에 방지합니다.

개요

간단히 말해서, config.py는 애플리케이션의 모든 설정을 중앙에서 관리하는 모듈로, 환경 변수 로딩, 타입 변환, 검증, 기본값 제공을 담당합니다. 설정 파일의 핵심은 "Single Source of Truth(단일 진실 공급원)" 원칙입니다.

모든 설정이 한 곳에 있으면 어디를 봐야 할지 명확하고, 변경 시 영향 범위를 쉽게 파악할 수 있습니다. 예를 들어, MAX_TOKENS를 2000에서 4000으로 변경하면 애플리케이션 전체에 즉시 반영됩니다.

또한 Config 클래스로 구조화하면 IDE의 자동완성이 작동하여 오타를 방지할 수 있습니다. 기존에는 "매직 넘버를 코드 곳곳에 하드코딩"했다면, 이제는 "명명된 상수로 중앙 관리"하여 가독성과 유지보수성을 확보합니다.

핵심 기능은 다음과 같습니다: (1) 환경 변수 로딩 및 타입 변환, (2) 합리적인 기본값 제공, (3) 필수 설정 검증, (4) 설정 그룹화 및 문서화, (5) 런타임 설정 변경 방지. 이러한 기능들이 설정 관련 버그를 대부분 사전에 차단합니다.

코드 예제

# config.py - 완전한 설정 관리 예시
import os
from typing import Optional
from dotenv import load_dotenv

# 환경 변수 로드
load_dotenv()

class Config:
    """ChatGPT 프로젝트 설정 관리

    환경 변수에서 설정을 로드하고, 타입 변환 및 검증을 수행합니다.
    .env 파일 또는 시스템 환경 변수에서 값을 읽어옵니다.
    """

    # OpenAI API 설정
    OPENAI_API_KEY: str = os.getenv('OPENAI_API_KEY', '')
    OPENAI_MODEL: str = os.getenv('OPENAI_MODEL', 'gpt-3.5-turbo')
    OPENAI_API_BASE: Optional[str] = os.getenv('OPENAI_API_BASE')

    # 모델 파라미터
    MAX_TOKENS: int = int(os.getenv('MAX_TOKENS', '2000'))
    TEMPERATURE: float = float(os.getenv('TEMPERATURE', '0.7'))
    TOP_P: float = float(os.getenv('TOP_P', '1.0'))

    # 대화 관리 설정
    MAX_HISTORY_LENGTH: int = int(os.getenv('MAX_HISTORY_LENGTH', '10'))
    SYSTEM_PROMPT: str = os.getenv(
        'SYSTEM_PROMPT',
        'You are a helpful AI assistant.'
    )

    # 애플리케이션 설정
    DEBUG: bool = os.getenv('DEBUG', 'False').lower() == 'true'
    LOG_LEVEL: str = os.getenv('LOG_LEVEL', 'INFO')

    @classmethod
    def validate(cls) -> None:
        """설정 검증 - 애플리케이션 시작 시 호출"""
        errors = []

        # 필수 설정 확인
        if not cls.OPENAI_API_KEY:
            errors.append("OPENAI_API_KEY가 설정되지 않았습니다")

        # 값 범위 검증
        if not 0 <= cls.TEMPERATURE <= 2:
            errors.append("TEMPERATURE는 0과 2 사이여야 합니다")

        if not 0 <= cls.TOP_P <= 1:
            errors.append("TOP_P는 0과 1 사이여야 합니다")

        if cls.MAX_TOKENS < 1:
            errors.append("MAX_TOKENS는 1 이상이어야 합니다")

        if errors:
            raise ValueError("설정 오류:\n" + "\n".join(f"- {e}" for e in errors))

    @classmethod
    def display(cls) -> None:
        """현재 설정 출력 (디버깅용)"""
        print("=== ChatGPT 설정 ===")
        print(f"모델: {cls.OPENAI_MODEL}")
        print(f"최대 토큰: {cls.MAX_TOKENS}")
        print(f"Temperature: {cls.TEMPERATURE}")
        print(f"최대 대화 기록: {cls.MAX_HISTORY_LENGTH}")
        print(f"디버그 모드: {cls.DEBUG}")
        print("=" * 30)

설명

이것이 하는 일: Config 클래스가 환경 변수를 읽어와 적절한 타입으로 변환하고, 기본값을 제공하며, validate() 메서드로 설정의 유효성을 검증하여 런타임 에러를 사전에 방지합니다. 첫 번째로, 클래스 변수로 설정을 정의하면 전역 변수보다 깔끔하고, 네임스페이스 충돌을 방지할 수 있습니다.

타입 힌트(: str, : int 등)를 추가하면 IDE가 타입 체크를 해주고, mypy 같은 정적 분석 도구로 타입 오류를 미리 찾을 수 있습니다. Optional[str]은 None이 허용된다는 의미로, OPENAI_API_BASE처럼 선택적인 설정에 사용합니다.

그 다음으로, 각 설정에 기본값을 제공하는 것이 중요합니다. 예를 들어 TEMPERATURE의 기본값 0.7은 대부분의 대화형 AI에서 적절한 창의성 수준입니다.

SYSTEM_PROMPT는 기본 메시지를 제공하되, 환경 변수로 덮어쓸 수 있게 합니다. 이렇게 하면 개발자가 모든 설정을 일일이 지정하지 않아도 합리적인 기본값으로 동작합니다.

validate() 메서드는 애플리케이션 시작 시 반드시 호출해야 합니다. 이 메서드가 OPENAI_API_KEY 누락, TEMPERATURE 범위 초과 등의 문제를 즉시 발견하여 명확한 에러 메시지를 제공합니다.

만약 검증 없이 실행하면 나중에 API 호출 시점에 알 수 없는 에러가 발생하여 디버깅이 어려워집니다. 조기 검증이 핵심입니다.

display() 메서드는 디버깅 시 매우 유용합니다. 프로그램 시작 시 현재 설정을 출력하여 어떤 값으로 실행되는지 확인할 수 있습니다.

단, API 키는 보안을 위해 출력하지 않거나 마스킹 처리해야 합니다. 여러분이 이 패턴을 사용하면 설정 변경이 5초 안에 끝납니다.

.env 파일에서 한 줄만 수정하면 되기 때문입니다. 새로운 설정 추가도 Config 클래스에 한 줄 추가하는 것으로 끝나고, 애플리케이션 전체에서 즉시 사용할 수 있습니다.

팀원들도 Config 클래스만 보면 어떤 설정이 가능한지 한눈에 파악할 수 있어 온보딩 시간이 단축됩니다.

실전 팁

💡 민감한 정보는 display()에서 마스킹하세요: f"API 키: {cls.OPENAI_API_KEY[:8]}..." 처럼 앞 8자만 표시합니다.

💡 설정이 많아지면 그룹별로 클래스를 분리하세요: OpenAIConfig, DatabaseConfig, AppConfig 등으로 나누면 관리가 쉽습니다.

💡 Pydantic을 사용하면 더 강력한 검증이 가능합니다: from pydantic import BaseSettings 상속으로 자동 타입 변환과 검증을 얻을 수 있습니다.

💡 Config를 불변(immutable)으로 만들려면 @dataclass(frozen=True)를 사용하세요. 런타임에 실수로 설정이 변경되는 것을 방지합니다.

💡 main.py의 첫 줄에서 Config.validate()를 호출하고, DEBUG 모드일 때만 Config.display()를 실행하세요.


#Python#ChatGPT#AI#환경설정#프로젝트구조#ai

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.