본문으로 건너뛰기
도구로 강제하는 규칙과 스포크 확장

생성 수정

IBM * 레드햇 AX 과정 · 18강

도구로 강제하는 규칙과 스포크 확장

2026년 6월 22일(월) ~ 6월 26일(금)

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

8. 규칙을 사람이 아니라 도구가 강제하게

8.1 왜 이 이야기가 이 주에 나오는가

6장에서 "스포크 간 순환 참조 금지"라는 규칙을 세웠습니다. 7장에서 "어댑터를 직접 부르지 말고 도메인을 거쳐라"라는 규칙을 세웠습니다.

규칙을 세우는 것과 지켜지는 것은 다른 일입니다. 특히 코드를 사람과 AI가 함께 쓰는 지금은, 규칙이 문서에만 있으면 반드시 깨집니다.

⭐ 판별 축 5 — 규칙을 사람이 지키는가(0) vs 도구가 강제하는가(1)

앞에서 배운 하네스 엔지니어링의 용어로 말하면, CLAUDE.md는 가이드(Feedforward, 행동 전 방향 설정) 이고, 린터·포매터·pre-commit은 센서(Feedback, 행동 후 결과 체크) 입니다. 둘 다 있어야 제대로 된 하네스입니다.

8.2 언어별 린터·포매터 세트

프로젝트가 파이썬 + 타입스크립트 + 다트(플러터) + 마크다운으로 늘어났습니다. 언어마다 도구가 다르므로 전부 걸어 둡니다.

Flutter (Dart)

파일: analysis_options.yaml

include: package:flutter_lints/flutter.yaml

linter:
  rules:
    avoid_print: error              # print 사용을 에러로
    prefer_const_constructors: true # 가능하면 const 생성자
dart format .      # 포매터 — 모양을 통일
dart analyze       # 린터 — 문제를 찾아냄

Python

파일: pyproject.toml

[tool.ruff]
line-length = 88
select = ["E", "F", "I", "N", "UP"]
코드무엇을 검사하나
Epycodestyle 에러 (PEP 8 스타일)
Fpyflakes (안 쓰는 import, 정의 안 된 이름)
Iisort (import 정렬 순서)
Npep8-naming (이름 규칙)
UPpyupgrade (옛날 문법을 최신 문법으로)

여기에 mypy(정적 타입 검사)를 함께 씁니다.

💡 line-length = 88 은 Black 포매터가 정한 관례입니다. 79(PEP 8)보다 조금 넉넉합니다. 숫자 자체보다 팀 전체가 같은 숫자를 쓴다는 사실이 중요합니다.

Next.js (TypeScript)

ESLint + .prettierrc

{
  "singleQuote": true,
  "tabWidth": 2,
  "printWidth": 80
}

문서 (Markdown)

파일: .markdownlint.json

⚠️ 문서에까지 린터를 거는 이유가 있습니다. 우리 프로젝트에서 마크다운은 읽을거리가 아니라 하네스의 일부입니다. CLAUDE.md와 _docs가 곧 AI에게 주는 지시서이므로, 형식이 깨지면 지시가 깨집니다.

정리표

대상포매터린터설정 파일
Flutterdart formatdart analyze (flutter_lints)analysis_options.yaml
Pythonruff formatruff + mypypyproject.toml
Next.jsPrettierESLint.prettierrc
문서—markdownlint.markdownlint.json
의존성 구조—import-linter / dependency-cruiser각 도구 설정

8.3 pre-commit — 전체 워크스페이스 강제의 핵심

⭐ 워크스페이스 전체에 규칙을 강제하는 것은 pre-commit이 핵심입니다.

린터를 설치만 해 두면 아무도 안 돌립니다. 커밋 순간에 자동으로 돌게 만들어야 합니다.

파일: .pre-commit-config.yaml 에 훅을 등록합니다.

훅하는 일
flutter-analyze다트 코드 정적 분석
flutter-formatdart format --set-exit-if-changed .
ruff파이썬 린트
mypy파이썬 타입 검사
eslint프론트엔드 린트

⚠️ dart format --set-exit-if-changed . 의 --set-exit-if-changed 가 중요합니다. 포맷이 바뀌었으면 종료 코드를 실패로 만들라는 뜻입니다. 이게 없으면 포매터가 조용히 고치고 넘어가서, 검사 역할을 못 합니다.

설치

pip install pre-commit
pre-commit install

pre-commit install 이 하는 일은 .git/hooks/pre-commit 파일을 만드는 것입니다. 이제 git commit 을 칠 때마다 등록한 훅이 전부 돌고, 하나라도 실패하면 커밋이 막힙니다.

⭐ 커밋이 막히는 것은 기능입니다. 버그가 아닙니다. 4장에서 배웠듯 main 은 허브입니다. 허브에 깨진 코드가 들어가면 모든 스포크가 영향을 받습니다. pre-commit은 허브를 지키는 문지기입니다.

8.4 CLAUDE.md 에 "코드 작성 후 필수 실행" 을 명시한다

마지막 한 조각입니다.

⭐ 루트 CLAUDE.md 에 "코드 작성 후 필수 실행" 섹션을 명시하면, 클로드코드가 작업을 마친 뒤 자동으로 린터를 돌립니다.

## 코드 작성 후 필수 실행

작업을 마치면 아래를 반드시 순서대로 실행하고, 실패 시 스스로 수정한 뒤 다시 실행할 것.

1. Python:   `ruff check --fix .` → `mypy .`
2. Flutter:  `dart format .` → `dart analyze`
3. Next.js:  `npm run lint`
4. 커밋 전:  `pre-commit run --all-files`

이렇게 되면 검사가 세 겹이 됩니다.

겹누가언제
1AI 자신코드 작성 직후 (CLAUDE.md 지시)
2pre-commit 훅git commit 순간
3CI푸시 후

앞의 겹에서 걸러질수록 비용이 싸집니다. CI에서 걸리면 그때는 이미 다른 사람 시간까지 씁니다.


9. 이번 주에 늘어난 스포크들

이번 주에 프로젝트는 백엔드 + 프론트엔드 + 모바일 앱 세 갈래가 되었습니다. 구조가 커졌으니 문서와 저장소도 같은 모양으로 정리해야 합니다.

9.1 문서 배치 프랙탈 규칙

⭐ 공통 문서는 루트 _docs, 각 프로젝트는 자기 폴더 아래 _docs, 그리고 루트에는 CLAUDE.md.

프로젝트루트/
├── CLAUDE.md              ← 최상위 규칙 (허브)
├── _docs/                 ← 공통 문서
├── tailor/                ← 백엔드 (FastAPI)
│   └── _docs/
├── taylor/                ← 프론트엔드 (Next.js)
│   └── _docs/
└── taper/                 ← 모바일 (Flutter)
    └── _docs/

세 프로젝트가 전부 같은 모양입니다. 이것이 3주차에서 배운 프랙탈입니다.

계층무엇이 있나누가 보나
루트 CLAUDE.md전 프로젝트 공통 규칙사람 + AI
루트 _docs/여러 프로젝트에 걸친 문서사람 + AI
xxx/_docs/그 프로젝트만의 문서그 프로젝트 작업자

💡 이 배치가 곧 문서의 스타 토폴로지입니다. taper/_docs 는 taylor/_docs 를 참조하지 않습니다. 공통이 필요하면 루트로 올립니다. 6.4절의 "스포크 간 직접 참조 금지"와 같은 규칙이 문서에 적용된 것입니다.

9.2 통합 저장소 하나

백엔드·프론트엔드·플러터를 하나의 저장소에 둡니다. 3주차에서 배운 분류로는 모노레포(Monorepo) 입니다.

이 선택의 결과
⭕ 좋은 점세 프로젝트의 버전이 한 커밋에 묶임. API가 바뀌면 프론트·앱도 같은 커밋에서 고침
⭕ 좋은 점pre-commit 하나로 세 언어를 전부 검사 가능 (8장)
⚠️ 대가저장소가 커지고, 클론이 무거워짐
⚠️ 대가main 이 진짜 단일 장애점이 됨 — 깨지면 셋 다 멈춤

⚠️ 모노레포 ≠ 모놀리식입니다. 3주차의 축 5를 다시 보세요. 저장소가 하나인 것과 배포 단위가 하나인 것은 다른 축입니다. 지금 우리는 모노레포 + (모듈러 모놀리식 백엔드 + 별도 프론트 + 별도 앱) 입니다.

9.3 네이티브 앱과 하이브리드 — 왜 웹뷰를 금지했는가

플러터로 첫 화면을 만들 때 지시가 하나 붙었습니다.

⭐ 웹뷰·하이브리드 앱은 금지하고, 반드시 네이티브 앱 형태로 만들 것.

이 지시가 왜 필요했는지는 분류로 보면 명확합니다.

구분네이티브 (Native)하이브리드 / 웹뷰 (WebView)
화면을 그리는 주체앱이 직접 (플러터 렌더링 엔진)앱 안에 띄운 브라우저가 그림
실제로 실행되는 것앱 코드웹페이지
앱 안에 있는 것UI 전부껍데기 + 주소
성능빠름브라우저를 한 겹 더 지남
오프라인가능서버가 죽으면 화면 자체가 안 뜸

⚠️ 웹뷰로 만들면 앱이 사실상 "웹사이트를 여는 버튼"이 됩니다. 그러면 앱은 스포크가 아니라 웹 프론트엔드에 종속된 껍데기가 되고, 웹이 죽는 순간 앱도 같이 죽습니다. 스포크가 다른 스포크에 붙어 버린 것입니다(6.4절 금지 규칙).

⭐ 네이티브로 만들어야 앱이 허브(FastAPI)에 직접 붙는 독립된 스포크가 됩니다. "AI야 웹뷰 쓰지 마"는 취향 지시가 아니라 토폴로지를 지키는 지시입니다.

💡 다만 프론트엔드와 디자인 테마는 통일합니다. 구조는 독립시키고 겉모습은 맞추는 것 — 이것도 "코어는 공유, 어댑터는 각자"와 같은 원칙입니다.

9.4 GPU 환경 — 왜 지금 CUDA를 잡는가

이번 주에 파이토치와 CUDA 환경을 따로 잡습니다. 갑작스러워 보이지만 이유가 있습니다.

앞에서 로컬 LLM을 배웠습니다. 올라마(Ollama) 위에 한국어 모델을 올리고, 전처리는 kiwipiepy로 하는 조합이었습니다. 그때는 CPU로도 어떻게든 돌았습니다.

그런데 이제 허브가 생겼고(6장), 허브가 온톨로지 인덱스와 전역 상태를 들게 됩니다. 모델을 우리 서버 안에서 제대로 돌려야 할 시점이 오는 것입니다. 그러려면 GPU가 필요하고, GPU를 쓰려면 CUDA와 파이토치의 버전이 정확히 맞아야 합니다.

층이번 주 기준안 맞으면
파이썬3.12패키지 휠(wheel)이 없어서 설치 실패
파이토치2.12GPU를 못 잡거나 임포트 에러
CUDA12.6torch.cuda.is_available() 가 False

⚠️ 이 세 개는 독립적으로 고를 수 없습니다. 서로 맞물린 조합표가 있습니다. "최신이면 좋겠지"로 올리면 반드시 깨집니다. 절차는 10.1~10.2절에 있습니다.

앞으로 다시 만납니다 이 GPU 환경 위에서 온프레미스 SLM(소형 언어 모델) 구축으로 이어집니다. 데이터 보안·비용 예측·초저지연·도메인 특화라는 네 가지 이유로 모델을 사내에 두는 전략인데, 그때 필요한 것이 지금 잡는 CUDA 환경입니다.

9.5 IDE — 이 모든 것이 한 창에서 돌아가는 이유

세 언어, 네 개의 린터, 그래프 도구까지 늘어나면 도구 이야기를 한 번 정리하고 가야 합니다.

IDE(Integrated Development Environment, 통합 개발 환경) — [개발 도구]인데, [편집기·컴파일러·디버거·터미널·버전관리를 하나의 창에 통합했다]는 점에서 단순 편집기와 구별된다.

구성 요소하는 일이번 주에 우리가 쓴 것
편집기코드 작성VSCode 본체
확장(Extension)언어별 기능 추가Flutter 확장
터미널명령 실행conda, npm, pre-commit
디버거중단점·변수 확인파이썬·다트 디버거
버전 관리커밋·브랜치내장 Git
AI 에이전트코드 생성·수정클로드코드

💡 IDE도 스타 토폴로지입니다. 편집기가 허브이고, 확장들이 스포크입니다. 확장끼리는 서로 모르고, 전부 IDE에만 붙습니다. 그래서 확장 하나가 깨져도 IDE는 살아 있고(장애 격리), IDE가 죽으면 전부 멈춥니다(단일 장애점). 어디를 봐도 같은 모양입니다.


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

10.1 파이토치용 가상환경 만들기

파이썬 3.12 가상환경을 아나콘다로 만듭니다.

conda create -n pytorch_env python=3.12
conda activate pytorch_env
부분뜻
-n pytorch_env환경 이름. -n 은 name
python=3.12이 환경에 넣을 파이썬 버전
conda activate그 환경 안으로 들어감

⚠️ conda activate 를 쳤는데 안 먹으면 conda init 을 한 번 실행하고 에디터를 완전히 껐다 켜세요. 셸이 새로 뜨기 전에는 반영되지 않습니다.

💡 왜 굳이 별도 환경인가: 파이토치는 CUDA 버전에 강하게 묶여 있습니다. 기존 환경에 설치하면 다른 프로젝트의 패키지 버전과 충돌합니다. 가상환경은 의존성의 장애 격리 장치입니다 — 이번 주 축 4가 여기에도 있습니다.

10.2 GPU가 실제로 잡혔는지 검증하기

torch_test.py 파일을 만들고 두 줄을 넣습니다.

import torch

print(torch.cuda.is_available())

그리고 AI에게 이렇게 요청합니다.

가상환경 pytorch_env 에
파이썬 3.12 / 파이토치 2.12 / 쿠다 12.6 이
잘 작동하는지 체크해줘

판정 기준

출력뜻다음 행동
TrueGPU를 쓸 수 있음성공
FalseGPU를 못 잡음아래 순서로 확인

False 일 때 확인 순서:

  1. nvidia-smi 로 드라이버가 GPU를 보고 있는지
  2. 설치된 파이토치가 CPU 전용 빌드가 아닌지 (torch.__version__ 뒤에 +cpu 가 붙으면 CPU 빌드)
  3. CUDA 버전과 파이토치 빌드가 맞는지

⚠️ 3주차에서 배운 원칙 그대로입니다 — 연결이 안 되면 코드를 고치기 전에 환경부터 봅니다.

10.3 플러터 설치와 프로젝트 생성

순서를 정확히 지켜야 합니다.

  1. VSCode 확장에서 flutter 를 검색해 설치
  2. Ctrl + Shift + P → flutter 입력
  3. Application 선택
  4. 미리 만들어 둔 빈 폴더(예: taper)를 선택
  5. 프로젝트명 입력
  6. OS 선택 — 윈도우는 windows, 맥은 iOS. 추가로 android, web 도 함께 선택
  7. VSCode가 닫혔다 다시 열리면 워크스페이스를 다시 연다
  8. 하단에 Java 설치가 진행되면 기다린다

🔗 플러터 SDK 설치 안내: https://docs.flutter.dev/learn/pathway/quick-install

⚠️ 4번을 놓치는 사람이 많습니다. 빈 폴더를 미리 만들어 두고 그것을 고르는 순서입니다. 플러터가 폴더를 만들어 주기를 기다리면 엉뚱한 위치에 프로젝트가 생깁니다.

⚠️ 8번의 Java 설치를 중간에 끊지 마세요. 안드로이드 빌드 도구가 Java에 의존합니다. 여기서 끊으면 나중에 원인을 알 수 없는 빌드 실패로 돌아옵니다.

💡 6번에서 android와 web을 같이 켜 두는 이유: 나중에 추가하려면 프로젝트 설정을 손봐야 합니다. 처음에 켜 두면 폴더만 생기고 손해가 없습니다.

10.4 플러터 인트로 화면 만들기

파일: taper/lib/main.dart

taper/lib/main.dart 에 인트로 화면을 만들어줘.
- 웹 인트로와 유사한 테마로 작성할 것
- ⚠️ 웹뷰·하이브리드 앱은 금지. 반드시 네이티브 앱 형태로 만들 것

금지 조항이 왜 필요한지는 9.3절에 있습니다. ⭐ AI에게 지시할 때 "하지 말 것"을 명시하는 것이 "할 것"보다 중요할 때가 많습니다. AI는 가장 쉬운 길을 고르는데, 웹뷰가 훨씬 쉽기 때문입니다.

10.5 프론트엔드 기준 버전 고정

package.json 의 기준 버전입니다. 버전이 어긋나서 나는 에러를 먼저 지웁니다.

패키지버전무엇
next16.2.4프레임워크
react^19UI 라이브러리
tailwindcss^4.2.0CSS
typescript5.7.3타입
zod^3.24.1런타임 스키마 검증
@neondatabase/serverless^1.1.0Neon(PostgreSQL) 클라이언트
@google/generative-ai^0.24.1제미나이 SDK
pdfjs-dist^6.0.227PDF 렌더링
recharts2.15.0차트

💡 ^ 가 있고 없고의 차이 ^19 는 "19.x 안에서는 올라가도 좋다"이고, 16.2.4 는 "정확히 이 버전"입니다. 프레임워크(next)와 언어(typescript)는 정확히 고정하고, 라이브러리는 마이너 업데이트를 허용한 배치입니다.

10.6 문서 배치와 통합 저장소 정리

공통 md 는 루트 _docs 로,
백엔드는 tailor/_docs, 프론트는 taylor/_docs, 플러터는 taper/_docs 로 옮기고
루트에는 CLAUDE.md 를 둬줘.

정리 후 구조는 9.1절과 같습니다. 그리고 백엔드·프론트·플러터를 하나의 저장소로 통합합니다(9.2절).

10.7 MCP 툴 파일 작성

apps/silicon_valley/adapter/inbound/mcp/piper_henricks_ceo_tools.py

이 경로에 MCP 툴 파일을 만듭니다. adapter/inbound/ 아래라는 것이 핵심입니다(7.2절).

⚠️ mcp.server.fastmcp 임포트 에러가 나면 requirements.txt 에 패키지를 추가하고 다시 설치합니다.

pip install -r requirements.txt

10.8 n8n 설치와 연동

npm install -g n8n

이후 4단계는 7.4절에 코드와 함께 있습니다. 순서만 다시 적으면:

  1. n8n에서 Webhook 노드 추가 → HTTP Method POST → URL 복사
  2. adapter/outbound/client/n8n_client.py 작성
  3. dependencies/providers.py 에 get_n8n_client() 추가 (URL은 os.environ 에서)
  4. @app.post("/tools/trigger-automation") 엔드포인트에서 Depends 로 주입받아 호출

성공 판정: 엔드포인트를 호출했을 때 n8n 워크플로우 실행 이력에 요청이 찍히면 성공입니다.

10.9 CLAUDE.md 에 허브·스포크 규칙 쓰기

fastapi/CLAUDE.md 에 아래 규칙을 명시합니다.

## Architecture: Star Topology

- The backend is a **modular monolith**.
- `apps/star_craft` is the **Hub**. All other apps under `apps/` are **Spokes**.
- The Hub owns: ontology index, routing, global state.
- Spokes MUST interact only through the Hub.
- Circular references between Spokes are STRICTLY FORBIDDEN.
- Allowed dependency direction: spoke → hub. Never hub → spoke, never spoke ↔ spoke.

💡 규칙 본문을 영어로 쓰는 이유: 앞에서 정한 CLAUDE.md 작성 원칙 그대로입니다. 모델이 영어 지시를 더 정확히 따르고, 코드 식별자와 표기가 섞이지 않습니다.

10.10 린터·포매터·pre-commit 설치

설정 파일 네 개를 만들고(8.2절), 훅을 등록한 뒤(8.3절) 설치합니다.

pip install pre-commit
pre-commit install

전체를 한 번 돌려 보기 — 설치 직후에는 기존 코드가 규칙을 안 지키고 있으므로 대량으로 걸립니다.

pre-commit run --all-files

⚠️ 여기서 나오는 수백 줄의 경고에 놀라지 마세요. 대부분 포매터가 자동으로 고칩니다. 자동으로 안 고쳐지는 것(mypy 타입 에러, 안 쓰는 변수)만 손으로 고칩니다. 그리고 이 한 번의 정리를 하고 나면 그 뒤로는 계속 깨끗합니다.

10.11 옵시디언 그래프뷰 정리

좌측 하단 톱니바퀴 → Files and links → Manage → 제외할 폴더·파일 유형 지정

노드가 너무 많아 그래프가 안 읽힐 때 씁니다(2.4절).


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

11.1 플러터 SDK 설치 가이드

🔗 https://docs.flutter.dev/learn/pathway/quick-install

이게 왜 이 주에 나왔는가: 이번 주에 프로젝트가 백엔드·프론트엔드에 이어 세 번째 갈래를 얻습니다. 스포크가 하나 늘어난 것입니다. 그리고 스포크를 늘리는 일이 선 하나 꽂는 정도로 끝나는가가 우리 구조가 진짜 스타인지 아닌지의 시험대입니다(3.3절 "확장 및 유지보수 용이").

11.2 IDE(통합 개발 환경)란 무엇인가

🔗 https://www.servicenow.com/kr/platform/what-is-ide.html

이게 왜 이 주에 나왔는가: 언어가 셋으로 늘고 린터가 넷으로 늘어난 주입니다. 도구가 늘어날 때 "이 도구들이 서로 어떤 관계인가" 를 정리하지 않으면 편집기 설정 지옥에 빠집니다. IDE라는 개념 자체가 도구들의 허브라는 것을 알면 정리가 됩니다(9.5절).

11.3 백엔드·프론트엔드·플러터 통합 저장소

🔗 https://github.com/langtailor/1924-hi-watson

이게 왜 이 주에 나왔는가: 4장에서 GitHub의 main 이 허브라고 배웠습니다. 그 허브에 이제 세 프로젝트가 전부 모입니다. 모노레포 선택의 결과를 실제 저장소에서 확인하는 자료입니다. 저장소를 열어 볼 때는 폴더 구조가 9.1절의 프랙탈 배치와 같은지를 먼저 보세요.

11.4 엔비디아에 대항하는 빅테크들

🔗 https://youtube.com/shorts/WkKcF7wi4zk

이게 왜 이 주에 나왔는가: 이 주에 우리는 CUDA 12.6 버전을 맞추느라 시간을 씁니다(10.2절). CUDA는 엔비디아의 것입니다. 그리고 CUDA에 맞춰야만 파이토치가 GPU를 잡습니다.

⭐ 이것이 산업 규모의 단일 장애점입니다.

우리 프로젝트AI 산업
apps/star_craft 가 허브엔비디아 GPU + CUDA 가 허브
스포크는 허브를 거쳐야 함거의 모든 AI 프레임워크가 CUDA를 거침
허브가 죽으면 전부 멈춤공급이 막히면 산업 전체가 멈춤
그래서 허브 이중화를 함그래서 빅테크가 자체 칩을 만듦

빅테크가 자체 AI 칩을 만드는 것은 3.5절에서 배운 "허브 이중화" 의 산업 버전입니다. 이 뉴스가 이 주에 나온 이유가 바로 그것입니다. 같은 판별 축이 코드에서도, 네트워크에서도, 산업에서도 똑같이 작동합니다.

⚠️ 다만 축을 헷갈리지 마세요. 자체 칩을 만든다고 CUDA가 사라지지는 않습니다. 허브를 없애는 것이 아니라 허브를 하나 더 만드는 것입니다. 허브가 둘이 되면 스타 두 개가 되고, 그 사이를 잇는 문제가 새로 생깁니다. "단일 장애점을 없앴다"가 아니라 "단일 장애점을 이중화하고 복잡도를 샀다"가 정확한 표현입니다.


부록 A. 용어 사전

용어영문상위 범주정의
온톨로지Ontology지식 지도데이터·지식 간의 의미와 관계를 기계가 처리하도록 정형화한 것
토폴로지Topology연결 지도노드들이 물리적·논리적으로 배치되어 연결된 구조와 형태
시맨틱Semantic성질형식이 아닌 의미 차원
개념Class온톨로지 요소같은 성질의 것을 묶은 범주
속성Property온톨로지 요소개념이 가지는 특징
관계Relation온톨로지 요소개념과 개념을 잇는 의미의 선 (is-a, part-of)
연결성Connectivity토폴로지 요소거리·크기와 무관하게 이어져 있는 상태
시맨틱 웹Semantic Web활용 분야웹 문서에 기계가 읽을 의미를 부여한 웹
지식 그래프Knowledge Graph활용 분야개념과 관계를 그래프로 저장한 지식 표현
그래프Graph자료구조노드 + 엣지로 이루어진 구조
노드Node / Vertice그래프 요소그래프의 점. 하나의 대상
엣지Edge / Link그래프 요소노드와 노드를 잇는 선
유방향 그래프Directed Graph그래프 종류엣지에 방향이 있는 그래프
무방향 그래프Undirected Graph그래프 종류엣지에 방향이 없는 그래프
스타 토폴로지Star Topology토폴로지 종류중앙 장치를 중심으로 모든 주변 장치가 1:1로 연결된 구조
허브 앤 스포크Hub-and-Spoke구조 모델스타 토폴로지의 다른 이름
허브Hub구조 요소데이터 교환과 흐름을 제어·중계하는 중앙 중심축
스포크Spoke구조 요소허브에 연결된 바퀴살 형태의 주변부 단말기
단일 장애점Single Point of Failure (SPOF)위험그것 하나가 죽으면 전체가 멈추는 지점
장애 격리Fault Isolation성질한 곳의 고장이 다른 곳으로 번지지 않는 성질
스위칭Switching동작허브가 데이터를 목적지로 중계하는 것
버스 토폴로지Bus Topology토폴로지 종류하나의 공용 회선에 모든 노드가 매달린 구조
링 토폴로지Ring Topology토폴로지 종류원형으로 옆 노드에 전달하는 구조
메시 토폴로지Mesh Topology토폴로지 종류노드끼리 서로 직접 연결된 구조
트리 토폴로지Tree Topology토폴로지 종류계층적으로 갈라지는 구조
병합MergeGit 동작브랜치의 변경을 다른 브랜치로 합치는 것
메인 브랜치main branchGit 구조저장소의 중앙 집중축이 되는 브랜치
모듈러 모놀리식Modular Monolith시스템 아키텍처배포는 하나, 내부는 모듈로 분리
모노레포Monorepo저장소 구조하나의 저장소에 여러 프로젝트
순환 참조Circular Reference문제 상황A가 B를, B가 A를 서로 참조하는 상태
헥사고날Hexagonal Architecture아키텍처중심 코어 + 포트·어댑터. 스타 토폴로지의 한 형태
퍼사드Facade구조 패턴복잡한 서브시스템 앞에 단순한 창구 하나를 세움
포트Port인터페이스"무엇을 할지"의 규격 (추상)
어댑터Adapter구현체포트를 특정 기술로 구현한 것 (구상)
인바운드Inbound방향바깥에서 시스템으로 들어오는 쪽
아웃바운드Outbound방향시스템에서 바깥으로 나가는 쪽
MCPModel Context Protocol프로토콜LLM이 도구·데이터를 규격에 맞춰 쓰게 하는 약속
Tool (MCP)ToolMCP 요소AI가 사용할 수 있는 기능 단위
ConnectorConnectorMCP 요소특정 앱·서비스에 연결해 주는 어댑터
n8n—자동화 도구노드-엣지로 워크플로우를 만드는 도구. 여기서는 아웃바운드 어댑터
웹훅Webhook연동 방식이벤트 발생 시 지정한 URL로 HTTP 요청을 보내는 것
CLICommand Line Interface인터페이스사람이 명령어로 컴퓨터를 다루는 창
린터Linter도구코드의 문제를 정적으로 찾아내는 도구
포매터Formatter도구코드의 모양을 규칙대로 통일하는 도구
ruff—린터파이썬 린터·포매터
mypy—도구파이썬 정적 타입 검사기
ESLint—린터자바스크립트·타입스크립트 린터
Prettier—포매터프론트엔드 코드 포매터
markdownlint—린터마크다운 문서 린터
pre-commit—Git 훅 도구커밋 직전에 검사를 자동 실행시키는 도구
Git 훅Git HookGit 기능특정 Git 동작 시점에 스크립트를 실행시키는 장치
dependency-cruiser—도구JS 의존성 그래프 분석·규칙 위반 검출
import-linter—도구파이썬 의존성 계약 검사
하네스Harness실행 구조모델을 감싸 실제 행동을 가능하게 하는 구조
가이드Guide (Feedforward)하네스 요소행동 전 방향을 정하는 것 (규칙·문서)
센서Sensor (Feedback)하네스 요소행동 후 결과를 확인하는 것 (테스트·린터·로그)
프랙탈Fractal구조 개념같은 구조가 크기를 바꿔 반복되는 것
네이티브 앱Native App앱 형태앱이 직접 화면을 그리는 방식
웹뷰 / 하이브리드WebView / Hybrid앱 형태앱 안에 브라우저를 띄워 웹페이지를 보여주는 방식
플러터Flutter프레임워크하나의 코드로 여러 OS의 네이티브 앱을 만드는 도구
Dart—언어플러터가 쓰는 프로그래밍 언어
CUDA—플랫폼엔비디아 GPU에서 연산을 돌리기 위한 병렬 컴퓨팅 플랫폼
파이토치PyTorch프레임워크딥러닝 프레임워크
가상환경Virtual Environment격리 장치프로젝트별로 패키지·파이썬 버전을 분리하는 것
IDEIntegrated Development Environment도구편집·빌드·디버깅·버전관리를 한 창에 통합한 환경
트레이드오프Trade-off개념하나를 얻으면 다른 하나를 잃는 관계

부록 B. 스스로 확인하기

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

#질문답이 있는 곳
1온톨로지와 토폴로지가 각각 던지는 질문 한 문장씩은?1.3, 1.4
2"노드가 100개 있다"는 온톨로지인가 토폴로지인가?1.6
3같은 그래프가 온톨로지가 되기도, 토폴로지가 되기도 하는 조건은?2.3
4Vertice와 Node는 다른 것인가?2.2
5스타 토폴로지의 장점과 단점이 왜 같은 뿌리에서 나오는가?3.3
6메시 토폴로지를 잘 안 쓰는 이유는?3.4
7GitHub의 main과 스타 토폴로지 허브가 다른 유일한 항목은?4.2, 4.3
8브랜치끼리 직접 머지가 기술적으로 가능한데 왜 금지하는가?4.3
9헥사고날이 스타 토폴로지의 한 형태인 이유는?5.1
10Facade와 허브는 무엇이 다른가?5.2
11허브의 세 가지 책임은? 그중 온톨로지인 것과 토폴로지인 것은?6.3
12스포크 간 순환 참조를 금지하면 무엇을 얻는가?6.4
13규칙이 지켜졌는지 사람이 아니라 무엇이 확인하는가?6.4, 8.3
14MCP는 라이브러리인가 프로토콜인가?7.2
15n8n이 우리 아키텍처에서 갖는 신분은?7.3
16n8n을 붙였는데 use case 코드가 안 바뀌는 이유는?7.6
17--set-exit-if-changed 가 없으면 왜 검사가 무의미해지는가?8.3
18왜 웹뷰 앱을 금지했는가? 토폴로지 용어로 답하시오9.3
19torch.cuda.is_available() 가 False 일 때 확인 순서는?10.2
20빅테크의 자체 AI 칩 개발은 이 장의 어느 개념인가?11.4

부록 C. 자주 하는 실수

실수바로잡기
"온톨로지 = 어려운 철학"❌ 지식 지도입니다. 개념·속성·관계 세 가지가 전부
"토폴로지 = 위상수학"❌ 연결 구조입니다. topo- 는 '장소'이지 '수학'이 아닙니다
"온톨로지와 토폴로지는 난이도로 갈린다"❌ 묻는 질문으로 갈립니다. 의미냐 통로냐
"그래프 DB를 쓰면 온톨로지가 된다"❌ 그릇일 뿐입니다. 엣지에 의미를 적어야 온톨로지
"vertex와 node는 다른 개념"❌ 분야별 이름 차이입니다. 같은 것
"그래프 = 막대그래프"⚠️ 영어권에선 차트(chart)와 그래프(graph)를 구별합니다
"스타 토폴로지와 허브 앤 스포크는 다른 것"❌ 같은 것의 두 이름입니다
"장애 격리가 되니 스타는 안전하다"❌ 위험이 한 곳에 모인 구조입니다. 허브 방어가 별도로 필요
"허브가 강력할수록 좋다"⚠️ 허브가 두꺼울수록 단일 장애점이 커집니다. 얇게 유지
"main은 가장 중요한 브랜치라서 중앙이다"❌ 기술적으로 동등합니다. 가운데로 정했기 때문에 중앙입니다
"브랜치 간 직접 머지는 불가능하다"⚠️ 가능하지만 금지합니다. 하는 순간 메시가 됩니다
"GitHub main = 네트워크 허브, 완전히 같다"⚠️ 구조적 목적이 다릅니다. main은 누적, 허브는 중계
"헥사고날은 육각형이라서 육각형이다"❌ 각의 개수는 무관합니다. 중심이 하나인 것이 본질
"Facade = 허브"❌ Facade는 입구(패턴), 허브는 교환대(토폴로지). 축이 다릅니다
"모듈러 모놀리식은 알아서 모듈이 분리된다"❌ 한 프로세스라 아무것도 안 막아 줍니다. 규칙과 도구로 막습니다
"모노레포 = 모놀리식"❌ 저장소 축과 배포 축은 다릅니다
"순환 참조는 에러로 바로 알 수 있다"⚠️ 파이썬은 실행 중 특정 경로에서 터집니다. 구조로 막아야 합니다
"MCP는 라이브러리다"❌ 프로토콜(약속) 입니다
"MCP와 CLI는 경쟁 관계"❌ 사람은 CLI, AI는 MCP. 역할이 다릅니다
"n8n이 시스템의 중심"❌ 아웃바운드 어댑터(스포크) 입니다. 로직은 허브에
"n8n 워크플로우에 비즈니스 로직을 넣으면 편하다"⚠️ 로직이 두 곳에 흩어집니다. 교체 불가능해집니다
"webhook URL을 코드에 적어 두면 편하다"❌ os.environ 에서 조회합니다. 키·URL은 환경변수로
"린터는 설치만 해 두면 된다"❌ 아무도 안 돌립니다. pre-commit으로 강제해야 합니다
"pre-commit이 커밋을 막는 건 불편하다"⚠️ 그게 기능입니다. 허브(main)를 지키는 문지기
"문서에 린터까지 걸 필요 있나"⚠️ 문서가 AI에게 주는 지시서입니다. 형식이 깨지면 지시가 깨집니다
"웹뷰로 만들면 개발이 빠르니 좋다"⚠️ 앱이 웹에 종속된 스포크가 됩니다. 웹이 죽으면 앱도 죽습니다
"파이토치는 최신 버전이 좋다"❌ 파이썬·파이토치·CUDA는 맞물린 조합입니다. 표를 보고 맞춥니다
"conda activate 가 안 먹는다"⚠️ conda init 후 에디터를 완전히 껐다 켜세요
"플러터가 폴더를 만들어 줄 것이다"❌ 빈 폴더를 미리 만들어 두고 그것을 선택합니다
"Java 설치가 오래 걸려서 껐다"❌ 안드로이드 빌드가 나중에 원인 모르게 실패합니다. 기다립니다
"자체 칩을 만들면 단일 장애점이 사라진다"⚠️ 허브가 둘이 되는 것입니다. 복잡도를 산 것

부록 D. 날짜별 색인

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

날짜다룬 내용이 장의 절
6/22 (월)파이썬 3.12 콘다 가상환경 생성, torch_test.py 로 CUDA 검증(파이토치 2.12 / CUDA 12.6), 플러터 VSCode 확장 설치와 프로젝트 생성 8단계, 플러터 인트로 화면(웹뷰·하이브리드 금지 / 네이티브 강제), 프론트엔드 package.json 기준 버전 9종9.3, 9.4, 10.1~10.5
6/23 (화)문서 배치 프랙탈 규칙(루트 _docs / tailor / taylor / taper, 루트 CLAUDE.md), 백엔드·프론트·플러터 통합 저장소, IDE(통합 개발 환경)란9.1, 9.2, 9.5, 10.6, 11.2, 11.3
6/24 (수)그래프 = 노드(Vertice/Node) + 엣지(Edge/Link, 방향성 유무), 분야별 명칭 통일, MCP 툴 파일 작성(adapter/inbound/mcp/)과 mcp.server.fastmcp 임포트 에러 해결, n8n 설치, FastAPI 클린 아키텍처 + MCP + n8n 스타 토폴로지 4단계 구현과 데이터 흐름2.1~2.3, 7, 10.7, 10.8
6/25 (목)⭐ 온톨로지 vs 토폴로지, 스타 토폴로지 = 허브 앤 스포크, GitHub main-branch 구조와의 메커니즘 대응, apps/star_craft 허브 지정과 스포크 규칙(순환 참조 금지), 하네스용 린터·포매터 세트(Flutter / Python / Next.js / 문서), pre-commit 훅 등록과 설치, CLAUDE.md 의 "코드 작성 후 필수 실행", 의존성 정적 분석(dependency-cruiser / import-linter), 옵시디언 그래프뷰 노드 제외 설정1, 3, 4, 5, 6, 8, 2.4, 10.9~10.11
6/26 (금)엔비디아에 대항하는 빅테크들 — 단일 장애점과 허브 이중화의 산업 버전11.4

부록 E. Gemini / NotebookLM 프롬프트

복습 문제 받기

이 9주차 교재만 근거로 8문제를 내줘. 비전공자 기준으로.
"온톨로지 vs 토폴로지", "스타 토폴로지 = 허브 앤 스포크",
"GitHub main-branch 구조와의 대응"은 반드시 포함해줘.
답은 바로 주지 말고, 내가 답한 다음에 채점하고
틀린 이유를 교재의 어느 절을 근거로 설명해줘. 교재에 없는 내용은 꺼내지 마.

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

「1.5 한 표로」와 「1.3 / 1.4」를 합쳐 인포그래픽 1장으로 만들어줘.
- 화면을 좌우로 나눠 왼쪽 온톨로지, 오른쪽 토폴로지
- 각 면에 [핵심 요소] [묻는 질문] [주요 활용]을 같은 위치에 배치해 대칭이 보이게
- 가운데에 "뜻 ↔ 길" 을 크게
- 하단에 같은 그래프 그림 하나를 두고, 엣지에 무엇을 적느냐로 갈린다는 것을 화살표 두 개로
- 전문용어는 한글(영문) 병기

인포그래픽 ② — GitHub와 스타 토폴로지

「4.2 네 항목 대응표」를 좌우 비교 인포그래픽으로 만들어줘.
- 왼쪽에 GitHub(main + 브랜치 4개), 오른쪽에 스타 토폴로지(허브 + 스포크 4개)를 같은 별 모양으로
- 두 그림 사이에 [중앙 집중축] [주변 확장부] [통신/흐름 방식] [장애 격리성] [구조적 목적] 5행을 연결선으로
- ⚠️ 마지막 행(동기화·누적 vs 중계·전송)만 다른 색으로 — 여기만 다르다는 것을 강조
- 브랜치끼리 직접 잇는 선에는 X 표시

인포그래픽 ③ — 같은 별이 반복된다

「5.4 프랙탈」의 표를 동심원 또는 계단식 인포그래픽으로 만들어줘.
- 네트워크 장비 → 저장소 → 서비스 아키텍처 → 앱 내부 → 헥사고날 → 문서 → 팀
- 각 층마다 작은 별 그림을 하나씩 그리고, 가운데에 허브 이름, 바깥에 스포크 이름
- "크기만 다르고 모양이 같다"를 한 문장으로 상단에

인포그래픽 ④ — FastAPI 허브의 안팎

「7.1 전체 그림」과 「7.5 데이터 흐름」을 한 장으로 만들어줘.
- 가운데 FastAPI 허브, 왼쪽 위에 MCP 클라이언트(인바운드), 오른쪽에 n8n(아웃바운드), 아래에 DB
- 화살표를 따라 [MCP 요청] → [접수/가공·검증] → [DI로 어댑터 호출] → [HTTP POST Webhook] 라벨
- MCP 클라이언트와 n8n 사이에는 선을 그리지 말고, 대신 "서로 모른다"를 회색 글씨로

막힐 때

9주차에서 "___" 가 이해가 안 돼.
이 교재의 판별 축 5개(의미/구조, 중앙집중/분산, 직접통신/허브경유,
장애격리/단일장애점, 사람이지킴/도구가강제)만 써서 다시 설명해줘.
교재에 없는 새 비유는 만들지 마.

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

이 교재에 나온 비유(지하철 노선도, 자전거 바퀴살, 별, 백화점 정문)를 전부 걷어내고,
"이것은 무엇의 한 종류인가 / 형제 개념과 무엇으로 갈리는가" 형식으로만
온톨로지·토폴로지·스타 토폴로지·허브·스포크·Facade·헥사고날을 다시 정의해줘.

앞 장과의 연결 확인

이 9주차 교재에서 "앞에서 배운"으로 시작하는 문장을 전부 찾아서,
어느 주차의 어떤 개념이 이번 주에 어떤 이름으로 다시 나왔는지 표로 정리해줘.
특히 6주차의 헥사고날·Facade가 이번 주에 어떻게 다시 해석됐는지를 맨 위에 놓아줘.

다음 장 연결 확인

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