Archive
Codex와 GPT image2, 그리고 하네스 엔지니어링으로 바이브코딩해보기 (feat. 초1 수학공부앱)
실밸개발자 채널의 [코덱스로 바이브 코딩하기 (feat. 하네스 엔지니어링)](https://www.youtube.com/watch?v=GJQ0rNvTfPw&t=1811s) 라이브를 보고, 그 내용을 제 기존 프로젝트 `math_assist`에 직접 적용해본 실습 기록입니다.
Details

영상에서 내가 얻은 Highlight
실밸개발자님의 130분짜리 영상의 포인트들 중 제가 따라 해본 건 3 가지였습니다.
-
하네스 세팅 — 코딩 전에 작업 환경부터 만든다. 안내문(AGENTS.md)과 검문소(hooks)를 분리해서, 진짜로 막고 싶은 건 hook으로 막습니다.
-
계획 수립 시 여러 번 개선을 요구하기 — 첫 번째 계획에서 바로 승인하지 않기! 계획은 3~5회 다른 각도에서 다시 검토해달라고 요청하면 결과 품질이 눈에 띄게 달라집니다.
-
30~40% 룰 — 컨텍스트(기억 공간)가 차오르면 AI의 머리는 복잡해지기 시작합니다(이른바 context rot). 채워질 때까지 끌고 가지 말고, 한 단계 끝나면 핸드오프를 남기고 새 세션에서 다시 연다. (혹은 /clear , /compact )
출발점
math_assist는 원래 초등학교 5학년 수학 연습장이었습니다.
- 단원별 간단한 개념 설명과 연습문제 풀이 위주
- 이미지 지원 없이 연습문제 중심
- 9개 단원, 총 450개의 연습문제
(이 프로젝트는 제 딸을 위해 만든 것이고, 제게는 바이브코딩 시도 + 문제 생성 및 퀄리티 검수를 간단한 'Eval' 프로세스로 돌린 것에 의의가 있었습니다)
여기에 초등학교 1학년 학생들을 위한 수학 문제를 게임처럼 확장하는 것이 이번 작업의 목표였습니다.
5학년 연습문제 웹앱을 만들며 깨달은 점은,
- 기본이 어렵다는 것이었습니다. 문제의 난이도가 적정해야 하고, 정답이 정확해야 했습니다. (딸깍으로는 그러지 못함..)
- 문제를 충분히 많이 만드는 것도 어려웠습니다.
- 또 수학 공식이나 기호를 제대로 표현하는 것도 까다로웠습니다.
- 가장 어려운 점은 실제 고객이 흥미를 가지고 문제를 풀어볼 만큼의 완성도가 있어야 했습니다.
1학년 버전은 둘째 아들을 위해 만들려고 했는데요,
1학년은 무엇보다 고객(초딩1학년..)이 흥미를 가져야 겠다고 생각했습니다.
그러려면 게임처럼 만들어야 겠다고 생각했죠.
실밸 영상에서 배운 것과 gpt imgage2와 함께 하는 코덱스라면 뭔가 되지 않을까 생각해봤습니다.
그렇게 해서 나온 결과가 이것!!
https://outliner-coach.github.io/math_assist/
/media/posts/2026/05/ec2b0107-7a29-41e7-be4a-c0021fdb8a40-2026-05-10-6-22-33.png
그럼 실제로 어떤 프롬프트를 넣고 어떤 과정을 거쳐 이런 결과물이 나올 수 있었는지 살펴봅시다.
작업은 총 여섯 세션으로 나뉘었습니다. 각 세션마다 제가 실제로 던진 프롬프트를 그대로 남겨 보겠습니다.
세션 1: 세팅
첫 세션의 목표는 단순했습니다. 코드를 짜기 전에 작업 환경부터 세팅하기
여기에 5번의 프롬프트를 입력했습니다.
1. https://github.com/jha0313/harness_framework 을 폴더에 다운로드 하고 하네스 프레임워크를 세팅해주세요.
2. 하네스를 코덱스에 맞게 바꿔주세요.
.claude > .codex
claude.md > codex.md
훅도 코덱스에 맞게 바꿔주세요.
3. 작업 시마다 테스트가 없으면 테스트를 만드는 tdd 강제 훅이 있나요?
4. https://github.com/nizos/tdd-guard 이걸 쓰면 가능한가요?
5. 우리가 만든 걸 사용하되, 아래 글을 참고해서 tdd-guard에서 차용할 부분을 차용합시다.
다섯 번째 프롬프트에 같이 붙인 글의 핵심은 영상에서도 강조됐던 “안내문 vs 검문소” 구분이었습니다.
AGENTS.md는 안내문이지 검문소가 아닙니다. 거기 “TDD 사용해라”라고 써 두는 건 강제가 아닙니다. AI가 어떤 행동을 못 하게 진짜로 막고 싶으시면, hook(자동 검사 장치)을 써야 합니다. 안내문은 무시당할 수 있지만, 검문소는 통과해야만 지나갑니다.
이 한 문단이 이번 작업 전체의 방향을 정해 줬습니다. 적어 두는 것과 막아 두는 것은 다릅니다. 그래서 외부 도구(tdd-guard)를 그대로 가져다 붙이는 대신, 우리 프로젝트의 변경 파일을 기준으로 동작하는 단순한 가드를 직접 만드는 쪽으로 갔습니다. 영상의 권고 중 “오픈소스 하네스를 그대로 쓰지 말고, AI에게 우리 프로젝트와 비교 분석시킨 뒤 차용할 부분만 가져오라”와 같은 결의 선택이었습니다.
여기서 또 한 가지 짚어 둘 점은 “이름만 바꿔주세요”로는 부족했다는 것입니다. .claude → .codex, CLAUDE.md → AGENTS.md 정도의 치환만으로는 하네스가 안 돕니다. 실행 경로, 훅 호출 방식, 단계별 커밋 흐름까지 코덱스에 맞춰 다시 짜야 했습니다.
세션 2: 세팅 계속 (훅 이슈가 있어서 수정)
세션 1에서 모양은 갖췄지만 실제로 훅이 매끄럽게 돌지 않았습니다. 두 번째 세션은 그래서 짧고 명확했습니다.
1. 현재 하네스 세팅이 되어 있습니다. 어떻게 되어 있나 확인해주세요.
2. 네 제대로 수정합시다. 그리고 tdd guard의 경우, 클로드코드 베이스이므로 코덱스에서도 잘 돌아가게 바꿔주세요.
“상태부터 확인해주세요”를 의도적으로 앞에 뒀습니다. 그냥 “고쳐주세요”라고 하면 에이전트가 머릿속에서 상상한 구조를 고치게 됩니다. 그러면 실제 파일과 어긋난 답이 옵니다. 이 세션 이후로 코드 수정의 첫 프롬프트는 거의 항상 “먼저 현재 상태부터 확인해주세요”가 되었습니다.
세션 3: 본격적인 기획 — 한 번에 안 묻는다
하네스가 굴러가게 된 뒤에야 본격적인 기능 기획에 들어갔습니다. 이 세션에서 영상의 “첫 번째 계획에 바로 코딩 시키지 마라”와 “계획을 3~5회 반복하라”를 본격적으로 따라 해봤습니다.
1. 앱에 초등학교 1학년을 위한 수학 기능을 추가하려고 합니다. 초등학교 1학년 수학 커리큘럼에 맞게 수학 문제를 풀 수 있게 하려고 해요. 그런데 이걸 게임처럼 만들려고 해요. 초등학교 1학년 아이들이 재미있어할 만한 게임을 확인하고 유사한 포맷으로 만들거에요.어떻게 만들면 좋을지 기획해주세요.
2. 무엇보다 아이들의 흥미를 끌 수 있어야 하고 수학을 재미있게 접근할 수 있어야 합니다. 사용자 관점에서 아이들의 니즈와 이 앱의 목적을 고려해서 계획을 보완해봅시다.
3. 문제들은 1학년이 풀기에 난이도가 적정해야 하고 정답이 맞아야 합니다. 문제와 정답의 퀄리티가 매우 중요한데 이 부분에 있어 보완할 부분은 없을까요?
4. ui, ux가 초등학생 사용자들에게 친화적일까요? 디자인은 첨부한 design.md를 참고하면 좋겠네요.
(design.md 출처: https://styles.refero.design/style/7088d695-362b-4e09-b325-fa8136d4f350)
5. imagegen 스킬을 사용해서 필요한 이미지와 아이콘셋, 그래픽 에셋을 확보하면 좋겠습니다.
6. /goal 1학년 게임형 수학 앱 그래픽 에셋 계획을 완수하여 브라우저 테스트까지 마친 상태로 실제 바로 사용할 수 있는 수준까지 구현해주세요.
/goal 한 줄도 영상에서 가져온 패턴입니다. 단순히 “이거 만들어줘”가 아니라, 목표와 끝나는 조건을 함께 박는 명령입니다. “브라우저 테스트까지 마친 상태로 실제 바로 사용할 수 있는 수준까지”가 거기서 “끝나는 조건”에 해당합니다.
한 번에 “1학년 게임 수학 앱 멋지게 만들어주세요”라고 던지면 결과는 그럴듯해 보이지만 어디 하나 단단한 곳이 없는 데모가 나옵니다. 한 축씩 좁히면서 합의를 만들고 마지막에 실행을 던지면, 에이전트가 자기가 동의한 기준대로 일을 합니다.
결과: 듀오링고 스타일의 게임형 연습문제 레이아웃이 나왔습니다. 단, 문제는 1개뿐이었습니다.
화면은 잡혔는데 콘텐츠는 데모 한 판이었습니다. 한 번에 끝나는 일이 아니었고, 여기서 세션을 끊는 게 맞다고 판단했습니다. 컨텍스트가 한참 차오르기 시작한 시점이었거든요. 영상의 30~40% 룰을 처음 적용한 지점이었습니다.
세션 4: 스케일업
세션을 새로 열고 다시 시작했습니다. 영상의 “30~40% 차면 새 세션에서 연다”는 권고가 여기서 처음 본격적으로 효과를 봤습니다. 이전 세션의 산출물(코드, 핸드오프, 단계 결과 파일)이 디스크에 남아 있으니, 새 세션은 그걸 다시 읽으며 시작하면 됩니다.
1. 지난 세션에서 1학년 수학 게임을 만들었습니다. 작업 내역을
확인해봅시다.
2. 1학년 문제가 현재 몇개인가요?
3. 이제 1학년 문제를 탐험섬 컨셉에 맞추어 스케일업해야 합니다.
확장 계획을 수립하고 에이전트들이 효율적으로 작업할 수 있게
구조를 만들어 줍시다.
4. 탐험섬 미션이 어떻게 확장되나요?
5. 이 스케일업 플랜에 대해 사용자 관점에서 더 보강할 부분은 없을까요?
6. 네 계획에 반영해주세요. 그리고 에러 핸들링 관점에서 추가로 고려할
점은 더 없을까요?
7. /goal 제안한 계획대로 브라우저 테스트까지 마친 상태로 실제 바로
사용할 수 있는 수준까지 구현해주세요.
이 세션의 프롬프트 패턴은 이렇습니다.
- 현재 상태 확인
- 숫자로 측정 가능한 사실 묻기 (“몇 개인가요?”)
- 계획 수립
- 결과 보여 달라 (“어떻게 확장되나요?”)
- 사용자 관점 보강
- 에러 핸들링 관점 보강
/goal로 실행
세션 3에서 익힌 “좁혀가기”가 정착됐고, 여기에 “지금 상태 확인”과 “관점별 보강”이 더해졌습니다. 사용자 관점과 에러 핸들링 관점은 따로 떼어 묻는 편이 결과가 좋았습니다. 한 번에 “좋게 만들어주세요”라고 하면 둘 다 어딘가 빠져 있곤 했거든요.
이 세션의 산출물은 24개의 결정론적 미션 템플릿, 수 세기 / 비교 / 10 이내 덧뺄셈 / 도형 문제, localStorage 진행 상태, 힌트와 재시도 흐름, 보상 공개 화면, validate:grade1 검증 스크립트, 단위 테스트와 Playwright E2E였습니다. 단계마다 TDD 가드가 통과했고, 단계 단위로 커밋이 남았고, phases/grade1-adventure-scaleup/index.json에 진행 상태가 기록됐습니다.
여기서 영상의 또 다른 권고가 자연스럽게 적용됐습니다. 큰 작업은 단계별로 쪼개서 외주처럼 흘려보낸다. 메인 세션이 모든 단계를 한 컨텍스트에 끌고 가지 않고, 각 단계가 별도 작업 단위로 실행돼서 결과만 디스크에 남깁니다. 다음 세션은 그 결과 파일들로 시작하면 되니까, 세션 길이를 의도적으로 짧게 유지할 수 있었습니다. 결국 컨텍스트 관리는 세션을 길게 끌고 가는 게 아니라, 세션과 세션 사이에 디스크가 기억하게 만드는 일이었습니다.
세션 5: 휴먼 인 더 루프 — 개선
여기서부터가 진짜 시작이었습니다. 만들어진 화면을 제가 직접 써봤고, 써본 사람만 보이는 결이 있었습니다.
1. UX 흐름에 개선할 점은 없는지 살펴봐주세요. 예를 들어 제가 써보니
문제를 풀고 바로 다음 문제로 이어가려면 '지도로 가기'를 누른 후,
'오늘의 추천 미션'을 선택하거나, 하단의 '오늘의 길'에서 다음
스테이지를 선택해야 해서 다소 번거롭네요.
2. 좋습니다. 작업을 다른 에이전트들이 이어서 작업할 때 작업 내역을
잘 확인하고 효율적으로 작업을 수행할 수 있게 문서화해주세요.
문서화가 완료되면 커밋과 푸시해주세요.
첫 프롬프트의 핵심은 “예를 들어”입니다. 추상적인 개선 요청 (“UX를 좀 더 매끄럽게”) 대신, 제가 실제로 마주친 동선을 그대로 적었습니다. 그러자 에이전트는 그 동선을 분해해서 보상 화면에 다음 미션 풀기 버튼을 직접 붙였습니다.
두 번째 프롬프트는 그 후로 거의 모든 세션의 마지막에 자리잡은 패턴이 됐습니다. 작업이 끝났다고 끝이 아니라, “다음 사람이 이어받을 수 있게 남겨주세요”까지가 한 단계의 끝이라는 정의였습니다. 영상에서 “기억 공간을 쓰지 않게 하는 가장 좋은 방법은 다음 세션이 디스크부터 읽기 시작하게 만드는 것”이라고 한 것과 같은 맥락입니다. 실제로 handoffs/2026-05-10-03-ui-and-visuals-codex.md 같은 파일이 이때 만들어졌고, 다음 세션은 “핸드오프 문서로 작업 내용을 먼저 확인해주세요”로 시작할 수 있게 됐습니다.
세션 6: 휴먼 인 더 루프 — 개선
또 한 번 직접 써보고 떠오른 두 가지를 모아 다시 던졌습니다.
1. 작업을 재개해봅시다. 개선 의견들이 몇가지 있습니다. 사용자 관점에서
각각의 개선사항을 검토하고 더 나은 사용자 경험을 제안해주세요.
1) 하단의 게임 설명이 있는데 이건 처음 시작 시에만 보이면 될 것
같습니다.
2) 보상을 받는데, 내가 받은 보상들을 확인할 수 없습니다. 하단에
내가 모은 보상의 종류와 개수를 확인할 수 있으면 좋겠어요.
2. 좋습니다. 제안대로 작업계획을 수립해주세요.
3. 좋습니다. 작업을 다른 에이전트들이 이어서 작업할 때 작업 내역을
잘 확인하고 효율적으로 작업을 수행할 수 있게 문서화해주세요.
문서화가 완료되면 커밋과 푸시해주세요.
여기서 의도적으로 한 게 두 가지 있습니다. 하나는 “이렇게 바꿔주세요”가 아니라 “사용자 관점에서 검토하고 더 나은 경험을 제안해주세요”라고 한 점입니다. 제 머릿속의 해결책을 그대로 받아 쓰게 하지 않고, 에이전트가 한 번 더 따져 보길 바랐습니다. 다른 하나는 두 가지를 한 번에 던져서 보상 수집과 안내 노출이라는 큰 흐름에서 일관되게 풀리도록 의도했습니다.
결과적으로 첫 시작 시에만 보이는 안내, 보물 가방이라는 보상 누적 화면, 보상 화면 안의 누적 개수 표시(숫자 조각 보상, 이제 1개예요.)가 묶음으로 들어왔습니다. 그리고 마지막 프롬프트는 또 동일했습니다. 작업 내역 문서화 → 커밋 → 푸시.
해보니 확실해진 것들
여섯 세션을 돌고 나서, 영상에서 짚어준 네 가지가 확실해졌습니다.
1. 하네스 세팅은 비생산적으로 보이는 가장 생산적인 시간이었습니다. 코드를 한 줄도 안 짠 첫 두 세션은 겉보기에 “아무것도 안 한 시간”처럼 보일 수 있지만, 그 뒤로 모든 세션이 그 위에서 굴러갔습니다. TDD 가드가 “테스트 없이 이 단계는 끝낼 수 없습니다”라고 한 번 막아주면, 그 다음부터는 “테스트 꼭 작성해주세요”라는 부탁이 필요 없어집니다. 적어 두는 것과 막아 두는 것은 정말로 다릅니다. AGENTS.md 같은 안내문은 “이렇게 하면 좋겠다”는 가이드일 뿐, 못 지나가게 막는 일은 결국 hook의 몫입니다.
2. 계획 수립을 여러 번 반복하는 것이 결과의 단단함을 결정했습니다. 영상에서 “첫 번째 계획에 바로 코딩 시키지 말라”고 한 게 가장 와닿았던 부분이었습니다. 한 번에 “좋게 만들어주세요”라고 하면 어딘가 비어 있는 결과가 나오고, 같은 일을 사용자 관점, 정확성, UI/UX, 에러 핸들링 같은 축으로 나눠 묻고 보강하면 결과가 단단해졌습니다. 세션 3에서 6번, 세션 4에서 7번 좁혀간 게 우연이 아니었던 셈입니다. 프롬프트 한 줄의 마법이 아니라, 같은 일을 여러 각도에서 보는 시간이 결과를 만듭니다.
3. 컨텍스트는 세션이 끌고 가는 게 아니라 디스크가 들고 가야 합니다. 핸드오프 문서, 단계별 커밋, phases/.../index.json 같은 진행 상태 파일이 사실상 “외장 컨텍스트”였습니다. 다음 세션은 첫 프롬프트로 “지난 세션 작업 내역부터 확인해주세요”만 던지면 됐습니다. 영상의 표현을 빌리자면, 메인 세션은 사무실이고 각 단계는 외주처럼 흘려보내는 구조에 가까웠습니다.
4. 30~40% 룰은 의외로 효과가 컸습니다. 끝까지 끌고 가면 응답 품질이 무뎌지고 토큰만 쓰게 되더군요(이른바 context rot). 한 단계가 끝나면 핸드오프를 남기고 세션을 끊는 습관이 생기니, 오히려 “이번 세션은 이 한 가지만 하자”라는 명료한 작업 단위가 자연스럽게 생겼습니다. 무관한 작업으로 넘어갈 때는 /clear, 연관 있는데 좀 길어진 정도면 /compact로 정리하는 식으로 컨텍스트를 도구로 관리하게 됐습니다. 영상에서 듣고 가장 의외로 효과가 컸던 부분이었습니다.
정리
여섯 세션을 다시 펼쳐 놓고 보면, 제가 쓴 프롬프트의 모양이 점점 달라지고 있었습니다.
처음에는 “이걸 해주세요” 형이 많았습니다. 클론해주세요, 깔아주세요, 바꿔주세요.
하네스가 자리잡고 나서는 **“현재 상태 확인 → 계획 → 사용자 관점 보강 → 에러 핸들링 관점 보강 → 실행”**으로 변했습니다. 한 번에 묻지 않고 축을 나눠 좁혀가는 모양입니다.
마지막에는 **“직접 써보니 이런 동선이 번거로웠습니다 → 사용자 관점에서 더 나은 경험을 제안해주세요 → 다음 사람이 이어받을 수 있게 문서화하고 커밋해주세요”**가 됐습니다. 사람이 본 사용자 경험이 입력이 되고, 출력은 다음 세션의 입력이 되도록 묶어 두는 모양입니다.
흥미로운 점은 모델이 똑똑해진다고 해서 프롬프트가 짧아진 게 아니라는 것입니다. 오히려 “지금 상태”와 “다음 사람이 받을 모양”을 같이 묶어 묻는 쪽으로 길어졌습니다. 짧은 프롬프트로도 컨텍스트가 무너지지 않을 만큼 작업 환경이 단단해지면, 사람은 더 사용자 관점이 담긴 질문에 시간을 쓸 수 있게 됩니다.
예전에는 AI 코딩을 잘한다는 게 프롬프트를 잘 쓰는 것에 가깝다고 생각했습니다. 영상을 보고 직접 따라 해본 지금은 영상의 한 줄로 정리됩니다. AI 코딩의 진짜 일은 코드를 쓰는 게 아니라, AI가 일할 환경을 설계하는 것이다. 하네스 엔지니어링은 그 환경을 만드는 일이었고, 프롬프트는 그 위에서 한 단계씩 좁혀가는 대화에 가까웠습니다.
참고 영상과 글