본문 바로가기
AI System/클린 아키텍처와 바이브 코딩을 활용한 AI Agent 시스템의 설계와 구

d01 - 1. 개발환경 구축

by Toddler_AD 2026. 6. 22.

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를 봤다면, 이제 "테스트로 코드를 믿을" 준비가 끝났다.

다음 교시: 우리가 만들 에이전트가 정확히 무엇을 해야 하는지 요구사항을 분해하고, 어디부터 테스트할지 전략을 세웁니다.