본문으로 건너뛰기
패키지·데이터 모델·웹 문서의 구조

생성 수정

IBM * 레드햇 AX 과정 · 6강

패키지·데이터 모델·웹 문서의 구조

2026년 5월 11일(월) ~ 5월 15일(금)

이 강의 문제풀이 — 배운 내용을 주관식 문답으로 확인해보세요.풀어보기 →

9. 파이썬 패키지 — __init__.py

9.1 폴더를 부품으로 바꾸는 파일

__init__.py 는 파이썬 폴더를 단순한 보관함에서 지능형 부품 꾸러미(패키지) 로 바꿔주는 파일입니다.

구분일반 폴더 (Directory)패키지 (Package)
비유일반 택배 박스밀키트 세트
특징안에 뭐가 들었는지 열어봐야 알고, 정리가 안 됨박스 겉면에 요리법이 적혀 있고, 열자마자 바로 조리 가능
파일__init__.py 없음__init__.py 포함
파이썬이 보는 관점단순한 저장소 (도구로 쓰기 어려움)공식적인 부품 세트 (도구/객체로 바로 활용)

9.2 세 가지 역할

① "나는 패키지입니다"라는 신분증 파이썬은 폴더 안에 __init__.py 가 있으면 그 폴더를 '창고'가 아니라 '실행 가능한 코드들의 집합(패키지)' 으로 인식합니다.

② 초기 설정 — init 은 Initialize(초기화)의 약자

  • 준비 운동: 식당 문을 열기 전에 테이블을 닦고 메뉴판을 놓는 것처럼, 패키지를 import 할 때 가장 먼저 자동 실행되는 코드를 담습니다.
  • 객체 생성: 폴더 내부의 여러 기능을 하나로 묶어, 외부에서 하나의 큰 도구(객체)처럼 꺼내 쓸 수 있게 입구를 설계합니다.

③ 지름길 만들기

파일이 없을 때파일이 있을 때
importimport 폴더.파일.함수 (길고 복잡)import 폴더 (간결)

9.3 백엔드와 프론트엔드의 철학 차이

구분백엔드 (Python)프론트엔드 (JS/TS)
핵심 파일__init__.pyindex.js / index.ts (선택)
인식 단위폴더(Package) 단위파일(Module) 단위
설계 철학엄격한 출입국 관리 (명시적 선언)자유로운 배달 시스템 (직접 연결)
필수 여부부품화를 위해 필수적선택적

백엔드가 __init__.py 를 쓰는 이유 (검수 도장) 서버는 방대한 데이터를 다루기 때문에, 어떤 폴더가 '공인된 기능'인지 명확히 구분해야 충돌이 없습니다. __init__.py 가 있다는 건 "이 폴더는 단순한 저장소가 아니라 하나의 독립된 기능 단위(부품)다" 라고 시스템에 선언하는 것입니다.

프론트엔드가 안 쓰는 이유 (주소 직접 입력) import 문으로 특정 파일 경로를 직접 적으면 되기 때문에, 폴더가 부품이라는 사실을 별도 파일로 증명할 필요가 없습니다. 브라우저에서 동작하는 코드는 가볍고 유연해야 하므로 불필요한 설정 파일보다 필요한 기능만 콕 집어 가져오는 방식을 선호합니다.

프론트엔드에도 비슷한 게 있습니다 — index.js. __init__.py 와 거의 같은 '대표 입구' 역할입니다. 다만 파이썬은 없으면 폴더를 기능으로 인식하지 못할 때가 많은 반면, 프론트엔드에서는 없어도 지장이 없습니다. 개발자의 선택입니다.

9.4 프랙탈 구조 — 같은 모양이 크기만 바꿔 반복된다

matrix 라는 폴더가 객체가 되려면 __init__.py 를 넣어 객체화합니다. 이때 __init__.py 가 속성, app/ 이 기능입니다. 앞서 배운 축 2가 폴더 수준에서 그대로 반복됩니다.

규모속성에 해당하는 것기능에 해당하는 것
변수 하나값—
객체 하나필드메서드
패키지 하나__init__.pyapp/ 내부 모듈들
서비스 하나DBAPI
시스템 전체데이터 계층애플리케이션 계층

객체지향의 근본 구조는 프랙탈입니다. 하나의 구조를 제대로 이해하면 아직 배우지 않은 것도 추론할 수 있습니다. 예를 들어 6주차 헥사고날의 domain/(속성 성격) ↔ use_cases/(기능 성격) 구분은 지금 이미 예측 가능합니다.

9.5 AI가 프로젝트를 읽는 순서

Cursor 같은 AI 도구가 프로젝트를 하나의 '객체'로 인식할 때 참조하는 우선순위입니다.

  1. .cursorrules (규칙) — 전체적인 행동 지침과 스타일 프로토콜
  2. README.md (맥락) — 프로젝트의 지도와 목적지
  3. __init__.py (객체화) — 폴더를 하나의 패키지(객체)로 묶는 기점
  4. requirements.txt (보급) — 외부에서 조달할 기능(라이브러리) 확인
  5. 실제 코드 (구현) — 세부적인 속성과 기능

AI 지침 파일을 만드는 프롬프트

@CLAUDE.md 이 안의 내용을 카파시의 의도대로 작성되었는지 체크하고,
안 되었으면 수정하고 md 스타일로 정리해줘

같은 프롬프트로 .cursorrules, CURSOR.md, README.md 도 생성할 수 있습니다.

9.6 개발 환경 전체를 골프로 보기

__init__.py 가 폴더를 부품으로 만든다면, 가상환경은 프로젝트 전체를 하나의 독립된 무대로 만듭니다.

요소골프 비유프로그래밍 개념핵심 의미
베이스(Base)골프카 / 필드Anaconda / venv안전하고 독립적인 실행 토대
명세서골프가방requirements.txt필요한 도구들의 이름표(명단)
의존성가방에 채워진 상태Dependency도구와 환경 사이의 필수적 연결 관계
라이브러리골프채pandas, NumPy 등특정 목적을 위해 가져온 전문 도구
메인 객체골퍼Main Script / Object도구를 사용해 경기를 완성하는 주체

활성화 순서

requirements.txt (가방)
   ↓ pip install -r requirements.txt
골퍼가 가방을 듦 → 골프카에 적재
   ↓ 설치 완료
골퍼가 골프카에 탑승 → 경기 시작 준비 완료

9.7 "Base"는 기초가 아니라 저장소다

여기서 짚고 넘어가야 할 번역 문제가 있습니다. 한국어 번역이 개념을 왜곡한 대표 사례입니다.

단어한국식 이해영어권 실제 의미
Base기초, 기반 (밑에 깔린 것)거점, 진지, 루(壘) — 나갔다가 돌아오는 안전한 곳
Database"데이터 기초"❓데이터의 거점 — 데이터가 모여 있다가 나가고 돌아오는 곳
Codebase"코드 기초"❓코드의 거점
base 환경"기본 환경"기준이 되는 거점 환경

야구에서 1루·2루·3루는 "기초"가 아닙니다. 주자가 안전하게 서 있을 수 있는 지점입니다. 군대의 base(기지)도 마찬가지 — 나갔다가 돌아오는 곳입니다.

"베이스는 발을 딛고 서는 안전한 지점이다."

  • 안전(Safe): 야구의 루처럼, 이 구역 안에 있을 때는 외부의 충돌(라이브러리 꼬임 등)로부터 보호받음
  • 기준(Origin): 모든 기능이 파생되어 나가는 뿌리이자 바닥

이 감각을 잡으면 git rebase(다시 거점을 잡는다), baseline(기준선), base class(다른 클래스가 딛고 서는 클래스)가 전부 한 번에 이해됩니다.

탄탄한 베이스(가상환경)를 구축하는 것은, 경기(개발) 도중 발생할 수 있는 '아웃(오류)'을 방지하는 가장 본질적인 준비입니다.


10. 데이터와 모델 — 타이타닉으로 배우는 것

10.1 모델의 두 얼굴

'모델'이라는 단어는 두 가지 뜻으로 쓰입니다. 둘 다 알아야 합니다.

공학적 모델리버럴(인문학적) 모델
정의입력값을 넣어 최적의 출력값을 뽑아내는 함수 · 계산 시스템복잡한 현실을 단순화해 핵심 특징만 남긴 지도 · 상징
묻는 것"얼마나 잘 맞히는가""왜 그런가"
타이타닉 예결정트리가 오차를 최소화하는 분기점을 찾음여성·1등석 생존율에서 계급과 규범을 읽음
도구Accuracy, Precision, Recall, F1해석, 서사, 맥락

결론: 공학적으로 설계하고, 리버럴 관점으로 해석할 것.

왜 이게 중요한가. 모델이 "1등석 여성 생존율 96%"라고 말할 때 공학은 거기서 멈춥니다. 하지만 "왜?" 를 묻지 않으면 그 모델을 다른 상황에 잘못 적용하게 됩니다. (구명정 배정 규칙 "여성과 어린이 먼저" 가 원인이지, 성별 자체가 생존을 만든 게 아닙니다.)

10.2 알고리즘의 뿌리

알고리즘(Algorithm) 은 문제를 해결하기 위한 엄격하고 논리적인 단계별 지침(SOP) 입니다.

  • 대수학적 뿌리: 알고리즘은 대수학(Algebra) 과 어원을 같이합니다. 구체적인 수치 대신 기호와 논리로 문제를 일반화하여 해결하는 과정입니다.
  • 특징: 유한성, 명확성, 입력/출력이 필수
  • 서구 공학의 강조점: 효율성(Time Complexity) 을 극도로 중시

이 어원이 중요한 이유는, "구체적인 것을 기호로 바꿔 일반화한다" 는 태도가 이 장 전체를 관통하기 때문입니다. 객체 = 속성 + 기능이라는 뺄셈식도, 포트/어댑터도, 전부 같은 태도의 산물입니다.

10.3 모델 검증 지표 — 언제 무엇을 보는가

지표계산뜻언제 중요한가
Accuracy (정확도)전체 중 맞힌 비율전체적인 안정성클래스가 균형 잡혔을 때
Precision (정밀도)"맞다"고 한 것 중 진짜 비율신중함, 결정력틀린 경보의 비용이 클 때 (스팸함에 중요 메일이 들어가면 곤란)
Recall (재현율)진짜 중 찾아낸 비율끈기, 기회 포착놓치는 비용이 클 때 (암 진단, 사기 탐지)
F1-Score정밀도와 재현율의 조화 평균둘 사이의 균형둘 다 중요할 때

핵심 관계: 정밀도와 재현율은 트레이드오프(Trade-off)입니다. 하나를 높이면 다른 하나가 낮아지는 경향이 있습니다.

  • "웬만하면 다 맞다고 하자" → Recall ↑ / Precision ↓
  • "확실할 때만 맞다고 하자" → Precision ↑ / Recall ↓

10.4 데이터 차원의 확장

데이터는 차원에 따라 이름이 달라집니다. 기하학의 점·선·면·체와 정확히 대응됩니다.

단계이름차원기하예설명
1캐릭터 / 스칼라0차원점 (Point)A, 5가장 기초적인 단일 데이터
2스트링 / 벡터1차원선 (Line)HELLO, [1, 2, 3]단일 데이터의 일렬 나열
3매트릭스2차원면 (Plane)엑셀 시트가로와 세로의 행렬 구조
4텐서 / 큐브3차원 이상체 (Volume)컬러 이미지 배치매트릭스가 여러 겹 쌓인 구조

딥러닝 프레임워크 이름이 TensorFlow 인 이유가 여기 있습니다. 텐서(고차원 배열)가 흘러다니는(flow) 것이 딥러닝 연산이기 때문입니다.

10.5 데이터 마이그레이션 — "데이터 이사"

정의: 낡은 집(기존 시스템)에서 새집(신규 시스템)으로 짐(데이터)을 옮기는 과정. 단순히 옮기기만 하는 게 아니라 필요 없는 물건은 버리고, 망가진 건 고치고, 새집 구조에 맞게 배치하는 것까지 포함합니다.

왜 중요한가

  • 신뢰도 하락: 고객 정보가 바뀌거나 사라져 업무가 마비될 수 있음
  • 운영 차질: 재고 데이터가 안 맞아 판매를 못 하는 상황

3단계 = ETL

단계영어비유하는 일
① 추출Extraction짐 싸기옛 시스템에서 필요한 데이터를 골라냄. 무엇을 가져가고 무엇을 버릴지 결정
② 변환Transformation짐 정리 및 수선가장 오래 걸리고 가장 중요한 단계
③ 로딩Loading짐 풀고 배치정리된 데이터를 새 시스템에 실제로 집어넣음

② 변환 단계의 세 작업

  • 정제: 중복된 데이터를 하나로 합침
  • 정비: 비어있는 정보를 채우거나 틀린 내용을 고침 (예: 주소 형식 통일)
  • 표준화: 새집의 규칙에 맞게 데이터의 이름이나 형식을 바꿈

③ 로딩의 기술력 이때 시스템을 잠시 멈춰야 할 수도 있는데, 이 시간을 최소화하는 것이 기술력입니다. 경주용 자동차가 달리는 도중 순식간에 타이어를 갈아 끼우는 것과 같습니다.

성공을 위한 두 가지

  • 현장의 목소리 듣기 — 데이터를 실제로 쓰는 사람(현업 담당자)이 참여해야 "이 데이터는 이렇게 고쳐야 해요"를 정확히 알려줄 수 있습니다
  • 철저한 연습 — 실제 이사 전에 여러 번 시뮬레이션해서 에러를 미리 찾아냅니다

마이그레이션은 단순한 복사·붙여넣기가 아니라, 데이터를 더 깨끗하고 쓰기 좋게 만들어 새 환경에 딱 맞게 옮기는 정교한 작업입니다.

이 개념은 지금 현실에서도 그대로 쓰입니다. 데이터센터의 GPU 서버 이전도 마이그레이션이고, 그 규모(GPU 26만 장 단위)가 곧 AI 인프라 경쟁의 실체입니다.


11. 웹 문서의 계보 — 마크업·마크다운·하이퍼텍스트

11.1 Mark(마크) — 이름표 붙이기

마킹이란 정보(데이터)에 특별한 성격이나 구조를 부여하기 위해 덧붙이는 표시입니다.

☐ 안녕하세요                    ← 무색무취. 이게 제목인지 본문인지 모름
☑ <h1>안녕하세요</h1>            ← "이건 제목이다"라는 이름표가 붙음

도서관의 책(데이터)이 소설인지 과학 서적인지 구분하기 위해 책등에 붙이는 색깔 스티커나 바코드와 같습니다.

11.2 Markup vs Markdown — 누구를 위한 이름표인가

구분Markup (HTML)Markdown (.md)
대상기계(브라우저)사람(작성자)
형태<html> <body> <div></div> — 태그를 열고 닫음# 제목 **강조** — 간결한 기호
성격정교하고 복잡한 기계의 설계도간결하고 읽기 쉬운 사람의 메모
목적기계가 오차 없이 읽게사람이 쓰고 읽기 편하게

이 구분이 왜 중요한가: AI 지침 파일(CLAUDE.md, .cursorrules, README.md)이 전부 .md 인 이유가 여기 있습니다. 그건 사람과 AI가 함께 읽을 문서이지 브라우저가 렌더링할 코드가 아니기 때문입니다.

11.3 프론트엔드와 백엔드에서의 역할

① 작성자      마크다운으로 내용 작성           (사람이 쓰기 편한 형태)
      ↓
② 백엔드      마크다운 데이터 보관 및 처리      (알맹이 = 데이터 관리)
      ↓
③ 변환        마크다운 → 마크업(HTML) 자동 변환
      ↓
④ 브라우저    <!DOCTYPE html> 선언 확인 후 화면 출력
      ↓
⑤ 사용자      하이퍼링크로 이동하거나 폼으로 데이터 전송
  • 입력(Markdown / 백엔드): 알맹이 데이터를 관리·보관할 때는 효율적인 마크다운
  • 출력(Markup / 프론트엔드): 시스템이 이를 마크업(HTML) 으로 변환해 브라우저에 전달

11.4 HyperText — 문서 사이의 순간이동

HTML의 앞글자 HT는 HyperText입니다.

클릭 한 번으로 다른 문서나 페이지로 즉시 연결되는 비선형적 텍스트를 뜻합니다.

일반 책은 앞뒤로만 넘길 수 있습니다. 하지만 하이퍼텍스트는 "관련 내용은 500페이지 참조" 라는 글을 누르면 즉시 500페이지로 소환되는 초능력을 가진 텍스트입니다.

11.5 하이퍼링크 vs 폼 태그 — 이동과 전송

사용자의 행동은 마크업에서 두 가지로 구분됩니다.

하이퍼링크 <a>폼 태그 <form>
하는 일이미 만들어진 길을 따라 걷기주문을 넣고 새 요리를 받기
성격정적 — 단순히 다른 정보를 조회하러 이동동적 — 이벤트가 발생해 백엔드로 데이터를 쏘아 올림
어디 중심프론트엔드 중심백엔드로 데이터 전송
비유이정표신청서

폼은 제출되면 서버가 이를 처리해 새로운 화면을 다시 보여줍니다. 이게 동적 상호작용입니다.

11.6 <!DOCTYPE html> 의 의미

모든 HTML 코드가 이 문장으로 시작하는 이유:

  • 이 문서가 최신 웹 표준인 HTML5 규격을 따른다는 작전 개시 선언
  • 브라우저에게 "이 이름표들은 최신 방식이니 헷갈리지 말고 제대로 그려줘!" 라고 명령하는 신호탄
  • 이어지는 <html> 은 모든 요소의 뿌리

12. 실습 — 이번 주에 손으로 한 것

12.1 프론트엔드 환경 — Node.js

Node.js 는 프론트엔드의 아나콘다에 해당합니다. 자바스크립트를 브라우저 밖에서 실행하고, 패키지를 관리하는 런타임입니다.

12.2 Neon(서버리스 PostgreSQL) 프로젝트 생성

  • Neon 콘솔 New project → Create project
  • Postgres version: 17
  • Region: AWS Asia Pacific 1 (Singapore)
  • 무료 플랜 사양
    • 0.5 GB storage
    • Scales to zero when inactive (안 쓰면 0으로 줄어듦 = 서버리스)
    • Autoscaling up to 2 CU
    • 10 branches per project
  • Enable Neon Auth 토글은 끈 상태로
    • Neon Auth는 사용자·세션을 DB에 직접 저장하는 관리형 인증 서비스입니다. 지금은 인증을 직접 배울 것이므로 끕니다.
  • 프로젝트는 용도별로 분리해 만드는 게 좋습니다 (수업용 / 개인용)

💡 "서버리스"의 뜻: 서버가 없다는 게 아니라, 안 쓸 때 0으로 줄었다가 요청이 오면 켜지는 방식입니다. 그래서 첫 요청이 느릴 수 있습니다(콜드 스타트). 대신 안 쓰는 동안 비용이 안 듭니다.

12.3 FastAPI ↔ Neon 비동기 연동

1. 접속 정보 Neon 대시보드 Connection Details 에서 Connection string 복사.

postgresql://[USER]:[PASSWORD]@[HOST]/[DATABASE]?sslmode=require

⚠️ Neon은 sslmode=require 가 반드시 필요합니다. 빠뜨리면 접속이 거부됩니다.

2. 설치

pip install fastapi uvicorn "sqlalchemy[asyncio]" "psycopg[binary]" python-dotenv

3. .env

DATABASE_URL=postgresql+psycopg://alex:password@ep-....neon.tech/neondb?sslmode=require

⚠️ SQLAlchemy 비동기 사용 시 접두어를 postgresql+psycopg 로 바꿔야 합니다. postgresql:// 만 쓰면 드라이버·비동기 설정과 안 맞습니다.

4-① database.py

load_dotenv()
DATABASE_URL = os.getenv("DATABASE_URL")

engine = create_async_engine(DATABASE_URL, echo=True)
AsyncSessionLocal = async_sessionmaker(
    bind=engine, class_=AsyncSession, expire_on_commit=False
)
Base = declarative_base()

async def get_db():
    async with AsyncSessionLocal() as session:
        yield session

4-② main.py

@app.get("/db-check")
async def db_check(db: AsyncSession = Depends(get_db)):
    result = await db.execute(text("SELECT NOW();"))
    now = result.scalar()
    return {"status": "success", "neon_time": now}

5. 헥사고날로 확장할 때

  • Domain에 OrderRepository 인터페이스
  • Infrastructure에서 PostgresOrderAdapter 구현
  • SQLAlchemy 엔티티와 순수 도메인 엔티티를 분리하고 Mapper로 변환

⚠️ 주의사항 2가지

  • IP 화이트리스트 — Settings > IP Allowlist 확인
  • SSL — ?sslmode=require 누락 시 접속 거부

12.4 DI 구조 만들기

프롬프트

@.../requirements.txt 여기에 DI 를 할 수 있도록 코드를 작성해줘.

1. requirements.txt 에 추가

sqlalchemy[asyncio]
psycopg[binary]
python-dotenv

(기존 fastapi, uvicorn[standard], pandas, scikit-learn 은 유지)

2. DI 구조

파일역할
apps/core/config.pyload_dotenv() 후 DATABASE_URL 읽기
apps/core/database.pyinit_engine() / dispose_engine(), 비동기 엔진·세션 팩토리
apps/deps.pyget_james_controller, get_doro_director, get_db — FastAPI Depends 용
apps/main.pylifespan 에서 DB 초기화·정리, 라우트에 Depends(...) 연결, GET /db/health

DB 주소는 psycopg v3 형식으로:

DATABASE_URL=postgresql+psycopg://USER:PASSWORD@HOST:5432/DBNAME

⚠️ .env 의 위치가 중요합니다. .env 는 상위 폴더가 아니라 현재 작업 디렉터리(CWD) 기준으로 읽힙니다. apps 폴더에서 서버를 띄우면 backend/apps/.env 에 두거나, load_dotenv 에 Path를 넘겨야 합니다.

검증: pip install -r requirements.txt 후 apps 기준으로 import main 이 성공하는지 확인

12.5 연결이 안 될 때 — 어디부터 보는가

막혔을 때 감으로 고치지 말고 순서대로 좁혀 들어가세요.

1단계: 환경변수가 앱에 실제로 들어오는지 database.py 는 load_dotenv() 후 os.getenv("DATABASE_URL") 만 봅니다. 실행 디렉터리가 backend\apps 면 그 폴더(또는 상위)의 .env 가 로드됩니다. 루트에만 있으면 값이 빌 수 있습니다.

2단계: get_db 경로 확인 AsyncSessionLocal is None 이면 다음이 발생합니다.

HTTPException(status_code=503, detail="DATABASE_URL이 .env 등에 설정되지 않았습니다.")

⭐ 즉 503은 "DB 연동 실패"가 아니라 "URL이 아예 안 읽혔다"는 뜻입니다. 이걸 모르면 DB 설정을 계속 만지면서 시간을 버립니다.

3단계: HTTP로 끝까지 확인

uvicorn main:app --reload
# 브라우저나 curl 로 http://127.0.0.1:8000/db-check
응답의미다음에 볼 곳
{"status":"success","neon_time": ...}✅ 정상—
{"status":"error","message":"..."}URL은 있으나 연결·인증·SSL·SQL 오류접속 문자열, 비밀번호, sslmode
503DATABASE_URL 미로드.env 위치, CWD

echo=True 로 두었으므로, 요청 시 터미널에 SQLAlchemy 로그가 찍히면 엔진·세션까지는 탔다는 뜻입니다.

4단계: URL 형식 postgresql+psycopg://... 여야 합니다.

5단계: lifespan 정리 finally: await dispose_engine() 이 있고, Ctrl+C 종료 시 예외 없이 내려가는지로 간접 확인합니다.

12.6 LLM을 내 서비스에 붙이기

5단계 절차

  1. Google AI Studio에서 무료 API 키 발급 (https://aistudio.google.com)
    • 좌측 하단 Get API key → API Keys → 우측 상단 Create API key
    • Filter by에서 프로젝트 선택 → 생성된 키 행 우측 Copy API key
  2. pip install fastapi uvicorn google-generativeai
  3. Cursor에서 Ctrl + K 로 요청

    모델 gemini-2.5-flash, 사용자가 JSON으로 메시지를 보내면 답변을 반환하는 /chat POST 엔드포인트

  4. 프론트 연결
  5. 에러는 메시지를 복사해 Ctrl + L 채팅창에 붙여넣고 수정 요청

⭐ 모델 버전을 gemini-2.5-flash 로 올린 것이 이 실습의 핵심이었습니다. 처음에 1.5-flash 로 시도하면 응답 품질이 눈에 띄게 떨어집니다. 모델 버전은 코드가 아니라 설정입니다. 안 될 때 코드부터 고치지 말고 버전을 먼저 확인하세요.

화면에 붙이는 프롬프트

@frontend/app/page.tsx 메인화면에서 프로젝트 문의와 공지사항 보기를 삭제하고,
그 자리에 제미나이와 채팅 가능한 컴포넌트를 만들어줘

12.7 API 키를 안전하게 관리하기

① 하드코딩을 없앤다 @backend/apps/main.py 의 GEMINI_API_KEY = "..." 하드코딩을 .env 로 옮기고 import 방식으로 바꿉니다.

② 키 관리 객체로 모은다 — keymaker.py main.py 안에 흩어진 키 관리 코드를, 전체 시스템의 모든 API 키를 관리하는 단일 객체로 이관합니다. 이때 쓰는 것이 앞에서 배운 싱글톤 패턴입니다. 키메이커는 단 하나만 존재해야 키 유출을 막을 수 있습니다.

③ 안 될 때의 에러 흐름을 읽는다

서버에 GEMINI_API_KEY가 설정되어 있지 않습니다

프론트가 axios로 POST
   ↓
백엔드가 .env 에서 키 확인 → 실패
   ↓
에러 응답

해결 순서

  1. .env(또는 Vercel 설정)에 유효한 키 등록
  2. 서버 재시작 (환경변수는 시작할 때 한 번만 읽습니다)
  3. 코드의 변수명과 환경변수명이 정확히 일치하는지 확인

서버 실행 축약 명령어

uvicorn main:app --reload

에러가 나면 직접 고치려 하지 말고, 에러 메시지를 그대로 복사해 AI에게 주고 반복 요청하세요. 이게 이 수업 전체의 작업 방식입니다.

12.8 v0로 화면 만들고 코드로 가져오기

v0 사용 순서

  • 우측 상단 프로필 → Credits 잔여 확인. 모델 드롭다운은 v0 Auto / v0 Mini / v0 Max
  • 채팅은 깃허브 레포의 main 브랜치를 Clone해서 시작 → Initialized project v1
  • 프롬프트 예:

    화면 상단에 네비게이션바를 설치하고, 우측에 로그인 버튼을 생성해줘.

  • 상단 Create PR → 드롭다운에 View PR / Merge PR / Preview Deployment / Published Site
    • PR 생성 후 버튼이 PR #1 로 바뀝니다
  • 저장소 초록색 Code → Local > HTTPS 주소 복사
  • 로컬 빈 폴더에서 우클릭 → 터미널에서 열기 → PowerShell에서 git clone 까지 입력 후 마우스 우클릭하면 주소가 붙습니다 → 실행

화면 만드는 프롬프트 예시

@frontend/app/page.tsx 맨 우측에 로그인 버튼, 그 왼쪽에 [타이타닉] 버튼.
클릭 시 흰 화면 중앙에 "타이타닉 홈" 텍스트 페이지로 이동,
모든 페이지 최상단에 홈의 네비게이션 바 유지
@frontend/app/titanic/page.tsx 타이타닉 홈에 titanic.csv를 업로드할 수 있는
업로드 창과 업로드 버튼 두 방식으로 구성

v0 코드를 레포지토리로 만들고 정리하기

  • v0 프로젝트 우측 상단 Publish → Publish 패널에서 Create Repository
  • 깃허브에서 그 레포 → Settings 탭 → Repository name 수정 → Rename
  • Edit repository details 에서 Description과 Website를 채움

💡 서브도메인을 시스템 성격에 맞게 고르기 프론트엔드가 agora.example.cloud 라면 백엔드는 vote.example.cloud 처럼 기능이 드러나게 짓습니다.

유형예언제
표준형api, backend무난하게
기능 강조형judge, vote, eval그 서비스가 하는 일이 뚜렷할 때
아키텍처 강조형core, hub, engine중심 허브 역할일 때

12.9 로컬 코드를 배포까지 반영하기

git add .
git commit -m "feat: 업데이트된 로컬 코드 반영"
git push origin main

⚠️ 푸시만으로 끝나지 않습니다. 세 가지를 더 확인하세요.

  1. 대시보드에서 자동 빌드·배포 로그 확인
  2. 배포된 프론트가 localhost:8000 이 아닌 운영 API 주소를 보고 있는지, CORS 가 맞는지 확인
  3. 배포 환경의 환경변수 점검 (로컬 .env 는 배포 서버에 따라가지 않습니다)

12.10 로컬 AI 도구 — 피노키오와 bolt.diy

피노키오(Pinokio) 는 AI 앱을 원클릭으로 설치·실행해주는 런처입니다.

  • 설치 페이지: https://pinokio.co/apps/github-com-pinokiofactory-bolt
  • 진행바가 11/13 등으로 단계를 표시
  • 맨 아래 Disconnected 가 뜨면 설치 성공 (헷갈리기 쉬우니 주의)
  • 상단 1.55GB 옆 Start → 버튼이 로켓 이모지 Open Web UI 로 바뀌면 클릭
  • 가운데 Click to open in browser

12.11 작업 공간 정리 — 옵시디언 저장소 분리

노트를 수업용과 개인 프로젝트용으로 분리해 두면 나중에 검색이 정확해집니다. 같은 이유로 DB 프로젝트도, 깃 저장소도 용도별로 나눕니다. 경계를 긋는 습관이 곧 아키텍처 감각입니다.


13. 이 주의 읽을거리와 그 맥락

수업에서 함께 다룬 자료들입니다. 각각 왜 이 주에 나왔는지가 중요합니다.

13.1 하네스 엔지니어링

이 주의 4P(디스크/메모리)와 직접 연결됩니다. AI 하네스는 이 구조를 기업 차원에서 안전하게 통제하는 체계입니다.

  1. 데이터 및 정책 관리 (디스크) — AI가 참조할 공식 데이터와 보안 정책을 디스크 상에 올바르게 정의하고 관리
  2. 실행 환경 및 권한 통제 (메모리) — AI가 메모리에서 실행되는 과정(프로세스)에서 사용자 권한을 확인하고 답변의 일관성을 검증

핵심: "디스크에 올바른 기준을 저장하고, 메모리에서 안전하게 실행한다"는 원칙을 개인의 역량이 아닌 조직의 시스템으로 만드는 것이 AI 하네스입니다.

"모델 경쟁이 끝났다"는 말은 모델이 더 이상 중요하지 않다는 뜻이 아니라, 모델은 비슷해졌고 이제 그것을 어떻게 붙들어 쓰느냐(harness)가 승부처라는 뜻입니다.

13.2 아키텍처 자료

마지막 링크(MSA → 모듈러 모놀리식)가 이 주의 결론입니다. 업계가 MSA로 다 갔다가 돌아오고 있다는 사실 자체가, "큰 것이 항상 좋은 게 아니다" 라는 판단 기준을 줍니다.

13.3 개인정보 보호 종합대책

유출 사고 시 CEO 책임 법제화, ISMS-P 인증 의무화 추진.

이게 왜 이 주의 자료인가: 같은 주에 API 키를 .env 로 옮기고 싱글톤 키메이커를 만들었습니다. 그 작업이 "깔끔한 코드"의 문제가 아니라 법적 책임의 문제가 되어가고 있다는 맥락입니다. 키 하나가 새면 회사 대표가 책임을 집니다. 그래서 키를 하드코딩하지 않습니다.

13.4 프랙탈 이론

🔗 https://namu.wiki/w/프랙탈%20이론

객체지향의 근본 구조가 프랙탈이라는 이야기와 연결됩니다. 같은 구조가 크기만 바꿔 반복되기 때문에, 하나를 제대로 이해하면 아직 안 배운 것도 추론됩니다.

13.5 한 컴퓨터과학 교수가 졸업생에게 남긴 편지

🔗 https://wikidocs.net/blog/@jaehong/12479/

이 글에서 이 수업이 가져온 한 문장:

미국에서 Base는 '기초'가 아니라 '저장소'다.

(9.7절에서 자세히 다뤘습니다.)


부록 A. 용어 사전

용어영문상위 범주정의
객체Object메모리 실체속성 + 기능을 모두 가진 것
개체Entity데이터 단위객체 − 기능. 저장만 되는 것
함수Function실행 코드객체 − 속성. 변화만 일으키는 것
메서드Method함수특정 객체에 소속된 함수
주체Subject—행위를 하는 쪽 (Object의 반대말)
클래스Class설계도객체를 만들기 위한 정의. 디스크에 있음
인스턴스Instance실체클래스로부터 메모리에 만들어진 것
인스턴스화Instantiation동작클래스로부터 인스턴스를 만드는 것
필드Field클래스 구성요소클래스 안의 변수. 객체가 무엇을 아는가
클래스 변수Class Variable필드모든 인스턴스가 공유. Method Area
인스턴스 변수Instance Variable필드인스턴스마다 따로. Heap
지역 변수Local Variable변수메서드 안에서만 사는 변수. Stack
캡슐화EncapsulationOOP 원리관련 데이터와 기능을 하나로 묶는 것
Method Area—메모리 영역클래스 정보·메서드 코드·클래스 변수 (공유)
Heap Area—메모리 영역인스턴스가 사는 곳
Stack Area—메모리 영역지역 변수·호출 정보 (스레드마다 따로)
프로그램Program메모리 상태실행되려고 메모리에 올라온 명령어 집합
프로세스Process메모리 상태실제로 CPU를 쓰며 실행 중인 것
스레드Thread실행 단위프로세스 안에서 코드를 실행하는 주체
런타임Runtime시간·환경프로그램이 실제 실행되고 있는 동안
프로젝트Project디스크 자산프로덕트를 만들기 위한 계획·자원의 집합
프로덕트Product디스크 결과물고객에게 전달되는 완성품
직렬화Serialization변환메모리 객체를 저장·전송 가능한 형태로 펴는 것
역직렬화Deserialization변환저장된 것을 다시 메모리 객체로 되살리는 것
영속성Persistence성질프로그램이 꺼져도 데이터가 남는 성질
상속Inheritance (IS-A)객체 관계~는 ~의 한 종류다
연관관계Association (HAS-A)객체 관계필드로 소유. __init__ 에서 생성
의존관계Dependency (USES-A)객체 관계잠시 빌려 씀. 메서드 안에서 생성
동기Synchronous처리 방식앞 작업이 끝나야 다음을 시작
비동기Asynchronous처리 방식앞 작업을 기다리지 않고 다음을 시작
블로킹Blocking대기 상태응답이 올 때까지 멈춰 있음
시블링Sibling구조 관계같은 부모를 둔 동등한 레벨의 요소
아키텍처Architecture구상 구조이 시스템의 실제 구조 (설계 청사진)
아키텍트Architect역할그 구조를 정의하고 유지하는 사람
트레이드오프Trade-off개념하나를 얻으면 다른 하나를 잃는 관계
디자인 패턴Design Pattern추상 해법반복되는 문제의 검증된 해결 방식
GoFGang of Four패턴 모음23개 고전 디자인 패턴
싱글톤Singleton생성 패턴인스턴스가 딱 하나만 존재하도록 강제
팩토리Factory생성 패턴객체 생성 과정을 캡슐화
빌더Builder생성 패턴복잡한 객체의 생성 단계와 표현을 분리
어댑터Adapter구조 패턴호환 안 되는 인터페이스를 연결
데코레이터Decorator구조 패턴객체에 동적으로 기능을 추가
프록시Proxy구조 패턴접근을 제어하는 대리자
퍼사드Facade구조 패턴복잡한 시스템에 단순한 입구를 제공
전략 패턴Strategy행위 패턴알고리즘을 갈아끼울 수 있게 캡슐화
옵저버Observer행위 패턴상태 변화를 관련 객체에 통지
템플릿 메서드Template Method행위 패턴골격을 정의하고 일부를 하위에서 구현
다형성PolymorphismOOP 원리같은 이름의 호출이 대상에 따라 다르게 동작
헥사고날Hexagonal Architecture아키텍처비즈니스 로직을 중심에 두고 포트·어댑터로 외부 연결
클린 아키텍처Clean Architecture아키텍처동심원 계층, 의존성은 안쪽으로만
DDDDomain-Driven Design설계 방법론비즈니스 도메인 복잡성에 집중, 보편적 언어 사용
보편적 언어Ubiquitous LanguageDDD 개념코드와 비즈니스가 같은 단어를 쓰게 하는 것
Bounded Context—DDD 개념하나의 모델이 일관되게 통하는 경계
애그리거트AggregateDDD 개념함께 다뤄져야 하는 엔티티들의 묶음
값 객체Value Object (VO)DDD 개념식별자 없이 속성값 조합으로 정의되는 불변 객체
포트Port인터페이스도메인이 정의한 "무엇을 할지"의 명세 (추상)
어댑터(헥사고날)Adapter구현체포트를 특정 기술로 실제 구현한 것 (구상)
MSAMicroservice Architecture시스템 아키텍처기능을 별도 서버로 쪼개어 운영
모듈러 모놀리식Modular Monolith시스템 아키텍처배포는 하나, 내부는 모듈로 분리
서버리스Serverless배포 형태안 쓸 때 0으로 줄었다 요청 시 켜지는 방식
모노레포Monorepo저장소 구조하나의 저장소에 모든 프로젝트
멀티레포Multirepo저장소 구조프로젝트마다 별도 저장소
서브모듈SubmoduleGit 기능저장소 안에 다른 저장소를 참조로 포함
보일러플레이트Boilerplate코드 유형어디서나 반복되는 정형화된 뼈대 코드
DIDependency Injection기법필요한 객체를 밖에서 넣어주는 것
DIPDependency Inversion PrincipleSOLID 원칙둘 다 추상에 의존하게 만드는 원칙
IoCInversion of Control원리제어권이 내 코드에서 프레임워크로 넘어감
OCPOpen-Closed PrincipleSOLID 원칙확장에는 열려 있고 수정에는 닫혀 있어야 함
DTOData Transfer Object데이터 객체계층 간 전달만을 위한 순수 데이터 그릇
ORMObject-Relational Mapping기술객체와 테이블 행을 서로 변환
매퍼Mapper구성요소두 계층의 모델을 서로 변환해주는 것
CQRSCommand Query Responsibility Segregation패턴읽기 모델과 쓰기 모델을 분리
RDBMSRelational DBMSDB 분류테이블(행·열) + SQL 기반
NoSQL—DB 분류비관계형. Document/KV/Wide-Column/Graph
폴리글랏 퍼시스턴스Polyglot Persistence전략서비스마다 다른 DB를 쓰는 전략
ACID—DB 성질원자성·일관성·격리성·지속성
엔터티(DB)EntityDB 설계업무에 필요한 관리 대상. 테이블에 대응
주식별자Primary Key (PK)DB 개념각 행을 유일하게 구분하는 값
역색인Inverted Index검색 구조단어 → 문서 위치를 거꾸로 저장한 색인
마이그레이션Migration작업데이터를 새 시스템으로 옮기는 것
ETLExtract-Transform-Load절차추출 → 변환 → 적재
마크업Markup표기법기계를 위한 태그 기반 표기 (HTML)
마크다운Markdown표기법사람을 위한 간결한 표기 (.md)
하이퍼텍스트HyperText개념클릭으로 다른 문서로 건너뛰는 비선형 텍스트
DOCTYPE—선언이 문서가 HTML5 규격임을 선언
__init__.py—파이썬 파일폴더를 패키지로 만드는 신분증이자 초기화 코드
패키지Package파이썬 구조__init__.py 를 가진 폴더
Node.js—런타임브라우저 밖에서 JS를 실행하는 환경
Axios—라이브러리프론트에서 HTTP 요청을 보내는 도구
RESTRepresentational State Transfer설계 원칙자원을 URL로, 행위를 메서드로 표현하는 규칙
CORSCross-Origin Resource Sharing브라우저 규칙다른 출처의 요청을 허용할지 정하는 규칙
CRUDCreate-Read-Update-Delete동작 분류데이터를 다루는 네 가지 기본 동작
콜드 스타트Cold Start현상잠들어 있던 서버가 깨어나느라 첫 요청이 느린 것
알고리즘Algorithm절차문제 해결을 위한 유한·명확한 단계별 지침
정확도AccuracyML 지표전체 중 맞힌 비율
정밀도PrecisionML 지표맞다고 한 것 중 진짜 비율
재현율RecallML 지표진짜 중 찾아낸 비율
F1-Score—ML 지표정밀도와 재현율의 조화 평균
결정트리Decision TreeML 알고리즘조건 분기를 반복해 분류·예측하는 모델
프랙탈Fractal구조 개념같은 구조가 크기를 바꿔 반복되는 것
스칼라Scalar데이터 차원0차원. 단일 값
벡터Vector데이터 차원1차원. 값의 일렬 나열
매트릭스Matrix데이터 차원2차원. 행과 열
텐서Tensor데이터 차원3차원 이상

부록 B. 스스로 확인하기

먼저 답해보고, 막히면 옆의 절을 펼치세요.

#질문답이 있는 곳
1객체·개체·함수를 뺄셈식으로 쓸 수 있는가?1.1
2클래스와 인스턴스는 각각 디스크와 메모리 중 어디에?2.2
3필드와 메서드가 다른 메모리 영역에 저장되는 이유는?2.6
4__init__ 안의 A() 와 메서드 안의 A() 는 무엇이 다른가?3.2
5비동기는 왜 CPU 연산에는 도움이 안 되는가?4.3
6전략 패턴·DIP·IoC·DI·포트&어댑터의 공통점은?5.4
7싱글톤을 API 키에 쓰는 세 가지 이유는?5.5
8모노레포와 모놀리식은 왜 다른 축인가?6.1
9503 에러는 무엇을 뜻하는가?12.5
10Database의 'base'는 무슨 뜻인가?9.7

부록 C. 자주 하는 실수

실수바로잡기
"개체 = 객체 오타"❌ 다른 단어입니다. Entity ↔ Object
"클래스도 메모리에 있다"⚠️ 클래스 정보는 실행 시 Method Area로 올라옵니다. 원본은 디스크의 .py
"메서드는 인스턴스마다 하나씩 복사된다"❌ 하나만 있고 공유합니다. 메모리 절약
"비동기가 더 빠르다"⚠️ 한 건의 시간은 같습니다. 처리량이 늘어납니다
"async를 다 붙이면 좋다"❌ CPU 계산에는 효과 없습니다. I/O 대기에만
"모노레포 = 모놀리식"❌ 저장소 축과 배포 축은 다릅니다
"패턴 = 아키텍처"❌ 패턴은 추상(해결 방식), 아키텍처는 구상(실제 구조)
"Base = 기초"❌ 미국식으론 거점·저장소
"503이면 DB 연동 실패"❌ DATABASE_URL 이 로드 안 된 것
".env는 프로젝트 루트에 두면 됨"⚠️ 실행하는 디렉터리(CWD) 기준으로 읽힙니다
"환경변수 고쳤는데 안 바뀜"⚠️ 서버를 재시작해야 합니다
"MSA가 모놀리식보다 발전한 것"⚠️ 규모에 따라 다릅니다. 소규모엔 모듈러 모놀리식이 유리
"싱글톤 많이 쓰면 좋다"⚠️ 사실상 전역 변수. 테스트가 어려워집니다
"__init__.py는 빈 파일이니 없어도 됨"⚠️ 빈 파일이어도 "이건 패키지다" 라는 선언 자체가 역할
"푸시하면 배포 끝"⚠️ 빌드 로그·API 주소·CORS·배포 환경변수를 확인해야 합니다
"AI 답이 이상하면 코드부터 고친다"⚠️ 모델 버전부터 확인하세요

부록 D. 날짜별 색인

이 장의 내용이 실제 수업에서 어느 날 다뤄졌는지입니다.

날짜다룬 내용이 장의 절
5/11 (월)연관관계 vs 의존관계, 결정트리 첫 모델링, 모델의 두 관점, Git/GitHub, Copy vs Clone, 클래스·인스턴스, 필드·메서드, 메모리 3영역, 프로그램·프로세스·런타임·스레드, ML 검증 지표, 서브도메인 네이밍2.2, 2.62.8, 3, 10.110.3, 6.6, 12.8
5/12 (화)4P(디스크/메모리), 아키텍처 vs 아키텍트, GoF 23패턴, 절차지향 vs 객체지향, 전략 vs 전술, 프레임워크와 IoC, 파이썬 파일 구조, 검색엔진·역색인, DB 엔터티 6기준, MVC·CRUD, 객체/개체/함수 판서, MSA 하네스 확장, CLAUDE.md 프롬프트, 개인정보위 대책1, 2.3, 5.15.3, 5.9, 6.4, 7.57.7, 9.5, 13.3
5/13 (수)미시구조 4패턴, 전략 패턴, 어댑터 4단계, DB 선택 가이드, Neon 생성, FastAPI 비동기 연동, DI 구조, 연결 진단, v0 업데이트, Node.js, 골프 비유, 데이터 생애주기, 동기/비동기, 부모-자식-시블링, Base=저장소5.45.8, 7, 12.112.5, 12.8, 9.6~9.7, 2.5, 4
5/14 (목)모노레포/멀티레포, 모듈러 모놀리식, git remote -v, 소·중·대전략, 패턴은 추상 아키텍처는 구상, 마크업/마크다운/하이퍼텍스트/DOCTYPE, 클린 아키텍처 자료, 하네스 시대6, 5.15.2, 11, 13.113.2
5/15 (금)제미나이 연동 5단계, API 키 보안, 키메이커 싱글톤, 프랙탈, uvicorn 실행, 에러 흐름 읽기, v0→로컬 동기화·배포, 피노키오/bolt.diy, __init__.py, 백엔드 vs 프론트 폴더 철학, Axios/REST/API 물류, 데이터 마이그레이션 ETL, 데이터 차원 확장12.612.10, 5.5, 9, 8.2, 10.410.5

부록 E. Gemini / NotebookLM 프롬프트

복습 문제 받기

이 3주차 교재만 근거로 7문제를 내줘. 비전공자 기준으로.
"객체 / 개체 / 함수" 구분과 "메모리 3영역"은 반드시 포함해줘.
답은 바로 주지 말고, 내가 답한 다음에 채점하고
틀린 이유를 교재의 어느 절을 근거로 설명해줘. 교재에 없는 내용은 꺼내지 마.

인포그래픽 ① — 이 장의 중심 개념

「1.2 좌표평면으로 보기」와 「1.3 각 칸이 실제로 어디에 있는가」를 합쳐
인포그래픽 1장으로 만들어줘.
- 2×2 좌표평면 (가로축: 기능 있음/없음, 세로축: 속성 있음/없음)
- 각 칸에 객체/개체/함수를 배치하고, 실제 위치(메모리/DB/화면)와 기술명을 함께
- "객체 = 속성 + 기능 / 개체 = 객체 − 기능 / 함수 = 객체 − 속성" 뺄셈식을 크게
- 전문용어는 한글(영문) 병기

인포그래픽 ② — 전체 흐름

「8. 데이터가 흘러가는 전체 길」을 세로 흐름도 인포그래픽으로 만들어줘.
- 브라우저 → 라우터 → 유스케이스 → 리포지토리 → DB 순서
- 각 화살표에 데이터의 형태(JSON / Schema / DTO / ORM Entity)를 표시
- 각 단계가 객체/개체/함수 중 무엇인지 색으로 구분
- 오른쪽에 "추상 / 구상" 을 세로 띠로 표시

인포그래픽 ③ — 메모리

「2.6 메모리 3영역」과 「2.8 스레드와 메모리」를 한 장으로 만들어줘.
Method Area / Heap / Stack 을 위아래로 배치하고,
"모두 공유 / 참조하는 쪽끼리 / 각자 따로" 를 색으로 구분해줘.
스레드 여러 개가 Method Area는 같이 보고 Stack은 각자 갖는 걸 화살표로.

막힐 때

3주차에서 "___" 가 이해가 안 돼.
이 교재의 판별 축 5개(디스크/메모리, 속성/기능, 공유/개별, 동기/비동기, 하나/여럿)만
써서 다시 설명해줘. 교재에 없는 새 비유는 만들지 마.

미국식 분류로 다시 정리하기

이 교재에 나온 비유(식당, 골프, 야구, 기차, 창고와 작업대)를 전부 걷어내고,
"이것은 무엇의 한 종류인가 / 형제 개념과 무엇으로 갈리는가" 형식으로만
객체·개체·함수·메서드·클래스·인스턴스를 다시 정의해줘.

다음 장 연결 확인

이 교재에서 "6주차" 또는 "앞으로 다시 만납니다"라고 표시된 부분을 모두 찾아서,
이번 장의 어떤 개념이 나중에 어떤 이름으로 다시 나오는지 표로 정리해줘.