각 프롬프트는 원고의 해당 절에 수록된 원문입니다. 어두운 상자는 브라우저 설정 값 또는 명령어, 밝은 상자는 Claude Code 대화창에 입력하는 프롬프트입니다. Plan 모드는 Shift+Tab으로 켭니다.
10.3.2 Plan 모드로 이사 계획 세우기 — qa-board 서버리스 전환 Plan 모드 · Shift+Tab
계획 요청 프롬프트 (qa-board 폴더에서 Claude Code 실행, Plan 모드 켠 뒤)
이 게시판을 Vercel에 배포하고 싶어.
## 알고 있는 것
- Vercel은 서버리스라서 지금처럼 파일(data 폴더)에 데이터를 저장할 수 없다고 들었어
- GitHub 저장소(qa-board)와 Vercel 계정은 준비되어 있어
## 요청
- 배포를 위해 무엇을 바꿔야 하는지 계획을 보여줘
- 데이터 저장은 무료로 시작할 수 있는 데이터베이스(Upstash Redis 등)를 추천해줘
- 7장에서 만든 통제 장치들(욕설 필터, 도배 방지, 검증, 모니터링)이
배포 후에도 작동하는지 계획에 포함해줘
※ 이후 대화형 선택 — 데이터 저장: "1. Upstash Redis (추천)" / 실시간 갱신(SSE 불가): "1. 폴링으로 전환 (추천)" / Review → Submit → "Ready to code?"에서 "1. Yes, and use auto mode" 승인. 화면에서 Upstash Redis가 1번이 아니면 Upstash Redis를 선택합니다(책과의 동기화 목적).
수정 완료 후 — GitHub에 푸시 (9.5에서 만든 명령어)
/저장
※ 이후는 브라우저 작업(Claude Code가 알려주는 "다음 단계"): ② Vercel → Import qa-board → Preset: Express 확인 → Deploy ③ Storage → Upstash for Redis 생성(Region: Tokyo/Singapore, Free 플랜) → qa-board에 Connect(접속 정보 자동 주입) ④ Settings → Environments → Production → Environment Variables에 ANTHROPIC_API_KEY 추가 ⑤ Redeploy.
10.3.3 환경 변수 — Vercel의 전용 금고 Environment Variables
등록 값 (Add Environment Variable 화면)
Key : ANTHROPIC_API_KEY
Value : sk-ant-api03-… (7.8에서 발급한 Claude API Key)
Environments : Production → Save → Redeploy
※ .env는 9장에서 금고 반입 금지 목록에 넣어 GitHub에 없습니다. Vercel 환경 변수에 직접 등록하면 코드에도, GitHub에도 비밀이 없는 구조가 됩니다. Upstash 열쇠(KV_URL 등)는 Storage 연결 시 자동 주입됩니다.
10.3.4 배포 — LTE/5G의 순간 사람의 확인 4종
확인 1: LTE/5G로 접속되는가? (와이파이 꺼짐 확인)
확인 2: 스마트폰에서 등록한 질문이 컴퓨터 브라우저에서도 보이는가?
(= 데이터베이스가 작동한다는 증거)
확인 3: 컴퓨터를 종료한 상태에서도 접속되는가?
확인 4: 7.2의 욕설 필터가 배포된 서비스에서도 작동하는가?
(금지어를 등록해 볼 것 — 파괴 테스트는 어디서나)
※ 접속 주소는 프로젝트 화면의 Domains(예: qa-board-kohl.vercel.app). QR 공유 — "Visit" 옆 화살표를 누르면 QR 코드가 나옵니다. 배포 실패 시 부록 A.2("Vercel 빌드 에러"·"데이터 저장 안 됨"·"AI 답변만 실패").
10.4 맛집 추천 챗봇 배포 — ① 검문 · ② 비공개 푸시 food-chatbot · 9장 재사용
① GitHub에 올리기 전 검문 (food-chatbot 폴더에서)
GitHub에 올리기 전에 검문을 하자.
## 임무
- 이 프로젝트에서 API 키, 비밀번호, 개인 정보(사용자 질문, 로그, 데이터 파일)가
들어 있는 파일을 전부 찾아줘
- 그런 파일들이 GitHub에 올라가지 않도록 .gitignore를 만들어줘
- node_modules처럼 올릴 필요 없는 폴더도 제외해줘
## 보고
- 무엇을 제외했고, 왜 제외했는지 표로 보여줘
② 비공개 저장소로 푸시 (XXXXXXXX는 본인 계정)
이 프로젝트를 GitHub에 비공개(private) 저장소로 올려줘.
## 조건
- GitHub 계정: XXXXXXXX
- 저장소 이름: food-chatbot
- 나는 GitHub 계정만 있고, 이 컴퓨터에서 GitHub을 처음 사용해
- 필요한 도구 설치나 인증이 있으면 단계별로 안내해줘
## 완성 후
- 내가 브라우저에서 확인할 수 있는 저장소 주소를 알려줘
※ 9장에서 이미 GitHub을 사용했더라도 "처음 사용해"라고 적어 걱정 없습니다 — 연결이 준비돼 있으면 Claude Code가 기존 연결을 사용합니다.
10.4 ③ Plan 모드 — 서버리스 전환 + 지갑을 지키는 방어 Plan 모드 · 도배 방지 필수
계획 요청 프롬프트 (Plan 모드 켠 뒤)
이 챗봇을 Vercel에 배포하고 싶어.
## 알고 있는 것
- Vercel은 서버리스라서 지금처럼 파일(chats 폴더)에 데이터를 저장할 수 없다고 들었어
- GitHub 저장소(food-chatbot)와 Vercel 계정은 준비되어 있어
## 요청
- 배포를 위해 무엇을 바꿔야 하는지 계획을 보여줘
- 데이터 저장은 무료로 시작할 수 있는 데이터베이스를 추천해줘
- 같은 사용자의 짧은 시간 내 질문 횟수와 하루 전체 질문 수를 제한해줘.
이 기록은 Vercel의 각 실행 공간에 따로 저장하지 말고,
모든 실행이 함께 사용하는 데이터베이스에 저장해줘.
- 여러 질문이 거의 동시에 들어와도 횟수가 빠지거나 중복 계산되지 않도록 만들고,
제한 방법과 그 한계를 쉬운 말로 설명해줘.
- 하루 전체 질문 수에도 상한을 둬서, 상한을 넘으면
"오늘은 마감되었습니다"라고 답하게 해줘.
※ 대화형 선택 — 하루 상한: "1. 300건/일 (Recommended)" 등에서 선택(처음엔 낮은 값으로 시작해 실사용을 보며 늘리는 것도 좋은 전략) / 도배 식별 기준: "1. IP 주소 (Recommended)" (세션 ID는 우회가 쉬워 권장 안 함 — reviewer가 지적했던 부분).
④~⑥ 이후 브라우저 작업
④ Storage: food-chatbot용 새 Upstash Redis 생성·연결 권장
(qa-board와 공유 시 데이터 이름 충돌 방지 작업 필요)
Settings → Environment Variables에 3종 등록:
ANTHROPIC_API_KEY / NAVER_CLIENT_ID / NAVER_CLIENT_SECRET
(선택: DAILY_CAP — 비우면 300)
⑤ Redeploy
⑥ LTE/5G 확인
⑥ 사람의 확인 3종
확인 1: LTE/5G에서 질문했을 때, 배포된 서버가 네이버 지역 검색 API를 호출해
실제 가게 정보를 가져오는가? 추천 결과에 가게 이름·주소·검색 출처가 표시되는가?
확인 2: 연속 질문을 빠르게 보내면 차단되는가?
확인 3: GitHub의 food-chatbot 저장소에 .env가 없는가?
다른 코드 파일에도 Claude API 키, 네이버 Client ID와 Client Secret이
직접 적혀 있지 않은가? (검문 재확인)
10.5 수정하고, GitHub에 올리면 — 자동 배포의 완성 가장 마법 같은 실습
실험 1 — 스마트폰으로 배포 화면을 열어 둔 채, 컴퓨터에서
대화창 맨 위의 "맛집 박사" 옆에 "since 2026"이라는 문구를 작게 추가해줘.
※ 말하기 → Claude Code 수정 → GitHub 푸시 → Vercel 자동 배포(Ready) → 스마트폰 새로고침. 실제 검사 완료와 GitHub 업로드 여부는 직접 확인합니다.
실험 2 — 500 에러 해결: 에러 번호만 줄 때 (기본)
다음과 같은 에러가 발생한다.
500: INTERNAL_SERVER_ERROR
Code: FUNCTION_INVOCATION_FAILED
ID: icn1::f6rj7-1782338976703-bb0b25399984
실험 2 — Vercel Logs의 상세 메시지까지 줄 때 (더 빠르고 정확)
다음과 같은 에러가 발생한다.
500: INTERNAL_SERVER_ERROR
Code: FUNCTION_INVOCATION_FAILED
ID: icn1::f6rj7-1782338976703-bb0b25399984
에러를 찾아보니 다음과 같다:
📝 맛집 검색 도구 활성화 (네이버 지역 검색)
Invalid export found in module "/var/task/server.js".
The default export must be a function or server.
Node.js process exited with exit status: 1.
The logs above can help with debugging the issue.
※ 상세 로그는 Vercel 대시보드 → Logs → 빨간 글자 클릭으로 확보합니다. 전달 전 API 키·비밀번호·사용자 질문·이메일 같은 민감 정보가 없는지 확인하고, 민감한 값은 ***로 가린 뒤 오류 시각과 함께 전달하세요. 수정 후에는 같은 기능을 다시 실행하고 Vercel 로그·사용자 화면을 직접 확인합니다.
10.6 배포 후 통제 체계 작동 확인 — 5가지 고삐 재점검 사람의 확인 3종
확인 1: 일부러 망가뜨린 배포를 롤백으로 복구해 봤는가?
(Deployments 목록 → 이전 Ready 배포 → 롤백 실행.
롤백은 코드 버전만 되돌림 — DB의 질문·환경 변수·외부 데이터는 그대로)
확인 2: 스마트폰 접속이 Vercel 로그에 실시간으로 찍히는가?
(Logs 메뉴 — 배포 직후엔 비어 있다가 접속 순간 줄이 올라옴)
확인 3: 관리자 대시보드가 배포된 주소에서 로그인한 관리자에게만 열리는가?
관리자 암호는 코드나 GitHub에 직접 적지 않고 Vercel 환경 변수에 저장했는가?
잘못된 암호를 여러 번 입력하면 잠시 차단되는가?
(7.6의 NOTE — 이제 정말 중요합니다)
※ 7.6의 대시보드가 "서비스 내용"의 CCTV라면, Vercel 로그는 "건물 출입구"의 CCTV. 데이터 구조를 바꾼 뒤에는 이전 코드와 현재 데이터가 함께 작동하는지도 확인해야 합니다.