← 자료실 홈
직접 코딩 0% — CLAUDE CODE로 진짜 서비스 만들고 배포·운영까지

7장. 통제 장치 적용하기 ①

익명 질문 게시판 — 문제를 겪고, 다섯 고삐로 통제하는 실전

직접 코딩 0%1 / 20
7.1 시작 전 — 결정적 차이 하나

전단지에서 카페 카운터

지금까지 — 아티팩트 = 전단지

보여주는 것이 전부. 데이터는 어디에도 남지 않고, 브라우저를 닫으면 끝. 전단지끼리 서로 연결되지 않습니다.

이번 장 — 서버(Server) = 카페 카운터

여러 브라우저가 같은 게시판을 보고, 한쪽의 질문이 다른 쪽에도 나타나고, 닫았다 열어도 데이터가 남습니다. 주문을 받고·기록하고·관리하는 카운터가 내 컴퓨터에서 실행됩니다.

5장 감정 일기장은 "혼자 쓰는 카페"였습니다. 이번엔 많은 손님이 동시에 줄 서는 카페 — 줄을 세우고, 100번 주문을 막고, 쓰러진 카운터를 다시 세우고, 매출을 확인해야 합니다. 그게 바로 5가지 고삐입니다.

직접 코딩 0%7.1 서버란2 / 20
7장의 흐름

문제 5개, 고삐 5개, 실습 3개

BUILD · 기본 서비스
7.1[실습] 익명 Q&A 게시판 구축
CONTROL · 문제와 고삐
7.2부적절한 글 → 규칙
7.3도배 → 울타리
7.4답변 오류 → 검증
7.5서버 중단 → 안전벨트
7.6현황 파악 → 모니터링
EXPAND · 비교와 확장
7.7통제 전후 비교
7.8[선택] AI 자동 답변
7.9[실습] 기념일 카운트다운
7.10[실습] 통합 관제센터
7.11이 장에서 달라진 것들
학습 리듬문제 발견 → 고삐 적용 → 증거로 재검증
직접 코딩 0%7장 · 목차3 / 20
7.1 [실습] 익명 Q&A 게시판

이름표를 떼면, 좋은 질문이 나옵니다

프롬프트 핵심 (mkdir qa-board → cd → claude)

· 익명 질문 등록 + 실시간 목록 + 좋아요 투표
관리자 화면에서 답변 작성·게시 (3줄 이내)
데이터는 data 폴더에 JSON 저장 · 초록+흰색 톤 · 375px 반응형
★ 체크리스트 7항목 — 특히 "브라우저 두 개에서 열고, 한쪽 질문이 다른 쪽에 새로고침 없이 나타나는가"
매 단계 상태 출력 + 증거 요구 + 실패 시 재검증

[단계 0] 환경 확인 ✅ Node v20
[단계 1] 서버/데이터 계층 ✅
[단계 2] 메인 화면 ✅ [단계 3] 관리자 ✅
[단계 4] 서버 기동 ✅ localhost:3000
[단계 5] 체크리스트 검증 — 콘솔 에러:
  favicon 404 발견 → 수정 → 재검증 0건 ✅
☑ 완성 — 전부 실제 테스트로 통과 (그림 7.2)

localhost:3000 = "내 컴퓨터 안의 주소", 카페의 우리 가게 정문. 안 뜨면 npm start(=카페 오픈). 접속 불가 시 부록 A.2.

'익명으로 모은다'는 어디에나 통합니다 — 의견을 받으면 만족도 설문, 칭찬을 받으면 롤링페이퍼, 제보를 받으면 사내 건의함. 공개(QR 접속)는 10장 배포에서.

직접 코딩 0%7.1 게시판 구축4 / 20
7.2 첫 번째 문제 → 고삐 ① 규칙

"야 이 씨X 수업 왜 이따위로 해" — 필터가 없다

규칙 추가 프롬프트

1. 욕설·비속어 → 차단 + "부적절한 질문입니다"
2. 개인정보(이름·연봉·주소) 질문 → 차단
3. 주제 무관 질문 → "주제와 관련된 질문을 해주세요"
4. 차단 질문은 관리자 화면에서만 보이게
+ CLAUDE.md에도 규칙 추가, ★ 체크리스트 4항목 + 증거

우리가 한 일 — 코드 수정이 아니라 자연어로 규칙을 적은 것. Claude Code가 filter.js를 만들어 등록 전에 거치도록 연결했습니다. (그림 7.7~7.8)

단어·패턴 필터는 변형 욕설을 놓치거나 정상 질문을 잘못 막을 수 있음 — 변형 표현과 정상 질문을 직접 넣어 시험하고, 운영 중 발견 사례를 계속 추가.

NOTE — 규칙은 어떻게 힘을 갖는가: 적은 것은 규칙(고삐 1)이지만, 작동하는 것은 AI가 만든 필터 코드(고삐 2의 형태)입니다. 사람이 말로 적고, AI가 어길 수 없는 장치로 바꾼다 — 고삐는 첫 실습부터 함께 작동합니다. 4장의 "한국어로 답해줘"가 편의의 규칙이었다면, 이것은 안전의 규칙. (법적 책임은 11장)
직접 코딩 0%7.2 규칙 적용5 / 20
7.3 두 번째 문제 → 고삐 ② 울타리

도배는 욕설이 아니라 — 규칙에 안 걸립니다

울타리 프롬프트 — "얼마나"의 경계

1. 10초 이내 재질문 → "잠시 후에 다시 질문해주세요"
2. 길이 최소 5자 ~ 최대 300자
3. 같은 내용 연속 → 차단
4. 1분에 5개 이상 → 5분간 입력 차단

★ 파괴 테스트 — "네가 알아서 부숴봐"

빈칸만·공백 300개 + "추가 시나리오를 최소 2개 발굴할 것"
→ 저자 실행 시 AI가 8개를 추가 발굴: 제로폭 공백, 공백 패딩 위장, 필드 누락, 잘못된 JSON, 사용자별 제한 격리, 경계값 5·300자, 슬라이딩 윈도우… 전부 통과 (그림 7.9)

규칙이 "무엇을 하면 안 되는지"를, 울타리가 "얼마나 할 수 있는지"를 정합니다 — Lv.2 달성. 단, 브라우저·네트워크를 바꾸는 우회까지 완전히 막지는 못함 — 공개 서비스에는 서버·DB의 공통 기록 기반 제한이 필요(10장). AI가 한 일: rate-limiter.js를 만들어 필터(고삐1) → 제한(고삐2) 순으로 연결.
직접 코딩 0%7.3 울타리 설정6 / 20
7.4 세 번째 문제 → 고삐 ③ 검증

틀린 답변이 그대로 게시되었다 — 2단계 검증

1단계 · 자동 — 코드가 먼저 걸러냄

· 숫자·날짜 포함 답변 → "검증 필요" 태그 자동 부착
좋아요 집계·정렬 자동 테스트 (5>3>1 정렬, 10번 → 정확히 10 증가)
화면 좋아요 수 ≠ 실제 기록 수 → "집계 불일치" 경고

이것은 사실 검증이 아니라 위험 표시 — 사람이 확인할 답을 골라내는 것.

2단계 · 수동 — 사람이 최종 확인

· "검증 필요" 답변은 게시 보류 → "검증 대기" 상태
관리자가 원문·공식 안내와 대조 후 승인 게시 또는 수정 후 게시 (그림 7.11~7.12)

6.3의 루프가 처음 완전체로 돕니다 — 위험한 답변 앞에서 고리가 멈추고 사람을 기다림. '고리 안의 사람' = 당신.

NOTE — 기대 결과를 먼저 적고 자동 테스트로 확인한 것: 비개발자의 TDD 경험입니다. 남은 두 한계 — ① 형식 검증은 "숫자가 진짜인지"를 모름 ② 출제자와 채점자가 같은 AI(검증 코드도 Claude Code 작품). 둘 다 8장에서 해결.
직접 코딩 0%7.4 검증 적용7 / 20
7.5 네 번째 문제 → 고삐 ④ 안전벨트

서버가 죽었다 — 죽은 코드는 스스로를 살릴 수 없다

규칙·울타리·검증은 전부 "정상 작동 중"의 일 — 서버가 죽으면 셋 다 무용지물.
멈춘 코드는 "5초 후 재시작"을 실행할 수 없으니, 외부의 감시자가 필요합니다.

  • PM2 = 서버가 죽으면 자동으로 다시 켜주는 프로세스 매니저 — "알바가 쓰러지면 대타를 불러주는 매니저"
  • 요구사항: ecosystem.config.js 생성 · 종료 시 5초 후 재시작 · 5분에 3번 초과 시 "심각한 문제" 경고 · 데이터 유지 · restart-log.txt 기록
  • 핸들의 원리를 몰라도 운전하듯 — 검증된 기술이니 믿고 쓰면 되는 명령
주의 — PM2는 "비정상 종료 시 재실행" 장치입니다. 코드를 이전 버전으로 되돌리기(9장 Git)·배포 버전 복구(10장 Vercel 롤백)와는 다른 복구. JSON 파일 저장은 실습용 — 동시 쓰기 충돌이 나는 실전에서는 DB를 씁니다(10장). Lv.3 완성.
직접 코딩 0%7.5 안전벨트 구성8 / 20
7.5 안전벨트 — 직접 죽여보기

정말 살아나는지, 서버를 직접 죽여봅니다

$ npx pm2 start ecosystem.config.js # 카페 오픈
qa-board │ status: online │ ↺ 0
$ cat ~/.pm2/pids/qa-board-0.pid # 식별번호 확인
8312
$ kill -9 8312 # Windows: taskkill /PID 8312 /F
$ npx pm2 status
qa-board │ status: online │ ↺ 1 ← 재시작 횟수 증가!
  • 죽인 직후 접속하면 "사이트에 연결할 수 없음"(그림 7.18) — 그리고 수 초 내 부활
  • PM2가 너무 빨라 오류 화면을 못 볼 수도 — 재시작 횟수(↺)나 pid 변경으로 확인하는 것이 확실
  • 명령 4종: start · status · logs · stop

번거로울 뿐 어렵지 않은 과정 — 꼭 직접 해보기를 권합니다. "죽으면 자동으로 살아난다"를 눈으로 확인하는 순간, 안전벨트가 체감됩니다.

직접 코딩 0%7.5 재시작 실험9 / 20
7.6 다섯 번째 과제 → 고삐 ⑤ CCTV

이번엔 문제가 아니라 궁금증입니다

관리자 대시보드 — 보여줄 7가지

현재 접속자(실시간) · 오늘 질문/답변 수 · 차단 질문 수 · 검증 대기 수 · 서버 응답 시간 · 오늘 재시작 횟수 · 최근 1시간 질문 추이 그래프

URL은 /admin/dashboard, 로그인한 관리자만 접속. 파괴 테스트: 데이터 0건 표시, 비로그인 접근 거부 + AI 추가 발굴 2개.

접속하면 모든 현황이 한눈에(그림 7.22) — 문제가 생기기 전에 "뭔가 이상하다"를 알 수 있습니다.

Lv.4 달성 — 5가지 고삐 완성. Q&A 게시판은 이제 "통제된 서비스"입니다.

기본 암호('admin')는 반드시 바꾸세요 — 지금은 내 컴퓨터뿐이지만 Part 4에서 공개되는 순간 누구든 들어올 수 있습니다. "관리자 암호를 내가 정한 것으로 바꾸고 .env에서 읽어오게 해줘" — 이것도 울타리(고삐 2)입니다.
직접 코딩 0%7.6 모니터링10 / 20
7.7 비교 — 같은 명령, 전혀 다른 결과

통제 없이 vs 5가지 통제 적용

상황통제 없는 게시판5가지 고삐를 채운 게시판
욕설 입력그대로 전체 공개차단 + 관리자 화면에만 보관
도배 시도목록이 도배로 뒤덮임쿨타임·중복·횟수 제한이 자동 차단
숫자 든 답변 실수틀린 답이 그대로 게시"검증 대기" → 관리자 승인 후 게시
서버 다운수업 중단, 수동 복구까지 정지PM2가 수 초 내 자동 재시작 + 기록
이용 현황알 방법 없음대시보드에서 실시간 확인

코드는 한 줄도 직접 쓰지 않았습니다 — 문제를 말로 설명하고, 경계와 시험과 복구를 요구했을 뿐.
이것이 하네스 엔지니어링입니다.

직접 코딩 0%7.7 비교11 / 20
7.8 [선택 실습] AI 자동 답변 — 준비

고삐의 진짜 무대 — 먼저 지갑에 울타리부터

Claude API 크레딧 준비 (console.anthropic.com)

① Console 가입 → 크레딧 화면에서 $5만 충전 (+세금 $0.50)
"자동 새로고침(자동 충전)"은 반드시 끄기 — $5를 다 쓰면 AI가 멈출 뿐, 비용 폭발이 물리적으로 불가능
③ 구매 버튼 비활성화? 주소 "자동 채우기" 오류 의심 — 빈칸 직접 확인 (그림 7.27~7.31)

API Key — 유료 기능의 출입증

· "API 키 받기" → 생성 → 그 화면에서 즉시 복사 (다시 못 봄)
sk-ant-로 시작하는 문자열 = 인증 정보. 절대 타인 공유 금지, 코드·캡처·대화창에도 적지 않기
유출 의심 시 Console에서 즉시 폐기·재발급 (그림 7.32~7.37)

NOTE — Key는 시스템 환경 변수가 아니라 프로젝트 폴더의 .env 파일에만. 시스템 전역에 넣으면 Claude Code가 구독 대신 API로 과금해 크레딧이 엉뚱하게 소진됩니다. .env는 금고가 아닌 일반 텍스트 — .gitignore 등록 확인(9장). 확장자 함정(.env.txt)은 4장 CLAUDE.md 때와 동일.
직접 코딩 0%7.8.1 Key 발급 · 비용 울타리12 / 20
7.8.2 AI 자동 답변 추가

게시판 안에 "실행 중 스스로 판단하는 AI"가 들어왔다

프롬프트 핵심

· 관리자 화면에 "AI 자동 답변" 버튼 — .env의 Key로 Claude API 호출, 3줄 이내 답변 생성
현재 사용 가능한 Haiku 모델 ID를 확인해 적용하고 보고에 명시
생성 답변은 관리자 검토 후 게시 (그림 7.38~7.42)

모델 선택 — Opus / Sonnet / Haiku

Opus: 복잡한 추론, 느리고 크레딧 큼 · Sonnet: 속도·지능 균형 · Haiku: 가장 빠르고 저렴

짧은 답변·낮은 비용 우선이므로 Haiku — 단 중요한 답변은 모델과 무관하게 근거 확인 + 관리자 검토.

이중 안전장치 — AI 답변은 곧바로 게시되지 않고 관리자 입력창으로 들어가며, "답변 게시"를 눌러도 기존 검증 파이프라인(숫자·날짜 → 검증 대기)을 한 번 더 거칩니다. 문제는 — 이 AI가 무슨 말을 할지 우리가 미리 알 수 없다는 것.
직접 코딩 0%7.8.2 AI 자동 답변13 / 20
7.8.3 같은 5고삐, 다른 무게

AI의 출력에 고삐를 재적용합니다

고삐AI 답변에 적용한 내용
① 규칙욕설·차별·위험 내용이 있으면 게시하지 않음
② 울타리답변 3줄 이내 · AI 호출 분당 횟수 제한
③ 검증단정 표현 → "정확하지 않을 수 있음" 면책 · 숫자·날짜·범위 → "관리자 확인 필요" 태그
④ 안전벨트API 실패 시 앱은 계속 동작 + "관리자가 직접 답변해 주세요" 표시, 무한 재시도 금지·원인 로그
⑤ CCTV호출 수·응답 시간·토큰·예상 비용·면책 답변 수 → /api/ai-status 에서 JSON 조회

무관한 질문("이성원 교수에 대해 설명하라") → "제공된 자료가 없어 확실히 답변할 수 없습니다. 관리자에게 문의하세요. ※ 정확하지 않을 수 있습니다." (그림 7.43) — 태그는 오답의 증거가 아니라 사람이 대조하라는 신호입니다.

TIP — 7.4의 검증은 "코드가 짠 집계"(같은 입력 → 같은 결과, 검증 쉬움), 7.8의 검증은 "매번 새로 지어내는 말"(매번 다르게 틀릴 수 있음). 자율적으로 동작하는 AI 앞에서 고삐는 선택이 아니라 생존 조건. 크레딧 사용량은 Console '분석 → 사용량'에서 확인 — 예상보다 줄었다면 멈추고 호출 로그부터.
직접 코딩 0%7.8.3 AI 출력 통제14 / 20
7.8.4 비교표

코드 통제 vs AI 통제 — 같은 이름, 다른 긴장감

고삐코드 답변 (7.1~7.7)AI 답변 (7.8)
규칙정해진 문구라 위반 자체가 드묾무슨 말을 할지 몰라 차단 규칙이 필수
울타리길이·횟수 형식적 제한폭주·비용까지 막는 실질 제한
검증같은 조건 → 같은 결과, 반복 검증 쉬움같은 질문에도 답이 달라짐 — 지속 검증 필수
안전벨트서버 다운 대비외부 API 실패까지 대비
모니터링접속·요청 지표호출·토큰·비용·면책까지 관측

정해진 출력에는 고삐가 형식적이지만 — 스스로 판단하는 출력 앞에서 고삐는 생존의 조건입니다.
하네스 엔지니어링이 특히 중요한 곳: 실행할 때마다 새로운 답을 만드는 생성형 AI 기능.

직접 코딩 0%7.8.4 코드 통제 vs AI 통제15 / 20
7.9 [실습] 커플 기념일 카운트다운

"사후 대응"에서 "사전 설계"

CLAUDE.md — 처음부터 5고삐 내장 (d-day-countdown)

기능: 커플 이름+시작일 → "사귀기 000일째", 100·200·365일 카드, 하트 애니메이션, PNG 저장, 포트 3100
고삐 1 비속어 이름 차단·부정 표현 교체·"사랑해" 금지 · 고삐 2 미래 날짜 불가·이름 1~20자·새로고침 1분 3회 · 고삐 3 D-day 자동 테스트 · 고삐 4 PM2 · 고삐 5 /api/stats 통계 + ★ 체크리스트 8항목

Skill.md — 감성 메시지 큐레이션 전문가

· 톤: 따뜻하되 과하지 않게, 구체적 장면 언급 ("우리가 처음 만났던 그 카페처럼…")
길이 3~5문장 · 기념일별 톤 변화 (100일 설렘 → 200일 편안 → 365일 감사)
금지: "사랑해" 직접 사용 · "영원히"·"죽을 만큼" · "반드시" 같은 의무 표현

실행 프롬프트는 역시 두 줄 — "CLAUDE.md를 읽고 만들어줘…"

7.1~7.6은 문제가 터진 뒤 고삐를 채웠지만, 이번엔 작성 시점에 5고삐를 모두 설계 — 하네스 엔지니어링의 성숙한 형태입니다. 7.8을 건너뛴 독자도 OK(API 미사용). 확인 핵심은 5번: 메시지에 "사랑해"가 없는가 — Skill.md가 품질을 통제하는 증거.
직접 코딩 0%7.9 사전 설계 실습16 / 20
7.9.3 통제하기 · 응용

다듬고, 공유하고, 변신시키기

통제 — 외형 개선도 회귀 검증과 함께

"카드 배경을 파스텔 핑크 그라데이션, 손글씨 폰트로 + PNG 다운로드 + 카카오톡 공유 버튼. 수정 후 기존 체크리스트 7개가 여전히 통과하는지도 확인해줘." (그림 7.49~7.50)

응용 — 하나의 구조, 여러 서비스

"커플 기념일" → "팀 프로젝트 D-day", "수능 D-day", "여행 카운트다운". Skill.md의 톤을 "응원 메시지"로 바꾸면 수능 앱 완성. Part 4에서 배포하면 공개 URL — 연인에게 "이거 내가 만들었어"라고 보내세요.

AI가 메시지를 직접 만들게 하려면 (선택)

Skill.md에 "메시지 생성 방식" 절 추가 — Claude API(Haiku) 사용, Key는 서버 .env에서만, 톤·금지 규칙 준수, /api/ai-status 지표 제공 → "이 규칙을 읽고 수정해줘".

직접 코딩 0%7.9.3 통제·응용17 / 20
7.10 [실습] 통합 모니터링 관제센터

매장이 두 개 — CCTV에서 관제센터

monitoring-hub (포트 4000, API 미사용)

· 대상: Q&A 게시판(3000) + 기념일 앱(3100)
공통 지표: 온라인/오프라인 초록불·빨간불, 접속자, 오늘 요청, 에러, 재시작 횟수, 1시간 추이 — 각 서비스의 /api/stats에서 수집
AI 지표 자동 감지: /api/ai-status 응답이 오면 표시, 404면 영역 자체를 숨김(에러 아님)
어두운 배경 + 밝은 카드, 5초 자동 갱신

확인 — 기념일 앱을 kill로 죽여도 PM2가 즉시 살려 대시보드는 태연 → 하지만 "서버 재시작: 1회"가 증거를 남깁니다(그림 7.53).

통제 — "오프라인/재시작 시 ▲ [시각] 팝업 경고 + 기존 체크리스트 재확인" (그림 7.55)

확장 가능한 모니터링 — 새 서비스가 /api/stats만 제공하면 config.json에 URL 추가로 끝. 서비스가 10개가 되어도 한 화면.

세 서비스 일괄 관리: 각 폴더에서 npx pm2 start ecosystem.config.js — 종료는 npx pm2 stop qa-board / d-day-countdown / monitoring-hub (그림 7.56~7.61).

직접 코딩 0%7.10 관제센터18 / 20
7.11 이 장에서 달라진 것들

Lv.1 → Lv.4 — 문제 → 해결 → 고삐, 5번의 반복

문제해결채운 고삐
부적절한 글CLAUDE.md에 필터 규칙 추가① 규칙 쓰기 (Instructions/Rules)
도배쿨타임·길이 제한·중복 차단② 울타리 치기 (Guardrails)
답변 오류자동 검증 + 관리자 승인 + 자동 테스트③ 시험 보기 (Testing/Evals)
서버 다운PM2 자동 재시작④ 안전벨트 (Auto-recovery)
상태 파악 불가실시간 모니터링 대시보드⑤ CCTV (Monitoring/Observability)
직접 코딩 0%7.11 정리19 / 20
7장 마무리 — .md 파일 체계의 완성을 향해

CLAUDE.md(4장) = 회사 규정 · Skill.md(5장) = 자격증 —
그리고 8장에서 .claude/agents/의 직무기술서가 더해져,
'만드는 AI'와 '검사하는 AI'의 역할이 마침내 분리됩니다.

NEXT · 8장. 맛집 추천 챗봇 — 출제자와 채점자의 분리

형식 검증을 넘어 내용 검증으로, 성숙도 Lv.5로.
※ 8장은 Claude API를 사용합니다 — 7.8을 건너뛴 독자는 먼저 7.8(Key 발급)을 마치고 오세요.

직접 코딩 0%20 / 20
1 / 20 · ←/→ 이동 · F 전체화면