2026.09.05 · 한국예술종합학교 · 2회차

바이브 코딩의
지형지물

1 · 챗봇지난주 그 사이트 — 열어서 뜯어본다 · 3–23분
2 · 랜드스케이프바이브 코딩 어휘 — 거기서 나온 단어로 지도를 세운다 · 23–48분
3 · 사주 웹앱실습 1 — 그 지도 위에서 만든다 · 48–76분
4 · 슈팅게임실습 2 — 만들고, 고친다 · 76–110분

수강생은 따라 치지 않습니다 · 마지막에 각자 폰으로 접속합니다

P01 · 오늘의 지도 · 3분 · 2회차 120분 = 오프닝 3 · 챗봇 20 · 랜드스케이프 25 · 사주 28 · 슈팅 34 · 회수+과제 7 · 버퍼 3

가져갈 문장 — "오늘도 문법은 안 가르칩니다. 지형을 그립니다."

수요일 육성 그대로: "한 시간 만에 코딩을 알 리가 없습니다. 중국어 모르는 사람한테 한 시간 만에 중국어 못 가르쳐요." [10:02]

"그런데 중국 여행에는 중국어보다 — 몇 개의 성이 있고, 어떤 제스처가 기분 나쁘고, 공안은 무서운 사람이라는 정보가 더 중요할 수 있어요. 오늘은 그겁니다. 중국 옆에 한국, 오른쪽에 동해." [10:34] [54:14]

오늘 순서: 지난주 그 사이트를 연다 → 거기서 나온 단어로 지도를 세운다 → 그 위에서 두 개를 만든다. 여러분은 따라 치지 않습니다. 마지막에 폰만 꺼내세요.

화면은 4챕터 제목만 세로로. 그림 없음. 3분.

왜 지형지물인가 — 구현은 더 이상 허들이 아니다
위 · 사람의 몫
무엇을 만들 것인가
사용자 경험 · 내용 · 스토리 — 그것을 경험하는 사람의 관점, 그리고 그것을 의도한 감독의 관점
아래 · 기술
무조건 밑에서 떠받친다
서버 · 배포 · CLI · 운영체제 · Git · 오픈소스 · API — 예전과 달리 세부는 몰라도 되지만 대략적인 지도는 있어야 한다
수업에서 한 말

구현은 이제 허들이 아니게 됐습니다. 상당 부분은요. 그러면 인간의 목표로 남는 게 있고, AI의 목표로 남는 게 있을 거잖아요.

얼마나 선명하게 자기가 원하는 것을 그려내는가. 그게 중요합니다.

뭘 두드리면 뭐가 나오니까 나오긴 한다. 그게 쓸만한 건지 아닌지의 판단은 각자의 관점에서 나온다.
지형지물이라는 말

이 동네에 어떤 건물이 있고, 어디 가서 뭘 사야 하고, 마트가 어디 있는지 — 그 정도의 지도입니다. 아주 세부적인 것들은 몰라도 됩니다. 대신 대략적인 지도는 있어야 해요.

P01b · 2분 · 오프닝 논지 — 이 문장이 120분 내내 형태를 바꿔 가며 반복된다 · 근거 2026.09.05 전사 [00:00:42]~[00:02:53]

원고에 없던 장(2026.09.08 추가). 토요일 오프닝 3분의 논지를 학생 배포판에 남긴다.

"의지가 중요하고, 또 한 가지 강조하고 싶은 것은 뭘 만들고 싶은지 머릿속에 선명하게 그리는 것." [00:00:42]

두 레이어 — "위에서 뭘 할지는 각자의 맥락에 맞춰서 하시면 되는데, 제가 안내드리고 싶은 것은 그 기술적인 것들을 활용할 때 필요한 지형지물입니다." [00:02:10]

챗봇 사이트 소개
① 첫 화면 — "모든 스토리"

팩 카드 · 포스터

② 팩 선택 후 오프닝

이야기가 시작되는 첫 장면

③ 대화 + 배경·캐릭터

장면에 맞는 배경과 캐릭터 이미지가 뜬다

④ 선택지 A/B/C

다음 행동을 고른다

Story Deck — 대화형 스토리 아카이브

Story Deck — Interactive Story Archive
주소localhost:3010 · Next.js · 로컬
red_riding_hood(빨간 모자) · broken_hallway — 2개

지난주에 딸깍으로 만든 그 사이트. 오늘은 열어서 뜯어봅니다.

이야기 하나가 폴더 하나로 들어가 있고, 그 폴더를 AI가 읽으면서 연출을 한다.

오프닝 · 대화 · 선택지 · 중간의 보이스까지 전부 실시간으로 생성된다. 미리 만들어 둔 것이 아니다 — 실제 서비스에서는 비용 때문에 이렇게 서빙하기 어렵다.

P02 · 3분 · 붙는 단어 없음(아직) · 준비물 스크린샷은 아침 실제 Chrome에서

"지난주에 딸깍으로 만든 그 사이트입니다. 오늘은 이걸 열어서 뜯어봅니다."

40~50대 영화인이 보고 있다는 걸 잊지 않는다: "이야기 하나가 폴더 하나로 들어가 있고, 그 폴더를 AI가 읽으면서 연출을 합니다."

붙는 단어: 없음(아직). 이름을 얹기 전에 그림부터. 3분.

⚠ 준비물 — 스크린샷은 아침에 실제 Chrome에서 찍는다. 09.02 핸드오버 §7-7: 자동화 브라우저에서는 포스터·씬 이미지가 안 실렸다. 육안 확인이 곧 준비다.

실제 동작 — 화면과 로그
$ tail -n 20 logs/sessions/2026-09-04_16-53_red_riding_hood_session-3882/events.jsonl
{"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…
  1. 팩을 열고 대화를 두세 줄만 굴린다 — 배경이 바뀌고 캐릭터가 뜬다
  2. 옆 터미널을 가리킨다 — 로그가 흐른다. 화면 뒤에서 누가 일하고 있다
  3. 선택지를 하나 고른다 — 이 선택이 어딘가에 적힌다. 기억
P03 · 5분 · 화면(프론트엔드) ● · 서버·콘솔·로그 ● · 실패 시 P02 스크린샷으로 대체하고 P04로

두 창을 나란히 — 브라우저(사이트) + 옆에 터미널 로그.

① 팩을 열고 대화를 두세 줄만 굴린다. 배경이 바뀌고 캐릭터가 뜨는 걸 본다.

② 옆 터미널을 가리킨다. 로그가 흐른다. "화면 뒤에서 누가 일하고 있죠. 무슨 일을 했는지 여기 남습니다."

③ 선택지를 하나 고른다. "이 선택이 어딘가에 적힙니다. 기억이죠." [03:38]

붙는 단어(이름만 얹는다, 정의 안 함): 화면(프론트엔드) ● · 서버·콘솔·로그 ● — 5분.

⚠ 실패 시 — 로컬 서버가 안 뜨면 P02 스크린샷으로 대체하고 P04로 간다. 어젯밤 확인: 맥에 3010이 이미 떠 있다(+ 3011·3013·3020 중복 서버 — 아침에 하나만 남길 것).

오른쪽 로그 박스는 실제 logs/sessions/2026-09-04_16-53_red_riding_hood_session-3882/events.jsonl 마지막 20줄(폭에 맞춰 잘라 표시). 라이브에서는 진짜 터미널을 띄운다.

아키텍처 — 화면 · 서버 · 팩
Frontend
화면
앞무대
←→
Backend
서버
뒤 — 기억이 남는다
←→
Story pack
팩 = 이야기 폴더
재료

실행되면 서버 안에 기억이 남는다. LLM은 기억력이 좁아서 서버는 팩에서 필요한 장만 읽는다 — 현재 챕터와 옆 챕터만.

오늘의 포인트 — 준비된 리소스를 LLM이 에이전틱하게 골라 쓴다팩 안의 배경·캐릭터·음악·효과음은 이름표 붙은 목록(04_resources.txt)으로 들어 있고, 매 턴 무엇을 꺼내 쓸지는 LLM이 정한다 — 사람이 "이 장면엔 이 그림"이라고 일일이 안 붙인다. 주방을 꾸려 놓은 것.

알아서 하는 게 아니라, 수칙을 읽고 일하는 작업 도우미다.

수업에서 한 말

여러분이 서버 화면을 볼 일은 거의 없을 거예요. 그래도 굳이 이 복잡한 화면을 보여드린 건 — 바이브 코딩으로 웹 기반의 무엇인가를 만드신다면 무조건 프론트엔드, 그리고 백엔드라는 구조를 만나게 되기 때문입니다.

프론트엔드는 여러분이 보는 페이지(화면), 백엔드는 서버. 이 둘을 다 묶어서 보여주는 것이 구조화된 스토리팩이다.
P04 · 5분 · 프론트엔드/백엔드 ● · 서버 ● · 컨텍스트(기억력) ○

상자 셋. 그 이상 그리지 않는다.

"화면 / 화면을 띄우는 서버 / 스토리팩. 실행되면 서버 안에 기억이 남습니다." [00:41]

"LLM은 기억력이 좁아요. 처음엔 똑똑하다가 엉뚱한 소리를 하는 이유가 그겁니다. 그래서 필요한 장만 읽게 짰어요." [01:41] — 현재 챕터와 옆 챕터만 준다.

오늘의 포인트: 팩 안에는 배경·캐릭터·음악·효과음이 이름표 붙은 목록으로 들어 있고(04_resources.txt), 매 턴 어떤 걸 꺼내 쓸지는 LLM이 정한다. 사람이 "이 장면엔 이 그림"이라고 일일이 안 붙인다. "재료를 갖춰 놓으면 알아서 꺼내 씁니다. 으레 식탁 위에 포크와 나이프가 있죠. 에이전트가 눈 뜨자마자 '아, 여기서 밥을 푸는구나' 알도록 주방을 꾸려 놓은 겁니다." [13:29]

한 줄로: "이건 알아서 하는 게 아니고 수칙을 읽고 일하는 작업 도우미예요." [46:35]

붙는 단어: 프론트엔드/백엔드 ● · 서버 ● · 컨텍스트(기억력) ○ — 5분.

스토리팩의 구조
public/game-packs/
red_riding_hood/팩 하나 = 이야기 하나
  manifest.json제목·모델·캐릭터·엔딩 정의
  poster.webp  banner.webp목록에 뜨는 표지
  CLAUDE.md  AGENTS.md에이전트가 처음 읽는 글
  README.md  STORYPACK_SPEC.md  MODEL_AND_MEDIA.md사람이 읽는 규격서
  .env.example열쇠 넣는 자리(빈 틀)
  prompts/
    system/  ← 안 건드림
      00_response_format.txt
      01_gm_role.txt
      02_character.txt
      03_current_state.txt
    content/  ← 이야기가 들어가는 곳
      00_opening.txt첫 화면 연출과 대사
      01_worldview.txt장소·시대·규칙·갈등
      02_characters.txt인물의 욕망·비밀·말투
      04_resources.txt모델이 꺼내 쓸 리소스 ID 목록
      story/
        overview.txt전체 개요·상태 변수·엔딩 목록
        clues_system.txt단서 규칙
        chapter_1.txt  chapter_2.txt
        chapter_3.txt  chapter_4.txt진행도 0~25 / 25~50 / 50~75 / 75~100%
  resources/
    backgrounds/5장 · bg_forest_fork · bg_red_home_kitchen …
    characters/4장 · char_red · char_wolf · char_mother · char_grandmother
    scenes/11장 · scene_chapter_2_wolf_at_fork …
    endings/4장 · ending_wise_return · ending_basket_lost …
    music/8곡 + bgm_manifest.json
    effects/12개 + sfx_manifest.json
    references/11장 · 캐릭터 기준 이미지·스타일 앵커
    audio_source/elevenlabs_2026.09.02/생성 원본(음악 8 · 효과음 12)
    image_manifest.json  resource_list.json이 전부를 만들어 낸 명세
  resources_restyle_2026-09-02/같은 팩을 다른 톤으로 재생성한 것
파일 114개 · 폴더 19개 — 이야기 하나가 이만큼이다. 그런데 사람이 손대는 건 content/ 안의 글 몇 장뿐이다.

내용과 뼈대를 분리한 폴더 구조

본다에이전트는 폴더를 열면 이름과 구조만 본다 — _template이 있으면 “여러 개 붙는 구조구나”를 이름만으로 안다
따로내용과 뼈대가 따로 — 내용만 갈아끼운다. “고등학교 일진의 모험담” 한 문장이 주인공이 된 이유
반대엉망진창 다운로드 폴더에 “분석해 줘” — 그다음부터 엉망진창으로 일한다
구조화돼 있으면 LLM이 그걸 자산화해서 이미지든 소리든 만들어 준다.
세 갈래만 기억하면 된다prompts/system — 규칙. 손대지 않는다
prompts/content — 이야기. 여기만 고친다
resources — 그림·소리. 명세(resource_list.json)에서 자동 생성된다
P05 · 4분 · 프로젝트·폴더·파일 ● · 컨텍스트 ○ · CLAUDE.md ○ · 실제 팩 전체 트리(생략 없음) — 파일 114개

폴더 트리 한 장. 실제 경로 그대로. 옆에 packs/_template/(빈 틀)도 보인다.

"에이전트는 폴더를 열면 이름하고 구조만 봅니다. _template이 있으면 '아, 여러 개 붙는 구조구나'를 이름만으로 압니다." [20:44]

"내용하고 뼈대가 따로 있으니까 내용만 갈아끼울 수 있어요. 지난주에 '고등학교 일진의 모험담' 한 문장 던졌더니 주인공이 만들어졌잖아요. 그게 되는 이유가 이 폴더예요." [11:37]

반대 사례(웃긴 대목): "엉망진창인 다운로드 폴더 잡고 '분석해 줘' 하면, 그다음부터 엉망진창으로 일합니다." [44:55]

결론 한 줄: "구조 자체가 자산입니다. 구조화돼 있으면 LLM이 그걸 자산화해서 이미지든 뭐든 해줍니다." [44:25]

CLAUDE.md가 보이면 한 마디만: "네오가 깨어나 처음 읽는 글." [12:05]

붙는 단어: 프로젝트·폴더·파일 ● · 컨텍스트 ○ · CLAUDE.md ○ — 4분.

구조화는 누가 하는가 — 실제로 던진 조건은 다섯 줄
학생

아무것도 모르는 상태에서 “이런 프로그램을 만들고 싶다”고 했을 때, 어떻게 구조화해야 할지를 저희는 모르잖아요. 그것조차 “구조화를 해 줘”라고 시키면 되는 건가요?

강사

맞아요. 이 구조는 제가 짠 게 아닙니다. 저는 어떤 것을 만들 것인지에 대한 조건만 던졌어요. 다만 그 조건은 구체적으로, 절차적으로 말해야 합니다.

수업에서 한 말

정말 딱 이 정도만 입력했습니다. 더 상세하게 적은 것도 아니에요. 그런데 이걸 만들기에 앞서 샘플 스토리팩의 구조를 짜는 데는 오랜 시간을 썼어요. 딸깍이 가능했던 이유는 근본적으로 구조화를 잘 해놨기 때문입니다.

실제로 던진 조건 — 이게 전부다
  1. 프롬프트를 나눠서 제공할 것 LLM은 한 번에 다 밀어 넣으면 말을 잘 못한다
  2. 리소스 폴더를 따로 두고, 장면·캐릭터별로 폴더링할 것
  3. 주요 캐릭터를 먼저 만들고 캐릭터 시트로 설정을 잠근 다음 각 장면을 만들 것
  4. 음악·SFX 폴더를 분리하고, 이 전부를 묶는 명세 파일을 하나 둘 것 파일이 많아지면 한 번에 볼 수 있는 목록이 필요하다
  5. 에이전트가 바라볼 마크다운 — CLAUDE.md · AGENTS.md를 둘 것
CLAUDE.md는 무엇인가 — 매트릭스의 네오머리에 케이블을 꽂았다 뺀 직후의 네오 — 똑똑하지만 눈뜨자마자는 아무 정보가 없다. 이 폴더가 뭐고, 이 프로젝트가 뭐고, 사용자가 누구고, 어떻게 행동해야 하는지를 LLM이 눈 뜨자마자 처음 읽는 파일이 CLAUDE.md다.
사람의 역할

개념을 머릿속에 미리 잡아 놨기 때문에 결과물을 보고 “이거 아니야”라고 말할 수 있는 겁니다. 그 판단이 사람의 역할이고, 그걸 할 수 있는 연습이 필요합니다.

P05b · 4분 · 구조화 ● · CLAUDE.md ● · 근거 2026.09.05 전사 [00:13:51]~[00:18:07] — 학생 질문과 답을 그대로 옮겼다

원고에 없던 장(2026.09.08 추가). 토요일 수업의 실제 질의응답 [00:14:21]에서 나온 다섯 조건을 학생 배포판에 남긴다.

화자 표기는 “학생”으로만 — 성문 미확정(SPEAKER_02).

네오 비유는 수요일에도 썼고 토요일에 다시 꺼냈다. [00:16:38]

에셋 생성 — 명세 하나에서 이미지·음악·효과음으로
resources/resource_list.json명세 한 파일
"style_guide"화풍 · 품질 · 금지어
"backgrounds" [ ] { id, name, description, prompt, mood }
id: "bg_forest_fork" name: "숲의 두 번째 길"
"characters" [ ] id: "char_red" name: "빨간 모자"
"scenes" [ ] · "endings" [ ]
"music_descriptions" [ ] id: "bgm_calm_joyful_sunlit_morning"
"sound_effects" [ ] id: "sfx_red_boots_forest_steps"
npm run pack:images · pack:audio · pack:video
resources/실제로 생성된 파일
backgrounds/ 5 characters/ 4 scenes/ 11
music/ 9 effects/ 13 endings/ 4
01
명세
배경·캐릭터·씬·음악·효과음·엔딩을 한 파일에 적는다
02
Dry Run
--dry-run — 몇 건이 생성될지만 출력. 돈이 안 나간다
03
병렬
명시하지 않으면 한 장씩 만든다
이미지 제공자를 갈아끼운다--provider gemini(기본) · byteplus(Seedream). 텍스트 하나가 여러 양태로 뻗는다.
$ tail logs/sessions/…_red_riding_hood_session-3882/events.jsonl — 두 번째 턴, LLM이 목록에서 골라 낸 것
{"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":"…
연출을 정하고(gm_direction) → 음악과 효과음을 걸고(staging_command) → 배경을 고르고(action_executed) → 기억에 적는다(story_update).
골라 쓴 trackId · sfxId · imageId는 전부 resource_list.json에 있던 id다.
P06 · 3분 · API ● · API 키·비용 ● · 명세·제작 목록 ○ · Dry Run·병렬 ○ · 라이브 생성은 안 한다 — 사전 생성 결과를 연다

왼쪽은 명세, 오른쪽은 절차, 아래는 실제 로그. 라이브 생성은 하지 않는다 — 이미 나온 결과를 연다.

"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분.

챕터 1 마무리 — 에이전트를 무엇으로 볼 것인가
“에이전트를 바이브 코딩·웹사이트 만드는 걸로만 보지 마세요.
구조화된 재료로 프로젝트에 필요한 리소스를
생성하는 도구로 보세요.”
여러분에게는 원래 하시던 이 있습니다.
그 업의 지식을 에이전트로 최대로 발산하는 것 — 그게 바이브 코딩보다 중요합니다.
P07 · 1분 · 붙는 단어 없음 · 두 문장 — 수요일 [37:07] · 토요일 [00:18:21]

문장 하나만. 설명을 덧붙이지 않는다.

"에이전트를 바이브 코딩·웹사이트 만드는 걸로만 보지 마세요. 구조화된 재료로 프로젝트에 필요한 리소스를 생성하는 도구로 보세요." [37:07]

토요일 육성: "사람들이 다 바이브 코딩을 얘기하니까 꼭 에이전트 활용의 결과물인 것처럼 생각할 수 있는데, 저는 그렇게 생각하지 않습니다. 원래 하셨던 업에서 하시던 지식을 에이전트를 활용해서 최대로 발산하는 것이 중요합니다." [00:18:21]

1분 → 챕터 2(랜드스케이프)로 넘어간다.

지도 한 장 — 단어를 놓을 세 칸
Local
내 컴퓨터
  • 브라우저 · 화면
  • 폴더 · 파일 · 구조
  • 로컬 · 내 기억
Server
남의 컴퓨터
  • 서버 · 배포
  • 주소 · IP · 도메인 · DNS
  • (오늘 우리 서버는 없다)
External
바깥
  • API · 열쇠 · 비용
  • ← 오픈소스로 받아온 것
내 컴퓨터 안 사설 · 나만
localhost127.0.0.1과 같은 곳. “이 컴퓨터”라는 뜻이라, 남의 폰에서 치면 그 폰을 가리킨다
192.0.0.2같은 와이파이 안에서만 통하는 번호(사설 IP). 옆자리 노트북은 http://192.0.0.2:8000으로 내 화면을 볼 수 있다 — 카페 밖에서는 안 된다
같은 자리를 부르는 이름이 여럿이다 — localhost · 127.0.0.1 · 0.0.0.0 셋 다 같은 서버를 연다(방금 실제로 확인했다). 이름은 여러 개, 자리는 하나.
인터넷 어디서나 공인 · 남도
172.66.44.185전 세계 어디서 쳐도 같은 곳에 닿는 번호(공인 IP). 배포하면 이런 번호를 받는다
srl-saju-fortune.pages.dev사람이 외우는 이름. 번지수 대신 부르는 상호
DNS이름 → 번지수로 바꿔 주는 전화번호부. 주소창에 이름을 치면 먼저 여기에 물어본다
구조는 같다
http://주소:포트/경로
내 컴퓨터http://localhost:8000
같은 와이파이http://192.0.0.2:8000
인터넷https://srl-saju-fortune.pages.dev
셋 다 같은 모양이다. 바뀌는 건 주소 자리뿐 — 얼마나 멀리서 부를 수 있느냐만 다르다.
시간을 쓴다 이름만 스친다 오늘 안 꺼낸다 · 질문이 나오면 그때 한 마디
P08 · 4분 · 주소 ● · 사설 IP ○ · 공인 IP ○ · 도메인 ○ · DNS ○ · localhost·127.0.0.1·0.0.0.0 동치는 실측 확인 · 다음 일곱 장이 놓일 세 칸을 세운다

챕터 목적 — "꽌시가 무슨 말인지 몰라도 되지만 그런 개념이 있다는 건 알아야 합니다." [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분.

배포 — 내 컴퓨터의 것을 남의 컴퓨터에 올린다, 그래서 위험하다
로컬내 컴퓨터브라우저·폴더·파일이 다 여기 있다. localhost, 192.…로 시작하는 숫자 주소 — 전부 내 컴퓨터를 부르는 이름이다. 우리 집 주소라고 이해하면 된다.
서버남의 컴퓨터보통 클라우드라고 부른다. 강사도 서버에 배포를 정말 많이 했지만 배포한 서버를 눈으로 본 적은 한 번도 없다. 어디 서버실에 있을 뿐이다.
배포올린다로컬에서 만든 것을 서버에 올려 남들이 볼 수 있게 하는 일. 지금 보고 있는 이 강의 자료도 그렇게 배포돼 있다 — HTML 슬라이드도 일종의 프로그램이다.
API열쇠이 열쇠로 남의 서비스를 부른다 — 제미나이·나노바나나 같은 모델, 네이버 지도, 네이버 검색. IP · 도메인 · DNS는 “이런 게 있구나” 정도로 넘어가도 된다.
수업에서 톤을 올린 자리
“배포는 위험한 겁니다.

여러분이 만든 정보가 밖으로 나가기 때문입니다. 내 살림살이 중에 남이 진짜 보면 안 되는 게 있는지 없는지를 알아야 해요. 업로드하면 남들이 다 볼 수 있게 되니까요.

언제API 키가 유출되는 시점이 바로 배포할 때
그러면탈취한 사람이 내 계정의 권한을 쓰고, 그 비용은 내가 낸다
그래서“뭐뭐 하다가 배포해 줘” 할 때는 한 번 더 생각한다
수업에서 한 말

중요한 것은 내 컴퓨터랑 남의 컴퓨터(서버)를 구분할 줄 아셔야 한다는 겁니다. 그리고 배포라는 말도 이해하셔야 돼요.

P08b · 3분 · 로컬 ● · 서버 ● · 배포 ● · API·열쇠 ● · 근거 2026.09.05 전사 [00:19:44]~[00:24:17] · 열쇠와 상자는 P14에서 다시

원고에 없던 장(2026.09.08 추가). P08 지도 위에 토요일 육성을 얹는다. 정의는 강사가 말한 순서 그대로 — 로컬 → 서버 → IP·도메인·DNS(가볍게) → 배포(톤 상승) → API.

"배포는 위험한 겁니다. 왜냐하면 여러분들이 만든 정보가 이제 밖으로 나가거든요." [00:22:31] / "API 키가 잘못되면 유출된다고 이야기하는데요, 그런 일이 일어날 수 있는 시점이 언제냐면 배포를 할 때입니다." [00:23:01]

컴퓨터에 말을 거는 방법
CLI명령줄마우스로 고르는 대신 글자로 지시하는 창메뉴판을 손가락으로 고르기 vs 주방에 대고 말로 주문하기
터미널Terminal그 창을 띄우는 프로그램인터폰 단말기
명령어Command그 창에 치는 한 줄“3번 조명 20% 다운”
터미널 — 내 컴퓨터
# ① 폴더를 하나 만든다
$ 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 -
따라 쳐 보기 — 네 줄
mkdir 내작품폴더를 만든다 make directory
cd 내작품그 폴더로 들어간다 change directory
ls안에 뭐가 있나 본다 · 윈도우는 dir
python3 -m http.server 8000내 컴퓨터가 웹서버가 된다. 브라우저에 localhost:8000 → 방금 그 폴더가 열린다 · 윈도우는 py
윈도우는 이 셋만 다르다창은 PowerShell · python3py · lsdir
수업에서 한 말
01컴퓨터는 원래 그렇게 생겨먹었다 — CLI가 근본(백본)이고, GUI는 그 위에 얹은 것
02그래서 CLI로 못 하는 게 거의 없다 — 서버 띄우기 · 프로그램 짜기 · 폴더 만들기 전부
03에이전트가 제일 잘 쓰는 게 CLI다 — 명령어를 외울 필요는 없고, 무엇이 돌아가는지만 알면 된다
04에이전트가 가끔 “이건 제가 직접 할 수 없어요, 터미널에 입력해 주세요”라고 한다 — 그때 터미널을 띄워 그 명령어를 치면 된다. 맥은 Terminal, 윈도우는 PowerShell·CMD — 다 같은 것이다
P09 · 5분 · CLI(명령줄) ○ · 터미널 ○ · 명령어 ○ · 실제 화면 — 이 네 줄은 강사 노트북에서 그대로 돌아간 결과다

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 기준으로 알려줘.”
수업에서 한 말

어떤 운영체제를 쓰느냐에 따라 에이전트가 줄 수 있는 것이 달라집니다. 폴더 경로 적는 규칙이 윈도우와 맥·리눅스가 달라요. 에이전트가 대개 알아서 처리하지만, 규칙이 다르다는 걸 모르면 결과물이 잘못됐다고 말할 수가 없습니다. 그래서 중요한 지형지물입니다.

오늘 어디서P23 슈팅 라이브에서 명령어를 칠 때 — 맥과 윈도우가 갈리는 자리를 그 화면에서 다시 짚는다
P10 · 4분 · 윈도우/맥 ● · PC ○ · 운영체제(OS) ○ · 아이폰/안드로이드폰 ○

인터넷 안내문 대부분이 맥 기준이다. 윈도우 쓰는 사람은 읽을 때마다 한 번씩 번역해야 하는데, 그 번역을 지금은 AI가 해준다.

실전 규칙 하나(이 장에서 가져갈 유일한 것): "나는 윈도우 11을 쓰고 있어. 명령어는 PowerShell 기준으로 알려줘." — 이 한 줄이 없으면 에이전트가 맥 명령어를 던지고, 학생은 "안 되는데요"에서 멈춘다. 수요일 막힘의 상당수가 여기였을 것.

폰은 만드는 쪽이 아니라 보는 쪽이다. 오늘 만드는 건 전부 웹. 폰은 결과를 확인하는 자리에만 등장한다(P13에서 이어짐).

P23에서 회수할 말: "저는 맥이라 이렇게 치는데 윈도우는 다릅니다."

붙는 단어: 윈도우/맥 ● · PC ○ · 운영체제(OS) ○ · 아이폰/안드로이드폰 ○ — 4분.

시간을 기록하고, 남과 나눈다
실제 화면 한 줄이 한 번의 저장 — 무엇을 · 누가 · 언제 · 어느 지점(02d8931)
실제 화면 MIT 라이선스 — 되는 것 / 안 되는 것 / 지킬 것
실제 화면 무료 게임 에셋 — Kenney

기록 · Git

Git
파일명 뒤에 _v1, _v2를 붙이던 걸 자동으로 해주는 프로그램 — 다만 파일 하나가 아니라 수많은 파일과 폴더를 통째로. final_02, final_진짜최종을 없애주는 물건
커밋 “여기까지를 한 지점으로 저장” — 편집 타임라인의 마커
브랜치 본선을 안 건드리고 따로 떠서 시도 — 감독판 따로 뽑기
되돌리기 어제 상태로 통째로 복귀 — 백업 릴 꺼내기

공유 · GitHub · 오픈소스

GitHub
Git으로 관리하는 프로젝트를 인터넷에 올려두는 대표 창고 — 위 세 화면이 전부 여기다
오픈소스
남이 만든 코드를 공개해 누구나 쓰게 한 것. 공짜지만 조건은 있다 — 무료 소스 라이브러리 · 플러그인. 두 실습 모두 여기에 걸린다
라이선스
그 조건. 상업적으로 써도 되는지, 출처를 밝혀야 하는지
README 프로젝트 첫 화면의 설명문. 처음 온 사람이 읽는 글

Git이 있으면 시간 여행이 된다 — 원하는 시점으로 언제든 돌아가고, 거기서 평행세계를 만들어 볼 수도 있다. Git은 프로그램, GitHub는 서비스 — 다른 것이다. 라이선스는 작품에 쓰시는 분들에게 실제로 걸린다.

오늘 어디서P18 만세력 한 줄(오픈소스 · 라이선스) · P22 엔진 · 그림 · 소리(오픈소스 두 번째) · P28 다시 올릴 때(Git 한 마디)
P12 · 3분 · Git ○ · GitHub ○ · 오픈소스 ○ · 라이선스 ○ · 커밋 · 브랜치 · 되돌리기 · README –

Git은 오늘 이름만: "고칠 때마다 올립니다. 이 기록을 훨씬 촘촘하게 해주는 게 Git이에요. 최종_진짜최종 없애주는 물건." diff · merge · rebase는 없다.

왼쪽 화면을 손으로 훑으며: "한 줄이 한 번의 저장이에요. 누가 언제 뭘 고쳤는지가 다 남습니다."

오픈소스는 이 청중에게 무료 소스 라이브러리 · 플러그인이라고 하면 바로 붙는다. 오른쪽 Kenney 화면이 P22에서 실제로 쓸 그림·소리다.

라이선스는 한 줄만: "작품에 쓰시는 분들은 이게 실제로 걸립니다." 가운데 카드에서 초록 체크(되는 것)와 빨간 엑스(안 되는 것)만 손가락으로 짚는다. (§결정 3 — 한 줄에서 멈춘다.)

붙는 단어: Git ○ · GitHub ○ · 오픈소스 ○ · 라이선스 ○ — 3분.

프론트엔드 — 우리가 보는 화면
앞무대 네이버 첫 화면. 로고 · 검색 입력칸 · 아이콘 · 버튼 · 그림 · 글자, 그리고 이것들이 놓인 배치까지 — 눈에 보이는 전부가 프론트엔드다
naver.com 화면 갈무리 2026.09.05 · 설명 목적 인용
프론트엔드Frontend화면

관객이 보는 앞무대. 버튼·글자·그림 — 눈에 보이는 전부가 여기다.

왜 이 말을 아는가AI에게 “화면만 먼저 만들어 줘”라고 말할 수 있게 된다. 뒤는 나중에 붙인다 — 오늘 우리가 그렇게 한다.
오늘 어디서P17 빈 폴더에서 이 화면이 먼저 나온다
P13a · 1분 · 프론트엔드 ● · 화면(수업에서 쓸 말)

정의를 먼저 말하지 않는다. 화면을 띄워 놓고 “지금 보시는 이게 앞무대예요”로 시작한다.

“프론트엔드라고 하면 어렵고, 화면이라고 하면 끝납니다. 오늘은 화면이라고 부르겠습니다.”

1분. 다음 장으로.

그 화면은 사실 글자다 — HTML
실제 화면 방금 그 페이지의 소스 — 브라우저에서 view-source: 로 누구나 볼 수 있다
소스 코드Source원본 글

앞 장의 그 화면이 이 글자들이다. 브라우저가 이걸 읽어서 화면으로 그린다.

촬영 원본에 해당편집본이 화면이면, 이건 원본 릴이다. 고칠 수 있는 건 이쪽뿐.
지금 바로 해 볼 수 있다아무 웹사이트에서나 마우스 오른쪽 → 페이지 소스 보기. 남의 사이트도 다 보인다 — 원래 그렇게 만들어져 있다.
수업에서 한 말

소스 코드는 브라우저가 화면을 완성하기 전에 컴퓨터가 어떻게 이해할지 적어놓은 글입니다. 봐도 알 수 없을 테니 “아, 소스 코드가 이렇게 생겼구나” 정도만 이해하고 넘어가면 됩니다.

P13b · 2분 · 소스 코드 ○ · HTML ○ · 실제로 한 번 열어 보인다

실제로 열어 보인다. 사주앱을 띄운 채 view-source:를 붙이거나 오른쪽 클릭 → 페이지 소스 보기.

“조금 전 그 예쁜 화면이 사실은 이 글자들입니다. 브라우저가 이걸 읽어서 그려 주는 거예요.”

“그리고 남의 사이트도 다 보입니다. 숨기는 게 아니에요. 원래 이렇게 만들어져 있습니다.” — 여기서 한 번 놀란다.

한글 주석(<!-- ① 정보 입력 화면 -->)을 짚는다: “여기 한글로 메모도 적혀 있죠. 사람이 읽으라고 적어 둔 겁니다.”

백엔드 — 화면 뒤에서 일하는 쪽
Frontend화면앞무대 — 사람이 본다
←→
Backend서버 안에서 일한다 · 기억이 남는다
실제 서버실 화면 뒤의 “뒤” — 남의 컴퓨터가 실제로 놓여 있는 곳. 지난주 챗봇의 대화가 기억된 자리도 이런 데다
BalticServers data center © BalticServers.com, CC BY-SA 3.0, via Wikimedia Commons
이 방 안에서 누가 뭘 달라고 했는지가 줄줄이 기록된다 — 그게 로그다. 오늘 만드는 둘은 뒤가 없어서 슈팅게임 점수가 안 남고, 사주 정보가 내 폰에만 있다.
백엔드Backend

화면이 “보여 주는” 쪽이면, 뒤는 실제로 처리하고 기억하는 쪽이다.

있으면 되는 것로그인 · 남의 글 불러오기 · 점수 저장 · 결제 · 알림
없으면 안 되는 것새로고침하면 사라진다. 옆사람은 내 것을 못 본다
오늘 어디서P36 슈팅게임 점수가 왜 안 남는가 — 그 답이 이 장이다
P13c · 2분 · 백엔드 ● · 뒤(수업에서 쓸 말) · 오늘 만드는 둘은 뒤가 없다

상자 둘. 그 이상 그리지 않는다.

“지난주 챗봇은 뒤가 있었어요. 그래서 대화가 이어졌고 선택이 기억됐죠. 오늘 만드는 둘은 뒤가 없습니다.

“그래서 이따 슈팅게임 점수가 안 남아요. 새로고침하면 0입니다. 남기려면 뒤가 필요하고, 그때부터 다른 얘기가 됩니다.” → P36에서 회수.

사주앱도 같다 — 내 정보가 내 폰에만 있는 이유가 뒤가 없어서다. 그게 이 앱의 장점이기도 하다(개인정보가 어디로도 안 간다).

서버 — 남의 컴퓨터, 항상 켜져 있는
실제 화면 브라우저가 13번 물어봤고 서버가 13번 답했다 — 페이지 하나를 여는 데
서버Server남의 컴퓨터

항상 켜져 있으면서 달라면 주는 컴퓨터. 우리가 “사이트를 연다”는 건 남의 컴퓨터에 파일을 달라고 하는 것이다.

200이라는 숫자여기 있습니다”라는 뜻. 404는 “그런 거 없습니다”
표를 보면내 파일 12개 + 남의 서버에서 온 것 1개(cdn.jsdelivr.net, 90 kB) — 그게 만세력 계산기다
오늘 어디서P09에서 python3 -m http.server 한 줄로 내 컴퓨터를 서버로 만들었다. 그게 이것이다
남의 컴퓨터 그 컴퓨터들이 실제로 놓여 있는 방
Virginia Tech data center © Christopher Bowns, CC BY-SA 2.0, via Wikimedia Commons
P13d · 2분 · 서버 ● · 요청·응답 ○ · 200/404 ○ · 실제 요청 13건 · 근거 srl-saju-fortune.pages.dev 실측

표를 손으로 훑는다. “페이지 하나 여는데 브라우저가 13번 물어봤어요. 파일 하나하나를 따로 달라고 합니다.”

200이 뭐냐 하면 ‘여기 있습니다’예요. 못 찾으면 404고요. 그 404 맞습니다.”

jsDelivr 줄을 짚는다. “이 한 줄만 남의 서버에서 옵니다. 90킬로바이트짜리 만세력 계산기예요 — 아까 그 오픈소스요.” → P18 예고.

“그리고 P09에서 제가 친 그 한 줄, python3 -m http.server — 그게 제 노트북을 서버로 만든 겁니다. 서버가 대단한 게 아니에요.”

로컬과 배포 — 나만 보는 것과 남도 보는 것
지금내 컴퓨터localhost:8000내 노트북이 켜져 있는 동안, 나만 볼 수 있다
올린다= 배포폴더를 끌어다 놓는다
올린 뒤남의 컴퓨터Cloudflare Pages내 노트북을 꺼도 24시간 켜져 있다
이름이 붙는다= 주소P08의 그 도메인
그래서누구나○○○.pages.dev링크만 있으면 옆사람 폰에서도 열린다
배포란 무엇인가 내 컴퓨터에 있던 폴더를 남의 컴퓨터로 옮기고, 거기에 이름을 붙이는 일. 오늘은 이 두 가지가 끌어다 놓기 한 번으로 끝난다
로컬Local내 컴퓨터 안
배포Deploy올린다

localhost:8000내 컴퓨터 안이다. 옆사람 폰에서는 안 열린다 — 그 주소는 그 사람 컴퓨터를 가리키니까.

말로 하면 5분, 폰으로 보이면 20초폰에 localhost:8000을 친다 → 안 열린다. 배포한 주소를 친다 → 열린다. 그 두 화면에 다 들어 있다
오늘 어디서P27 사주앱 · P39 슈팅게임 — 두 번 다 이 장면을 만든다
P13e · 2분 · 로컬 ● · 배포 ● · 올린다(수업에서 쓸 말) · 실패 시 사전 배포본으로

이 장은 말로 설명하지 않는다. P27에서 실제로 보인다 — 폰에서 localhost를 쳐서 실패시키고, 배포 주소로 성공시킨다. 여기서는 예고만.

localhost는 ‘이 컴퓨터’라는 뜻이에요. 그래서 여러분 폰에서 치면 여러분 폰을 가리킵니다. 제 노트북이 아니라요.”

“남도 보게 하려면 남의 컴퓨터에 올려야 합니다. 그게 배포고, 오늘은 폴더를 끌어다 놓는 걸로 끝납니다.”

주소 — 이름과 번지수, 그리고 전화번호부
실제 조회 세계 여러 곳에서 srl-saju-fortune.pages.dev를 물어본 결과 — 전부 같은 번지수 172.66.44.185
주소Domain · IP · DNS빌린 이름
IP 주소172.66.44.185기계가 쓰는 번지수
도메인srl-saju-fortune.pages.dev사람이 외우는 이름
DNS이름 → 번지수바꿔 주는 전화번호부
왼쪽 화면이 말하는 것시애틀·런던·상파울루·이스탄불에서 같은 이름을 물어봤는데 같은 번지수가 나온다. 전화번호부가 전 세계에 퍼져 있다는 뜻
P13f · 2분 · 주소 ● · IP ○ · 도메인 ○ · DNS ○ · 근거 whatsmydns.net 실측 조회

순서대로 짚는다. “남의 컴퓨터에 올렸으면 찾아갈 방법이 있어야죠. 기계는 숫자로 찾습니다 — IP 주소, 번지수예요.”

“근데 사람이 172.66.44.185를 어떻게 외웁니까. 그래서 이름을 붙입니다 — 도메인이에요. 그 이름을 번지수로 바꿔 주는 전화번호부DNS고요.”

왼쪽 화면: “시애틀, 런던, 상파울루, 이스탄불에서 같은 이름을 물어봤어요. 전부 같은 번지수가 나오죠. 전화번호부가 전 세계에 퍼져 있는 겁니다.”

.pages.dev빌린 이름이에요. 내 이름을 사고 싶으면 도메인을 사서 이 번지수에 연결합니다 — 오늘은 안 합니다.”

반응형 — 같은 코드가 화면 폭에 맞춘다
같은 파일 · 같은 주소 폭이 줄면 3단 → 2단 → 1단으로 배치가 다시 잡힌다. 내용은 그대로다
Responsive Web Design © Muhammad Rafizeldi, CC BY-SA 3.0, via Wikimedia Commons
반응형Responsive폰 화면과 PC 화면

두 화면은 같은 파일이다. 주소도 같다. 폭이 달라지면 배치가 다시 잡힌다.

웹앱주소만 있으면 폰 브라우저에서 그냥 열린다 — 설치도 가입도 없다
네이티브 앱앱스토어에서 받아 설치하는 것. 심사와 등록비가 든다 — 오늘은 안 만든다
브레이크포인트배치가 바뀌는 폭의 경계. 그림 아래 1024 · 768 · 320이 그 경계다
미디어 쿼리“폭이 768보다 좁으면 이렇게” 라고 코드에 적어 둔 문장 — 반응형은 이걸로 만든다
다음 장이걸 폰 없이 노트북에서 확인하는 법
수업에서 한 말

반응형 웹사이트를 만들어 줘”라고 하면 PC·태블릿·모바일에서 다 잘 동작하는 사이트를 달라는 말이 됩니다. 그러면 에이전트가 각 플랫폼에 맞게 검사를 하게 돼요 — 요새는 에이전트가 똑똑해져서 검사까지 직접 눈으로 다 합니다.

P13g · 2분 · 반응형 ○ · 브레이크포인트 ○ · 미디어 쿼리 – · 웹앱 ○ · 네이티브 앱 – · 같은 주소·같은 파일 · 다음 장에서 개발자 도구로 이어진다

두 캡처를 나란히 놓고 한 문장. “같은 주소, 같은 파일입니다. 폭만 달라졌어요.”

웹앱이라고 부릅니다 — 주소만 있으면 폰에서 그냥 열려요. 앱스토어 안 거치고요. 오늘 만드는 게 이겁니다.”

“앱스토어에서 받는 건 네이티브 앱이고, 심사도 받고 등록비도 냅니다. 오늘은 안 만듭니다.”

→ 다음 장(개발자 도구)으로 자연스럽게 넘어간다: “그런데 폰을 매번 꺼내야 할까요? 아닙니다.”

크롬 개발자 도구 — 폰 화면을 노트북에서 본다
DevToolsElementsConsoleSourcesNetwork
iPhone SE 375 × 667
여기에폰 화면이
그대로 뜬다
개발자 도구 창 — 오른쪽 번호가 그대로 ①~④ 순서다. ② 기기 모드 · ③ 기기 목록 · ④ 회전
기기 목록 = iPhone · 375 × 812

폰을 꺼내지 않고 확인한다

앞에서 본 반응형내 노트북에서 바로 확인하는 방법이다. 배포하기 전에도 된다.

1페이지에서 F12⌘ ⌥ I
2기기 모드 Ctrl Shift M⌘ ⇧ M
3위쪽 목록에서 기기를 고른다 — iPhone·Galaxy·iPad, 또는 Responsive로 폭을 직접 끈다
4회전 아이콘으로 가로·세로를 바꾼다
주소창에 내 컴퓨터 주소(localhost)를 넣고도 된다. 폰을 꺼내지 않고, 배포하지 않고, 여기서 먼저 본다.
수업에서 한 말

개발자 도구를 열면 오른쪽에 굉장히 무섭게 생긴 창이 하나 뜹니다. 원래 이걸 사람이 다 했는데, 이제 에이전트가 직접 해줄 수 있어요. 기억하실 건 하나 — “반응형으로 만들고, 개발자 도구로 직접 테스트까지 해 줘”. 그러면 에이전트가 사이즈를 줄여 보고 늘려 보면서 만듭니다.

P13b · 3분 · 개발자 도구 ○ · 반응형(회수) · 오늘 어디서 — 사주앱·슈팅게임을 QR로 열기 전에 이 화면으로 먼저 확인한다 · P15 콘솔이 같은 창이다

이 장은 학생이 집에서 실제로 쓸 수 있는 유일한 도구다. "폰으로 확인해 보세요"는 말이 쉽지, 배포 전에는 못 한다. 그런데 이건 지금 당장 된다.

"여러분 노트북에서 F12 한 번 누르면 창이 하나 열려요. 무섭게 생겼는데 오늘은 그중 딱 하나만 씁니다 — 폰 화면처럼 보기."

시연: 슈팅게임을 띄운 채로 F12 → Ctrl+Shift+M → 기기 목록에서 iPhone 선택. 같은 페이지가 그 자리에서 폰 모양으로 바뀐다. 여기서 한 번 웃음이 나온다.

이어서: "제가 아까 QR로 보여드린 것도 이겁니다. 다만 그건 진짜 폰이고, 이건 흉내예요. 흉내로 90%는 잡힙니다. 나머지 10%는 손가락 크기하고 실제 속도라서, 그것만 진짜 폰으로 봅니다."

붙는 단어: 반응형 · 폰 화면과 PC 화면 · (덤으로) 개발자 도구가 P15 콘솔과 같은 창이라는 것 — 두 장 뒤 P15에서 회수한다. 3분.

프로그램끼리 말하는 법 — API · 열쇠 · 상자
실제 화면 Gemini API 문서 — 왼쪽 API 키, 가운데 키 만들기 버튼, 오른쪽 목차에 환경 변수 사용(권장) · 유출 대응 체크리스트
API
두 프로그램 사이에 뚫린 창구. 정해진 방식으로 요청하면 정해진 방식으로 답이 온다 — 다른 회사 서비스한테 전화 거는 것
API 키
그 창구를 쓸 자격을 증명하는 출입증. 돈이 달려 있다집 열쇠 · 은행 열쇠
.env.local
그 출입증을 넣어두는 서랍. 코드와 따로 둔다 — 상자

키를 누가 가져가면 여러분인 것처럼 행세해서 AI 모델을 불러제낀다 — 한 번 부를 때마다 삼백 원, 오백 원, 칠백 원이 뜯겨 나간다. 노출되면 원칙은 로테이션, 새로 만드는 것.

키는 상자에, 상자는 내 컴퓨터에, 상자는 절대 같이 보내지 않는다.env는 environment의 줄임말, .local은 로컬 세팅 — 키나 환경 설정을 담는 상자.
오늘 어디서P06(방금, 명세 → API) · P20 사주 키 입력(각자 자기 열쇠) · P25 슈팅 그림 교체(같은 열쇠 다시)
P14 · 3분 · API ● · API 키 ● · .env.local ●

"API 키는 키예요. 집 열쇠, 은행 열쇠와 같아요. 누가 가져가면 여러분인 것처럼 행세해서 AI 모델을 불러제낍니다. 한 번 부를 때마다 삼백 원, 오백 원, 칠백 원 돈이 뜯겨 나가요." [30:21]

화면 오른쪽 목차를 손가락으로 짚는다 — "환경 변수 사용(권장), 그리고 유출 대응 체크리스트. 만든 사람들도 이게 새어 나간다는 걸 아니까 문서에 이렇게 적어둔 거예요."

".env는 environment의 줄임말, .local은 로컬 세팅. 키나 환경 설정을 담는 상자." [34:44]

규칙 한 줄로 접는다: 키는 상자에, 상자는 내 컴퓨터에, 상자는 절대 같이 보내지 않는다.

노출되면: "원칙은 로테이션. 새로 만드는 겁니다." [33:53]⚠ 수요일 키는 실제로 노출됐고, 오늘 새 키로 왔다(§준비물).

태도 한 마디: "저는 아직도 일레븐랩스 홈페이지에서 어디서 효과음 만드는지 몰라요. 키 던지고 API · 모델 · Best Practice 찾아오라고 시킵니다." [49:00] — P15의 Best Practice로 이어진다.

문제를 볼 때 — 콘솔과 로그

P03에서 화면 옆으로 흐르던 게 이것이다.

ElementsConsoleSourcesNetworkPerformance
error만세력 계산기를 불러오지 못했습니다app.js:42
logprofile loadedapp.js:18
warn키가 없습니다app.js:57
>
실제로 찍힌 세 줄 srl-saju-fortune.pages.dev 콘솔 — 빨간 줄 하나, 노란 줄 하나, 나머지는 그냥 흔적
콘솔 / 로그
프로그램이 무슨 일을 했는지 줄줄이 남기는 흔적
에러
그중 빨간 줄. 대부분 어디가 잘못됐는지 이미 적혀 있다 — 오른쪽 app.js:42몇 번째 줄인지까지 알려준다

안 될 때 강사가 보는 곳도 여기다. 빨간 줄을 복사해서 그대로 AI에게 던지면 된다.

검색어 뒤에 Best Practice를 붙인다[찾는 것] best practice우리말로 “정석”. 좋은 정보가 그 키워드 아래 잘 모여 있다.
오늘 어디서P27 슈팅 콘솔에서 숫자 바꾸기 — 콘솔이 무서운 곳이 아니라는 걸 여기서 뒤집는다 · 그리고 뭔가 깨질 때마다
P15 · 1분 · 콘솔/로그 ○ · 에러 ○ · 챕터 회수 한 호흡 = 화면 · 서버 · 팩 · 열쇠 · 주소

P03에서 옆에 흐르던 게 이것. "안 될 때 저는 여기를 봐요. 빨간 줄 복사해서 그대로 AI한테 던지면 됩니다."

화면의 세 줄은 수요일 사주앱에서 실제로 찍힌 것이다. 빨간 줄 = 만세력 계산기를 못 불러왔다(P18에서 붙일 그 부품), 노란 줄 = 키가 없다(P14의 그 열쇠). "무슨 말인지 몰라도 됩니다. 이 줄을 그대로 복사하면 돼요."

그리고 Best Practice: "검색어에 Best Practice를 붙이세요. 우리말로 정석. 좋은 정보가 그 키워드 아래 잘 모여 있습니다." [49:31]

1분. 짧게 끊고 넘어간다.

랜드스케이프 회수(한 호흡) — 다섯 단어: 화면 · 서버 · 팩 · 열쇠 · 주소. 나머지는 이 다섯에 매달린다. 여기까지가 48분 지점이어야 한다.

이제 CLI는 사람이 아니라 AI가 쓴다
요즘 만들어지는 프로그램은 사람이 아니라 AI가 쓸 것을 먼저 생각하고 만들어진다. 화면을 새로 그리는 대신 명령어설명서 파일을 내놓는다.
Visa CLIVisa Crypto Labs · 2026.04

“Give your AI agent a Visa card.”당신의 AI 에이전트에게 Visa 카드를 주세요 — 공식 문서 첫 줄

사람이 쓰는 결제창이 아니라 AI에게 카드를 쥐여 주는 도구다. 에이전트가 유료 이미지·영상 API를 스스로 결제해서 부르고, 카드 한도까지 조회·변경한다.

건당 $10 한도 · 결제 직전 사람 승인 · 카드번호는 내 PC에 저장 안 됨

같은 주소, 다른 페이지visacli.sh

“This content is for AI agents reading this page.
Human visitors see the marketing site above.”

비자 사이트에는 사람이 보는 화면 아래에 “이 내용은 이 페이지를 읽는 AI 에이전트용”이라는 구획이 따로 들어 있다.

같은 주소인데 사람에겐 광고를, AI에겐 설명서를 준다. 웹사이트가 손님을 두 종류로 나누기 시작했다.

Playwright CLIMicrosoft · 2026.01

웹을 자동으로 조작하는 도구인데, 필요 조건 항목에 사람이 없다 — “클로드 코드, 깃허브 코파일럿, 또는 다른 코딩 에이전트”.

“Token-efficient. Does not force page data into LLM.”화면을 보여주는 것보다 명령어가 훨씬 싸고 정확해서

최근 한 달 내려받기 326만

MCPAnthropic · 2024.11 → 리눅스 재단 2025.12

AI가 바깥 도구를 부르는 공용 규약. AI와 도구를 잇는 표준 콘센트라고 보면 된다.

2025년 12월, 아마존·구글·마이크로소프트·오픈AI·앤트로픽이 같은 재단에 이 규격을 함께 넘겼다. 서로 경쟁하면서도 콘센트 규격만은 통일한 것이다.

공개 서버 1만 개↑ · 관련 도구 월 내려받기 2억 건↑ · AGENTS.md 채택 6만 개↑ 프로젝트

지금까지는 우리가 프로그램 쓰는 법을 배웠다. 이제는 프로그램이 “AI가 나를 어떻게 부를까”를 먼저 생각하고 만들어진다.
P09b · 4분 · CLI(회수) ○ · MCP ○ · 근거 visacli.sh · github.com/microsoft/playwright-cli · anthropic.com — 수치는 npm 레지스트리 실측(2026.08)

앞 장 마지막 줄 “AI가 대신 칠 수 있다”에서 그대로 넘어온다.

“아까 제가 터미널에 네 줄 쳤죠. 그거 요즘은 제가 안 칩니다. AI한테 시켜요. 그런데 더 재밌는 건, 회사들이 그걸 알고 도구를 그렇게 만들기 시작했다는 거예요.”

비자 이야기를 먼저. “비자가 작년 봄에 낸 게 결제창이 아니라 명령어예요. 문서 첫 줄이 ‘당신의 AI 에이전트에게 비자 카드를 주세요’입니다.” — 여기서 웃음이 한 번 나온다.

두 번째 칸이 이 장의 하이라이트다. “비자 홈페이지를 열면 우리는 광고를 봅니다. 그런데 그 페이지 안에 ‘여기 아래는 이 페이지를 읽는 AI를 위한 것’이라고 적힌 구획이 따로 있어요. 같은 주소인데 손님을 둘로 나눈 겁니다.” → 이 청중에게 가장 오래 남는 장면.

마이크로소프트 칸에서는 이유를 짚는다: 그래픽 화면은 사람 눈을 위해 만들어졌고, AI가 그걸 이해하려면 스크린샷을 해석해야 해서 느리고 비싸고 자주 틀린다. 명령어는 짧고 모호하지 않다.

MCP는 이름만. “표준 콘센트” 한 마디면 된다. 숫자는 읽지 말고 손으로만 짚는다.

마무리 문장을 그대로 읽는다. 필요하면 현장 언어로 한 번 더: “내가 툴을 익히는 속도보다, 툴이 AI에게 맞춰지는 속도가 더 빠릅니다.

붙는 단어: CLI(회수) · MCP ○ — 4분.

오픈소스의 시작 — 고칠 수 없는 프로그램을 만난 1980년
리처드 스톨먼Richard Stallman
MIT 인공지능 연구소 연구원. GNU 프로젝트자유소프트웨어재단(FSF)을 시작한 사람.
사진 Patafisik / CC BY-SA 4.0 / Wikimedia Commons
“언론의 자유(free speech) 할 때의 free이지, 공짜 맥주(free beer) 할 때의 free가 아니다.”원문 “think of ‘free’ as in ‘free speech,’ not as in ‘free beer.’” — gnu.org
수업에서 한 말

그 시절 소스 코드는 된장국 레시피 같았어요 — “다시다 좀 쳐 봐, 생마늘 넣어 봐.” 60~70년대까지 엔지니어끼리, 기업끼리 그렇게 주고받았죠. 80년대에 큰 회사들이 권리를 걸어 잠그기 시작했고, 이 아저씨는 그게 싫었던 겁니다.

1980년, MIT 인공지능 연구소에 새 프린터가 들어옵니다. 제록스 9700. 종이가 자주 걸렸는데, 걸렸다는 사실을 알 방법이 없었습니다. 스톨먼은 이전 프린터에서는 그 알림 기능을 직접 만들어 붙였던 사람입니다. 이번에는 그럴 수 없었어요 — 소스코드(프로그램의 설계도. 사람이 읽고 고칠 수 있는 원본 텍스트)를 주지 않았기 때문입니다.

그 코드를 가진 카네기멜런의 한 교수를 찾아갑니다. 그리고 거절당해요. 이유는 “제록스에 안 주기로 약속했다” — 오늘날의 비밀유지계약(NDA)입니다. 그가 아무 말 없이 돌아선 그 일이, 이 뒤의 40년을 만듭니다.

1983.09.27유즈넷(초창기 인터넷 게시판)에 GNU 프로젝트를 공개 선언 — “완전히 자유로운 운영체제를 만들겠다”
1985.03GNU Emacs 첫 배포(3.20)와 GNU 선언문 — 1976년 자기가 만들었던 편집기를, 이번엔 아무도 잠글 수 없게 처음부터 다시 썼다
1985.10.04자유소프트웨어재단(FSF) 설립
1989GPL 1.0 — 카피레프트를 법으로 못 박은 첫 라이선스 (2.0 = 1991.06 · 3.0 = 2007.06)
카피레프트 copyleft

저작권(copyright)을 뒤집은 말장난입니다. 저작권을 없애는 게 아니라, 저작권을 이용해서 자유를 강제하는 겁니다. “가져다 마음대로 고쳐 써라. 대신 고친 것도 똑같이 열어라.” 영화로 치면 — 이 시나리오 마음대로 각색해도 되는데, 각색본도 남이 각색할 수 있게 공개해야 한다는 조건입니다.

자유 0쓸 자유어떤 목적으로든 마음대로 돌린다
자유 1뜯어볼·고칠 자유소스코드 접근이 전제 조건
자유 2나눠줄 자유그대로 복사해 남에게 준다
자유 3고친 걸 나눠줄 자유내 개조본도 남에게 준다
P15b · 4분 · 소스코드 ● · 오픈소스 ● · 카피레프트 ○ · 라이선스 ○ · 사진은 CC BY-SA — 크레딧 줄을 지우지 않는다 · 근거 gnu.org

사진 한 장과 일화 하나로 4분. 연도를 외우게 하는 장이 아니다. “고치고 싶은데 고칠 수가 없었다”는 감정 하나만 남기면 된다.

읽어도 되는 문장 — “1980년, MIT 인공지능 연구소에 새 프린터가 들어왔습니다. 종이가 자주 걸렸는데 연구소가 다른 층이라, 한참 뒤에 가보면 아무것도 안 뽑혀 있는 거죠. 스톨먼은 이전 프린터에서는 이 문제를 직접 고쳤던 사람입니다. 그런데 새 프린터는 그게 안 됐어요. 설계도를 안 줬거든요.”

“코드를 가진 교수를 찾아갑니다. 그리고 거절당해요. ‘제록스에 안 주기로 약속했다.’ 요즘 말로 NDA입니다. 당시엔 이게 소프트웨어 업계에 막 등장한 새 관행이었어요.”

⚠ 교수 이름(로버트 스프롤)은 정황 근거만 있고 1차 문헌이 단정하지 않는다 — “카네기멜런의 한 교수”로만 말한다.

free 두 가지 뜻은 말로 한 번 더 풀어 준다. “돈 받고 팔아도 됩니다. 문제는 값이 아니라 통제권이에요.” 자유 4가지는 번호가 0번부터 시작한다는 것 자체가 이 동네 문화라고 한 마디 붙이면 웃는다.

전환 — “여기까지는 한 사람의 원칙 이야기입니다. 이게 어떻게 산업이 됐을까요.”

사진 저작권: Patafisik, CC BY-SA 4.0, via Wikimedia Commons. 크레딧 줄은 법적 의무라 화면에 남겨 둔다.

성당이 아니라 시장 — 열어 놓고 만드는 방식이 이겼다
리누스 토르발스Linus Torvalds
1991년 헬싱키의 대학생. 리눅스 커널을 만들었고, 2005년에는 Git도 직접 만든다.
사진 Krd 촬영 / Von Sprat 크롭
CC BY-SA 4.0 / Wikimedia Commons
에릭 S. 레이먼드Eric S. Raymond
1997년 『성당과 시장』을 발표해 개발 방식 자체를 논쟁으로 만들었다. 1998년 OSI 공동 설립·초대 회장.
사진 jerone2 원본 / Bilby 2차 저작
CC BY-SA 2.0 / Wikimedia Commons
크리스틴 피터슨Christine Peterson
1998년 2월, “오픈소스(open source)”라는 이름을 떠올린 사람. 당시 포어사이트 연구소 상임이사.
사진 Randy Stewart
CC BY-SA 2.0 / Wikimedia Commons
1991.08.25헬싱키의 한 대학생이 게시판에 글을 올린다 — “그냥 취미로 만드는 거고, GNU처럼 크고 전문적이진 않을 것” · 그게 리눅스(GNU = “GNU is Not Unix” — 풀면 다시 GNU가 나오는 재귀 언어유희. 재귀는 프로그래밍의 흔한 패턴)
1997.05.27『성당과 시장』 — 성당은 소수의 장인이 문 닫고 몇 년을 짓고, 시장은 공개된 채로 시끄럽게 자란다 · “눈이 충분히 많으면 모든 버그는 얕다”
1998.01.22넷스케이프가 자기 브라우저의 소스코드를 공개하겠다고 발표한다 — 당시 업계에 충격
1998.02캘리포니아 팰로앨토 회의에서 이 물건에 “오픈소스”라는 새 이름이 붙는다 (회의 날짜는 출처마다 2월 3일·5일로 갈린다) → 그달 말 OSI 설립
1998.03.31 →
2004.11.09
mozilla.org 소스 공개 → 파이어폭스 1.0 · 넷스케이프라는 회사는 사라졌지만, 공개된 코드는 살아남아 브라우저 독점을 깼다
이름을 바꾼 이유

“free software”는 기업 임원에게 ‘공짜’로 들리고, 철학·정치 운동처럼 들렸습니다. 같은 물건에 붙인 다른 이름이에요. 스톨먼 쪽은 자유를, 레이먼드 쪽은 잘 돌아가는 개발 방법을 앞세웠고, 두 진영은 지금도 사이가 좋지 않습니다.

P15c · 4분 · 오픈소스 ● · 리눅스 ○ · 커널 –(이름만) · 명명 날짜는 “1998년 2월”까지만 · 사진 3장 CC BY-SA · 근거 opensource.org/history

사진 셋으로 사람 이름을 붙여 두고, 아래 연표는 손가락으로 짚으며 넘긴다. 4분 안에 다섯 줄이다 — 한 줄에 45초.

성당 vs 시장은 영화 비유로 바꾸면 바로 붙는다. “성당식은 완성될 때까지 아무에게도 안 보여주는 감독판입니다. 시장식은 러프컷을 매일 올려놓고 누구나 코멘트를 달게 하는 방식이에요. 상식적으로는 전자가 좋을 것 같은데, 소프트웨어에서는 후자가 이겼습니다.”

“눈이 충분히 많으면 모든 버그는 얕다” — “시사회에 100명이 앉아 있으면 편집 실수는 반드시 누군가 잡아냅니다.”

순서가 핵심이다. 넷스케이프가 먼저 열었고(1월), 이름은 그 뒤에 붙었다(2월). 회사가 실용적인 사업 판단으로 코드를 여는 시대가 오자 “다른 이름이 필요하다”가 된 것이다.

⚠ 명명 회의 날짜는 OSI 공식(2/3)과 피터슨 본인 회고(2/5)가 갈린다 — “1998년 2월”로만 말한다. 또 피터슨이 직접 제안한 게 아니라, 토드 앤더슨이 회의 중 그 표현을 끼워 넣어 퍼뜨렸다는 대목까지는 여유 있을 때만.

⚠ 피터슨 사진은 원본이 512×542로 작아 확대돼 흐리다. 그래서 셋 중 가장 작게 배치했다 — 화질 얘기는 굳이 하지 않는다.

전환 — “그래서, 지금 그게 어디까지 왔을까요.”

지금 어디에 있고, 누가 떠받치는가
500
TOP500 슈퍼컴퓨터가 한 대도 빠짐없이 리눅스
2017.11 이후 계속
92%
서버 운영체제가 파악되는 웹사이트 중 유닉스 계열
W3Techs 2026.09.04
1.8억
GitHub 개발자 — 1초에 한 명씩 새로 들어온다
GitHub Octoverse 2025
436만
npm에 올라와 있는 자바스크립트 부품
2026.09.05 조회
리눅스 커널 4,098만 줄 · 안드로이드는 리눅스 커널 위에서 돈다 — 활성 기기 30억 대(구글 공식 발표, 2021) · PyPI 파이썬 부품 88.7만 개 · GitHub 저장소 6.3억 개
떠받치는 쪽은 위태롭다
left-pad2016.0311줄짜리 부품 하나가 사라지자 리액트·바벨·웹팩 빌드가 줄줄이 멈췄다. 메타·페이팔·넷플릭스가 영향을 받았고, 복구에 약 두 시간이 걸렸다.
xz-utils2024.03사실상 한 사람이 관리하던 압축 도구. 3년에 걸쳐 신뢰를 쌓은 가짜 협력자가 전 세계 리눅스 서버의 뒷문을 열 뻔했다. 접속이 평소보다 0.5초 느린 걸 이상하게 여긴 엔지니어 한 명이 막았다.
60%Tidelift 2024메인테이너 조사에서 무보수라고 답한 비율. 앞선 조사에서는 58%가 관리하던 프로젝트를 그만뒀거나 그만둘까 생각했다고 답했다.
영화 쪽은 이미 이 위에 서 있다
『플로우』2025.03무료 3D 툴 블렌더만으로 만든 첫 오스카 수상작(장편애니메이션상). 제작비 €3.5M — 같은 부문 『와일드 로봇』은 US$78M이었다. 그 블렌더 자체가 2002년 망한 회사의 소프트웨어를 사용자들이 €100,000를 모아 사서 푼 결과물이다.
ASWF2018.08오스카를 주는 그 아카데미가 리눅스 재단과 함께 세운 아카데미 소프트웨어 재단. 설립 근거는 영화 산업의 약 84%가 이미 오픈소스를 쓰고 있다는 조사 결과였다. OpenEXR(HDR 이미지) · OpenColorIO(색 관리) · OpenVDB(연기·물·불)가 여기 있다.
FFmpeg2000.12유튜브·VLC·크롬·블렌더가 안에 넣어 쓰는 영상 변환 엔진. NASA는 화성 탐사선에 넣었다. 이름은 몰라도 매일 쓰고 있다.
P15d · 5분 · 라이선스 ● · 패키지·부품 ● · 메인테이너 ○ · 다빈치 리졸브는 오픈소스가 아니다 — 색보정은 OpenColorIO로 · 수치 기준일 2026.09.05

세 덩어리다. 위 = 얼마나 크냐, 가운데 왼쪽 = 얼마나 위태롭냐, 가운데 오른쪽 = 왜 당신 얘기냐, 아래 = 오늘 만들 앱 안에 이미 들어 있다. 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 — 암벽등반으로 이해하는 버전 관리
2005.04.03비트키퍼 무료 사용권이 끊기자 토르발스가 직접 만들기 시작한다 — “거장들은 생각이 다르다. 사야겠다가 아니라 만들어야겠다
2005.04.07착수 나흘 만에 Git이 Git 자신의 소스코드를 관리하기 시작
2008.04.10GitHub 공개 — Git을 쓰는 사람들이 모이는 광장
2018.10.26마이크로소프트가 GitHub를 75억 달러에 인수 완료
확보물에 로프를 거는 순간 = 커밋
아래로 이어진 로프 전체 = 히스토리 · 말뚝 간격 = 커밋 간격
같은 벽의 다른 루트 = 브랜치
암벽등반Git
벽을 오른다작업을 진행한다
확보물(말뚝)을 박고 로프를 건다커밋 — “여기까지 됐다”고 못을 박는다
떨어져도 마지막 말뚝까지만 떨어진다되돌리기 — 마지막 커밋 지점으로
아래로 이어진 로프 전체히스토리(로그) — 지나온 자리가 다 남는다
같은 벽의 다른 루트브랜치 — 원본을 건드리지 않고 딴 길을 시도
두 루트가 정상에서 만난다머지 — 갈라졌던 작업을 하나로 합친다
실제 화면은 이렇게 생겼다 — 메시지 · 작성자 · 날짜 · 해시가 한 줄씩 아래로 쌓인다. “Merge pull request”라고 적힌 줄이 두 루트가 만난 자리다.
P15e · 5분 · Git ● · 커밋 ● · 되돌리기 ● · 히스토리 ● · 브랜치 ○ · 머지 ○ · GitHub ○ · 표를 먼저 세우고 사진으로 확인시킨다 — 명령어는 치지 않는다

이 장이 이 챕터의 목적지다. 비유가 주인공이고 연혁은 배경이다 — 위 네 칸은 15초에 훑고, 표와 사진에 4분을 쓴다.

강사 대사 — “커밋을 자주 박을수록 떨어질 때 덜 떨어집니다. 말뚝을 10미터마다 박으면 10미터를 떨어지고, 1미터마다 박으면 1미터만 떨어져요. final_최종_진짜최종이 사라지는 이유가 이겁니다. 파일 이름으로 버전을 관리할 필요가 없어져요.”

사진 셋을 순서대로 짚는다 — ① 손이 퀵드로를 거는 순간이 커밋. ② 로프가 아래로 계속 이어지고 말뚝마다 걸려 있는 게 히스토리. 오른쪽 확대 컷에서 말뚝 간격을 짚으면 “자주 박아라”가 한 번에 붙는다. ③ 아래에서 같이 출발해 중간에 갈라지는 두 루트가 브랜치다.

“분산”은 한 문장이면 된다 — “모든 참여자가 전체 역사를 통째로 갖고 있습니다. 회사 서버가 날아가도 아무나 한 명의 노트북으로 완전히 복구돼요. 인터넷이 끊겨도 혼자 계속 기록할 수 있고요.”

GitHub 한 줄 정리 — “Git은 도구고, GitHub는 그 도구를 쓰는 사람들이 모인 광장입니다. 2018년에 마이크로소프트가 그 광장을 75억 달러에 샀어요. 한때 ‘오픈소스는 암이다’라고 했던 그 회사가요.”

오른쪽 GitHub 캡처는 겁을 주려고 띄우는 게 아니다. “한 줄에 하나씩, 누가·언제·무엇을 고쳤는지가 적혀 있을 뿐입니다. 여러분이 오늘 만들 앱도 이렇게 남습니다.”

⚠ 라이브로 git 명령을 치지 않는다. 이 장은 개념만이고, 실제 커밋·배포는 뒤 챕터에서 결과 화면으로만 보인다.

Git을 시나리오에 쓴다면 — 갈림길을 브랜치로 탐색한다
에이전트와의 대화는 이렇게 들린다
에이전트이 프로젝트를 진행하는데 버전 관리를 하고 싶다고 하셨죠. 제가 Git을 세팅할게요.
에이전트여기서는 커밋을 해야 할 것 같은데요.
이렇게 알아들으면 된다말뚝 박읍시다.” 여기까지 박아 두고, 더 올라가다 떨어져도 여기까지만 떨어지게.
수업에서 한 말

커밋이란 말을 기억해 주세요. 커밋은 말뚝 박는 겁니다. 직접 커밋할 일은 없겠지만, 에이전트가 “커밋할까요?” 하면 “뭔 소리야” 하지 마시고 말뚝을 박겠다는 말로 이해하시면 됩니다.

그리고

버전 관리는 다 되돌리는 것을 전제로 짜여 있습니다. 그러니까 너무 무서워할 필요 없어요.

시나리오의 절체절명 — 주인공이 결정하는 지점
커밋주인공이 결단하는 장면까지 썼다여기서 말뚝을 박고, 방향마다 브랜치를 새로 만든다
브랜치 A악에 굴복한다
브랜치 B악에 저항한다
브랜치 C아예 다른 형태로 돌아간다
되돌리기이 방향으로 써 보자 → 거기서 커밋 → 아니면 아까 그 브랜치로 다시 돌아간다. 원본은 그대로 남아 있다
머지 — 갈라진 것을 합친다웹사이트의 다크 모드를 만들 때, 원래 만들던 경로 위에 새 브랜치를 내고 거기서 구현한 다음 원래 브랜치에 머지하면 기능이 추가된다. 스토리텔링 예시에는 조금 덜 맞지만, 브랜치는 원래 이런 용도로 만든다.

버전 관리는 코드에만 쓰는 게 아니다. 시나리오·스토리텔링 작업에도 분명히 쓸 수 있다.

P15f · 3분 · 커밋 ●(회수) · 브랜치 ● · 머지 ○ · 근거 2026.09.05 전사 [00:45:06]~[00:48:34] — 강사가 든 시나리오 예시 그대로

원고에 없던 장(2026.09.08 추가). 토요일 Git 설명 중 이 청중(작가·영화인)에게 가장 가까웠던 대목 — 시나리오의 갈림길을 브랜치로 탐색한다.

"주인공이 어느 지점에 가서 절체절명의 순간에 결정을 하는 상황이 항상 생기지 않습니까. 각자의 방향 탐색을 할 때 커밋을 거기서 받고 브랜치를 새로 만들어 보는 겁니다. 악에 굴복하는 브랜치가 있을 수도 있고, 악에 저항하는 브랜치가 있을 수 있고." [00:46:36]

FFmpeg — 이름은 몰라도 매일 쓰고 있다
영상·오디오를 변환·자르기·합치기 하는 명령줄 도구 하나. 넷플릭스가 자사 기술블로그에서 직접 밝혔고, 크롬(Chromium)은 소스 안에 FFmpeg를 포함한다. 그런데 아무도 이름을 모른다.
수업에서 한 말

소수의 인원이 관리하고 있고, “이 프로그램이 무너지면 영상 산업 전체가 무너진다”는 말이 돌 정도예요. 자르기 · 코덱 변환 · 해상도 조정 — 영상 편집에서 하는 일 대부분이 됩니다. 기능을 다 소개하긴 힘드니 FFmpeg라는 키워드만 기억해 두세요.

에이전트에게: “내가 프로 작업할 때 FFmpeg를 어떻게 쓸 수 있을지 알려줘” — 이렇게 한 번 대화해 보면 쓸 수 있는 것들이 많이 나온다.
공식ffmpeg.org
무엇영상·소리 파일을 다른 형식으로 바꾸고, 자르고, 붙이고, 자막을 얹는 도구. 화면이 없다 — 명령어 한 줄로 쓴다
영화 쪽에서프리미어·다빈치가 뒤에서 하는 일의 상당 부분이 이런 처리다. FFmpeg는 그걸 사람 없이 시킬 수 있다 — 100개 파일을 한 번에
조건기본 LGPL 2.1+, 일부 부품을 켜면 GPL 2+가 전체에 적용된다. 상용 별도 라이선스는 없다 — 상업 배포 시 반드시 확인
예: 영상에서 소리만 뽑기
ffmpeg -i 촬영본.mp4 -vn 소리.mp3
P15b · 3분 · 오픈소스(회수) ○ · CLI(회수) ○ · 그림은 유명한 “의존성 탑” 밈의 구조를 옮긴 것 · 근거 ffmpeg.org

이 장의 목적은 하나다 — “오픈소스가 어디 있냐”는 질문에 대한 가장 강한 답. 이 방에 있는 모든 사람이 오늘 아침에도 FFmpeg를 썼다. 유튜브를 봤으니까.

왼쪽 그림을 가리키며: “위에 있는 게 우리가 아는 회사들이고, 저 밑에 가느다란 기둥 하나가 FFmpeg입니다. 2000년부터 자원봉사로 유지되고 있어요.”

→ 앞 장(오픈소스가 위태롭다 · left-pad · xz)과 바로 이어진다. “아까 그 얘기가 이겁니다.”

영화인용 연결: “프리미어나 다빈치가 뒤에서 하는 일의 상당 부분이 이런 처리예요. 차이는 FFmpeg는 사람 없이 시킬 수 있다는 것. 파일 100개를 한 번에 돌립니다.”

명령어 한 줄을 읽어 준다 — -i는 입력, -vn은 “영상 빼고”. “이게 CLI예요. 아까 본 그 창에 이 한 줄을 칩니다.”

유튜브는 말하지 마라. 공식 확인 문서를 못 찾았다(떠도는 건 개인 블로그 정황뿐). 넷플릭스는 확인됨 — 자사 기술블로그에 “an FFmpeg-based filter that runs together with other video transformations”라고 적혀 있다. 크롬도 소스 트리에 FFmpeg를 포함한다. 이 둘까지만.

yt-dlp — 주소 하나로 영상을 받아 오는 도구
1,363지원 사이트유튜브·인스타그램·틱톡·트위치·네이버TV… 사이트마다 따로 만든 해석기1,731개 들어 있다
189kGitHub 스타포크 16.4k · 커밋 약 24,000 · 최신 릴리스 2026.08.19
막히면 어떻게 넘어가나
브라우저인 척한다--impersonate — 크롬·엣지·사파리가 접속할 때 남기는 지문까지 흉내 낸다. 서버 눈에 사람이 쓰는 브라우저로 보인다
내 로그인을 빌린다--cookies-from-browser — 내 브라우저에 이미 있는 로그인 쿠키를 그대로 쓴다. 로그인해야 보이는 영상에 쓴다
다른 창구로 들어간다유튜브는 웹·아이폰·안드로이드·TV용 창구가 여럿이다. 하나가 막히면 다른 창구로 묻는다 — 창구에 따라 출처 증명(PO 토큰)을 요구한다
천천히 묻는다--sleep-requests — 요청 사이에 쉰다. 기계처럼 몰아치지 않는 것이 가장 확실한 우회다
도구가 자유롭다고 대상 영상까지 자유로운 건 아니다. 저작권과 각 사이트 이용약관은 그대로 적용된다 — 내 자료 백업·자막 확인·연구 범위에서 쓴다
공식github.com/yt-dlp/yt-dlp
무엇영상 주소 하나를 주면 영상·자막·썸네일을 받아 온다. 받은 뒤 합치고 자르는 일은 FFmpeg가 한다 — 둘은 짝이다
조건Unlicense — 사실상 퍼블릭 도메인. 저작권 표기 의무도 없다
수업에서 한 말

어떤 프로젝트를 하든 리소스 모으는 게 맨 처음 하는 일이잖아요. yt-dlp를 쓰면 굉장히 빠르게 모을 수 있어요 — 스레드(Threads)만 방어책이 있어 잘 안 됩니다.

클로드 코드에는 이렇게 말한다
이 유튜브 영상 받아서 한국어 자막 뽑고
앞 30초만 잘라 줘
에이전트가 알아서 치는 두 줄
yt-dlp --write-auto-subs --sub-langs ko --convert-subs srt "https://youtu.be/..."
ffmpeg -i 받은영상.mp4 -t 30 앞30초.mp4
P15c · 3분 · 오픈소스(회수) ○ · CLI(회수) ○ · FFmpeg와 짝 · 근거 github.com/yt-dlp/yt-dlp · supportedsites.md 실측 2026.09.05

앞 장(FFmpeg)에서 바로 이어진다. "FFmpeg가 영상을 다루는 도구라면, 이건 영상을 가져오는 도구예요. 둘은 거의 항상 같이 씁니다."

숫자 두 개만 짚는다: "1,363개 사이트를 지원합니다. 사이트마다 화면 구조가 다르니까 해석기를 1,731개 따로 만들어 뒀어요. 이걸 자원봉사로 유지합니다."

우회 이야기는 흥미롭게, 그러나 짧게. "사이트들이 막으려고 하죠. 그래서 브라우저인 척하고(--impersonate), 내 로그인을 빌리고, 유튜브처럼 창구가 여럿이면 다른 창구로 물어봅니다. 재밌는 건 가장 확실한 방법이 천천히 묻는 것이라는 거예요."

반드시 한 줄 붙인다: "도구가 자유롭다고 남의 영상까지 자유로운 건 아닙니다. 저작권과 약관은 그대로예요." — 이 말을 빼면 안 된다.

마무리는 클로드 코드 예시로. 오른쪽 두 상자를 나란히 짚는다. "제가 친 건 위에 있는 한국말 한 문장이고, 아래 두 줄은 에이전트가 알아서 친 겁니다. 오늘 배운 게 다 여기 있어요 — CLI, 오픈소스 도구 두 개, 그리고 그걸 사람 말로 시키는 것."

3분.

Vercel — 만든 것을 올리는 또 하나의 방법
공식vercel.com
무엇만든 웹페이지를 올려서 주소를 받는 서비스. 오늘 쓰는 Cloudflare Pages와 같은 종류
Hobby $0 — 다만 개인·비상업용만(공식 문구). 월 전송 100GB 상한
언제 쓰나Next.js 같은 서버가 필요한 사이트를 올릴 때 편하다. 오늘 우리가 만든 건 화면만 있는 정적 사이트라 어느 쪽이든 된다
수업에서AI가 이미 학습하고 있어서 “나 배포하고 싶어” 하면 선택지에 Vercel 이름이 나온다. 회원가입하고 “뭘 해야 돼?” 물어보면 사람이 할 것을 AI가 알려준다 — 그걸 하나씩 차근차근
같은 회사가 만든 것v0.app
무엇말로 설명하면 웹페이지 화면을 그려 주는 도구. 코드까지 같이 나온다
왜 여기 있나오늘 우리가 한 것 — 자연어로 명세를 적고 화면이 나오는 것 — 을 브라우저 안에서만 해 볼 수 있다. 설치가 없다
집에서터미널이 부담스러우면 여기서 먼저 감을 잡아도 된다
오늘 배포는 Cloudflare Pages로 한다. 이 강의 자료 사이트 자체가 여기 배포돼 있다 — 무료이고 정적 사이트는 용량 무제한이며 Claude Code가 잘 다루는 도구다. 무료 기준으로 Cloudflare는 상업적 사용에도 제한이 없고, Vercel Hobby는 개인·비상업용만이다. 작품을 파는 쪽이면 이 차이가 실제로 걸린다.
P15c · 2분 · 배포·호스팅(회수) ● · 오늘 배포는 Cloudflare Pages · 근거 vercel.com 요금 페이지

오늘 쓰지 않는 것을 왜 보여주나 — 집에 가서 검색하면 이 두 이름이 계속 나오기 때문이다. “같은 종류구나”만 알면 헷갈리지 않는다.

올리는 곳은 하나가 아니에요. 오늘은 Cloudflare Pages를 쓰는데, Vercel도 똑같이 폴더를 올리면 주소를 줍니다. 개인용은 둘 다 공짜예요.”

v0는 이 청중에게 실제로 유용하다 — 설치가 없다. 브라우저에서 말로 설명하면 화면이 나온다. “터미널이 아직 부담스러우시면 여기서 먼저 감을 잡으셔도 됩니다.”

차이를 한 줄로: Vercel은 서버가 필요한 사이트에 강하고, Cloudflare Pages는 화면만 있는 사이트에 간단하다. 오늘 만든 건 후자라 어느 쪽이든 된다.

집에 가서 열어 볼 것들
P15d · 2분 · 화면에 띄우고 손으로 훑기만 — 하나씩 설명하지 않는다 · 이 장은 단톡방 배포용

읽어 주지 않는다. 손으로 훑으며 “이 여덟 개는 집에서 열어 보세요. 단톡방에 올려두겠습니다.”

세 개만 짚는다 — Cloudflare Pages(오늘 쓰는 것) · Replit(터미널이 부담스러운 분) · Kenney(오늘 게임 그림이 여기서 왔다).

Hugging Face는 이 청중 중 영상·음성 생성에 관심 있는 분에게 다음 단계다. “모델이 뭐가 있는지 직접 보실 수 있어요.”

이 장은 안전망이다. 오늘 못 따라온 분도 이름 여덟 개는 가져간다.

실습 1

사주 웹사이트
바이브 코딩

조건을 하나씩 좁혀 간다 — 한 번에 다 말하지 않는다
1생년월일을 넣으면 사주 여덟 글자가 나오는 웹페이지를 만들어 줘. 폰에서 볼 거야.먼저 가장 단순한 한 문장. 여기서 뼈대가 나온다
2잠깐. 사주 계산은 네가 하지 마. 음력하고 절기 때문에 자주 틀려. 이미 공개된 만세력 라이브러리가 있는지 먼저 찾아보고, 한국 기준으로 맞는 걸로 골라서 그걸 써 줘. 라이선스도 같이 알려 줘.에이전트에게 온라인 조사를 시킨다 — 이 한 줄이 이 실습의 핵심
3내가 넣은 정보는 내 폰에만 남게 해 줘. 서버는 만들지 마. 새로고침해도 안 지워지게.제약을 건다 — 만들지 말 것을 먼저 정한다
4여덟 글자를 누르면 한자 뜻이 나오게. 이건 AI 부르지 말고 표로 미리 넣어 둬 — 22자면 되잖아.비용이 드는 곳과 안 드는 곳을 나눈다
5이제 AI가 문장으로 풀어 주는 부분. 키는 쓰는 사람이 자기 걸 넣게 해 줘. 내 키를 심지 마.열쇠의 주인을 정한다
6키가 없어도 여덟 글자하고 한자 뜻까지는 나와야 해. 거기서 막히면 안 돼.실패해도 쓸모가 남게 — 가장 중요한 제약
7폰 세로 화면 기준으로 다듬고, Cloudflare Pages에 올려 줘. 주소 나오면 알려 줘.배포까지 시킨다
기술 용어가 한 줄도 없다. 적은 것은 무엇을 · 무엇을 하지 말 것 · 무엇을 찾아볼 것뿐이다. — 수업 당일에는 이 흐름을 마이크로 한 번에 불렀다. 그 말 그대로가 두 장 뒤에 있다.
P16 · 4분 · 명세를 소리 내어 읽는다 · 2번(온라인 조사 시키기)이 이 장의 핵심 · 현장 제작 경계 — P17까지 라이브, P18 "한 줄 붙이기"까지 되면 최상

일곱 줄을 소리 내어 읽는다. 다 읽고 나서: "여기 기술 용어가 한 줄이라도 있었습니까. 없어요."

2번이 이 장의 핵심이다. "제가 '사주 계산 네가 하지 마'라고 했죠. AI는 음력하고 절기에서 자주 틀립니다. 그래서 직접 하지 말고 찾아보라고 시킨 거예요. 요즘 에이전트는 인터넷을 뒤져서 뭐가 있는지 보고, 골라서, 붙입니다. 라이선스까지 확인해서요."

→ P18에서 그 결과(@fullstackfamily/manseryeok, MIT, 한국천문연구원 기반)를 실제 화면으로 보여준다. 여기서 시킨 것이 저기서 나온다.

6번을 짚는다. "키가 없어도 여덟 글자는 나와야 한다 — 이게 제일 중요한 제약이에요. 오늘 60분 중에 키 발급까지 가는 분은 몇 안 됩니다. 그래도 다 쓸 수 있어야 하니까요."

"사람이 정할 건 대상·경험·목표·금지예요. 나머지는 도우미가 합니다." [47:05]

"6개월 전이면 훨씬 세부적으로 정의해야 한다고 했을 텐데, 지금은 생각하는 바를 자연어로 최대한 뱉어 보는 것이 더 중요해요." [18:32]

⚠ 현장 제작 경계 — P17까지 빈 폴더에서 라이브. 그 뒤는 완성본. 4분.

실습 전에 — 앱으로, 모델을 고르고, 마이크로 말한다
01 · 어디서
Claude Code는 으로
웹에서 시키면 만들기는 한다. 하지만 의도한 대로 만든 것이 아니다. 앱을 설치해서 쓴다.
02 · 무엇으로
모델과 Effort
Opus · Sonnet · Haiku 중 Sonnet — 복잡한 걸 만드는 게 아니니까. Effort는 기본값(높음). 오른쪽 아래 사용 가능한 토큰량을 확인한다.
03 · 어떻게
마이크로
강사는 요즘 타자보다 마이크를 더 쓴다. 논리 구조(워크플로우)를 말로 풀어 놓는다.
04 · 기억할 것
시키면 무조건 답한다
“AI 에이전트는 뭘 시키면 답변합니다, 무조건.” 만들기는 하지만 의도한 것이 아닐 수 있다 — 그래서 정확하게 서술해야 한다.
첫 문장에 이렇게 박아 두고 시작한다 — 수업에서 말한 그대로
“나는 기술을 아무것도 몰라. 그러니까 복잡한 건 네가 다 해 주고,
나는 내가 원하는 것만 부를 테니까 — 이게 구현 가능한지 이야기해 줘.”
수업에서 한 말

기술 용어를 자세하게 쓰실 필요는 없어요. 너무 어렵지 않게 접근하시면 됩니다. 두 번째 — 그러면 서술하는 내용은 적어도 정확해야 합니다. 대충 쓰는데 좋은 게 나올 리가 없죠. 뭘 만들고 싶은지가 명확해야 합니다.

P16-1 · 2분 · 근거 2026.09.05 전사 [00:58:18]~[01:01:26] · 모델·Effort는 당일 화면 기준(Sonnet · 높음)

원고에 없던 장(2026.09.08 추가). 라이브 시작 직전에 강사가 실제로 말한 네 가지와 첫 문장.

"클로드 코드 앱은 다 설치하셨죠? 앱으로 하셔야 되고, 웹에서 하면 안 됩니다." [00:59:54] / "AI 에이전트는 기억하세요, 뭘 시키면 답변합니다 무조건." [01:00:16]

수업에서 실제로 부른 프롬프트 — 워크플로우를 말로 풀어 놓는다
마이크에 대고 말한 순서 — 논리 구조가 곧 프롬프트다
  1. 사주 만들어 주는 사이트를 만들고 싶어. 플로우는 아마 이럴 것 같아 —
  2. 사용자가 접속하면 이름 · 생년월일 · 성별 · 생시를 입력하고
  3. 그 정보를 frontend storage에 저장해 줘
  4. API 키 없이 기계적으로 계산할 수 있는 것은 먼저 띄워 줘
  5. 그다음 Gemini API 키를 받아서 — 키가 생기면 오늘의 운세 · 직업운 · 연애운 같은 카테고리를 버튼으로 만들고, 누르면 답변이 나오게
  6. 이 과정에 프롬프트가 필요할 텐데, 그건 온라인 리서치로 확보하고
  7. 별도 서브 에이전트를 만들어 리서치를 한 번 더 — 잘 본다고 소문난 사주 철학관들이 어떤 포인트로 이야기하는지 분석해서 리포트로
  8. 그 리포트를 프롬프트에 반영한 다음, 최종적으로 사이트를 만들어 줘
학생

Search부터 무슨 말인지 모르겠어요.

강사

복잡한 말을 썼나요? 용어를 쓴 게 있긴 하지만, 기본적으로는 논리 구조 — 워크플로우를 만들려고 한 거예요. 미리 만들어 둔 사이트도 같은 흐름이었죠.

왜 “키 없이 계산할 수 있는 것”을 먼저인가태어난 연·월·일·시에 따라 사주 여덟 한자가 결정된다. 거기까지는 LLM이 없어도 얻을 수 있는 정적인 구조다. 그걸 해석하는 것에서만 Gemini가 필요하다.
왜 “로컬(프론트 저장소)에 저장”인가여러분도 이걸 배포할 수 있다. 그런데 API 키가 들어 있는 채로 배포되면 절대 안 된다. 그래서 키는 로컬에만 두라고 한 것이다 — P08b의 그 경고.
에이전트의 첫 응답

“이미 이거랑 거의 똑같은 걸 만들었는데, 왜 또 만드나요?” — “새로 만들어.” 그다음부터 필요한 질문들을 쭉 던진다.

P16-2 · 3분 · 근거 2026.09.05 전사 [01:01:30]~[01:06:09] — 음성 프롬프트를 문장 단위로 옮겼다 · 학생 화자는 미확정(SPEAKER_03)

원고에 없던 장(2026.09.08 추가). P16의 계획(7줄)과 실제 발화가 다르다 — 실제로는 워크플로우를 한 호흡에 불렀다. 학생 배포판에는 실제 발화를 남긴다.

"로컬에 저장하라고 한 것은, 앞서 설명드렸던 것처럼 API 키가 들어 있는 채로 배포가 되면 안 돼요, 절대로." [01:05:16]

건바이건으로 시키지 않는다 — 리서치, 병렬, 그리고 티키타카
01 · 단계를 나눈다
리서치 → 인사이트 → 구현
뭘 만들고 싶다 하면 일단 리서치를 돌리고, 거기서 인사이트를 뽑고, 그 인사이트로 일반적인 구현을 더 독특하게 만들어 달라고 한다. 강사가 가장 자주 쓰는 흐름이다.
02 · 병렬로
독립된 일은 동시에
스토리팩의 이미지 생성이 그랬다. 앞 이미지의 결과가 다음 이미지에 필요 없다 — 각각 독립된 작업이니 “병렬로 처리해 줘”. 서브 에이전트를 만들거나 스크립트를 병렬로 짠다. 토큰은 더 태우고, 대신 속도를 얻는다.
03 · 바로 실행하지 않는다
프롬프트를 먼저 다듬는다
“이 프롬프트에서 구체적이지 않은 부분, 논리적으로 말이 안 되는 부분, 병렬로 처리할 수 있는 부분을 짚어 줘. 나랑 티키타카하면서 결정하자.” — 그다음에 실행한다.
수업에서 한 말

Claude Code 같은 걸 통해서 업무를 시킬 때 건바이건으로 시키시면 안 돼요. 건바이건으로 시키는 건 책 보고 쓰는 거랑 거의 다를 바가 없거든요. 저는 단계를 여러 차례로 나눠서, 에이전틱하게 일을 줍니다.

왜 티키타카인가

머릿속에 구체적으로 있어야 한다고 계속 요청하지만, 사실 머릿속에 구체적으로 만들기가 힘들잖아요. 그 과정을 LLM 모델이랑 같이 겪어 나가는 겁니다.

“우리 모두 시간이 없죠. 그래서 저는 할 수 있는 것들은 항상 병렬로 처리합니다.”
P16-3 · 3분 · 에이전틱 워크플로우 ● · 병렬 ● · 서브 에이전트 ○ · 근거 2026.09.05 전사 [01:06:15]~[01:10:46]

원고에 없던 장(2026.09.08 추가). 라이브 생성이 도는 동안 강사가 설명한 작업 방식 세 가지.

병렬은 P06의 "피자 박스" 비유와 같은 자리다. "토큰을 더 많이 태울 가능성이 조금 더 있고, 그 반대급부로 얻는 것은 속도거든요." [01:08:59]

계획이 나오면 — 이해하고 넘어간다, 그것이 오너십이다
실행 전에 에이전트가 먼저 내놓은 것 — 수업 당일 화면의 순서
01아키텍처화면 · 저장 · 계산 · AI 호출이 어떻게 나뉘는지
02화면 흐름입력 → 여덟 글자 → 키 입력 → 운세 버튼
03프롬프트 리서치서브 에이전트가 독립적으로 진행 중
04빌드 위치파일을 어디에 만들 것인지
05검증 방법다 만든 뒤 어떻게 확인할 것인지
수업에서 한 말

이것들을 기본적으로는 다 이해하셔야 돼요. 이해가 안 되면 쉽게 설명해 달라고 요청하세요. 그리고 “진행해 줘” — 그러면 계획대로 쭉 진행합니다.

스킬 하나 — 나중에 설치해 둘 것
eli5 Explain Like I’m 5
다섯 살짜리 아이가 봐도 이해할 수 있게 설명해 줘.” 복잡한 용어를 쉬운 비유로 풀어 주는 스킬이다. 클로드 사 안에서도 인기라고 했다.
설치 — Claude Code에게
“eli5 스킬 좋다던데, 설치해 줘.”
쓸 때
“이 설계안 모르겠으니까, eli5 스킬로 내가 알기 쉽게 설명해 줘.”
→ 쭉 읽고, 그다음에 넘어간다.
오너십

코드를 전부 책임지기는 힘드실 거예요. 내용이 어려우니까. 하지만 AI와 어떤 위치에 서 있을지는 정의해야 합니다. 가장 중요한 건 — 에이전트가 하는 모든 행동에 대한 기본적인 오너십은 사람이 가지고 있어야 한다는 것.

P16-4 · 2분 · eli5 ○ · 오너십 ● · 근거 2026.09.05 전사 [01:10:52]~[01:13:17] — 계획 5항목은 강사가 화면을 읽어 준 순서

원고에 없던 장(2026.09.08 추가). 생성이 도는 동안 강사가 강조한 두 가지 — eli5와 오너십. 이 직후 휴식에 들어갔고 녹음은 거기서 끝난다.

"얘가 하는 모든 행동에 대해서 기본적인 오너십은 가지고 있어야 된다. 이해가 필요하다." [01:12:50]

라이브 ① — 빈 폴더에서 화면 뼈대까지

이름만 봐도 읽히는 폴더 구조

saju-webapp/빈 폴더에서 시작
index.html화면 한 장
css/style.css보이는 꼴
js/app.js전체를 잇는다
js/profile-storage.js기억 — 폰에만
js/saju-calc.js여덟 글자
js/gemini-client.js구글 AI에 전화
data/hanja-glossary.json한자 뜻 표
  1. 터미널을 켠다 — 무섭게 생겼지만 치는 건 한국어다. 첫 문장에 "나 윈도우 11이야"를 붙인다 (P09·P10 회수 30초)
  2. 앞 장의 기획 한 장을 그대로 에이전트에게 준다 → 화면 뼈대와 입력 폼이 나온다(이름·생년월일·시각·모름 체크)
  3. 폴더 트리를 잠깐 세운다 — 이름만 봐도 무엇을 하는 파일인지 읽힌다
  4. 브라우저로 연다. 폼이 뜬다 — 이 화면이 앞이고, 오늘은 뒤에 우리 서버가 없다
P17 · 8분 · CLI ○(회수) · 윈도우/맥 ● · 프로젝트·폴더·파일 ● · 프론트엔드 ● · 실패 시 완성본 폴더를 열어 트리만 보이고 P18로

화면 셋을 나란히 — 터미널 + 에디터 + 브라우저. 빈 폴더에서 시작한다.

① 터미널을 켜면서 P09 회수 30초: "무섭게 생겼는데 제가 치는 건 한국어예요." 이어서 P10 회수: "저는 맥이라 이렇게 치는데 윈도우는 다릅니다. 그래서 첫 문장에 '나 윈도우 11이야'."

② P16 기획 한 장을 그대로 준다. 화면 뼈대와 입력 폼(이름·생년월일·시각·모름 체크)이 나온다.

③ 트리를 세우고 — "이름 보면 뭐 하는 놈인지 알죠." P05 폴더 구조 이야기와 같은 자리다.

④ 브라우저로 연다. "여러분이 지금 보는 이 화면이 이에요. 오늘은 뒤에 우리 서버가 없어요."

⚠ 실패 시 — 에이전트가 늦으면 완성본 폴더를 열어 트리만 보이고 P18로 넘어간다. 8분을 넘기지 않는다.

멈추는 자리 — 만세력은 직접 만들지 않는다

남이 만들어 공개한 부품을 한 줄로 불러온다

js/saju-calc.js import { calculateSaju, lunarToSolar } from "https://cdn.jsdelivr.net/npm/@fullstackfamily/manseryeok@1.0.8/dist/index.mjs";
대조 11990-05-15 14:30 → 경오 신사 경진 계미
대조 22000-01-15 14:20 → 기묘 정축 임신 정미 — 연주가 2000년이 아니라 1999년 것으로 나오는 게 정상. 입춘을 지나야 그 해가 시작된다

음력과 절기 계산은 직접 만들면 며칠이 걸린다. 그런데 누가 이미 만들어서 공개해 뒀다 — 공짜인데 조건이 있고, 그 조건을 적어 둔 것이 라이선스다. 작품에 쓰는 사람에게는 이게 실제로 걸린다.

한자를 누르면 뜻이 붙는 것은 표 하나다 — data/hanja-glossary.json, 천간 10자 + 지지 12자 = 22자 고정. AI가 아니다.

P18 · 5분 · 오픈소스 ○ · 라이선스 ○(한 줄) · 패키지·CDN –(이름만) · 실패 시 CDN이 막히면 화면이 통째로 빈다 — 그 장면을 그대로 보여주고 완성본 캡처로

"음력이랑 절기를 계산해야 하는데 이건 제가 못 만듭니다. 만들면 며칠 걸려요. 근데 누가 이미 만들어서 공개해놨습니다. 공짜인데 조건이 있어요. 그 조건 적어놓은 게 라이선스고, 작품에 쓰시는 분들은 이게 실제로 걸립니다."

한 줄 붙인다 → 이름·생년월일 넣는다 → 여덟 글자가 나온다. 사람 앞에서 대조할 세트(REPLAY §3, 독립 라이브러리와 교차 검증 완료): 1990-05-15 14:30 → 경오 신사 경진 계미 / 2000-01-15 14:20 → 기묘 정축 임신 정미. 새벽 검증 추가분: 홍길동/1980-05-15 → 경신 신사 무자 기미.

연주가 1999년 것으로 나오는 대목에서 — "입춘을 지나야 그 해가 시작됩니다. 사주 특유의 규칙이에요."

"30초 만에 됐죠. 남이 만든 부품을 갖다 쓴 겁니다."

한자 뜻은 — "이건 표 하나예요. AI 아니에요."

⚠ 실패 시 — CDN이 막히면 화면이 통째로 빈다(어젯밤 재현: 헤더만 남고 본문 없음, 에러 문구도 없음). 그 순간을 그대로 보여주고 "바깥 부품을 못 불러오면 이렇게 됩니다" → 완성본 캡처로. §준비물에 벤더링 항목 있음.

기억 — 새로고침해도 남는다
여기서부터 완성본을 연다

브라우저가 가진 기억, 그 바깥의 서버

개발자도구 ▸ Application ▸ Local Storage ▸ 이 사이트 saju_profile ← 이름 · 생년월일 · 시각 (방금 넣은 것) saju_gemini_key ← 뒤에 넣을 열쇠도 같은 칸에 앉는다
남는다저장 → 새로고침 → 그대로 있다. 이 화면이 기억하고 있다
안 나간다그 기억은 본인 폰 안에만 있고 어디로도 안 나간다
없다옆사람 폰엔 없다 — 남도 보게 하려면 남의 컴퓨터에 있어야 한다. 그게 서버, 거기 쌓아 두는 게 데이터베이스. 오늘은 거기까지 안 간다

최소 생존 버전은 여기까지다 — 입력 폼 → 저장 → 여덟 글자 → 키 입력 → "오늘의 운세" 한 버튼 → 배포. 그 아래는 다 자를 수 있다.

P19 · 4분 · 로컬스토리지·기억 ● · 로컬 vs 서버 ● · 데이터베이스 –(한 마디) · 시간이 밀렸으면 P18부터 이미 완성본

저장 → 새로고침 → 그대로 있다를 눈앞에서 한 번. 그리고 개발자도구 Application 탭을 열어 saju_profile 키를 가리킨다.

"방금 페이지를 다시 불렀는데 아까 적은 게 그대로 있죠. 이 화면이 기억하고 있는 거예요. 이 기억은 여러분 폰 안에만 있고 어디로도 안 나가요."

"옆사람 폰엔 없어요. 남도 보게 하려면 남의 컴퓨터에 있어야 합니다. 그게 서버고, 거기 쌓아두는 게 데이터베이스예요. 오늘은 거기까지 안 갑니다."

여기서 완성본으로 전환한다(시간이 밀렸으면 P18부터 이미 완성본). REPLAY §0 최소 생존 버전 = 입력 폼 → 저장 → 여덟 글자 → 키 입력 → "오늘의 운세" 한 버튼 → 배포. 그 아래는 다 자를 수 있다.

키 이름 두 개는 실제 코드 그대로다 — saju_profile(profile-storage.js) · saju_gemini_key(app.js). 4분.

열쇠 — 각자 자기 것
① 주제 8개
② 키 입력 화면 — 값은 가려진다

구글 AI를 부를 때 신분을 증명하는 것

주제오늘의 운세 · 올해 총운 · 재물 · 애정 · 직업·일 · 인간관계 · 건강 · 이름 풀이 — 여덟 개
열쇠강사 열쇠가 아니라 각자 자기 열쇠. 입력칸은 가려지는 타입이고, 값은 화면에 띄우지 않는다
저장이 열쇠도 앞 장의 기억 창에 앉는다 — 본인 폰 브라우저에만. 딴 데로 안 간다
없으면키 없이 눌러도 앱이 죽지 않고 안내 문구가 뜬다. 한도가 넘으면 "1분 쉬었다 다시" 버튼이 뜬다
수업 소재 — 답이 "오늘은 2026년 9월"에서 잘렸다모델이 눈에 안 보이는 "생각"에 토큰을 먼저 쓰는데(thoughtsTokenCount 479), 출력 예산 500을 거의 다 먹은 것. thinkingConfig: { thinkingBudget: 0 } + 예산 1024로 고쳤다(a8f1218). 에러도 안 나고 그냥 답이 짧게 나온다 — 모르면 프롬프트를 탓하게 된다. 라이브에서 답이 이상하게 짧으면 이 설정부터 본다.
P20 · 4분 · API ● · API 키 ● · .env.local ●(오늘 이 앱엔 상자가 없다 — 브라우저에 저장) · 실패 시 키 한도·API 오류 → 어제 받아둔 샘플 응답 텍스트

"사주 풀이 문장은 우리가 쓰는 게 아니라 구글 AI한테 전화를 걸어서 받아 와요. 전화 걸 때 '저예요' 증명하는 게 이 열쇠예요. 제 열쇠가 아니에요. 각자 자기 열쇠. 그리고 이 열쇠도 아까 그 기억 창에 저장되고, 딴 데로는 안 가요."

키 없이 누르면 앱이 안 죽고 안내 문구가 뜬다(어젯밤 확인). 한도가 넘으면 "1분 쉬었다 다시" 버튼이 뜬다. 강사 키로 오늘의 운세 한 번 받아서 보인다.

발급 절차는 다음 장(P20b)으로 넘긴다 — "무료로 2분이면 됩니다. 단톡방에 올려둘게요."

수업 소재(원격 실측, a8f1218에서 수정됨) — 처음엔 답이 "오늘은 2026년 9월"에서 잘렸다. gemini-2.5-flash가 눈에 안 보이는 "생각"에 토큰을 먼저 쓰는데(thoughtsTokenCount 479) 출력 예산 500을 거의 다 먹은 것. thinkingConfig: { thinkingBudget: 0 } + 예산 1024로 잡았다. "에러도 안 나고 그냥 답이 짧게 나와요. 모르면 프롬프트를 탓하게 됩니다. 이런 게 실무예요." — 라이브 중 답이 이상하게 짧으면 이 설정부터.

⚠ 남은 확인 하나 — 배포 주소에서 실제 제미나이 호출은 아직 아무도 안 돌렸다(원격은 키 입력이 안전 분류기에 막힘, 맥은 키 없음). 아침에 폰으로 주소 열고 본인 키 넣어 "오늘의 운세" 1회 — 30초. 그게 실제 사용 경로다(§준비물 1).

⚠ 실패 시 — 키 한도·API 오류가 나면 어제 미리 받아둔 샘플 응답 텍스트로. "이 AI도 하루 먹을 양이 정해져 있어요." 4분.

부록 · 구글 API 키 ① — 어디까지 하느냐

구글 키는 한 번 부를 때마다 돈이 나갈 수 있는 열쇠다. 대신 오늘 수업 범위는 무료 한도로 끝난다 — 결제가 필요한 건 이미지 생성뿐이다.

어디까지필요한 것시간
사주 여덟 글자 · 한자 풀이없음없음
사주 AI 문장(8주제)A단계 키2분무료 한도
스토리팩 대화(플레이)A + .env.local3분무료 한도
이미지 생성(팩 에셋·게임 그림)A + B단계7분최소 $10 선불
전원 A단계까지면 충분하다. B는 이미지까지 해보고 싶은 분만.
P20b-1 · 30초 · API 키 ● · 무료 한도 횟수는 단정하지 않는다 — 본인 것은 aistudio.google.com/rate-limit 에서

P20 끝에 띄우고 한 마디만 — “키는 무료로 2분이면 만듭니다. 이 세 장을 단톡방에 올려두겠습니다.” 읽어 주지 않는다.

이 수업 권장 — 대화·사주 문장까지는 A만(카드 등록 없음). 전원 여기까지면 충분하다.

무료로 몇 번 되는지”는 단정하지 않는다. 구글이 숫자를 문서에서 뺐고 계정마다 다르다. 수요일에 무료 한도가 소진돼 주인공 한 장에서 멈춘 게 이 때문이다.

부록 · 구글 API 키 ② — 발급 2분, 그리고 어디에 넣나
A · 키 발급 — 무료 2분
  1. aistudio.google.com/apikey → 구글 계정 로그인 → 약관 동의
  2. Create API key → 키가 화면에 뜬다
  3. 복사한다. 창을 닫아도 같은 페이지에서 다시 볼 수 있다
여기서 만든다aistudio.google.com/apikey
흔한 잘못된 안내“지금 안 복사하면 끝”은 틀렸다. OpenAI·Anthropic은 한 번만 보여주지만 AI Studio는 다시 본다.
어디에 넣나 — 오늘은 두 갈래
물건넣는 곳어디에 저장되나
사주앱오늘 QR앱 안 키 입력 화면에 붙여넣기본인 폰 브라우저에만. 우리 서버는 없다
스토리팩 킷집에서.env.example 복사 → .env.local로 → GOOGLE_API_KEY= 뒤에 붙이고 저장내 컴퓨터의 상자. 서버가 켜져 있었다면 끄고 다시 켠다
변수명이 둘이다구글 문서는 GEMINI_API_KEY지만 우리 팩이 읽는 이름은 GOOGLE_API_KEY. 둘 다 있으면 GOOGLE_API_KEY가 우선이라 이 이름 하나로 맞는다.
P20b-2 · 30초 · 상자(.env.local) ● · 근거 ai.google.dev(api-key · quickstart) 2026.09.05 재확인

지킬 것 셋(화면에 없음, 말로만) — ① 키를 채팅창·단톡방·화면 공유에 붙이지 않는다. 붙였다면 샌 것으로 친다 ② 샌 것 같으면 지우고 새로 만든다(로테이션) ③ 폰에 넣은 키는 그 브라우저에만 남는다.

수요일에 실제로 걸린 것 — 켜져 있던 서버가 옛 키를 물고 있었다. 완전히 끄고 다시 켜야 새 키를 읽는다.

기존 Google Cloud 사용자는 자동 생성이 안 된다 → Projects에서 프로젝트를 먼저 가져온(import) 뒤 만든다. 현업 경험자 질문 대비.

부록 · 구글 API 키 ③ — 유료 전환은 이미지까지 할 때만
B · 유료 전환 — 7분
  1. /projects → 내 프로젝트 행 Billing TierSet up billing
  2. 결제 계정을 붙인다. 수업 비용을 분리하려면 Add new billing account
  3. Prepay(선불)로 간다 — 잔액이 0이 되면 그냥 멈춘다
  4. /billingBuy credits최소 $10
  5. Setup auto-reload를 켜지 않는다 — 충전액이 그대로 상한이 된다
  6. /spendMonthly spend cap을 프로젝트에 걸어 둔다
지금 상태 보는 법 — Projects의 Billing Tier 열
Set up billing결제 안 붙음 = 무료만
Set up Prepay계정은 붙었고 선불 설정 남음
No credits잔액 0 = 유료 호출 멈춤
실사용은 팩 하나 $3 안쪽이지만 최소 충전액이 $10이라 못 내린다. 대신 선불 자체가 하드캡이라 후불 카드보다 안전하다.
P20b-3 · 30초 · 비용·Dry Run ○(회수) · 근거 ai.google.dev(billing “minimum of $10 in prepaid credits”, 상태 3종) 2026.09.05 재확인

이 장은 이미지까지 해보고 싶은 분만. 화면에 띄우고 “여기까지 오실 분은 이 한 장 보시면 됩니다”로 끝낸다.

볼트 02_보강_2026.09.02의 구글API키_획득절차 · 학생용_무료API키_발급안내와 일치.

배포 — 주소가 생기고 예순 명이 들어온다
폰에서 연 화면
QR
https://srl-saju-fortune
.pages.dev
QR 이미지는 당일 생성기 탭에서 만들어 이 자리에 띄운다 · 주소를 직접 쳐도 된다
폰 카메라로 찍는다

내 컴퓨터 안에서 남의 컴퓨터 위로

  1. 폰에서 localhost:8080을 친다 → 안 열린다. 아직 강사 컴퓨터 안에만 있다 (P13에서 예고한 20초)
  2. 폴더를 통째로 드래그해서 올린다(Cloudflare Pages) — 남의 컴퓨터에 올리고 이름 하나를 빌린 것
  3. 주소가 뜬다 — srl-saju-fortune.pages.dev
  4. QR을 띄운다. 지금부터 각자 폰으로 들어온다 — 앱스토어도 가입도 필요 없다
키 없이여덟 글자와 한자 뜻은 열쇠 없이도 본다. AI 문장은 키를 넣으면 되고, 발급은 집에서(P20b)
개인정보생년월일은 강사가 만든 서버로 절대 안 간다 — 애초에 그런 서버가 없다. AI 문장을 누르는 그 순간만 구글로 직접 간다
P21 · 5분 · 로컬 vs 배포 ● · 배포·호스팅·주소 ● · 웹앱·기기 ○ · QR은 당일 생성기 탭에서 · 실패 시 사전 배포본 https://srl-saju-fortune.pages.dev 로

순서는 넷 — ① 폰에서 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 ① — 계정 만들고 드래그로 올리기

Cloudflare Pages는 돈이 안 달려 있다(무료·정적 사이트 무제한). 그래도 토큰이 새면 남이 내 사이트를 덮어쓰거나 지울 수 있다 — 여전히 열쇠다.

갈래가 셋이다
어디까지필요한 것시간열쇠
① 폴더를 드래그해서 올린다Cloudflare 계정(이메일)3분없음
터미널에서 올린다 (wrangler login)계정 + Node5분없음 — 브라우저 로그인 한 번
AI 에이전트가 대신 올린다계정 + API 토큰 + Account ID7분있음 — 다음 장
A · 계정 — 모두 공통 3분
  1. dash.cloudflare.comSign up → 이메일·비밀번호 → 인증 메일 확인
  2. 도메인을 추가하라는 화면은 건너뛴다(Skip). 오늘은 빌린 이름(*.pages.dev)만 쓴다
B · 드래그로 올리기 — 열쇠 없음
  1. 왼쪽 메뉴 Workers & PagesCreatePages 탭 → Upload assets
  2. 프로젝트 이름을 정한다 — 이게 그대로 주소가 된다(이름.pages.dev). 영문 소문자·숫자·하이픈
  3. 폴더를 통째로 창에 드래그. 거부하면 zip으로 압축해 올린다
  4. Deploy site → 주소가 뜬다. 폰으로 열어본다
  5. 고쳤으면 Create new deployment → 다시 드래그. 주소는 그대로
P21b-1 · 1분(P21에 흡수) · 배포·호스팅·주소 ● · 근거 Cloudflare Pages 문서(Direct Upload) · 볼트 사주 04 §5와 일치

P21 끝에 띄우고 한 마디만 — “집에서 하실 분은 이 두 장이면 됩니다. 단톡방에 올려두겠습니다.” 읽어 주지 않는다.

오늘 강사는 ①(드래그) 또는 ②(wrangler pages deploy)로 한다. ③은 “에이전트한테 ‘올려줘’까지 시키는” 사람의 길이다.

구글 키와의 차이를 한 번 짚는다 — 돈이 안 달려 있는데도 열쇠인 이유는 토큰이 새면 남이 내 사이트를 덮어쓰거나 지울 수 있어서다.

프로젝트 이름 = 주소. 오타가 영구 주소가 된다. 처음에 정한다(예: hong-saju).

부록 · Cloudflare ② — 에이전트에게 시키려면 (API 토큰)
C · API 토큰 — 7분
  1. 오른쪽 위 프로필 → My ProfileAPI TokensCreate Token
  2. 템플릿 말고 맨 아래 Create Custom Token템플릿 “Edit Cloudflare Workers”는 권한이 더 넓다 — 필요한 만큼만 준다
  3. Token name: hanyejong-pages 같은 알아볼 이름
  4. Permissions: Account · Cloudflare Pages · Edit — 이 한 줄이면 된다
  5. Account Resources: Include · 내 계정 → Continue to summaryCreate Token
  6. 토큰은 이 화면에서 한 번만 보인다. 바로 복사해 상자에 넣는다 — 놓치면 지우고 새로 만든다
D · Account ID
Workers & Pages 첫 화면 오른쪽에 Account ID(32자 16진수). 복사.
②로 로그인한 상태라면 npx wrangler whoami로도 나온다.
E · 상자에 넣고 에이전트에게 시키기
프로젝트 폴더의 .env.local — 값은 여기 안 적는다
CLOUDFLARE_API_TOKEN=(C에서 복사한 토큰)
CLOUDFLARE_ACCOUNT_ID=(D에서 복사한 ID)
에이전트에게나는 윈도우 11이야. .env.local에 있는 Cloudflare 토큰으로 site 폴더를 Pages에 올려줘. 프로젝트 이름은 내이름-saju. 토큰 값은 화면에 출력하지 마.
에이전트가 실제로 치는 건 이 한 줄
npx wrangler pages deploy site --project-name=내이름-saju
P21b-2 · 1분(P21에 흡수) · API 키·상자 ●(회수) · 로테이션 ○ · 근거 Cloudflare Pages 문서(토큰 = Account·Cloudflare Pages·Edit, 환경변수 CLOUDFLARE_API_TOKEN·CLOUDFLARE_ACCOUNT_ID)

이 장도 읽어 주지 않는다. “에이전트한테 배포까지 시키고 싶으신 분만 보세요.”

권한은 한 줄로 충분하다 — Account · Cloudflare Pages · Edit. 템플릿을 쓰면 필요 이상으로 넓어진다.

함정 둘(화면에 없음) — ① 고친 게 바로 안 보인다(캐시): 시크릿 창이나 하드 리프레시(Ctrl+Shift+R) ② wrangler login이 창을 못 띄우면(윈도우) 터미널에 뜬 URL을 복사해 직접 연다.

구글 키와 반대다 — AI Studio 키는 다시 볼 수 있지만 Cloudflare 토큰은 생성 직후 한 번뿐이다. 여기서만 “지금 복사하세요”가 맞는 말이 된다.

두 번째 실습 — 슈팅게임 만들기
사람이 적는 것 — 자연어 명세

세로로 긴 화면에서 비행기가 아래에 있고, 적이 위에서 계속 내려오는 슈팅게임을 만들어 줘. 옛날 오락실 1945 같은 느낌이면 좋겠어.

대상 — 게임을 안 해 본 사람도 30초 안에 이해할 것. 설명 없이 바로 손이 움직여야 해.

조작 — 마우스나 손가락으로 끌면 기체가 따라온다. 총알은 알아서 나간다 — 쏘는 버튼은 없어.

경험 — 처음 10초는 쉽게 이기게 해 줘. 그다음부터 적이 조금씩 많아지고, 1분 반쯤에 보스가 나오면 좋겠어.

보이는 것 — 점수, 남은 목숨, 보스 체력. 그 셋만. 화면을 숫자로 덮지 마.

금지 — 회원가입·로그인 없음. 설치 없음. 주소 하나로 폰에서 그냥 열릴 것.

부품 — 그림과 소리는 내가 만들지 않아. 무료로 공개된 것을 찾아서 써 줘. 조건은 확인하고.

이게 프롬프트다기술 용어가 한 줄도 없다. 대상 · 조작 · 경험 · 보이는 것 · 금지 · 부품 — 사람이 정할 것만 적었다.
그래서 나온 것
실제 화면 기체·적·총알·폭발·점수가 한 화면에
부품은 전부 남이 만든 것 — 오픈소스 두 번째
엔진 Phaser 3CDN 한 줄오픈소스
그림 기체·적·폭발Kenney.nlCC0
소리 BGM 6 · 효과음 12OpenGameArtCC0
실제 파일 · 32~104px
P22 · 3분 · 오픈소스 ○ · 라이선스 ○ · 명세를 소리 내어 읽는다 — 기술 용어가 한 줄도 없다는 걸 짚는 것이 이 장의 목적

사주앱(P16)과 같은 구조다. 거기선 대상·경험·목표·금지 넷을 적었고, 여기선 조작과 부품이 더 붙었을 뿐이다.

왼쪽 명세를 소리 내어 읽는다. 다 읽고 나서: “여기 기술 용어가 한 줄이라도 있었습니까. 없어요. 제가 적은 건 누가 보고, 어떻게 만지고, 뭘 느끼고, 뭘 하지 말라는 것뿐입니다.”

총알은 알아서 나간다, 쏘는 버튼은 없다” — 이 한 줄이 왜 중요한지 짚는다. 60명이 폰으로 처음 잡는 게임이라 버튼이 하나라도 늘면 안 된다. 제약을 먼저 적는 것이 좋은 명세다.

오른쪽으로 넘어가며: “게임 엔진도 남이 만든 겁니다. 그림하고 소리도요. 이거 없으면 이 게임 못 만들어요.

오픈소스 두 번째 — 아까는 계산기 하나(만세력), 이번엔 엔진·그림·소리 전부.

assets/CREDITS.txt를 잠깐 띄운다: “조건이 ‘표기’인 것도 있어요. 이 파일이 그겁니다.”

⚠ 스프라이트 실물은 img/sprites/의 진짜 파일이다(32~104px). 확대해서 각이 지는 건 원래 그렇다고만 말하고 넘어간다. boss_body.png가 1024×64라는 것은 P24에서 “보스가 찌그러져 보인다”를 설명 없이 이해시키는 복선 — 필요하면 그때 짚는다.

라이브 제작 ② — 검은 화면에서 총알이 나가기까지
  1. 빈 폴더에 index.html 하나 + Phaser CDN 한 줄 → 검은 화면이 뜬다
  2. 기체 스프라이트 하나 + 방향키 이동 → 움직인다
  3. 스페이스 → 총알이 나간다
  4. (시간 되면) 적이 내려오고, 맞으면 터지고, 점수가 오른다

REPLAY 실측으로 1~3단계는 85분이 걸렸다. 오늘 무대에서 하는 것은 골격까지 10분이다.

파일 이름은 사람도 읽고 기계도 읽는다
player_ship.png
누구의(player) + 무엇(ship) — 내가 조종하는 기체
enemy_scout.png
누구의(enemy) + 무엇(scout) — 적 정찰기. 이름만 보고 어느 편인지 안다
bullet_player_viper.png
무엇(bullet) + 누구의(player) + 어떤 무기(viper) — 세 토막으로 읽힌다
item_weapon_viper.png
같은 viper가 아이템 이름에도 붙는다 — 무기와 아이템이 이름으로 이어진다
P23 · 10분 · 윈도우/맥 ● · 파일 이름·구조 ● · 소스 코드 ○ · 실패 시 2번에서 막히면 완성본으로 바로 전환, 골격은 캡처 3장으로 대체

화면 셋을 나란히 — 터미널 + 에디터 + 브라우저.

REPLAY 1~2단계, 필요하면 3단계까지. 4번은 시간이 될 때만.

명령어를 칠 때 P10(기기와 운영체제 — 같은 말을 다르게 친다)을 한 번 더 회수한다.

파일 이름을 보이면서: "이름을 왜 이렇게 붙였을까요. 사람도 알아보고 기계도 알아보라고요."

붙는 단어: 윈도우/맥 ● · 파일 이름·구조 ● · 소스 코드 ○ — 10분.

⚠ 시간 관리 — REPLAY 실측은 1~3단계 85분이다. 오늘은 골격만 10분이 목표다. 2번(이동)에서 막히면 붙들지 말고 완성본으로 전환하고, 골격은 미리 찍어 둔 캡처 3장으로 대체한다.

⚠ bullet_player_viper.png는 화면에서 점처럼 작아 스프라이트 실물을 안 띄운다(그 줄만 그림 없음). 대신 이름이 세 토막이라는 것만 짚는다.

완성본 — 배포된 주소를 연다

완성본은 배포된 주소에서 그대로 돈다

https://srl-hanyejong-shmup.pages.dev
규모js/ 파일 11개 · 1,300줄
내용6종 · 무기 4종 · 폭탄 2종 · 보스 3페이즈 · 사운드
에셋assets/sprites/ enemy_weak/ · enemy_mid/ · boss/
확인어젯밤 라이브 200 · 로컬과 SHA-256 일치 — 6c95de8 완성 커밋이 그대로 배포돼 있다

새 탭에 주소를 치고, 강사가 30초 플레이한다.

코드 폴더를 잠깐 띄우되 읽지는 않는다 — 이렇게 살이 붙었다는 것만 본다. 이걸 다 라이브로 하면 오늘은 라이브 코딩만 보다가 끝난다.

라이브로 만든 골격(P23)과 같은 물건이다. 그 위에 시간을 더 부은 것뿐이다.

P24 · 2분 · 붙는 단어 없음 · 주소는 어젯밤 라이브 확인(200)

"이제 어젯밤에 미리 다 만들어둔 완성본을 열겠습니다."

"이렇게 살이 붙었다는 것만 보세요. 이걸 다 라이브로 하면 오늘 라이브 코딩만 보다가 끝납니다."

━━━ ⚠ 시연 자세 (새벽 실측) — 이 세 가지를 지키지 않으면 무대에서 멈춘다 ━━━

⚠ ① 하단 중앙을 클릭하고, 커서를 거기 둔 채 마우스로 조작한다. 키보드만 쓰면 기체가 좌상단(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 · 93×84
  1. 이미지 생성 서비스에 새 그림을 시킨다 — 다른 회사 서비스에 전화를 거는 일이다. 아까 그 열쇠를 여기서 또 쓴다
  2. 받은 그림으로 같은 파일을 덮어쓴다 — 이름도 자리도 그대로다
  3. 하드 리프레시로 다시 불러온다 → 다른 색 적이 내려온다
일반 새로고침으로는 그림이 안 바뀐다Ctrl+Shift+R Cmd+Shift+R브라우저는 한 번 받은 그림을 기억해 두려고 한다(캐시). 강제로 다시 받아오라고 알려주는 것이 하드 리프레시다. 대본을 쓰다가 실제로 한 번 걸렸던 자리다(REPLAY C-1) — 무대에서도 걸린다고 보고 들어간다.
P25 · 8분 · API 키 ●(회수) · 캐시 –(한 마디) · 실패 시 생성 API가 막히면 미리 만들어 둔 3색 버전 중 하나로 파일만 교체 + 하드 리프레시

순서: 이미지 생성 → assets/sprites/enemy_weak/enemy_scout.png 덮어쓰기 → 하드 리프레시(Ctrl+Shift+R / Cmd+Shift+R) → 다른 색 적이 내려온다.

"지금 얘한테 그림 하나를 새로 그려 달라고 시킬 건데, 다른 회사 서비스한테 전화를 거는 거예요. 아까 그 열쇠, 여기서 또 씁니다." — P20 API 키 회수.

함정을 숨기지 말고 그대로 보여준다. 일반 새로고침으로는 안 바뀐다. "브라우저는 그림을 한 번 보면 기억해 두려고 해서, 강제로 다시 불러오라고 알려줘야 해요. 그게 방금 누른 새로고침이에요."

⚠ REPLAY C-1: 대본을 쓰다가 실제로 한 번 걸렸다. 무대에서 당황하지 말고 그 자리에서 설명 재료로 쓴다.

붙는 단어: API 키 ●(회수) · 캐시 –(한 마디) — 8분.

라이브 변경 ② — 적 한 종류를 추가한다
site/js/difficulty.js — SHMUP.ENEMY_BASE 에 항목 하나 추가
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'
},
같은 파일 — SHMUP.WAVES 의 types 에 한 단어
types: [ … , 'ufo' ]   // 단어 하나만 더한다

저장 → 새로고침. 이건 일반 새로고침으로 된다 — 그림이 아니라 코드라서.

변경 범위 — 건드릴 데와 안 건드릴 데
건드린다
site/js/difficulty.js
적의 목록. 이름·체력·속도 같은 수치가 모여 있다 — 여기에 항목 하나를 더한다
안 건드린다
site/js/enemies.js
적을 실제로 움직이는 코드. 오늘 한 줄도 건드리지 않는다

건드릴 데와 안 건드릴 데를 먼저 말하는 것이 프롬프트를 잘 쓰는 것보다 중요하다.

게임을 움직이는 큰 코드는 이 목록만 읽고 "적이 몇 종류 있구나"를 안다. 그래서 적 하나 추가는 게임 전체를 다시 짜는 일이 아니라 목록에 한 줄 더하는 일이 된다.

P05에서 본 구조 자체가 자산이다의 회수 지점이다.

P26 · 6분 · 변경 범위 ● · 구조=자산(회수) · 시간이 밀리면 제일 먼저 자르는 장 · 실패 시 7종 버전 별도 배포 주소로 대체

먼저 변경 범위를 말한다: "건드릴 데하고 안 건드릴 데를 먼저 말합니다. 이게 프롬프트 잘 쓰는 것보다 중요해요." — enemies.js(움직이는 코드)는 한 줄도 안 건드린다.

"이 목록 하나만 봐주세요. 게임을 움직이는 큰 코드는 이 목록만 읽고 '적이 몇 종류 있구나' 하거든요. 그래서 적 하나 추가하는 게 게임 전체를 다시 짜는 일이 아니라, 이 목록에 한 줄 더하는 일이 돼요." — P05 "구조 자체가 자산"의 회수.

붙는 단어: 변경 범위 ● · 구조=자산(회수) — 6분. 시간이 밀리면 제일 먼저 자르는 장이다.

⚠ 계획서 불일치 — 볼트 04_수업활용_리허설.mdenemies.json을 가정했지만 실제 구현엔 그 파일이 없다. 무대에서는 이 문서/REPLAY.md만 본다. 학생이 파일명을 물으면 difficulty.js라고 답한다.

⚠ 실패 시 — REPLAY는 "7종 버전 별도 배포 주소"를 대체로 적었다. 그 주소가 실제로 있는지 아침에 확인(준비물 항목).

라이브 변경 ③ — 숫자 두 개, 그리고 보스를 앞당기는 한 줄
게임이 돌아가는 채로 개발자도구 콘솔(F12)
콘솔 — 새로고침 없이 다음 프레임부터 바뀐다
SHMUP.LIVE_TUNE.enemySpeedMultiplier = 3.0   // 적 속도 3배
SHMUP.LIVE_TUNE.spawnInterval = 0.3          // 등장 간격 30%

영구히 바꾸려면 difficulty.js 맨 위 LIVE_TUNE 세 값을 고치고 저장 → 새로고침.

보스를 보이려면 — 시작 전에 콘솔 한 줄
시작 전 — 15초에 보스, 20초 안에 격파
SHMUP.BOSS_WARN_SEC = 10; SHMUP.BOSS_START_SEC = 15; SHMUP.BOSS.hp = 80;

같은 장의 연장이라 자연스럽다 — 숫자를 세 개 더 바꿨더니 보스가 15초에 온다.

기본보스는 고정 105초에 나온다
격파등장 뒤 2~3.5분이 더 든다 — 호밍니들 113초 · 바이퍼 178초
합계자연 플레이로 보스를 보려면 4~5분. 34분짜리 챕터에서 낼 시간이 아니다
시연위 한 줄이면 15초에 등장 · 20초 안에 격파

치기 전에 먼저 묻는다 — 이 두 숫자가 바뀌면 게임이 어떻게 달라질 것 같은지.

그리고 방금 그것을 무섭게 보이던 콘솔에서 했다. P15의 뒤집기다.

P27 · 4분 · 소스 코드 ● · 콘솔 ○(무섭지 않다) · 실패 시 콘솔이 막히면(교내 정책) 파일 수정 + 새로고침

치기 전에 묻는다: "숫자 두 개만 바꿀 거예요. 하나는 적이 내려오는 속도, 하나는 나오는 간격. 이게 이렇게 바뀌면 게임이 어떻게 달라질 것 같으세요?"

바뀐 뒤: "숫자 하나 바꿨는데 게임이 달라지죠. 그리고 방금 그 무서운 콘솔에서 한 거예요." — P15(문제를 볼 때)의 뒤집기.

영구히 바꾸려면 difficulty.js 맨 위 LIVE_TUNE 세 값 → 저장 → 새로고침.

보스 시연 (실측 검증) — 보스는 고정 105초에 나오고 잡는 데 2~3.5분이 더 든다(호밍니들 113초 · 바이퍼 178초). 자연 플레이로는 4~5분. 그래서 시작 전에 콘솔 한 줄을 미리 친다. "숫자 세 개 더 바꿨더니 보스가 15초에 옵니다."

⚠ 보스전에 들어가면 3번 키(펄스레이저)를 쓰지 않는다 — 사거리가 안 닿아 데미지 0이다(P24 시연 자세 ②).

붙는 단어: 소스 코드 ● · 콘솔 ○(무섭지 않다) — 4분.

재배포 — 같은 주소, 예순 대의 폰
재배포 — 고친 것을 같은 주소에 덮어쓴다
$ npx wrangler pages deploy site

폰에서 열었을 때 — 세로 화면

QR — 현장에서 띄운다
https://srl-hanyejong-shmup.pages.dev

같은 주소가 PC에서도 폰에서도 열린다. 60명 최초 로드가 1인당 2.1MB — QR은 쉬는 시간에 미리 열게 하면 안전하다.

폰에서 되는 것 · 안 되는 것 (새벽 실측)
  • 탭 → 시작
  • 드래그하면 기체가 손가락을 1:1로 따라온다
  • 자동 발사 · 격추 · 점수 · 게임오버 후 탭 재시작
  • 375×812에서 가로 스크롤 0 · 가로모드도 잘림 없음(세로 권장)
  • 폭탄 2종 · 무기 전환은 폰에서 안 된다SPACE · 우클릭 · 숫자키 전용(player.js:35,88,93-96)
  • 하단 안내문("방향키/WASD+마우스 · SPACE · 우클릭")은 폰에선 전부 틀린 말이다
결과폰 유저는 목숨 3 · 방어 0 · 1인당 40~90초면 끝난다 — 금방 죽는 게 정상이다
이유터치 전용 코드는 한 줄도 없다. 포인터 추적 덕에 "우연히" 되는 구조
P28 · 3분 · 재배포·Git ○ · 반응형·기기 ○ · 플레이는 P29·P30 말하는 동안 계속 · 실물 iOS Safari·Android Chrome은 미검증(에뮬레이션 통과)

"고칠 때마다 올립니다. 이 기록을 훨씬 촘촘하게 해주는 게 Git이에요." — P12 회수, 여기까지만.

"같은 주소가 PC에서도 폰에서도 열립니다." → 예순 명이 각자 폰으로 한 판. 시간이 남으면 적 하나를 더 라이브로 추가한다.

폰 안내 문구: "폰에서는 손가락으로 끌면 됩니다. 폭탄은 PC에서만요. 금방 죽는 게 정상이에요."

⚠ 하단 안내문이 폰에서는 틀린 말이다("방향키/WASD+마우스 · SPACE · 우클릭"). 학생이 그걸 보고 헤매기 전에 먼저 말해 준다.

⚠ 실물 iOS Safari·Android Chrome은 미검증이다(에뮬레이션만 통과). 아침에 폰 1대로 연타·핀치 줌을 확인한다.

⚠ 60명 최초 로드 = 1인당 2.1MB. QR을 쉬는 시간에 미리 열게 하면 동시 접속 부하를 피할 수 있다.

붙는 단어: 재배포·Git ○ · 반응형·기기 ○ — 3분.

마무리 — 점수가 남지 않는 이유

뒤가 없다 — 그래서 점수가 안 남는다

지금게임오버 화면의 점수는 새로고침하면 사라진다
이유이 게임엔 뒤(백엔드)가 없다 — 화면만 있는 물건이다
남기려면남의 컴퓨터(서버)와 거기 쌓아 두는 곳(데이터베이스)이 필요하다 — 거기부터는 다른 얘기다

챗봇은 뒤가 있어서 기억이 남았다. 그래서 오늘 그것만 드래그로 못 올렸다 — P04의 상자 셋, P13의 "화면은 앞, 서버는 뒤".

사주 웹앱의 기억은 각자 폰 안에만 있었다. 옆사람 폰엔 없었다 — P19.

오늘 만진 셋의 차이가 여기서 한 문장으로 묶인다. 뒤가 있느냐 없느냐.

P29 · 1분 · 백엔드 ●(회수) · 데이터베이스 –

게임오버 화면. 점수. 새로고침하면 사라진다. 1분. 짧게 끊는다.

"점수가 저장이 안 되죠. 이 게임엔 뒤가 없어요. 그래서 점수가 안 남습니다. 남기려면 서버가 필요하고, 그때부터 다른 얘기가 됩니다. 아까 챗봇은 뒤가 있어서 기억이 남았고, 그래서 드래그로 못 올린 거예요."

P04(화면·서버·팩) · P13(웹이 돌아가는 구조) · P19(기억은 내 폰 안에만)를 한 문장으로 묶는 장이다. 새로 설명하지 않는다.

붙는 단어: 백엔드 ●(회수) · 데이터베이스 – — 1분.

학생들은 이 말을 듣는 동안에도 폰으로 계속 게임을 하고 있다(P28). 그대로 두고 P30으로 넘어간다.

회수 — 오늘 만든 것을 지도에 되돌려 놓는다
Local
내 컴퓨터
  • 사주앱 화면 · 내 사주(기억)
  • 게임 코드 · difficulty.js
  • 브라우저 · 폴더 · 파일
Server
남의 컴퓨터
  • 두 주소 · pages.dev
  • 올리면 남도 본다
  • 점수는 여기 없다
External
바깥
  • 구글 AI · 이미지 생성
  • 열쇠 · 비용
  • ← 만세력 · Phaser · Kenney
01
화면은 앞, 서버는 뒤.
02
로컬은 나만, 올리면 남도.
03
열쇠는 상자에.
04
남이 만든 걸 갖다 쓴다. 조건은 확인한다.
05
만드는 것보다 고치는 게 실력이다.
P30 · 5분 · 회수 — P08 지도에 오늘 만든 것을 얹는다 · 새 단어 없음

P08에서 봤던 그 지도 그대로. 이번엔 칸마다 오늘 만든 것이 들어가 있다. 새 단어를 얹지 않는다 — 이미 나온 것만 제자리에 놓는다.

왼쪽부터 짚는다. 내 컴퓨터 — 사주앱 화면과 내 사주(기억), 게임 코드와 difficulty.js. 남의 컴퓨터 — 두 주소(pages.dev). "올렸으니 남도 봅니다. 다만 점수는 여기 없어요 — 각자 폰에만 있습니다." 바깥 — 구글 AI, 이미지 생성, 열쇠와 비용. 그리고 왼쪽으로 들어온 것: 만세력·Phaser·Kenney.

회수 문장 다섯을 하나씩 읽는다. 설명을 덧붙이지 않는다.

클로징: "어떤 시스템과 스토리텔링이 합쳐져 돌아가는 구조를 만드는 것, 전체가 그렇게 어려운 과업은 아닙니다." [27:39]

5분.

과제 — 다음 주까지 해 볼 것
과제 — 다음 주까지
  1. 오늘 만든 것 중 하나를 자기 재료로 바꿔 본다사주앱의 주제 버튼 하나 / 게임의 적 그림 하나
  2. 안 되면 어디까지 됐는지 캡처를 남긴다환경 문제는 창작 실패가 아니다
  3. 주소가 나오면 단톡방에
  4. (선택) AI에게 첫 문장으로 내 환경을 말하는 습관 — “나는 윈도우 11이야.”
수업에서 부탁한 것 — 집에 가서
  • Claude Code 앱 설치 확인 — 웹으로 하지 않는다
  • eli5 스킬 설치 — “eli5 스킬 좋다던데, 설치해 줘”
  • Cloudflare Pages 계정을 만들어 연결해 둔다
  • 나눠 준 스토리팩의 리소스 폴더를 열어 구조가 어떻게 돼 있는지 본다
  • 도구 목록(집에 가서 열어 볼 것들)에 들어가 보고 에이전트에게 어떻게 쓸지 생각해 본다
실습 1 · 사주 웹앱https://srl-saju-fortune.pages.dev
실습 2 · 슈팅게임https://srl-hanyejong-shmup.pages.dev
P31 · 2분 · 두 주소는 단톡방에 · 안 되면 캡처를 남긴다 · 오른쪽 다섯은 토요일 수업 중 강사가 직접 부탁한 것(핵심정리 액션 아이템)

네 줄만 읽고 끝낸다.

① 오늘 만든 것 중 하나를 자기 재료로 바꿔 본다 — 사주앱의 주제 버튼 하나, 게임의 적 그림 하나. 둘 다 안 해도 된다. 하나면 된다.

② 안 되면 어디까지 됐는지 캡처를 남긴다. 환경 문제는 창작 실패가 아니다. "실패해도 어디까지 됐는지 말할 수 있으면 됩니다."

③ 주소가 나오면 단톡방에.

④ (선택) P10에서 본 실전 규칙 — AI에게 첫 문장으로 내 환경을 말하는 습관. "나는 윈도우 11이야."

두 주소는 화면에 띄운 채로 두고, 단톡방에도 올린다. 2분.

1 / 0
← → 이동  ·  N 노트  ·  O 목차  ·  F 전체화면  
발표자 노트