수강생은 따라 치지 않습니다 · 마지막에 각자 폰으로 접속합니다
가져갈 문장 — "오늘도 문법은 안 가르칩니다. 지형을 그립니다."
수요일 육성 그대로: "한 시간 만에 코딩을 알 리가 없습니다. 중국어 모르는 사람한테 한 시간 만에 중국어 못 가르쳐요." [10:02]
"그런데 중국 여행에는 중국어보다 — 몇 개의 성이 있고, 어떤 제스처가 기분 나쁘고, 공안은 무서운 사람이라는 정보가 더 중요할 수 있어요. 오늘은 그겁니다. 중국 옆에 한국, 오른쪽에 동해." [10:34] [54:14]
오늘 순서: 지난주 그 사이트를 연다 → 거기서 나온 단어로 지도를 세운다 → 그 위에서 두 개를 만든다. 여러분은 따라 치지 않습니다. 마지막에 폰만 꺼내세요.
화면은 4챕터 제목만 세로로. 그림 없음. 3분.
팩 카드 · 포스터
이야기가 시작되는 첫 장면
장면에 맞는 배경과 캐릭터 이미지가 뜬다
다음 행동을 고른다
지난주에 딸깍으로 만든 그 사이트. 오늘은 열어서 뜯어봅니다.
이야기 하나가 폴더 하나로 들어가 있고, 그 폴더를 AI가 읽으면서 연출을 한다.
"지난주에 딸깍으로 만든 그 사이트입니다. 오늘은 이걸 열어서 뜯어봅니다."
40~50대 영화인이 보고 있다는 걸 잊지 않는다: "이야기 하나가 폴더 하나로 들어가 있고, 그 폴더를 AI가 읽으면서 연출을 합니다."
붙는 단어: 없음(아직). 이름을 얹기 전에 그림부터. 3분.
⚠ 준비물 — 스크린샷은 아침에 실제 Chrome에서 찍는다. 09.02 핸드오버 §7-7: 자동화 브라우저에서는 포스터·씬 이미지가 안 실렸다. 육안 확인이 곧 준비다.
{"seq":18,"type":"user_message","timestamp":"2026-09-04T16:54:59.862Z","data":{"text":"…
{"seq":19,"type":"pipeline_start","timestamp":"2026-09-04T16:54:59.863Z","data":{"turnIn…
{"seq":20,"type":"quick_direction","timestamp":"2026-09-04T16:54:59.863Z","phase":"gm","…
{"seq":21,"type":"bgm_update","timestamp":"2026-09-04T16:54:59.863Z","phase":"action","d…
{"seq":22,"type":"sfx_play","timestamp":"2026-09-04T16:54:59.864Z","phase":"action","dat…
{"seq":23,"type":"visual_action","timestamp":"2026-09-04T16:54:59.866Z","phase":"action"…
{"seq":24,"type":"story_update","timestamp":"2026-09-04T16:54:59.866Z","data":{"result":…
{"seq":25,"type":"npc_dialogue","timestamp":"2026-09-04T16:54:59.866Z","phase":"npc","da…
{"seq":26,"type":"suggestions_shown","timestamp":"2026-09-04T16:55:06.005Z","data":{"rep…
{"seq":27,"type":"pipeline_done","timestamp":"2026-09-04T16:55:06.006Z","data":{"progres…
{"seq":28,"type":"user_message","timestamp":"2026-09-04T16:55:06.007Z","data":{"text":"…
{"seq":29,"type":"pipeline_start","timestamp":"2026-09-04T16:55:06.008Z","data":{"turnIn…
{"seq":30,"type":"quick_direction","timestamp":"2026-09-04T16:55:13.168Z","phase":"gm","…
{"seq":31,"type":"bgm_update","timestamp":"2026-09-04T16:55:13.169Z","phase":"action","d…
{"seq":32,"type":"sfx_play","timestamp":"2026-09-04T16:55:13.169Z","phase":"action","dat…
{"seq":33,"type":"visual_action","timestamp":"2026-09-04T16:55:13.170Z","phase":"action"…
{"seq":34,"type":"npc_dialogue","timestamp":"2026-09-04T16:55:13.172Z","phase":"npc","da…
{"seq":35,"type":"story_update","timestamp":"2026-09-04T16:55:13.173Z","data":{"result":…
{"seq":36,"type":"suggestions_shown","timestamp":"2026-09-04T16:55:13.173Z","data":{"rep…
{"seq":37,"type":"pipeline_done","timestamp":"2026-09-04T16:55:13.174Z","data":{"progres…두 창을 나란히 — 브라우저(사이트) + 옆에 터미널 로그.
① 팩을 열고 대화를 두세 줄만 굴린다. 배경이 바뀌고 캐릭터가 뜨는 걸 본다.
② 옆 터미널을 가리킨다. 로그가 흐른다. "화면 뒤에서 누가 일하고 있죠. 무슨 일을 했는지 여기 남습니다."
③ 선택지를 하나 고른다. "이 선택이 어딘가에 적힙니다. 기억이죠." [03:38]
붙는 단어(이름만 얹는다, 정의 안 함): 화면(프론트엔드) ● · 서버·콘솔·로그 ● — 5분.
⚠ 실패 시 — 로컬 서버가 안 뜨면 P02 스크린샷으로 대체하고 P04로 간다. 어젯밤 확인: 맥에 3010이 이미 떠 있다(+ 3011·3013·3020 중복 서버 — 아침에 하나만 남길 것).
오른쪽 로그 박스는 실제 logs/sessions/2026-09-04_16-53_red_riding_hood_session-3882/events.jsonl 마지막 20줄(폭에 맞춰 잘라 표시). 라이브에서는 진짜 터미널을 띄운다.
실행되면 서버 안에 기억이 남는다. LLM은 기억력이 좁아서 서버는 팩에서 필요한 장만 읽는다 — 현재 챕터와 옆 챕터만.
알아서 하는 게 아니라, 수칙을 읽고 일하는 작업 도우미다.
상자 셋. 그 이상 그리지 않는다.
"화면 / 화면을 띄우는 서버 / 스토리팩. 실행되면 서버 안에 기억이 남습니다." [00:41]
"LLM은 기억력이 좁아요. 처음엔 똑똑하다가 엉뚱한 소리를 하는 이유가 그겁니다. 그래서 필요한 장만 읽게 짰어요." [01:41] — 현재 챕터와 옆 챕터만 준다.
오늘의 포인트: 팩 안에는 배경·캐릭터·음악·효과음이 이름표 붙은 목록으로 들어 있고(04_resources.txt), 매 턴 어떤 걸 꺼내 쓸지는 LLM이 정한다. 사람이 "이 장면엔 이 그림"이라고 일일이 안 붙인다. "재료를 갖춰 놓으면 알아서 꺼내 씁니다. 으레 식탁 위에 포크와 나이프가 있죠. 에이전트가 눈 뜨자마자 '아, 여기서 밥을 푸는구나' 알도록 주방을 꾸려 놓은 겁니다." [13:29]
한 줄로: "이건 알아서 하는 게 아니고 수칙을 읽고 일하는 작업 도우미예요." [46:35]
붙는 단어: 프론트엔드/백엔드 ● · 서버 ● · 컨텍스트(기억력) ○ — 5분.
_template이 있으면 “여러 개 붙는 구조구나”를 이름만으로 안다resource_list.json)에서 자동 생성된다폴더 트리 한 장. 실제 경로 그대로. 옆에 packs/_template/(빈 틀)도 보인다.
"에이전트는 폴더를 열면 이름하고 구조만 봅니다. _template이 있으면 '아, 여러 개 붙는 구조구나'를 이름만으로 압니다." [20:44]
"내용하고 뼈대가 따로 있으니까 내용만 갈아끼울 수 있어요. 지난주에 '고등학교 일진의 모험담' 한 문장 던졌더니 주인공이 만들어졌잖아요. 그게 되는 이유가 이 폴더예요." [11:37]
반대 사례(웃긴 대목): "엉망진창인 다운로드 폴더 잡고 '분석해 줘' 하면, 그다음부터 엉망진창으로 일합니다." [44:55]
결론 한 줄: "구조 자체가 자산입니다. 구조화돼 있으면 LLM이 그걸 자산화해서 이미지든 뭐든 해줍니다." [44:25]
CLAUDE.md가 보이면 한 마디만: "네오가 깨어나 처음 읽는 글." [12:05]
붙는 단어: 프로젝트·폴더·파일 ● · 컨텍스트 ○ · CLAUDE.md ○ — 4분.
--dry-run — 몇 건이 생성될지만 출력. 돈이 안 나간다--provider gemini(기본) · byteplus(Seedream). 텍스트 하나가 여러 양태로 뻗는다.{"seq":2,"type":"gm_direction","timestamp":"2026-09-04T16:55:08.154Z","turnIndex":2,"phase":"gm","data":{"direction":{"narrativeDirection":"빨간 모자가 숲의 입구에서 갈림길에 도달하여 주변을 탐…
{"seq":3,"type":"staging_command","timestamp":"2026-09-04T16:55:08.154Z","turnIndex":2,"phase":"gm","data":{"emulatorCommand":{"trackId":"bgm_calm_joyful_sunlit_morning","volume":0.6,"fa…
{"seq":4,"type":"staging_command","timestamp":"2026-09-04T16:55:08.155Z","turnIndex":2,"phase":"gm","data":{"emulatorCommand":{"sfxId":"sfx_red_boots_forest_steps","volume":0.5,"delay":0…
{"seq":5,"type":"action_executed","timestamp":"2026-09-04T16:55:08.155Z","turnIndex":2,"data":{"action":{"action":"select","imageId":"bg_forest_fork","displayStyle":"inline"},"result":{}…
{"seq":7,"type":"story_update","timestamp":"2026-09-04T16:55:10.116Z","turnIndex":2,"data":{"variables":{"setFlags":[{"key":"stage_2_entered","value":true}],"incrementCounters":[{"key":"…왼쪽은 명세, 오른쪽은 절차, 아래는 실제 로그. 라이브 생성은 하지 않는다 — 이미 나온 결과를 연다.
"resource_list가 만들어졌다는 게 되게 중요한 발견이에요. 요소를 다 명세화하고 API로 한 번에 생성해 낼 수 있다는 건 엄청난 겁니다. CG·게임·영화로 치면 이 명세가 그대로 제작 목록이에요." [36:02]
같은 명세로 이미지도, 효과음도, 음악도 나왔다. 이 앱엔 pack:images · pack:audio · pack:video 명령이 있고, 이미지 제공자는 Gemini·BytePlus Seedream 등으로 갈아끼운다. 텍스트 하나가 여러 양태로 뻗는다.
절차는 셋 — 명세 → Dry Run(돈 안 나감) → 병렬. "피자 박스를 열 명이 접으면 빨리 끝나죠. 명시 안 하면 한 장씩 합니다." [41:12] [50:21]
정직하게 한 마디: "수요일에 무료 등급이 소진돼서 주인공 한 장에서 멈췄죠. 실무에서 매일 일어나는 일입니다." [52:20]
아래 로그 박스는 실제 events.jsonl 두 번째 턴이다. 사람이 "이 장면엔 이 음악"이라고 붙인 게 아니라, LLM이 목록에서 골랐다. (seq 6 npc_dialogue는 지면상 생략 — 라이브에서는 터미널에서 그대로 보인다.)
붙는 단어: API ● · API 키·비용 ● · 명세·제작 목록 ○ · Dry Run·병렬 ○ — 3분.
문장 하나만. 설명을 덧붙이지 않는다.
"에이전트를 바이브 코딩·웹사이트 만드는 걸로만 보지 마세요. 구조화된 재료로 프로젝트에 필요한 리소스를 생성하는 도구로 보세요." [37:07]
1분 → 챕터 2(랜드스케이프)로 넘어간다.
127.0.0.1과 같은 곳. “이 컴퓨터”라는 뜻이라, 남의 폰에서 치면 그 폰을 가리킨다http://192.0.0.2:8000으로 내 화면을 볼 수 있다 — 카페 밖에서는 안 된다localhost · 127.0.0.1 · 0.0.0.0 셋 다 같은 서버를 연다(방금 실제로 확인했다). 이름은 여러 개, 자리는 하나.http://주소:포트/경로챕터 목적 — "꽌시가 무슨 말인지 몰라도 되지만 그런 개념이 있다는 건 알아야 합니다." [10:19] 외우는 게 아니다. 다음에 만났을 때 "아, 그거"가 되면 된다.
"용어를 알아야 한다는 것에 사로잡히기 쉬운데, 그보다 관계가 중요하고, 그 이전에 구조화하는 사고방식이 중요합니다." [10:49]
원칙 — 정의를 먼저 말하지 않는다. 방금 P03~P06에서 본 화면에 이름을 얹거나, 곧 실습에서 만날 자리를 예고한다. 장마다 "오늘 어디서"가 있는 이유.
세 칸을 손으로 훑으면서 한 번만 걷는다. 왼쪽 = 내 컴퓨터, 가운데 = 남의 컴퓨터, 오른쪽 = 바깥.
주소 · IP · DNS — 가운데 칸에서 한 번 짚는다. "남의 컴퓨터에 올렸으면 찾아갈 방법이 있어야 하죠. 기계는 숫자로 찾습니다 — 그게 IP 주소, 번지수예요. 근데 사람이 172.66.47.83을 어떻게 외웁니까. 그래서 이름을 붙입니다 — 그게 도메인이에요. 그 이름을 번지수로 바꿔 주는 전화번호부가 DNS고요."
이어서: "여러분이 주소창에 이름을 치면, 브라우저가 먼저 DNS한테 물어봅니다 — '이 이름 번지수가 뭐야?' 번지수를 받아서 그제야 그 컴퓨터에 갑니다. 이게 매번 일어나요."
사설 IP와 공인 IP를 여기서 가른다. "localhost는 '이 컴퓨터'예요. 그래서 여러분 폰에서 치면 여러분 폰을 가리킵니다 — 제 노트북이 아니라요. 이게 이따 P27에서 폰이 안 열리는 이유입니다."
"그런데 같은 와이파이 안이면 얘기가 달라져요. 제 노트북 번호 192.0.0.2를 치면 옆자리에서 제 화면이 열립니다. 딱 이 방 안에서만요. 카페 밖에서는 안 됩니다."
"그리고 재밌는 게, 같은 자리를 부르는 이름이 여러 개예요. localhost, 127.0.0.1, 0.0.0.0 — 셋 다 같은 데로 갑니다. 이름은 여러 개, 자리는 하나."
오른쪽 칸이 이 장의 회수다. 세 주소가 같은 모양이라는 걸 손으로 짚는다 — http://주소:포트/경로. "바뀌는 건 주소 자리 하나뿐이에요. 얼마나 멀리서 부를 수 있느냐만 다릅니다."
회수 예고: P21·P28에서 *.pages.dev 주소가 생기는 순간 "이름 하나를 빌린 것"이라고 다시 짚는다. 도메인 구입·연결은 오늘 안 한다 — 질문이 나오면 "그 이름을 사서 이 번지수에 연결하는 것"까지만.
3분.
# ① 폴더를 하나 만든다 $ mkdir 내작품 # ② 그 폴더로 들어간다 $ cd 내작품 # ③ 안에 뭐가 있는지 본다 $ ls index.html # ④ 내 컴퓨터를 웹서버로 만든다 $ python3 -m http.server 8000 Serving HTTP on :: port 8000 ... ::1 - - [05/Sep/2026 07:56:26] "GET / HTTP/1.1" 200 - ::1 - - [05/Sep/2026 07:56:26] "GET /index.html HTTP/1.1" 200 -
CLI는 이 방에서 가장 많이 멈추는 단어다(08.29 점심 진단). 정의보다 왜 굳이 글자로 치는가를 먼저.
네 줄을 직접 쳐 보인다. ①②③은 10초. ④에서 멈춘다 — 브라우저에 localhost:8000을 치면 방금 만든 폴더가 열린다. "지금 보고 계신 이게 제 노트북 안입니다. 인터넷에 올린 게 아니에요." → P13 로컬 vs 배포로 그대로 이어진다.
왼쪽 터미널의 초록 줄 두 개를 짚는다: "브라우저가 뭘 달라고 했는지 여기 그대로 남습니다. 이게 로그예요." → P15 콘솔 예고.
화면을 가리키며: "무섭게 생겼는데 제가 여기 치는 건 한국어예요."
윈도우 분들껜 셋만: PowerShell, py, dir — P10에서 이어 말한다.
붙는 단어: CLI ○ · 터미널 ○ · 명령어 ○ — 5분.
| 용어 | 말 한 줄 | 등급 |
|---|---|---|
| PC | 원래는 개인용 컴퓨터 전부. 한국에선 보통 윈도우 컴퓨터. 맥도 엄밀히는 PC | ○ |
| 운영체제(OS) | 컴퓨터를 굴리는 바탕 규칙. 윈도우 · macOS · iOS · 안드로이드가 각각 하나 | ○ |
| 윈도우 / 맥 | 수강생 다수는 윈도우, 강사는 맥 | ● |
| 아이폰 / 안드로이드폰 | iOS · 안드로이드가 도는 손안의 컴퓨터 | ○ |
| 갈리는 지점 | 윈도우 수강생 다수 | 맥 강사 |
|---|---|---|
| 명령창 이름 | PowerShell, 명령 프롬프트 | 터미널 |
| 폴더 주소 | C:\Users\상훈\작업 | /Users/sanghun/작업 |
| 설치 | 설치 파일 받아 실행 | 명령어 한 줄인 경우가 많음 |
인터넷 안내문 대부분이 맥 기준이다. 윈도우 쓰는 사람은 읽을 때마다 한 번씩 번역해야 하는데, 그 번역을 지금은 AI가 해준다.
실전 규칙 하나(이 장에서 가져갈 유일한 것): "나는 윈도우 11을 쓰고 있어. 명령어는 PowerShell 기준으로 알려줘." — 이 한 줄이 없으면 에이전트가 맥 명령어를 던지고, 학생은 "안 되는데요"에서 멈춘다. 수요일 막힘의 상당수가 여기였을 것.
폰은 만드는 쪽이 아니라 보는 쪽이다. 오늘 만드는 건 전부 웹. 폰은 결과를 확인하는 자리에만 등장한다(P13에서 이어짐).
P23에서 회수할 말: "저는 맥이라 이렇게 치는데 윈도우는 다릅니다."
붙는 단어: 윈도우/맥 ● · PC ○ · 운영체제(OS) ○ · 아이폰/안드로이드폰 ○ — 4분.
final_02, final_real, final_진짜최종을 없애주는 물건Git은 오늘 이름만 꺼낸다 — 고칠 때마다 올리고, 그 기록을 훨씬 촘촘하게 해주는 물건. 라이선스는 작품에 쓰시는 분들에게 실제로 걸린다.
Git은 오늘 이름만: "고칠 때마다 올립니다. 이 기록을 훨씬 촘촘하게 해주는 게 Git이에요. 최종_진짜최종 없애주는 물건." diff · merge · rebase는 없다.
왼쪽 화면을 손으로 훑으며: "한 줄이 한 번의 저장이에요. 누가 언제 뭘 고쳤는지가 다 남습니다."
오픈소스는 이 청중에게 무료 소스 라이브러리 · 플러그인이라고 하면 바로 붙는다. 오른쪽 Kenney 화면이 P22에서 실제로 쓸 그림·소리다.
라이선스는 한 줄만: "작품에 쓰시는 분들은 이게 실제로 걸립니다." 가운데 카드에서 초록 체크(되는 것)와 빨간 엑스(안 되는 것)만 손가락으로 짚는다. (§결정 3 — 한 줄에서 멈춘다.)
붙는 단어: Git ○ · GitHub ○ · 오픈소스 ○ · 라이선스 ○ — 3분.
관객이 보는 앞무대. 버튼·글자·그림 — 눈에 보이는 전부가 여기다.
정의를 먼저 말하지 않는다. 화면을 띄워 놓고 “지금 보시는 이게 앞무대예요”로 시작한다.
“프론트엔드라고 하면 어렵고, 화면이라고 하면 끝납니다. 오늘은 화면이라고 부르겠습니다.”
1분. 다음 장으로.
view-source: 로 누구나 볼 수 있다앞 장의 그 화면이 이 글자들이다. 브라우저가 이걸 읽어서 화면으로 그린다.
실제로 열어 보인다. 사주앱을 띄운 채 view-source:를 붙이거나 오른쪽 클릭 → 페이지 소스 보기.
“조금 전 그 예쁜 화면이 사실은 이 글자들입니다. 브라우저가 이걸 읽어서 그려 주는 거예요.”
“그리고 남의 사이트도 다 보입니다. 숨기는 게 아니에요. 원래 이렇게 만들어져 있습니다.” — 여기서 한 번 놀란다.
한글 주석(<!-- ① 정보 입력 화면 -->)을 짚는다: “여기 한글로 메모도 적혀 있죠. 사람이 읽으라고 적어 둔 겁니다.”
화면이 “보여 주는” 쪽이면, 뒤는 실제로 처리하고 기억하는 쪽이다.
상자 둘. 그 이상 그리지 않는다.
“지난주 챗봇은 뒤가 있었어요. 그래서 대화가 이어졌고 선택이 기억됐죠. 오늘 만드는 둘은 뒤가 없습니다.”
“그래서 이따 슈팅게임 점수가 안 남아요. 새로고침하면 0입니다. 남기려면 뒤가 필요하고, 그때부터 다른 얘기가 됩니다.” → P36에서 회수.
사주앱도 같다 — 내 정보가 내 폰에만 있는 이유가 뒤가 없어서다. 그게 이 앱의 장점이기도 하다(개인정보가 어디로도 안 간다).
항상 켜져 있으면서 달라면 주는 컴퓨터. 우리가 “사이트를 연다”는 건 남의 컴퓨터에 파일을 달라고 하는 것이다.
cdn.jsdelivr.net, 90 kB) — 그게 만세력 계산기다python3 -m http.server 한 줄로 내 컴퓨터를 서버로 만들었다. 그게 이것이다표를 손으로 훑는다. “페이지 하나 여는데 브라우저가 13번 물어봤어요. 파일 하나하나를 따로 달라고 합니다.”
“200이 뭐냐 하면 ‘여기 있습니다’예요. 못 찾으면 404고요. 그 404 맞습니다.”
jsDelivr 줄을 짚는다. “이 한 줄만 남의 서버에서 옵니다. 90킬로바이트짜리 만세력 계산기예요 — 아까 그 오픈소스요.” → P18 예고.
“그리고 P09에서 제가 친 그 한 줄, python3 -m http.server — 그게 제 노트북을 서버로 만든 겁니다. 서버가 대단한 게 아니에요.”
localhost:8000내 노트북이 켜져 있는 동안, 나만 볼 수 있다Cloudflare Pages내 노트북을 꺼도 24시간 켜져 있다○○○.pages.dev링크만 있으면 옆사람 폰에서도 열린다localhost:8000은 내 컴퓨터 안이다. 옆사람 폰에서는 안 열린다 — 그 주소는 그 사람 컴퓨터를 가리키니까.
localhost:8000을 친다 → 안 열린다. 배포한 주소를 친다 → 열린다. 그 두 화면에 다 들어 있다이 장은 말로 설명하지 않는다. P27에서 실제로 보인다 — 폰에서 localhost를 쳐서 실패시키고, 배포 주소로 성공시킨다. 여기서는 예고만.
“localhost는 ‘이 컴퓨터’라는 뜻이에요. 그래서 여러분 폰에서 치면 여러분 폰을 가리킵니다. 제 노트북이 아니라요.”
“남도 보게 하려면 남의 컴퓨터에 올려야 합니다. 그게 배포고, 오늘은 폴더를 끌어다 놓는 걸로 끝납니다.”
srl-saju-fortune.pages.dev를 물어본 결과 — 전부 같은 번지수 172.66.44.185순서대로 짚는다. “남의 컴퓨터에 올렸으면 찾아갈 방법이 있어야죠. 기계는 숫자로 찾습니다 — IP 주소, 번지수예요.”
“근데 사람이 172.66.44.185를 어떻게 외웁니까. 그래서 이름을 붙입니다 — 도메인이에요. 그 이름을 번지수로 바꿔 주는 전화번호부가 DNS고요.”
왼쪽 화면: “시애틀, 런던, 상파울루, 이스탄불에서 같은 이름을 물어봤어요. 전부 같은 번지수가 나오죠. 전화번호부가 전 세계에 퍼져 있는 겁니다.”
“.pages.dev는 빌린 이름이에요. 내 이름을 사고 싶으면 도메인을 사서 이 번지수에 연결합니다 — 오늘은 안 합니다.”
두 화면은 같은 파일이다. 주소도 같다. 폭이 달라지면 배치가 다시 잡힌다.
두 캡처를 나란히 놓고 한 문장. “같은 주소, 같은 파일입니다. 폭만 달라졌어요.”
“웹앱이라고 부릅니다 — 주소만 있으면 폰에서 그냥 열려요. 앱스토어 안 거치고요. 오늘 만드는 게 이겁니다.”
“앱스토어에서 받는 건 네이티브 앱이고, 심사도 받고 등록비도 냅니다. 오늘은 안 만듭니다.”
→ 다음 장(개발자 도구)으로 자연스럽게 넘어간다: “그런데 폰을 매번 꺼내야 할까요? 아닙니다.”
앞에서 본 반응형을 내 노트북에서 바로 확인하는 방법이다. 배포하기 전에도 된다.
이 장은 학생이 집에서 실제로 쓸 수 있는 유일한 도구다. "폰으로 확인해 보세요"는 말이 쉽지, 배포 전에는 못 한다. 그런데 이건 지금 당장 된다.
"여러분 노트북에서 F12 한 번 누르면 창이 하나 열려요. 무섭게 생겼는데 오늘은 그중 딱 하나만 씁니다 — 폰 화면처럼 보기."
시연: 슈팅게임을 띄운 채로 F12 → Ctrl+Shift+M → 기기 목록에서 iPhone 선택. 같은 페이지가 그 자리에서 폰 모양으로 바뀐다. 여기서 한 번 웃음이 나온다.
이어서: "제가 아까 QR로 보여드린 것도 이겁니다. 다만 그건 진짜 폰이고, 이건 흉내예요. 흉내로 90%는 잡힙니다. 나머지 10%는 손가락 크기하고 실제 속도라서, 그것만 진짜 폰으로 봅니다."
붙는 단어: 반응형 · 폰 화면과 PC 화면 · (덤으로) 개발자 도구가 P15 콘솔과 같은 창이라는 것 — 두 장 뒤 P15에서 회수한다. 3분.
키를 누가 가져가면 여러분인 것처럼 행세해서 AI 모델을 불러제낀다 — 한 번 부를 때마다 삼백 원, 오백 원, 칠백 원이 뜯겨 나간다. 노출되면 원칙은 로테이션, 새로 만드는 것.
.env는 environment의 줄임말, .local은 로컬 세팅 — 키나 환경 설정을 담는 상자."API 키는 키예요. 집 열쇠, 은행 열쇠와 같아요. 누가 가져가면 여러분인 것처럼 행세해서 AI 모델을 불러제낍니다. 한 번 부를 때마다 삼백 원, 오백 원, 칠백 원 돈이 뜯겨 나가요." [30:21]
화면 오른쪽 목차를 손가락으로 짚는다 — "환경 변수 사용(권장), 그리고 유출 대응 체크리스트. 만든 사람들도 이게 새어 나간다는 걸 아니까 문서에 이렇게 적어둔 거예요."
".env는 environment의 줄임말, .local은 로컬 세팅. 키나 환경 설정을 담는 상자." [34:44]
규칙 한 줄로 접는다: 키는 상자에, 상자는 내 컴퓨터에, 상자는 절대 같이 보내지 않는다.
노출되면: "원칙은 로테이션. 새로 만드는 겁니다." [33:53] — ⚠ 수요일 키는 실제로 노출됐고, 오늘 새 키로 왔다(§준비물).
태도 한 마디: "저는 아직도 일레븐랩스 홈페이지에서 어디서 효과음 만드는지 몰라요. 키 던지고 API · 모델 · Best Practice 찾아오라고 시킵니다." [49:00] — P15의 Best Practice로 이어진다.
P03에서 화면 옆으로 흐르던 게 이것이다.
app.js:42가 몇 번째 줄인지까지 알려준다안 될 때 강사가 보는 곳도 여기다. 빨간 줄을 복사해서 그대로 AI에게 던지면 된다.
P03에서 옆에 흐르던 게 이것. "안 될 때 저는 여기를 봐요. 빨간 줄 복사해서 그대로 AI한테 던지면 됩니다."
화면의 세 줄은 수요일 사주앱에서 실제로 찍힌 것이다. 빨간 줄 = 만세력 계산기를 못 불러왔다(P18에서 붙일 그 부품), 노란 줄 = 키가 없다(P14의 그 열쇠). "무슨 말인지 몰라도 됩니다. 이 줄을 그대로 복사하면 돼요."
그리고 Best Practice: "검색어에 Best Practice를 붙이세요. 우리말로 정석. 좋은 정보가 그 키워드 아래 잘 모여 있습니다." [49:31]
1분. 짧게 끊고 넘어간다.
랜드스케이프 회수(한 호흡) — 다섯 단어: 화면 · 서버 · 팩 · 열쇠 · 주소. 나머지는 이 다섯에 매달린다. 여기까지가 48분 지점이어야 한다.
“Give your AI agent a Visa card.”당신의 AI 에이전트에게 Visa 카드를 주세요 — 공식 문서 첫 줄
사람이 쓰는 결제창이 아니라 AI에게 카드를 쥐여 주는 도구다. 에이전트가 유료 이미지·영상 API를 스스로 결제해서 부르고, 카드 한도까지 조회·변경한다.
건당 $10 한도 · 결제 직전 사람 승인 · 카드번호는 내 PC에 저장 안 됨
“This content is for AI agents reading this page.
Human visitors see the marketing site above.”
비자 사이트에는 사람이 보는 화면 아래에 “이 내용은 이 페이지를 읽는 AI 에이전트용”이라는 구획이 따로 들어 있다.
같은 주소인데 사람에겐 광고를, AI에겐 설명서를 준다. 웹사이트가 손님을 두 종류로 나누기 시작했다.
웹을 자동으로 조작하는 도구인데, 필요 조건 항목에 사람이 없다 — “클로드 코드, 깃허브 코파일럿, 또는 다른 코딩 에이전트”.
“Token-efficient. Does not force page data into LLM.”화면을 보여주는 것보다 명령어가 훨씬 싸고 정확해서
최근 한 달 내려받기 326만
AI가 바깥 도구를 부르는 공용 규약. AI와 도구를 잇는 표준 콘센트라고 보면 된다.
2025년 12월, 아마존·구글·마이크로소프트·오픈AI·앤트로픽이 같은 재단에 이 규격을 함께 넘겼다. 서로 경쟁하면서도 콘센트 규격만은 통일한 것이다.
공개 서버 1만 개↑ · 관련 도구 월 내려받기 2억 건↑ · AGENTS.md 채택 6만 개↑ 프로젝트
앞 장 마지막 줄 “AI가 대신 칠 수 있다”에서 그대로 넘어온다.
“아까 제가 터미널에 네 줄 쳤죠. 그거 요즘은 제가 안 칩니다. AI한테 시켜요. 그런데 더 재밌는 건, 회사들이 그걸 알고 도구를 그렇게 만들기 시작했다는 거예요.”
비자 이야기를 먼저. “비자가 작년 봄에 낸 게 결제창이 아니라 명령어예요. 문서 첫 줄이 ‘당신의 AI 에이전트에게 비자 카드를 주세요’입니다.” — 여기서 웃음이 한 번 나온다.
두 번째 칸이 이 장의 하이라이트다. “비자 홈페이지를 열면 우리는 광고를 봅니다. 그런데 그 페이지 안에 ‘여기 아래는 이 페이지를 읽는 AI를 위한 것’이라고 적힌 구획이 따로 있어요. 같은 주소인데 손님을 둘로 나눈 겁니다.” → 이 청중에게 가장 오래 남는 장면.
마이크로소프트 칸에서는 이유를 짚는다: 그래픽 화면은 사람 눈을 위해 만들어졌고, AI가 그걸 이해하려면 스크린샷을 해석해야 해서 느리고 비싸고 자주 틀린다. 명령어는 짧고 모호하지 않다.
MCP는 이름만. “표준 콘센트” 한 마디면 된다. 숫자는 읽지 말고 손으로만 짚는다.
마무리 문장을 그대로 읽는다. 필요하면 현장 언어로 한 번 더: “내가 툴을 익히는 속도보다, 툴이 AI에게 맞춰지는 속도가 더 빠릅니다.”
붙는 단어: CLI(회수) · MCP ○ — 4분.
1980년, MIT 인공지능 연구소에 새 프린터가 들어옵니다. 제록스 9700. 종이가 자주 걸렸는데, 걸렸다는 사실을 알 방법이 없었습니다. 스톨먼은 이전 프린터에서는 그 알림 기능을 직접 만들어 붙였던 사람입니다. 이번에는 그럴 수 없었어요 — 소스코드(프로그램의 설계도. 사람이 읽고 고칠 수 있는 원본 텍스트)를 주지 않았기 때문입니다.
그 코드를 가진 카네기멜런의 한 교수를 찾아갑니다. 그리고 거절당해요. 이유는 “제록스에 안 주기로 약속했다” — 오늘날의 비밀유지계약(NDA)입니다. 그가 아무 말 없이 돌아선 그 일이, 이 뒤의 40년을 만듭니다.
저작권(copyright)을 뒤집은 말장난입니다. 저작권을 없애는 게 아니라, 저작권을 이용해서 자유를 강제하는 겁니다. “가져다 마음대로 고쳐 써라. 대신 고친 것도 똑같이 열어라.” 영화로 치면 — 이 시나리오 마음대로 각색해도 되는데, 각색본도 남이 각색할 수 있게 공개해야 한다는 조건입니다.
사진 한 장과 일화 하나로 4분. 연도를 외우게 하는 장이 아니다. “고치고 싶은데 고칠 수가 없었다”는 감정 하나만 남기면 된다.
읽어도 되는 문장 — “1980년, MIT 인공지능 연구소에 새 프린터가 들어왔습니다. 종이가 자주 걸렸는데 연구소가 다른 층이라, 한참 뒤에 가보면 아무것도 안 뽑혀 있는 거죠. 스톨먼은 이전 프린터에서는 이 문제를 직접 고쳤던 사람입니다. 그런데 새 프린터는 그게 안 됐어요. 설계도를 안 줬거든요.”
“코드를 가진 교수를 찾아갑니다. 그리고 거절당해요. ‘제록스에 안 주기로 약속했다.’ 요즘 말로 NDA입니다. 당시엔 이게 소프트웨어 업계에 막 등장한 새 관행이었어요.”
⚠ 교수 이름(로버트 스프롤)은 정황 근거만 있고 1차 문헌이 단정하지 않는다 — “카네기멜런의 한 교수”로만 말한다.
free 두 가지 뜻은 말로 한 번 더 풀어 준다. “돈 받고 팔아도 됩니다. 문제는 값이 아니라 통제권이에요.” 자유 4가지는 번호가 0번부터 시작한다는 것 자체가 이 동네 문화라고 한 마디 붙이면 웃는다.
전환 — “여기까지는 한 사람의 원칙 이야기입니다. 이게 어떻게 산업이 됐을까요.”
사진 저작권: Patafisik, CC BY-SA 4.0, via Wikimedia Commons. 크레딧 줄은 법적 의무라 화면에 남겨 둔다.
“free software”는 기업 임원에게 ‘공짜’로 들리고, 철학·정치 운동처럼 들렸습니다. 같은 물건에 붙인 다른 이름이에요. 스톨먼 쪽은 자유를, 레이먼드 쪽은 잘 돌아가는 개발 방법을 앞세웠고, 두 진영은 지금도 사이가 좋지 않습니다.
사진 셋으로 사람 이름을 붙여 두고, 아래 연표는 손가락으로 짚으며 넘긴다. 4분 안에 다섯 줄이다 — 한 줄에 45초.
성당 vs 시장은 영화 비유로 바꾸면 바로 붙는다. “성당식은 완성될 때까지 아무에게도 안 보여주는 감독판입니다. 시장식은 러프컷을 매일 올려놓고 누구나 코멘트를 달게 하는 방식이에요. 상식적으로는 전자가 좋을 것 같은데, 소프트웨어에서는 후자가 이겼습니다.”
“눈이 충분히 많으면 모든 버그는 얕다” — “시사회에 100명이 앉아 있으면 편집 실수는 반드시 누군가 잡아냅니다.”
순서가 핵심이다. 넷스케이프가 먼저 열었고(1월), 이름은 그 뒤에 붙었다(2월). 회사가 실용적인 사업 판단으로 코드를 여는 시대가 오자 “다른 이름이 필요하다”가 된 것이다.
⚠ 명명 회의 날짜는 OSI 공식(2/3)과 피터슨 본인 회고(2/5)가 갈린다 — “1998년 2월”로만 말한다. 또 피터슨이 직접 제안한 게 아니라, 토드 앤더슨이 회의 중 그 표현을 끼워 넣어 퍼뜨렸다는 대목까지는 여유 있을 때만.
⚠ 피터슨 사진은 원본이 512×542로 작아 확대돼 흐리다. 그래서 셋 중 가장 작게 배치했다 — 화질 얘기는 굳이 하지 않는다.
전환 — “그래서, 지금 그게 어디까지 왔을까요.”
세 덩어리다. 위 = 얼마나 크냐, 가운데 왼쪽 = 얼마나 위태롭냐, 가운데 오른쪽 = 왜 당신 얘기냐, 아래 = 오늘 만들 앱 안에 이미 들어 있다. 5분이면 아래 사진 석 장은 가리키기만 해도 된다.
숫자를 감각으로 바꾸는 문장 — “GitHub에 1초마다 개발자 한 명이 새로 들어옵니다. 이 강의 90분 동안 5,400명이 들어와요.”
left-pad — “11줄 때문에요. 리액트가, 바벨이 멈췄습니다.” xz — “한 사람의 우연한 호기심이 인터넷을 구했습니다. 반대로 말하면, 인터넷이 한 사람의 우연한 호기심에 매달려 있었다는 뜻입니다.”
영화 쪽 — “여러분이 오스카 시상식에서 본 그 영화, 아무나 지금 무료로 내려받을 수 있는 프로그램으로 만들었습니다.” / “오픈소스는 실리콘밸리 얘기가 아닙니다. 여러분에게 상을 주는 그 아카데미가 2018년에 직접 오픈소스 재단을 차렸어요. 조사해 보니 영화 산업의 84%가 이미 오픈소스로 굴러가고 있었거든요.” / “영상 파일 포맷 바꿔본 적 있으시죠. 그거 열에 아홉은 FFmpeg가 한 겁니다.”
⚠ “다빈치 리졸브가 오픈소스”는 오류다 — 말하지 않는다. 무료 버전이 있을 뿐이다. 색보정 쪽 오픈소스 사례는 OpenColorIO로 말한다.
⚠ 안드로이드 “39억~42억 대”는 업계 추정치다. 화면에 쓴 30억 대는 구글이 공식 확인한 마지막 숫자(2021.05, Google I/O)다. 굳이 최신처럼 말하지 않는다. / xz의 0.5초는 발견자 본인 메일과 보안업계 보도 기준이고, 위키피디아 본문에는 밀리초 수치가 없다.
닫는 한 줄 — “‘오픈소스는 암’이라던 회사가 20년 뒤 그 광장을 75억 달러에 샀습니다. 그런데 그 광장을 떠받치는 사람들 중 60%는 여전히 무보수입니다.” (75억 달러 이야기는 다음 장에서 다시 나온다 — 여기서는 한 문장만.)
| 암벽등반 | Git |
|---|---|
| 벽을 오른다 | 작업을 진행한다 |
| 확보물(말뚝)을 박고 로프를 건다 | 커밋 — “여기까지 됐다”고 못을 박는다 |
| 떨어져도 마지막 말뚝까지만 떨어진다 | 되돌리기 — 마지막 커밋 지점으로 |
| 아래로 이어진 로프 전체 | 히스토리(로그) — 지나온 자리가 다 남는다 |
| 같은 벽의 다른 루트 | 브랜치 — 원본을 건드리지 않고 딴 길을 시도 |
| 두 루트가 정상에서 만난다 | 머지 — 갈라졌던 작업을 하나로 합친다 |
이 장이 이 챕터의 목적지다. 비유가 주인공이고 연혁은 배경이다 — 위 네 칸은 15초에 훑고, 표와 사진에 4분을 쓴다.
강사 대사 — “커밋을 자주 박을수록 떨어질 때 덜 떨어집니다. 말뚝을 10미터마다 박으면 10미터를 떨어지고, 1미터마다 박으면 1미터만 떨어져요. final_최종_진짜최종이 사라지는 이유가 이겁니다. 파일 이름으로 버전을 관리할 필요가 없어져요.”
사진 셋을 순서대로 짚는다 — ① 손이 퀵드로를 거는 순간이 커밋. ② 로프가 아래로 계속 이어지고 말뚝마다 걸려 있는 게 히스토리. 오른쪽 확대 컷에서 말뚝 간격을 짚으면 “자주 박아라”가 한 번에 붙는다. ③ 아래에서 같이 출발해 중간에 갈라지는 두 루트가 브랜치다.
“분산”은 한 문장이면 된다 — “모든 참여자가 전체 역사를 통째로 갖고 있습니다. 회사 서버가 날아가도 아무나 한 명의 노트북으로 완전히 복구돼요. 인터넷이 끊겨도 혼자 계속 기록할 수 있고요.”
GitHub 한 줄 정리 — “Git은 도구고, GitHub는 그 도구를 쓰는 사람들이 모인 광장입니다. 2018년에 마이크로소프트가 그 광장을 75억 달러에 샀어요. 한때 ‘오픈소스는 암이다’라고 했던 그 회사가요.”
오른쪽 GitHub 캡처는 겁을 주려고 띄우는 게 아니다. “한 줄에 하나씩, 누가·언제·무엇을 고쳤는지가 적혀 있을 뿐입니다. 여러분이 오늘 만들 앱도 이렇게 남습니다.”
⚠ 라이브로 git 명령을 치지 않는다. 이 장은 개념만이고, 실제 커밋·배포는 뒤 챕터에서 결과 화면으로만 보인다.
ffmpeg -i 촬영본.mp4 -vn 소리.mp3
이 장의 목적은 하나다 — “오픈소스가 어디 있냐”는 질문에 대한 가장 강한 답. 이 방에 있는 모든 사람이 오늘 아침에도 FFmpeg를 썼다. 유튜브를 봤으니까.
왼쪽 그림을 가리키며: “위에 있는 게 우리가 아는 회사들이고, 저 밑에 가느다란 기둥 하나가 FFmpeg입니다. 2000년부터 자원봉사로 유지되고 있어요.”
→ 앞 장(오픈소스가 위태롭다 · left-pad · xz)과 바로 이어진다. “아까 그 얘기가 이겁니다.”
영화인용 연결: “프리미어나 다빈치가 뒤에서 하는 일의 상당 부분이 이런 처리예요. 차이는 FFmpeg는 사람 없이 시킬 수 있다는 것. 파일 100개를 한 번에 돌립니다.”
명령어 한 줄을 읽어 준다 — -i는 입력, -vn은 “영상 빼고”. “이게 CLI예요. 아까 본 그 창에 이 한 줄을 칩니다.”
⚠ 유튜브는 말하지 마라. 공식 확인 문서를 못 찾았다(떠도는 건 개인 블로그 정황뿐). 넷플릭스는 확인됨 — 자사 기술블로그에 “an FFmpeg-based filter that runs together with other video transformations”라고 적혀 있다. 크롬도 소스 트리에 FFmpeg를 포함한다. 이 둘까지만.
--impersonate — 크롬·엣지·사파리가 접속할 때 남기는 지문까지 흉내 낸다. 서버 눈에 사람이 쓰는 브라우저로 보인다--cookies-from-browser — 내 브라우저에 이미 있는 로그인 쿠키를 그대로 쓴다. 로그인해야 보이는 영상에 쓴다--sleep-requests — 요청 사이에 쉰다. 기계처럼 몰아치지 않는 것이 가장 확실한 우회다이 유튜브 영상 받아서 한국어 자막 뽑고 앞 30초만 잘라 줘
yt-dlp --write-auto-subs --sub-langs ko --convert-subs srt "https://youtu.be/..." ffmpeg -i 받은영상.mp4 -t 30 앞30초.mp4
앞 장(FFmpeg)에서 바로 이어진다. "FFmpeg가 영상을 다루는 도구라면, 이건 영상을 가져오는 도구예요. 둘은 거의 항상 같이 씁니다."
숫자 두 개만 짚는다: "1,363개 사이트를 지원합니다. 사이트마다 화면 구조가 다르니까 해석기를 1,731개 따로 만들어 뒀어요. 이걸 자원봉사로 유지합니다."
우회 이야기는 흥미롭게, 그러나 짧게. "사이트들이 막으려고 하죠. 그래서 브라우저인 척하고(--impersonate), 내 로그인을 빌리고, 유튜브처럼 창구가 여럿이면 다른 창구로 물어봅니다. 재밌는 건 가장 확실한 방법이 천천히 묻는 것이라는 거예요."
⚠ 반드시 한 줄 붙인다: "도구가 자유롭다고 남의 영상까지 자유로운 건 아닙니다. 저작권과 약관은 그대로예요." — 이 말을 빼면 안 된다.
마무리는 클로드 코드 예시로. 오른쪽 두 상자를 나란히 짚는다. "제가 친 건 위에 있는 한국말 한 문장이고, 아래 두 줄은 에이전트가 알아서 친 겁니다. 오늘 배운 게 다 여기 있어요 — CLI, 오픈소스 도구 두 개, 그리고 그걸 사람 말로 시키는 것."
3분.
오늘 쓰지 않는 것을 왜 보여주나 — 집에 가서 검색하면 이 두 이름이 계속 나오기 때문이다. “같은 종류구나”만 알면 헷갈리지 않는다.
“올리는 곳은 하나가 아니에요. 오늘은 Cloudflare Pages를 쓰는데, Vercel도 똑같이 폴더를 올리면 주소를 줍니다. 개인용은 둘 다 공짜예요.”
v0는 이 청중에게 실제로 유용하다 — 설치가 없다. 브라우저에서 말로 설명하면 화면이 나온다. “터미널이 아직 부담스러우시면 여기서 먼저 감을 잡으셔도 됩니다.”
차이를 한 줄로: Vercel은 서버가 필요한 사이트에 강하고, Cloudflare Pages는 화면만 있는 사이트에 간단하다. 오늘 만든 건 후자라 어느 쪽이든 된다.
읽어 주지 않는다. 손으로 훑으며 “이 여덟 개는 집에서 열어 보세요. 단톡방에 올려두겠습니다.”
세 개만 짚는다 — Cloudflare Pages(오늘 쓰는 것) · Replit(터미널이 부담스러운 분) · Kenney(오늘 게임 그림이 여기서 왔다).
Hugging Face는 이 청중 중 영상·음성 생성에 관심 있는 분에게 다음 단계다. “모델이 뭐가 있는지 직접 보실 수 있어요.”
이 장은 안전망이다. 오늘 못 따라온 분도 이름 여덟 개는 가져간다.
일곱 줄을 소리 내어 읽는다. 다 읽고 나서: "여기 기술 용어가 한 줄이라도 있었습니까. 없어요."
2번이 이 장의 핵심이다. "제가 '사주 계산 네가 하지 마'라고 했죠. AI는 음력하고 절기에서 자주 틀립니다. 그래서 직접 하지 말고 찾아보라고 시킨 거예요. 요즘 에이전트는 인터넷을 뒤져서 뭐가 있는지 보고, 골라서, 붙입니다. 라이선스까지 확인해서요."
→ P18에서 그 결과(@fullstackfamily/manseryeok, MIT, 한국천문연구원 기반)를 실제 화면으로 보여준다. 여기서 시킨 것이 저기서 나온다.
6번을 짚는다. "키가 없어도 여덟 글자는 나와야 한다 — 이게 제일 중요한 제약이에요. 오늘 60분 중에 키 발급까지 가는 분은 몇 안 됩니다. 그래도 다 쓸 수 있어야 하니까요."
"사람이 정할 건 대상·경험·목표·금지예요. 나머지는 도우미가 합니다." [47:05]
"6개월 전이면 훨씬 세부적으로 정의해야 한다고 했을 텐데, 지금은 생각하는 바를 자연어로 최대한 뱉어 보는 것이 더 중요해요." [18:32]
⚠ 현장 제작 경계 — P17까지 빈 폴더에서 라이브. 그 뒤는 완성본. 4분.
화면 셋을 나란히 — 터미널 + 에디터 + 브라우저. 빈 폴더에서 시작한다.
① 터미널을 켜면서 P09 회수 30초: "무섭게 생겼는데 제가 치는 건 한국어예요." 이어서 P10 회수: "저는 맥이라 이렇게 치는데 윈도우는 다릅니다. 그래서 첫 문장에 '나 윈도우 11이야'."
② P16 기획 한 장을 그대로 준다. 화면 뼈대와 입력 폼(이름·생년월일·시각·모름 체크)이 나온다.
③ 트리를 세우고 — "이름 보면 뭐 하는 놈인지 알죠." P05 폴더 구조 이야기와 같은 자리다.
④ 브라우저로 연다. "여러분이 지금 보는 이 화면이 앞이에요. 오늘은 뒤에 우리 서버가 없어요."
⚠ 실패 시 — 에이전트가 늦으면 완성본 폴더를 열어 트리만 보이고 P18로 넘어간다. 8분을 넘기지 않는다.
음력과 절기 계산은 직접 만들면 며칠이 걸린다. 그런데 누가 이미 만들어서 공개해 뒀다 — 공짜인데 조건이 있고, 그 조건을 적어 둔 것이 라이선스다. 작품에 쓰는 사람에게는 이게 실제로 걸린다.
한자를 누르면 뜻이 붙는 것은 표 하나다 — data/hanja-glossary.json, 천간 10자 + 지지 12자 = 22자 고정. AI가 아니다.
"음력이랑 절기를 계산해야 하는데 이건 제가 못 만듭니다. 만들면 며칠 걸려요. 근데 누가 이미 만들어서 공개해놨습니다. 공짜인데 조건이 있어요. 그 조건 적어놓은 게 라이선스고, 작품에 쓰시는 분들은 이게 실제로 걸립니다."
한 줄 붙인다 → 이름·생년월일 넣는다 → 여덟 글자가 나온다. 사람 앞에서 대조할 세트(REPLAY §3, 독립 라이브러리와 교차 검증 완료): 1990-05-15 14:30 → 경오 신사 경진 계미 / 2000-01-15 14:20 → 기묘 정축 임신 정미. 새벽 검증 추가분: 홍길동/1980-05-15 → 경신 신사 무자 기미.
연주가 1999년 것으로 나오는 대목에서 — "입춘을 지나야 그 해가 시작됩니다. 사주 특유의 규칙이에요."
"30초 만에 됐죠. 남이 만든 부품을 갖다 쓴 겁니다."
한자 뜻은 — "이건 표 하나예요. AI 아니에요."
⚠ 실패 시 — CDN이 막히면 화면이 통째로 빈다(어젯밤 재현: 헤더만 남고 본문 없음, 에러 문구도 없음). 그 순간을 그대로 보여주고 "바깥 부품을 못 불러오면 이렇게 됩니다" → 완성본 캡처로. §준비물에 벤더링 항목 있음.
최소 생존 버전은 여기까지다 — 입력 폼 → 저장 → 여덟 글자 → 키 입력 → "오늘의 운세" 한 버튼 → 배포. 그 아래는 다 자를 수 있다.
저장 → 새로고침 → 그대로 있다를 눈앞에서 한 번. 그리고 개발자도구 Application 탭을 열어 saju_profile 키를 가리킨다.
"방금 페이지를 다시 불렀는데 아까 적은 게 그대로 있죠. 이 화면이 기억하고 있는 거예요. 이 기억은 여러분 폰 안에만 있고 어디로도 안 나가요."
"옆사람 폰엔 없어요. 남도 보게 하려면 남의 컴퓨터에 있어야 합니다. 그게 서버고, 거기 쌓아두는 게 데이터베이스예요. 오늘은 거기까지 안 갑니다."
여기서 완성본으로 전환한다(시간이 밀렸으면 P18부터 이미 완성본). REPLAY §0 최소 생존 버전 = 입력 폼 → 저장 → 여덟 글자 → 키 입력 → "오늘의 운세" 한 버튼 → 배포. 그 아래는 다 자를 수 있다.
키 이름 두 개는 실제 코드 그대로다 — saju_profile(profile-storage.js) · saju_gemini_key(app.js). 4분.
"사주 풀이 문장은 우리가 쓰는 게 아니라 구글 AI한테 전화를 걸어서 받아 와요. 전화 걸 때 '저예요' 증명하는 게 이 열쇠예요. 제 열쇠가 아니에요. 각자 자기 열쇠. 그리고 이 열쇠도 아까 그 기억 창에 저장되고, 딴 데로는 안 가요."
키 없이 누르면 앱이 안 죽고 안내 문구가 뜬다(어젯밤 확인). 한도가 넘으면 "1분 쉬었다 다시" 버튼이 뜬다. 강사 키로 오늘의 운세 한 번 받아서 보인다.
발급 절차는 다음 장(P20b)으로 넘긴다 — "무료로 2분이면 됩니다. 단톡방에 올려둘게요."
수업 소재(원격 실측, a8f1218에서 수정됨) — 처음엔 답이 "오늘은 2026년 9월"에서 잘렸다. gemini-2.5-flash가 눈에 안 보이는 "생각"에 토큰을 먼저 쓰는데(thoughtsTokenCount 479) 출력 예산 500을 거의 다 먹은 것. thinkingConfig: { thinkingBudget: 0 } + 예산 1024로 잡았다. "에러도 안 나고 그냥 답이 짧게 나와요. 모르면 프롬프트를 탓하게 됩니다. 이런 게 실무예요." — 라이브 중 답이 이상하게 짧으면 이 설정부터.
⚠ 남은 확인 하나 — 배포 주소에서 실제 제미나이 호출은 아직 아무도 안 돌렸다(원격은 키 입력이 안전 분류기에 막힘, 맥은 키 없음). 아침에 폰으로 주소 열고 본인 키 넣어 "오늘의 운세" 1회 — 30초. 그게 실제 사용 경로다(§준비물 1).
⚠ 실패 시 — 키 한도·API 오류가 나면 어제 미리 받아둔 샘플 응답 텍스트로. "이 AI도 하루 먹을 양이 정해져 있어요." 4분.
구글 키는 한 번 부를 때마다 돈이 나갈 수 있는 열쇠다. 대신 오늘 수업 범위는 무료 한도로 끝난다 — 결제가 필요한 건 이미지 생성뿐이다.
| 어디까지 | 필요한 것 | 시간 | 돈 |
|---|---|---|---|
| 사주 여덟 글자 · 한자 풀이 | 없음 | — | 없음 |
| 사주 AI 문장(8주제) | A단계 키 | 2분 | 무료 한도 |
| 스토리팩 대화(플레이) | A + .env.local | 3분 | 무료 한도 |
| 이미지 생성(팩 에셋·게임 그림) | A + B단계 | 7분 | 최소 $10 선불 |
P20 끝에 띄우고 한 마디만 — “키는 무료로 2분이면 만듭니다. 이 세 장을 단톡방에 올려두겠습니다.” 읽어 주지 않는다.
이 수업 권장 — 대화·사주 문장까지는 A만(카드 등록 없음). 전원 여기까지면 충분하다.
“무료로 몇 번 되는지”는 단정하지 않는다. 구글이 숫자를 문서에서 뺐고 계정마다 다르다. 수요일에 무료 한도가 소진돼 주인공 한 장에서 멈춘 게 이 때문이다.
aistudio.google.com/apikey → 구글 계정 로그인 → 약관 동의| 물건 | 넣는 곳 | 어디에 저장되나 |
|---|---|---|
| 사주앱오늘 QR | 앱 안 키 입력 화면에 붙여넣기 | 본인 폰 브라우저에만. 우리 서버는 없다 |
| 스토리팩 킷집에서 | .env.example 복사 → .env.local로 → GOOGLE_API_KEY= 뒤에 붙이고 저장 | 내 컴퓨터의 상자. 서버가 켜져 있었다면 끄고 다시 켠다 |
GEMINI_API_KEY지만 우리 팩이 읽는 이름은 GOOGLE_API_KEY. 둘 다 있으면 GOOGLE_API_KEY가 우선이라 이 이름 하나로 맞는다.지킬 것 셋(화면에 없음, 말로만) — ① 키를 채팅창·단톡방·화면 공유에 붙이지 않는다. 붙였다면 샌 것으로 친다 ② 샌 것 같으면 지우고 새로 만든다(로테이션) ③ 폰에 넣은 키는 그 브라우저에만 남는다.
수요일에 실제로 걸린 것 — 켜져 있던 서버가 옛 키를 물고 있었다. 완전히 끄고 다시 켜야 새 키를 읽는다.
기존 Google Cloud 사용자는 자동 생성이 안 된다 → Projects에서 프로젝트를 먼저 가져온(import) 뒤 만든다. 현업 경험자 질문 대비.
/projects → 내 프로젝트 행 Billing Tier → Set up billing/billing → Buy credits → 최소 $10/spend → Monthly spend cap을 프로젝트에 걸어 둔다이 장은 이미지까지 해보고 싶은 분만. 화면에 띄우고 “여기까지 오실 분은 이 한 장 보시면 됩니다”로 끝낸다.
볼트 02_보강_2026.09.02의 구글API키_획득절차 · 학생용_무료API키_발급안내와 일치.
순서는 넷 — ① 폰에서 localhost:8080 → 안 열린다 ② 드래그로 올린다(Cloudflare Pages) ③ 주소가 뜬다 ④ QR.
①에서 — "지금은 저만 볼 수 있어요. 아직 제 컴퓨터 안에만 있거든요." (P13에서 예고했던 20초를 여기서 회수한다.)
②③ — "남의 컴퓨터에 올립니다. 이름 하나를 빌린 거예요."
④ — "지금부터 여러분 폰에 이 주소를 찍어 보세요. 각자 자기 생년월일을 넣으면 자기 사주 여덟 글자가 나와요. 앱스토어도 가입도 필요 없어요." 키 없는 학생도 여덟 글자·한자는 본다. AI 문장은 "키 넣으면 됩니다. 발급은 집에서."
개인정보는 정확하게 — "여러분 생년월일은 저희가 만든 서버로는 절대 안 가요. 애초에 그런 서버가 없거든요. AI 문장 누르는 순간만 구글로 직접 갑니다."
⚠ 주소 — 반드시 https://srl-saju-fortune.pages.dev. 계획 문서들이 적어 둔 saju-webapp.pages.dev는 존재하지 않는 주소다. QR도 이 주소로 만든다.
⚠ 실패 시 — 라이브 배포가 막히면 사전 배포본 https://srl-saju-fortune.pages.dev 로 간다(200 응답, 로컬 a8f1218과 SHA 일치). 5분.
Cloudflare Pages는 돈이 안 달려 있다(무료·정적 사이트 무제한). 그래도 토큰이 새면 남이 내 사이트를 덮어쓰거나 지울 수 있다 — 여전히 열쇠다.
| 어디까지 | 필요한 것 | 시간 | 열쇠 |
|---|---|---|---|
| ① 폴더를 드래그해서 올린다 | Cloudflare 계정(이메일) | 3분 | 없음 |
② 터미널에서 올린다 (wrangler login) | 계정 + Node | 5분 | 없음 — 브라우저 로그인 한 번 |
| ③ AI 에이전트가 대신 올린다 | 계정 + API 토큰 + Account ID | 7분 | 있음 — 다음 장 |
dash.cloudflare.com → Sign up → 이메일·비밀번호 → 인증 메일 확인*.pages.dev)만 쓴다이름.pages.dev). 영문 소문자·숫자·하이픈P21 끝에 띄우고 한 마디만 — “집에서 하실 분은 이 두 장이면 됩니다. 단톡방에 올려두겠습니다.” 읽어 주지 않는다.
오늘 강사는 ①(드래그) 또는 ②(wrangler pages deploy)로 한다. ③은 “에이전트한테 ‘올려줘’까지 시키는” 사람의 길이다.
구글 키와의 차이를 한 번 짚는다 — 돈이 안 달려 있는데도 열쇠인 이유는 토큰이 새면 남이 내 사이트를 덮어쓰거나 지울 수 있어서다.
프로젝트 이름 = 주소. 오타가 영구 주소가 된다. 처음에 정한다(예: hong-saju).
hanyejong-pages 같은 알아볼 이름Account · Cloudflare Pages · Edit — 이 한 줄이면 된다Include · 내 계정 → Continue to summary → Create Tokennpx wrangler whoami로도 나온다..env.local — 값은 여기 안 적는다CLOUDFLARE_API_TOKEN=(C에서 복사한 토큰) CLOUDFLARE_ACCOUNT_ID=(D에서 복사한 ID)
.env.local에 있는 Cloudflare 토큰으로 site 폴더를 Pages에 올려줘. 프로젝트 이름은 내이름-saju. 토큰 값은 화면에 출력하지 마.npx wrangler pages deploy site --project-name=내이름-saju
이 장도 읽어 주지 않는다. “에이전트한테 배포까지 시키고 싶으신 분만 보세요.”
권한은 한 줄로 충분하다 — Account · Cloudflare Pages · Edit. 템플릿을 쓰면 필요 이상으로 넓어진다.
함정 둘(화면에 없음) — ① 고친 게 바로 안 보인다(캐시): 시크릿 창이나 하드 리프레시(Ctrl+Shift+R) ② wrangler login이 창을 못 띄우면(윈도우) 터미널에 뜬 URL을 복사해 직접 연다.
구글 키와 반대다 — AI Studio 키는 다시 볼 수 있지만 Cloudflare 토큰은 생성 직후 한 번뿐이다. 여기서만 “지금 복사하세요”가 맞는 말이 된다.
세로로 긴 화면에서 비행기가 아래에 있고, 적이 위에서 계속 내려오는 슈팅게임을 만들어 줘. 옛날 오락실 1945 같은 느낌이면 좋겠어.
대상 — 게임을 안 해 본 사람도 30초 안에 이해할 것. 설명 없이 바로 손이 움직여야 해.
조작 — 마우스나 손가락으로 끌면 기체가 따라온다. 총알은 알아서 나간다 — 쏘는 버튼은 없어.
경험 — 처음 10초는 쉽게 이기게 해 줘. 그다음부터 적이 조금씩 많아지고, 1분 반쯤에 보스가 나오면 좋겠어.
보이는 것 — 점수, 남은 목숨, 보스 체력. 그 셋만. 화면을 숫자로 덮지 마.
금지 — 회원가입·로그인 없음. 설치 없음. 주소 하나로 폰에서 그냥 열릴 것.
부품 — 그림과 소리는 내가 만들지 않아. 무료로 공개된 것을 찾아서 써 줘. 조건은 확인하고.
| 엔진 Phaser 3 | CDN 한 줄 | 오픈소스 |
| 그림 기체·적·폭발 | Kenney.nl | CC0 |
| 소리 BGM 6 · 효과음 12 | OpenGameArt | CC0 |
사주앱(P16)과 같은 구조다. 거기선 대상·경험·목표·금지 넷을 적었고, 여기선 조작과 부품이 더 붙었을 뿐이다.
왼쪽 명세를 소리 내어 읽는다. 다 읽고 나서: “여기 기술 용어가 한 줄이라도 있었습니까. 없어요. 제가 적은 건 누가 보고, 어떻게 만지고, 뭘 느끼고, 뭘 하지 말라는 것뿐입니다.”
“총알은 알아서 나간다, 쏘는 버튼은 없다” — 이 한 줄이 왜 중요한지 짚는다. 60명이 폰으로 처음 잡는 게임이라 버튼이 하나라도 늘면 안 된다. 제약을 먼저 적는 것이 좋은 명세다.
오른쪽으로 넘어가며: “게임 엔진도 남이 만든 겁니다. 그림하고 소리도요. 이거 없으면 이 게임 못 만들어요.”
오픈소스 두 번째 — 아까는 계산기 하나(만세력), 이번엔 엔진·그림·소리 전부.
assets/CREDITS.txt를 잠깐 띄운다: “조건이 ‘표기’인 것도 있어요. 이 파일이 그겁니다.”
⚠ 스프라이트 실물은 img/sprites/의 진짜 파일이다(32~104px). 확대해서 각이 지는 건 원래 그렇다고만 말하고 넘어간다. boss_body.png가 1024×64라는 것은 P24에서 “보스가 찌그러져 보인다”를 설명 없이 이해시키는 복선 — 필요하면 그때 짚는다.
REPLAY 실측으로 1~3단계는 85분이 걸렸다. 오늘 무대에서 하는 것은 골격까지 10분이다.
화면 셋을 나란히 — 터미널 + 에디터 + 브라우저.
REPLAY 1~2단계, 필요하면 3단계까지. 4번은 시간이 될 때만.
명령어를 칠 때 P10(기기와 운영체제 — 같은 말을 다르게 친다)을 한 번 더 회수한다.
파일 이름을 보이면서: "이름을 왜 이렇게 붙였을까요. 사람도 알아보고 기계도 알아보라고요."
붙는 단어: 윈도우/맥 ● · 파일 이름·구조 ● · 소스 코드 ○ — 10분.
⚠ 시간 관리 — REPLAY 실측은 1~3단계 85분이다. 오늘은 골격만 10분이 목표다. 2번(이동)에서 막히면 붙들지 말고 완성본으로 전환하고, 골격은 미리 찍어 둔 캡처 3장으로 대체한다.
⚠ bullet_player_viper.png는 화면에서 점처럼 작아 스프라이트 실물을 안 띄운다(그 줄만 그림 없음). 대신 이름이 세 토막이라는 것만 짚는다.
새 탭에 주소를 치고, 강사가 30초 플레이한다.
코드 폴더를 잠깐 띄우되 읽지는 않는다 — 이렇게 살이 붙었다는 것만 본다. 이걸 다 라이브로 하면 오늘은 라이브 코딩만 보다가 끝난다.
라이브로 만든 골격(P23)과 같은 물건이다. 그 위에 시간을 더 부은 것뿐이다.
"이제 어젯밤에 미리 다 만들어둔 완성본을 열겠습니다."
"이렇게 살이 붙었다는 것만 보세요. 이걸 다 라이브로 하면 오늘 라이브 코딩만 보다가 끝납니다."
━━━ ⚠ 시연 자세 (새벽 실측) — 이 세 가지를 지키지 않으면 무대에서 멈춘다 ━━━
⚠ ① 하단 중앙을 클릭하고, 커서를 거기 둔 채 마우스로 조작한다. 키보드만 쓰면 기체가 좌상단(12,12)에 박힌다 — player.js:59가 키 입력 200ms 뒤 마우스 포인터를 따라가는데, 포인터가 캔버스에 안 들어왔으면 (0,0)이라 거기로 간다. 화면 안내문의 "방향키"를 믿고 키만 누르면 무조건 터진다.
⚠ ② 보스전에서 3번 키(펄스레이저) 금지. 사거리 225px(pierceDuration 0.25s × 900px/s)라 보스(y≤196)에 안 닿는다 — 실측 데미지 0. 보스전 중엔 잡몹이 안 나와(spawner.js:36) 아이템으로 무기 교체도 불가능하다. 그 자리에서 시연이 멈춘다.
⚠ ③ 보스 그림이 찌그러져 보이는 건 말로 넘긴다. 1024×64 그림을 120×100으로 눌러서다(boss.js:25). 빔에서 티가 난다. → "보스는 그림이 아직 못생겼습니다. 이것도 이따 고치는 목록에 올립니다."
붙는 단어 없음. 2분.
순서: 이미지 생성 → assets/sprites/enemy_weak/enemy_scout.png 덮어쓰기 → 하드 리프레시(Ctrl+Shift+R / Cmd+Shift+R) → 다른 색 적이 내려온다.
"지금 얘한테 그림 하나를 새로 그려 달라고 시킬 건데, 다른 회사 서비스한테 전화를 거는 거예요. 아까 그 열쇠, 여기서 또 씁니다." — P20 API 키 회수.
함정을 숨기지 말고 그대로 보여준다. 일반 새로고침으로는 안 바뀐다. "브라우저는 그림을 한 번 보면 기억해 두려고 해서, 강제로 다시 불러오라고 알려줘야 해요. 그게 방금 누른 새로고침이에요."
⚠ REPLAY C-1: 대본을 쓰다가 실제로 한 번 걸렸다. 무대에서 당황하지 말고 그 자리에서 설명 재료로 쓴다.
붙는 단어: API 키 ●(회수) · 캐시 –(한 마디) — 8분.
ufo: {
key: 'ufo', name: 'UFO',
hp: 2, speed: 90, bulletSpeed: 200,
fireInterval: 2.0, score: 200,
pattern: 'straightDown',
attack: 'straight', tier: 'weak',
sprite: 'enemy_scout'
},types: [ … , 'ufo' ] // 단어 하나만 더한다저장 → 새로고침. 이건 일반 새로고침으로 된다 — 그림이 아니라 코드라서.
건드릴 데와 안 건드릴 데를 먼저 말하는 것이 프롬프트를 잘 쓰는 것보다 중요하다.
게임을 움직이는 큰 코드는 이 목록만 읽고 "적이 몇 종류 있구나"를 안다. 그래서 적 하나 추가는 게임 전체를 다시 짜는 일이 아니라 목록에 한 줄 더하는 일이 된다.
P05에서 본 구조 자체가 자산이다의 회수 지점이다.
먼저 변경 범위를 말한다: "건드릴 데하고 안 건드릴 데를 먼저 말합니다. 이게 프롬프트 잘 쓰는 것보다 중요해요." — enemies.js(움직이는 코드)는 한 줄도 안 건드린다.
"이 목록 하나만 봐주세요. 게임을 움직이는 큰 코드는 이 목록만 읽고 '적이 몇 종류 있구나' 하거든요. 그래서 적 하나 추가하는 게 게임 전체를 다시 짜는 일이 아니라, 이 목록에 한 줄 더하는 일이 돼요." — P05 "구조 자체가 자산"의 회수.
붙는 단어: 변경 범위 ● · 구조=자산(회수) — 6분. 시간이 밀리면 제일 먼저 자르는 장이다.
⚠ 계획서 불일치 — 볼트 04_수업활용_리허설.md는 enemies.json을 가정했지만 실제 구현엔 그 파일이 없다. 무대에서는 이 문서/REPLAY.md만 본다. 학생이 파일명을 물으면 difficulty.js라고 답한다.
⚠ 실패 시 — REPLAY는 "7종 버전 별도 배포 주소"를 대체로 적었다. 그 주소가 실제로 있는지 아침에 확인(준비물 항목).
SHMUP.LIVE_TUNE.enemySpeedMultiplier = 3.0 // 적 속도 3배 SHMUP.LIVE_TUNE.spawnInterval = 0.3 // 등장 간격 30%
영구히 바꾸려면 difficulty.js 맨 위 LIVE_TUNE 세 값을 고치고 저장 → 새로고침.
SHMUP.BOSS_WARN_SEC = 10; SHMUP.BOSS_START_SEC = 15; SHMUP.BOSS.hp = 80;
같은 장의 연장이라 자연스럽다 — 숫자를 세 개 더 바꿨더니 보스가 15초에 온다.
치기 전에 먼저 묻는다 — 이 두 숫자가 바뀌면 게임이 어떻게 달라질 것 같은지.
그리고 방금 그것을 무섭게 보이던 콘솔에서 했다. P15의 뒤집기다.
치기 전에 묻는다: "숫자 두 개만 바꿀 거예요. 하나는 적이 내려오는 속도, 하나는 나오는 간격. 이게 이렇게 바뀌면 게임이 어떻게 달라질 것 같으세요?"
바뀐 뒤: "숫자 하나 바꿨는데 게임이 달라지죠. 그리고 방금 그 무서운 콘솔에서 한 거예요." — P15(문제를 볼 때)의 뒤집기.
영구히 바꾸려면 difficulty.js 맨 위 LIVE_TUNE 세 값 → 저장 → 새로고침.
보스 시연 (실측 검증) — 보스는 고정 105초에 나오고 잡는 데 2~3.5분이 더 든다(호밍니들 113초 · 바이퍼 178초). 자연 플레이로는 4~5분. 그래서 시작 전에 콘솔 한 줄을 미리 친다. "숫자 세 개 더 바꿨더니 보스가 15초에 옵니다."
⚠ 보스전에 들어가면 3번 키(펄스레이저)를 쓰지 않는다 — 사거리가 안 닿아 데미지 0이다(P24 시연 자세 ②).
붙는 단어: 소스 코드 ● · 콘솔 ○(무섭지 않다) — 4분.
$ npx wrangler pages deploy site
폰에서 열었을 때 — 세로 화면
같은 주소가 PC에서도 폰에서도 열린다. 60명 최초 로드가 1인당 2.1MB — QR은 쉬는 시간에 미리 열게 하면 안전하다.
"고칠 때마다 올립니다. 이 기록을 훨씬 촘촘하게 해주는 게 Git이에요." — P12 회수, 여기까지만.
"같은 주소가 PC에서도 폰에서도 열립니다." → 예순 명이 각자 폰으로 한 판. 시간이 남으면 적 하나를 더 라이브로 추가한다.
폰 안내 문구: "폰에서는 손가락으로 끌면 됩니다. 폭탄은 PC에서만요. 금방 죽는 게 정상이에요."
⚠ 하단 안내문이 폰에서는 틀린 말이다("방향키/WASD+마우스 · SPACE · 우클릭"). 학생이 그걸 보고 헤매기 전에 먼저 말해 준다.
⚠ 실물 iOS Safari·Android Chrome은 미검증이다(에뮬레이션만 통과). 아침에 폰 1대로 연타·핀치 줌을 확인한다.
⚠ 60명 최초 로드 = 1인당 2.1MB. QR을 쉬는 시간에 미리 열게 하면 동시 접속 부하를 피할 수 있다.
붙는 단어: 재배포·Git ○ · 반응형·기기 ○ — 3분.
챗봇은 뒤가 있어서 기억이 남았다. 그래서 오늘 그것만 드래그로 못 올렸다 — P04의 상자 셋, P13의 "화면은 앞, 서버는 뒤".
사주 웹앱의 기억은 각자 폰 안에만 있었다. 옆사람 폰엔 없었다 — P19.
오늘 만진 셋의 차이가 여기서 한 문장으로 묶인다. 뒤가 있느냐 없느냐.
게임오버 화면. 점수. 새로고침하면 사라진다. 1분. 짧게 끊는다.
"점수가 저장이 안 되죠. 이 게임엔 뒤가 없어요. 그래서 점수가 안 남습니다. 남기려면 서버가 필요하고, 그때부터 다른 얘기가 됩니다. 아까 챗봇은 뒤가 있어서 기억이 남았고, 그래서 드래그로 못 올린 거예요."
P04(화면·서버·팩) · P13(웹이 돌아가는 구조) · P19(기억은 내 폰 안에만)를 한 문장으로 묶는 장이다. 새로 설명하지 않는다.
붙는 단어: 백엔드 ●(회수) · 데이터베이스 – — 1분.
학생들은 이 말을 듣는 동안에도 폰으로 계속 게임을 하고 있다(P28). 그대로 두고 P30으로 넘어간다.
P08에서 봤던 그 지도 그대로. 이번엔 칸마다 오늘 만든 것이 들어가 있다. 새 단어를 얹지 않는다 — 이미 나온 것만 제자리에 놓는다.
왼쪽부터 짚는다. 내 컴퓨터 — 사주앱 화면과 내 사주(기억), 게임 코드와 difficulty.js. 남의 컴퓨터 — 두 주소(pages.dev). "올렸으니 남도 봅니다. 다만 점수는 여기 없어요 — 각자 폰에만 있습니다." 바깥 — 구글 AI, 이미지 생성, 열쇠와 비용. 그리고 왼쪽으로 들어온 것: 만세력·Phaser·Kenney.
회수 문장 다섯을 하나씩 읽는다. 설명을 덧붙이지 않는다.
클로징: "어떤 시스템과 스토리텔링이 합쳐져 돌아가는 구조를 만드는 것, 전체가 그렇게 어려운 과업은 아닙니다." [27:39]
5분.
네 줄만 읽고 끝낸다.
① 오늘 만든 것 중 하나를 자기 재료로 바꿔 본다 — 사주앱의 주제 버튼 하나, 게임의 적 그림 하나. 둘 다 안 해도 된다. 하나면 된다.
② 안 되면 어디까지 됐는지 캡처를 남긴다. 환경 문제는 창작 실패가 아니다. "실패해도 어디까지 됐는지 말할 수 있으면 됩니다."
③ 주소가 나오면 단톡방에.
④ (선택) P10에서 본 실전 규칙 — AI에게 첫 문장으로 내 환경을 말하는 습관. "나는 윈도우 11이야."
두 주소는 화면에 띄운 채로 두고, 단톡방에도 올린다. 2분.