3. 고쳐도 안 깨지는 코드

파일을 어떻게 나눌 것인가

이 차시를 마치면

프로젝트를 어떤 파일로 나눌지 정하고, 나누는 이유를 설명합니다.

파일을 어떻게 나누느냐가 나중에 고칠 때의 난이도를 정합니다. 처음에는 한 파일로 충분합니다. 다만 언제 나눠야 하는지는 알아야 합니다.

최소형 — 학습 초기

mini-project/
├─ .env
├─ requirements.txt
└─ app.py

app.py 하나에 State, Node, Edge, Graph compile, invoke 를 모두 넣습니다.

장점단점
전체 흐름을 한눈에 봅니다규모가 커지면 수정 영향 범위가 커지고, 테스트하기 어렵습니다

권장형

my-agent/
├─ .env
├─ .env.example
├─ .gitignore
├─ pyproject.toml
├─ langgraph.json
├─ src/
│  └─ my_agent/
│     ├─ __init__.py
│     ├─ state.py
│     ├─ schemas.py
│     ├─ tools.py
│     ├─ nodes.py
│     ├─ routing.py
│     ├─ prompts.py
│     ├─ graph.py
│     └─ settings.py
├─ tests/
│  ├─ test_tools.py
│  ├─ test_nodes.py
│  ├─ test_routing.py
│  └─ test_graph.py
└─ README.md

LangGraph 공식 Application Structure 문서도 state.py, nodes.py, tools.py, graph 구성 파일, dependency file, .env, langgraph.json 을 분리하는 예를 제시합니다. 확인 필요 해당 공식 문서는 이번 작업에서 접속 확인하지 않았습니다.

각 파일의 역할

파일역할
state.pyGraph 가 공유할 상태 구조
schemas.pyLLM Structured Output, Tool 입출력 등 데이터 계약
tools.py검색, 계산, DB 조회 등 외부 기능
nodes.pyState 를 입력받아 작업하고 State 갱신값을 반환
routing.py조건부 Edge 를 위한 routing function
prompts.pySystem prompt 와 template
graph.pyStateGraph 생성, Node 등록, Edge 연결, compile
settings.py환경설정과 환경변수 로딩
tests/각 영역을 독립적으로 검증

왜 나누는가

학습팩은 이렇게 못 박습니다. 파일을 나누는 목적은 '예쁘게 정리'하는 것이 아닙니다.

  1. State 계약을 명확히 하기 위해
  2. 외부 side effect 와 순수 로직을 분리하기 위해
  3. routing 을 독립적으로 테스트하기 위해
  4. prompt 변경과 graph 구조 변경을 분리하기 위해
  5. 운영 장애 시 어느 층이 문제인지 찾기 위해

비유

2번은 주방 설계와 같습니다. 불을 쓰는 자리를 한곳에 모아 두면 어디를 조심해야 하는지 분명해집니다. 가스레인지가 주방 곳곳에 흩어져 있으면 매번 전체를 살펴야 합니다.

2번은 보안 설계의 토대이기도 합니다. side effect 가 tools.py 와 특정 Node 에만 모여 있으면, "이 Agent 가 밖으로 무엇을 할 수 있는가"를 두 파일만 읽고 답할 수 있습니다. 흩어져 있으면 전체를 읽어야 합니다. 분석

실행 흐름

사용자 입력
   ↓
Input State 생성
   ↓
Graph.invoke()
   ↓
START → Node → State update → Edge / Router → 다음 Node → ... → END
   ↓
Output State

Agent 를 쓰는 경우에는 특정 Node 내부 또는 그래프의 일부가 create_agent() 기반 Agent 가 될 수 있습니다.

이해도 확인

문항을 불러오는 중입니다.