1교시 · OT 및 개발환경 구축
1일차 10:00–11:00 · 이론/실습 선행: 없음 (이 과정의 출발점) 실습 환경: Windows 11 + PowerShell
🎯 학습 목표
- 이 과정에서 만들 매출 인사이트 에이전트의 전체 그림과, 그것을 통해 배우는 "방법론"을 이해한다.
- uv로 파이썬 가상환경과 의존성을 구성할 수 있다.
- VS Code와 .gitignore로 안전한 작업 환경을 갖춘다. (Copilot 설정은 12교시)
- pytest가 정상 실행되는 것을 직접 확인한다. (앞으로 모든 코드의 "신뢰 근거")
📖 개념 1 — 왜 "환경 구축"에 한 시간을 통째로 쓰는가
이 과정의 핵심 약속은 단 한 문장입니다.
우리는 테스트가 통과한 코드만 믿는다.
왜 이 약속이 중요할까요? 좋은 코드란 "그럴듯해 보이는 코드"가 아니라 "의도한 대로 동작함이 증명된 코드" 입니다. 사람이 한 줄씩 눈으로 검사하는 것은 느리고 부정확합니다. 그래서 우리는 자동 검증 장치(테스트) 를 먼저 갖추고, "이 코드가 테스트를 통과하는가?"로 신뢰 여부를 판단합니다. 이 습관은 2일차 후반(12·13교시)에서 GitHub Copilot으로 바이브 코딩을 할 때 결정적인 안전장치가 됩니다 — AI가 만든 코드도 결국 "테스트를 통과하는가"로 믿을지 말지를 가르기 때문입니다.
이 판단을 하려면 먼저 두 가지 도구가 필요합니다.
| 도구 | 역할 | 비유 |
| uv | 파이썬 실행·의존성 관리 | 작업대(코드를 돌리는 환경) |
| pytest | 코드가 맞는지 자동 검증 | 검사기(통과/실패를 알려 줌) |
📌 이 과정의 학습 순서: 1~11교시에서는 Copilot 없이 직접 손으로 클린 아키텍처와 TDD로 전체 프로젝트를 완성합니다. 그 과정을 충분히 이해한 뒤, 12·13교시에서 같은 작업을 GitHub Copilot(바이브 코딩)으로 빠르게 재현·확장하며 "AI가 왜 규칙과 테스트를 필요로 하는가"를 몸으로 익힙니다. 즉, 먼저 원리를 손에 익히고, 그다음 도구로 가속합니다.
오늘 두 도구를 갖추면, 1일차와 2일차 전반은 "기능을 정의 → 테스트 작성 → 직접 구현 → 통과 확인" 이라는 한 가지 리듬의 반복입니다. 그래서 첫 시간의 환경 구축이 과정 전체의 토대가 됩니다.
📖 개념 2 — 왜 pip이 아니라 uv인가
기존에는 파이썬 프로젝트 하나를 만들려면 여러 도구를 조합했습니다. python -m venv(가상환경 생성), pip(패키지 설치), requirements.txt(의존성 기록)를 각각 다뤄야 했고, 사람마다 절차가 달라 "제 컴퓨터에선 되는데요" 문제가 잦았습니다.
uv는 이 일들을 하나로 묶은 도구입니다.
- 파이썬 인터프리터 자체도 필요하면 자동 설치합니다.
- 가상환경을 자동으로 만들고 관리합니다.
- uv run <명령>으로 가상환경을 수동 활성화하지 않고도 명령을 실행합니다 — 교육장에서 환경 차이로 인한 사고가 크게 줍니다.
- 의존성을 pyproject.toml 한 파일에 표준 형식으로 기록합니다.
정리하면, uv는 "환경 때문에 막히는 시간"을 없애 본질(아키텍처·테스트)에 집중하게 해 줍니다.
✏️ 미니 실습 — 현재 상태 확인
PowerShell을 열고 입력해 봅니다. (없다고 나와도 정상입니다. 곧 설치합니다.)
python --version
git --version
code --version
🔍 관찰 포인트: code는 VS Code의 명령줄 도구입니다. 인식되지 않으면 VS Code에서 Ctrl+Shift+P → "Shell Command: Install 'code' command in PATH"를 실행하세요.
🔒 진행 게이트
- 제출물(기록): python·git·code 세 버전 출력. (없으면 설치 후 다시)
- 이 결과가 있어야 다음 교시로 넘어갑니다.
- 정답·해설(별도 파일): solutions/미니실습정답_01.md
💻 실습 1 — uv 설치
Windows 11 PowerShell에서 아래 한 줄을 실행합니다.
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
명령 풀이: irm은 Invoke-RestMethod의 별칭으로, 설치 스크립트를 웹에서 내려받습니다. | iex(Invoke-Expression)는 그 스크립트를 실행합니다. -ExecutionPolicy ByPass는 이번 실행에 한해 스크립트 실행 제한을 풀어 줍니다.
설치 후 PowerShell 창을 새로 열고 확인합니다.
uv --version
🛠️ 트러블슈팅 — uv : 용어가 cmdlet ... 인식되지 않습니다 설치 직후엔 PATH(명령을 찾는 경로 목록)가 갱신되지 않습니다. PowerShell 창을 완전히 닫고 새로 여세요. VS Code를 쓰는 경우 VS Code 자체를 종료 후 재실행하면 확실합니다.
💻 실습 2 — 프로젝트 생성
작업할 폴더로 이동한 뒤(예: C:\work) 프로젝트를 만듭니다.
Set-Location C:\work # 원하는 작업 폴더로. 없으면 New-Item -ItemType Directory C:\work
uv init sales-insight-agent
Set-Location sales-insight-agent
uv init이 만든 파일을 봅니다.
Get-ChildItem # 폴더 내용 보기 (ls, dir 도 동작)
대략 이런 구성이 보입니다.
sales-insight-agent/
├── .python-version
├── pyproject.toml
├── README.md
└── main.py # (uv 버전에 따라 hello.py일 수 있음 — 곧 지웁니다)
🔍 관찰 포인트: pyproject.toml이 이 프로젝트의 "신분증"입니다. 의존성, 파이썬 버전, 빌드 정보, 도구 설정이 모두 이 한 파일에 모입니다. 예전처럼 requirements.txt, setup.py, 도구별 설정 파일을 따로 두지 않습니다. 앞으로 의존성을 추가하면 이 파일이 자동으로 갱신됩니다.
파이썬 버전 고정
uv python pin 3.12
팀원·교육생 모두 같은 파이썬 버전을 쓰도록 못 박는 명령입니다. 버전 차이로 인한 미묘한 동작 차이를 예방합니다.
이 과정에서 쓸 패키지 추가
uv add pandas matplotlib streamlit openai python-dotenv
uv add --dev pytest pytest-cov
🔍 관찰 포인트: --dev로 추가한 pytest, pytest-cov는 "개발할 때만" 필요한 도구입니다. 실제 사용자에게 배포하는 환경에는 포함되지 않습니다. 이렇게 의존성을 운영용/개발용으로 구분하는 습관은, 곧 배울 클린 아키텍처의 "관심사 분리(역할별로 나누기)" 정신과 정확히 같습니다. "검사 도구"와 "제품"을 섞지 않는 것이죠.
💻 실습 3 — 폴더 골격 만들기
지금은 빈 골격만 잡아 둡니다. 각 폴더가 무엇을 담는지는 3·4교시에서 자세히 채웁니다. 다만 폴더 이름이 곧 클린 아키텍처의 4계층이라는 점만 기억해 두세요.
# 소스/테스트 폴더 골격 만들기 (-Force: 이미 있어도 오류 없이 진행)
New-Item -ItemType Directory -Force -Path `
src/sales_agent/domain, `
src/sales_agent/usecases, `
src/sales_agent/adapters, `
src/sales_agent/infra, `
tests
명령 풀이: New-Item -ItemType Directory는 폴더를 만듭니다. 끝의 백틱(`)은 PowerShell에서 "명령이 다음 줄로 이어진다"는 표시입니다. -Path에 쉼표로 여러 경로를 한 번에 줄 수 있습니다.
이어서, 파이썬이 각 폴더를 "패키지"로 인식하도록 빈 __init__.py 파일을 만듭니다.
New-Item -ItemType File -Force -Path `
src/sales_agent/__init__.py, `
src/sales_agent/domain/__init__.py, `
src/sales_agent/usecases/__init__.py, `
src/sales_agent/adapters/__init__.py, `
src/sales_agent/infra/__init__.py, `
tests/__init__.py
🔍 관찰 포인트: __init__.py는 "이 폴더는 단순한 폴더가 아니라 파이썬 패키지다"라고 알리는 표식 파일입니다. 비어 있어도 됩니다. 이게 있어야 나중에 from sales_agent.domain.models import SalesRecord 같은 임포트가 동작합니다.
uv init이 만든 진입 파일 제거
Remove-Item main.py -ErrorAction SilentlyContinue
Remove-Item hello.py -ErrorAction SilentlyContinue
명령 풀이: -ErrorAction SilentlyContinue는 "해당 파일이 없어도 오류를 내지 말고 조용히 넘어가라"는 옵션입니다. uv 버전에 따라 main.py 또는 hello.py 중 하나만 있을 수 있어 둘 다 시도합니다.
pyproject.toml 설정 — pytest 경로와 패키지 빌드 정보
pyproject.toml 파일을 VS Code에서 열고, 맨 아래에 다음을 추가합니다.
[tool.pytest.ini_options]
pythonpath = ["src"]
testpaths = ["tests"]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["src/sales_agent"]
🔍 관찰 포인트: 세 블록의 의미입니다.
- pythonpath = ["src"] / testpaths = ["tests"] — pytest가 src를 임포트 경로에 넣고 tests 폴더에서 테스트를 찾게 합니다.
- [build-system] + [tool.hatch.build.targets.wheel] — 이 프로젝트를 설치 가능한 패키지로 만들고, 패키지 위치가 src/sales_agent임을 빌드 도구(hatchling)에 알려 줍니다. (uv init은 기본적으로 비패키지 앱을 만들기 때문에, 이 설정을 직접 추가해야 합니다.)
- 소스를 src/ 아래 두는 배치를 "src 레이아웃"이라 부르며, 테스트가 실제 설치되는 형태의 패키지를 검증하도록 강제하는 표준 방식입니다.
패키지를 가상환경에 설치 (중요)
이제 프로젝트 자신을 편집형(editable) 으로 설치합니다. 그래야 pytest뿐 아니라 일반 python 실행, streamlit 앱 등 어디서든 import sales_agent가 됩니다.
uv sync
🔍 왜 필요한가: pythonpath = ["src"]는 pytest를 실행할 때만 적용됩니다. 그래서 uv run python -c "import sales_agent..."처럼 pytest 밖에서 import하려면, 패키지가 가상환경에 설치되어 있어야 합니다. uv sync가 위 빌드 설정을 읽어 sales_agent를 editable로 설치해 줍니다. (4교시 미니실습의 import sales_agent 점검, 10교시 streamlit run app.py가 모두 이 설치에 의존합니다.)
💻 실습 4 — .gitignore 작성 (버전 관리에서 제외할 것)
프로젝트를 git으로 관리할 때 올리면 안 되는 것들을 미리 제외 목록에 넣어 둡니다. 프로젝트 루트에 .gitignore 파일을 만들고 다음을 작성합니다.
# 가상환경·캐시
.venv/
__pycache__/
*.pyc
.pytest_cache/
# 비밀값 (절대 커밋 금지) — 9교시에서 OPENAI_API_KEY를 여기에 둡니다
.env
# 생성 산출물
outputs/
*.png
# 커버리지 결과
.coverage
🔍 관찰 포인트: 특히 .env를 신경 써서 제외합니다. API 키가 든 파일을 실수로 GitHub(특히 공개 저장소)에 올리면 키가 외부에 노출되어 악용·과금 사고로 이어집니다. .gitignore는 이 사고를 막는 1차 방어선입니다. 지금은 .env가 아직 없지만(9교시에서 만듭니다), 제외 규칙을 미리 넣어 두는 것이 안전합니다.
💻 실습 5 — pytest 실행 확인 (가장 중요)
진짜 기능을 만들기 전에, 테스트 도구 자체가 도는지 확인하는 "스모크 테스트(연기 테스트: 전원을 켰을 때 연기가 나는지 보는, 최소한의 동작 확인)"를 둡니다.
tests/test_smoke.py 파일을 만들고 다음을 작성합니다.
def test_pytest_runs():
"""환경이 정상이면 반드시 통과하는 '연기 테스트(smoke test)'.
실제 기능을 검증하는 게 아니라, pytest 자체가 테스트를 발견하고 실행할 수
있는지(=환경이 살아 있는지)를 최소한으로 확인한다.
"""
assert 1 + 1 == 2 # 항상 참. 이게 통과하면 테스트 실행 환경이 정상이라는 뜻.
실행합니다.
uv run pytest -v
기대 출력:
tests/test_smoke.py::test_pytest_runs PASSED
========================= 1 passed in 0.0Xs =========================
🔍 관찰 포인트: uv run을 앞에 붙이면, 가상환경을 수동으로 활성화(.venv\Scripts\Activate.ps1)하지 않아도 됩니다. uv가 알아서 이 프로젝트 전용 환경에서 명령을 실행합니다. 앞으로 모든 파이썬 명령은 uv run ... 형태로 실행합니다.
✅ 체크포인트
아래가 모두 되면 1교시 통과입니다.
- [ ] uv --version이 버전을 출력한다
- [ ] sales-insight-agent 폴더 안에 src/sales_agent/... 4개 폴더와 tests/가 있다
- [ ] pyproject.toml에 pandas, streamlit, openai, pytest가 보인다
- [ ] pyproject.toml에 [tool.pytest.ini_options]와 [build-system] 설정이 있다
- [ ] 루트에 .gitignore가 있고 .env가 포함돼 있다
- [ ] uv sync로 패키지가 설치됐고, uv run python -c "import sales_agent; print('ok')"가 ok를 출력한다
- [ ] uv run pytest -v에서 1 passed가 나온다
🛠️ 트러블슈팅 모음
| 증상 | 원인 | 해결 |
| uv : 인식되지 않습니다 | PATH 미갱신 | PowerShell/VS Code 재시작 |
| 이 시스템에서 스크립트를 실행할 수 없으므로... | 실행 정책 제한 | 설치 명령에 이미 포함된 -ExecutionPolicy ByPass 사용. 또는 관리자 PowerShell에서 Set-ExecutionPolicy -Scope CurrentUser RemoteSigned |
| ModuleNotFoundError(테스트에서) | pythonpath 미설정 | pyproject.toml의 [tool.pytest.ini_options] 확인 |
| ModuleNotFoundError: No module named 'sales_agent'(python -c·앱에서) | 패키지 미설치 (pytest 밖에선 pythonpath가 안 통함) | pyproject.toml에 [build-system]·[tool.hatch.build.targets.wheel]을 넣고 uv sync 실행. 급할 땐 $env:PYTHONPATH="src" 후 재실행 |
| pytest 명령을 못 찾음 | dev 의존성 미설치 | uv add --dev pytest |
| uv sync 시 빌드/패키지 오류 | packages 경로 불일치 | [tool.hatch.build.targets.wheel] packages = ["src/sales_agent"]가 실제 폴더와 같은지 확인 |
🔑 핵심 정리
- 1~11교시의 무기는 uv(실행) + pytest(검증) 두 가지이며, 코드는 직접 손으로 만든다. (Copilot 가속은 12·13교시)
- 폴더를 domain / usecases / adapters / infra로 미리 나눈 것은 우연이 아니라 클린 아키텍처의 4계층이다. (3·4교시에서 채운다)
- uv run pytest에서 passed를 봤다면, 이제 "테스트로 코드를 믿을" 준비가 끝났다.
다음 교시: 우리가 만들 에이전트가 정확히 무엇을 해야 하는지 요구사항을 분해하고, 어디부터 테스트할지 전략을 세웁니다.
'AI System > 클린 아키텍처와 바이브 코딩을 활용한 AI Agent 시스템의 설계와 구' 카테고리의 다른 글
| d01 - 6. 데이터 처리 로직 구현 (0) | 2026.06.22 |
|---|---|
| d01 - 5. 첫번째 TDD 사이클 (0) | 2026.06.22 |
| d01 - 4. AI Agent 구조 설계 (0) | 2026.06.22 |
| d01 - 3. 클린 아키텍처 핵심 이해 (0) | 2026.06.22 |
| d01 - 2. 문제정의와 구현전략 (0) | 2026.06.22 |