(3/5) AI 가 쓴 코드를 뭘로 믿나 — 검증 · 리뷰 · 테스트 · 디버깅 질문
🧪 바이브 코딩 면접 가이드 — 면접관을 위한 배경 지식과 질문 5부작 — “이 사람이 짠 코드인지 AI 가 짠 코드인지 모르겠어요.” 이제 거의 모든 면접에서 부딪히는 문제예요. AI 를 못 쓰게 막고 보는 건 답이 아니고, 그렇다고 완성된 산출물을 믿을 수도 없고요. 이 시리즈는 면접관 입장에서 필요한 것만 골라 담았습니다. 각 편은 ① 5분이면 따라오는 배경 설명 → ② 실제로 던질 질문 → ③ 답을 못 알아들어도 쓸 수 있는 채점 포인트 순서로 이어져요. 전체 그림과 판별 전략을 먼저 잡고(1편), 도구 운용(2편), 검증·리뷰·디버깅(3편), 보안·비용·규정(4편), 실기 과제와 60분 진행 시나리오(5편)까지 갑니다. 전체 5편.
- 뭘 물어야 하나 — 전체 그림과 판별 전략
- 도구를 어떻게 굴리나 — 컨텍스트 · 규칙 파일 · 계획
- AI 코드를 뭘로 믿나 — 검증 · 리뷰 · 디버깅 ← 지금 글
- 사고는 여기서 난다 — 보안 · 비용 · 라이선스 · 사내 규정
- 실기 과제 + 60분 진행 시나리오 + 채점표
Summary
1편에서 위임형 이라는 갈래를 이야기했어요. AI 산출물을 읽지 않고 그대로 넘기는 사람이요. 이 편은 사실상 그 사람을 걸러내기 위한 글입니다.
왜 이게 중요하냐면, AI 코드는 틀릴 때도 아주 잘 생겼기 때문 이에요. 예전 주니어 코드는 틀리면 티가 났습니다. 들여쓰기가 이상하고, 변수명이 temp2 고, 주석이 없었죠. 지금은 아니에요. 틀린 코드도 타입이 붙어 있고, 주석이 정갈하고, 예외 처리까지 들어가 있습니다. 겉모습이 더 이상 품질 신호가 아니에요.
그래서 면접에서 물어야 할 게 딱 하나로 좁혀집니다.
“그게 맞다는 걸 무엇을 근거로 아셨어요?”
이 질문의 답이 “돌아가던데요” 하나뿐이면, 그 사람은 코드가 아니라 운 을 관리하고 있는 거예요.
💡 이 글에서 다루는 것
- AI 코드가 틀리는 여섯 가지 패턴 — 이것만 알아도 면접이 됩니다
- “읽지 않은 코드” 가 6개월 뒤에 청구되는 방식
- 검증 사다리 다섯 층 — 후보자가 몇 층까지 갖고 있는가
- AI 가 테스트를 짜면 생기는 함정 (토톨로지 · 테스트를 고쳐서 통과시키기)
- 코드 리뷰가 어떻게 바뀌었나 — 리뷰어 병목
- AI 가 끝까지 못 고치는 버그 세 종류, 그리고 그때가 진짜 면접
- 질문 10개 + 채점 포인트
- 20분짜리 PR 리뷰 실기 (그대로 쓰셔도 됩니다)
1. 배경 — AI 코드가 틀리는 여섯 가지 패턴
면접관이 코드를 못 읽어도 됩니다. 이 여섯 개 이름만 알면, 후보자가 어떤 걸 겪어봤는지 물어볼 수 있어요.
① 존재하지 않는 것을 호출하기
없는 함수, 없는 옵션, 없는 라이브러리를 그럴듯한 이름으로 만들어 씁니다. 다행히 이건 바로 터져서 금방 잡혀요. 위험도는 낮은 편입니다.
② 옛날 버전 문법
모델이 학습한 시점의 문법으로 짜는 경우예요. 라이브러리가 메이저 버전을 올리면서 바뀐 부분에서 자주 나옵니다. 이것도 대개 실행하면 터져요.
③ 엣지 케이스 누락 — 여기부터 위험합니다
정상 경로는 완벽한데 가장자리가 비어 있어요. 빈 배열, null, 0, 음수, 타임존, 동시 요청, 네트워크 실패 같은 것들이요. 테스트를 돌려도 통과합니다. 테스트 자체가 정상 경로만 보거든요.
④ 요구사항을 살짝 바꿔서 구현하기
시킨 것과 미묘하게 다른 걸 만들어요. “실패하면 3번 재시도” 라고 했는데 총 3번 시도(즉 재시도는 2번)로 구현하는 식이요. 코드는 멀쩡하고 테스트도 통과하는데 명세가 어긋납니다. 사람이 읽지 않으면 절대 안 잡혀요.
⑤ 과잉 구현
안 시킨 기능을 덤으로 붙이고, 필요 없는 추상화 계층을 만들고, 설정 옵션을 잔뜩 넣습니다. 당장은 문제가 없어요. 6개월 뒤에 아무도 못 건드리는 코드가 됩니다.
⑥ 조용한 삭제
이게 가장 무서운 패턴이에요. 파일을 고치면서 기존 코드를 조용히 지웁니다. 예외 처리 한 줄, 로깅 한 줄, 특수 케이스 분기 한 줄 같은 것들이요. 커밋이 크면 리뷰에서 안 보이고, 그 한 줄이 6개월 전 사고 때문에 들어간 방어선이었던 경우가 많아요.
💡 면접에서 쓰는 법. 이 여섯 개를 후보자에게 나열하지 말고, 그냥 이렇게 물으세요.
“AI 가 만든 코드에서 자주 발견하는 실수 패턴이 있나요?”
실제로 매일 리뷰하는 사람은 자기만의 목록을 갖고 있어요. ③~⑥ 중 하나라도 나오면 진짜 읽는 사람입니다. ①②만 말하면 얕게 겪은 것 이에요. 그건 실행만 해봐도 알게 되는 거라서요.
2. 배경 — “읽지 않은 코드” 는 6개월 뒤에 청구됩니다
AI 이전에도 남의 코드는 있었어요. 다만 그때는 누군가는 그 코드를 이해하고 있었습니다. 짠 사람이요.
지금 위임형이 만드는 상태는 다릅니다. 아무도 이해하지 않는 코드가 저장소에 쌓여요. 그러면 이런 일이 벌어집니다.
| 시점 | 벌어지는 일 |
|---|---|
| 1개월 | 잘 돌아갑니다. 오히려 개발 속도가 빨라 보여요 |
| 3개월 | 버그가 나는데 원인 찾는 데 이상하게 오래 걸립니다 |
| 6개월 | 기능 하나 추가하려니 어디를 고쳐야 할지 모릅니다 |
| 12개월 | “이 부분은 건드리지 말자” 는 영역이 생깁니다 |
이건 클라우드 잘못 뽑았을 때와 똑같은 곡선이에요. 늦게, 크게 터지는 유형입니다. 그래서 면접에서 비용을 들여서라도 잡아야 해요.
⚠️ 오해를 막기 위해 짚을게요. AI 코드를 한 줄 한 줄 다 읽어야 한다는 뜻이 아닙니다. 그건 현실적이지도 않고, 속도 이점을 다 버리는 거예요. 잘하는 사람은 읽을 곳과 안 읽을 곳을 나눕니다. 2편에서 말한 “멈추는 지점” 이 그거예요. 면접에서 볼 건 “다 읽느냐” 가 아니라 “나누는 기준이 있느냐” 입니다.
3. 배경 — 검증 사다리 다섯 층
후보자가 몇 층까지 갖고 있는지 세어보면 됩니다. 층이 많을수록 아래층을 통과한 코드가 위로 올라가면서 걸러져요.
| 층 | 무엇 | 잡히는 것 | 비용 |
|---|---|---|---|
| 0층 | 그냥 돌려보기 | 바로 터지는 것 (패턴 ①②) |
없음 |
| 1층 | 타입 검사 · 린트 | 형식 오류, 안 쓰는 코드 |
싸고 즉시 |
| 2층 | 자동 테스트 | 명세를 적어둔 부분의 회귀 |
만드는 데 시간 듦 |
| 3층 | 사람 리뷰 | 패턴 ④⑤⑥ (의도 어긋남) |
가장 비쌈 |
| 4층 | 스테이징 · 운영 관측 |
실제 데이터에서만 나오는 것 |
인프라 필요 |
0층만 있는 사람이 위임형이에요. 그리고 실무에서 가장 자주 비어 있는 층이 3층입니다 — AI 가 코드를 쏟아내는 속도를 사람 리뷰가 못 따라가거든요.
💡 “AI 가 짠 걸 어떻게 확인하세요?” 라고 물었을 때, 답에서 층이 몇 개 나오는지 세어보세요. 하나면 하, 둘~셋이면 중, 넷 이상이고 각 층의 역할을 구분해서 말하면 상입니다.
4. 배경 — AI 가 테스트를 짜면 생기는 함정
“테스트도 AI 한테 시키면 되잖아요” 는 절반만 맞아요. 세 가지 함정이 있습니다.
함정 1. 구현을 베낀 테스트 (토톨로지)
구현 코드의 계산식을 테스트에서 한 번 더 쓰는 거예요.
# 구현
def discount(price, rate):
return price - price * rate
# AI 가 짠 테스트 — 통과하지만 아무것도 검증 못 함
def test_discount():
price, rate = 10000, 0.1
assert discount(price, rate) == price - price * rate
이 테스트는 구현이 어떻게 틀리든 항상 통과 합니다. 같은 식을 두 번 썼으니까요. 제대로 된 테스트라면 assert discount(10000, 0.1) == 9000 처럼 정답을 사람이 박아 넣어야 해요.
함정 2. 테스트가 통과하도록 테스트를 고치기
에이전트에게 “테스트 통과시켜줘” 라고 하면, 코드를 고치는 대신 테스트를 고쳐버리는 경우가 있어요. 기대값을 실제 출력에 맞추는 거죠. 이러면 빨간 불이 초록으로 바뀌긴 하는데, 버그는 그대로 남습니다.
⚠️ 이걸 겪어본 사람은 반드시 방어책을 갖고 있어요. “테스트 파일은 손대지 말고 구현만 고치라고 명시합니다” 같은 답이 나오면, 실제로 당해본 사람입니다.
함정 3. 목(mock) 과다
외부 의존성을 전부 가짜로 바꿔놓으면 테스트는 빨리 돌지만 실제로 아무것도 검증하지 않는 상태가 돼요. AI 는 테스트를 통과시키는 방향으로 목을 늘리는 경향이 있습니다.
그래서 순서가 중요해요
잘하는 사람은 이 순서로 갑니다.
- 사람이 무엇을 검증할지 정합니다 (기대 동작, 엣지 케이스 목록)
- 테스트를 먼저 만듭니다 — 이때 AI 를 써도 괜찮아요, 정답값은 사람이 확인하고요
- 테스트가 실패하는 걸 확인 합니다 (이게 빠지면 의미 없는 테스트일 수 있어요)
- 구현을 AI 에게 시킵니다
- 통과하면, 테스트가 안 바뀌었는지 확인합니다
💡 3번과 5번이 판별 포인트예요. “테스트가 처음에 실패하는 걸 확인하시나요?” 이 질문에 “네, 안 그러면 그 테스트가 진짜 도는 건지 모르니까요” 라고 답하면 테스트를 제대로 아는 사람입니다.
5. 배경 — 코드 리뷰가 바뀌었어요
리뷰어가 병목이 됩니다
생산 속도는 몇 배가 됐는데 리뷰 속도는 그대로예요. 그래서 요즘 팀의 병목은 거의 항상 리뷰 입니다. 이걸 겪어본 사람은 대응책을 갖고 있어요.
- PR 을 작게 유지하는 규칙
- 위험 영역(권한·결제·마이그레이션)만 집중 리뷰하고 나머지는 가볍게
- AI 리뷰 도구를 1차로 돌리고 사람이 2차
- 자동 검사로 걸러낼 수 있는 건 리뷰에서 아예 빼기
AI 가 짠 PR 을 리뷰하는 요령
일반 리뷰와 보는 곳이 달라요. 이건 면접관도 알아두면 좋습니다.
| 일반 리뷰에서 보던 것 | AI PR 에서 더 봐야 하는 것 |
|---|---|
| 오타 · 스타일 | (자동 도구가 다 잡아요) |
| 로직 오류 | 명세와 어긋나는지 (패턴 ④) |
| 변수명 | 지워진 줄이 있는지 (패턴 ⑥) |
| 성능 | 안 시킨 게 들어왔는지 (패턴 ⑤) |
diff 에서 초록(추가)보다 빨강(삭제)을 먼저 보라 는 게 요령이에요. 추가된 건 잘못돼도 대개 티가 나는데, 지워진 건 조용하거든요.
📎 리뷰를 에이전트에 태우는 실제 구성은 Orca — 코드 리뷰와 DesignMode 편에 정리해뒀어요. 후보자가 AI 리뷰 도구 이야기를 하면 깊이를 재는 데 쓸 수 있습니다.
6. 배경 — AI 가 못 고치는 버그가 진짜 면접입니다
에이전트는 대부분의 버그를 고쳐요. 그래서 못 고치는 나머지 가 그 사람의 바닥 실력이 됩니다. 못 고치는 건 대체로 세 종류예요.
① 재현이 안 되는 버그
가끔만 나는 것, 특정 사용자에게만 나는 것, 부하가 걸릴 때만 나는 것. AI 는 실행해볼 수 없는 상황을 추론만으로는 잘 못 잡아요. 여기서 필요한 건 재현 조건을 좁혀 들어가는 능력 입니다.
② 여러 시스템에 걸친 버그
우리 코드는 멀쩡한데 네트워크, DB 설정, 캐시, 외부 API 쪽에서 오는 문제요. AI 가 보는 건 저장소 안이라서, 밖에 원인이 있으면 안 보입니다.
③ 요구사항 자체가 틀린 경우
“이렇게 만들어달라” 는 요청이 애초에 잘못된 거예요. AI 는 시킨 대로 잘 만들어줍니다. 이걸 잡으려면 “근데 이게 맞나요?” 라고 되묻는 습관 이 필요해요.
💡 “AI 가 끝까지 못 고쳤던 문제 하나만 얘기해 주세요” — 1편 Q5 와 같은 질문인데, 여기서는 어느 종류였는지 를 봅니다. ①②③ 중 하나에 해당하고, 좁혀 들어간 과정이 구체적이면 상입니다.
좋은 답에 들어 있는 것들
체계적으로 디버깅하는 사람의 이야기에는 이런 게 나와요.
- 최소 재현 — 문제를 재현하는 가장 작은 코드를 만들었다
- 이분 탐색 — 언제부터 깨졌는지 커밋을 반씩 잘라 찾았다
- 가설과 반증 — “A 때문이라고 생각했는데 아니었다” 는 이야기가 있다
- 관측 추가 — 로그·지표를 먼저 넣고 기다렸다
- AI 를 껐다 — 어느 순간 직접 읽기 시작했다
반대로 이런 답은 걸립니다. “모델을 바꿔봤어요”, “다시 시켰어요”, “새 세션에서 물어봤어요” 만 반복되는 경우예요. 그건 전략이 아니라 재시도입니다.
7. 던질 질문 10개
Q1. AI 가 짠 코드가 맞다는 걸 어떻게 확인하세요?
- 왜 묻나 — 검증 사다리의 층 수를 셉니다. 이 편의 중심 질문이에요.
- 👍 좋은 답 — 층이 여러 개 나오고, 각 층이 뭘 잡는지 구분합니다.
- ⚠️ 걸리는 답 — “돌려봐요” 하나로 끝. 위임형 신호예요.
Q2. AI 코드에서 자주 보이는 실수 패턴이 있나요?
- 왜 묻나 — 실제로 읽는 사람인지. 매일 읽는 사람은 자기 목록이 있어요.
- 👍 좋은 답 — 엣지 케이스 누락, 명세 어긋남, 조용한 삭제 같은 깊은 층 이 나옵니다.
- ⚠️ 걸리는 답 — “없는 함수 만들어내는 거요” 만. 그건 실행만 해도 알아요.
Q3. AI 가 만든 걸 어디까지 읽고 어디부터 안 읽으세요?
- 왜 묻나 — 기준이 있는지 봅니다. “다 읽는다” 도 “안 읽는다” 도 답이 아니에요.
- 👍 좋은 답 — 위험 영역 목록이 명확해요. 권한, 돈, 삭제, 마이그레이션 같은.
- ⚠️ 걸리는 답 — “다 읽습니다” (속도 이점을 다 버렸거나, 사실이 아니거나) / “굳이 안 읽어요.”
Q4. 테스트는 누가 만드세요? AI 한테 시키면 뭐가 문제던가요?
- 왜 묻나 — 토톨로지 함정을 겪어봤는지.
- 👍 좋은 답 — 기대값은 사람이 정한다는 원칙이 있어요. “테스트가 구현을 그대로 베끼더라” 는 이야기가 나오면 아주 좋습니다.
- ⚠️ 걸리는 답 — “테스트도 다 시킵니다” 로 끝나고 검토 이야기가 없어요.
Q5. 테스트가 처음에 실패하는 걸 확인하시나요?
- 왜 묻나 — 테스트를 제대로 아는지 가르는 짧은 질문이에요.
- 👍 좋은 답 — “네, 안 그러면 그 테스트가 진짜 도는 건지 모르니까요.”
- ⚠️ 걸리는 답 — 질문 자체를 이해 못 합니다.
Q6. AI 가 테스트를 고쳐서 통과시킨 적 있나요?
- 왜 묻나 — 함정 2 를 겪었는지. 겪은 사람은 대개 웃으면서 답해요.
- 👍 좋은 답 — 겪었고, 그 뒤에 방어책(테스트 파일 수정 금지 규칙 등)을 만들었습니다.
- ⚠️ 걸리는 답 — “그런 게 되나요?” — 테스트를 에이전트에 안 태워본 거예요.
Q7. 팀에서 AI PR 리뷰는 어떻게 하세요?
- 왜 묻나 — 팀 경험. 리뷰 병목을 겪었는지 봅니다.
- 👍 좋은 답 — PR 크기 규칙, 위험 영역 집중, 자동 검사와 사람 리뷰의 역할 분담이 나와요.
- ⚠️ 걸리는 답 — “그냥 승인해요” / “리뷰 문화가 없어요.” 조직 사정일 수 있으니 톤은 부드럽게, 다만 기록은 남기세요.
Q8. 리뷰할 때 diff 에서 어디를 먼저 보세요?
- 왜 묻나 — 조용한 삭제(패턴 ⑥)를 아는지 겨냥한 질문이에요.
- 👍 좋은 답 — 삭제된 줄 을 본다는 답이 나오면 아주 좋습니다.
- ⚠️ 걸리는 답 — “위에서부터 쭉이요.”
Q9. AI 가 끝까지 못 고친 버그 하나만 처음부터 끝까지 얘기해 주세요
- 왜 묻나 — 바닥 실력. 이 편에서 가장 중요한 질문 이에요.
- 👍 좋은 답 — 최소 재현, 이분 탐색, 틀린 가설, 관측 추가 같은 게 나옵니다. 어느 순간 AI 를 끄고 직접 읽은 이야기가 나오면 최고예요.
- ⚠️ 걸리는 답 — 모델 바꾸기·재시도만 반복. 또는 “그런 적 없어요.”
Q10. 본인이 AI 로 만든 코드 중에 지금도 남에게 설명할 수 있는 건 몇 퍼센트예요?
- 왜 묻나 — 솔직함과 자기 인식을 봅니다. 정직한 사람은 100% 라고 안 해요.
- 👍 좋은 답 — 숫자가 현실적이고, 왜 나머지는 설명 못 하는지 를 구분해서 말합니다. “핵심 로직은 다 설명되고, 화면 스타일 쪽은 솔직히 모릅니다” 같은.
- ⚠️ 걸리는 답 — “전부 다요” (거의 사실이 아니에요) / “거의 없어요” (그건 그냥 위임형입니다).
8. 20분짜리 실기 — 나쁜 PR 리뷰시키기
이 편에서 가장 잘 먹히는 실기예요. 후보자에게 코드를 짜라고 하지 말고, 리뷰를 시키세요. AI 로 쉽게 통과되지 않고, 검증 능력을 정면으로 잽니다.
준비
일부러 흠을 심은 100~150줄짜리 PR 하나를 준비합니다. 여러분 팀의 실제 코드 스타일로 만들되, 앞의 패턴 ③~⑥ 을 하나씩 심으세요. 예를 들면 이런 것들이요.
# 심어둘 흠 예시 (실제 PR 은 여러분 스택으로)
# ③ 엣지 케이스 — items 가 빈 리스트면 ZeroDivisionError
def average_price(items):
return sum(i.price for i in items) / len(items)
# ④ 명세 어긋남 — "3번 재시도" 를 총 3회 시도로 구현
def fetch_with_retry(url, retries=3):
for _ in range(retries):
r = http_get(url)
if r.ok:
return r
raise FetchError(url)
# ⑥ 조용한 삭제 — 원래 있던 감사 로그 호출이 사라짐
def transfer(from_acct, to_acct, amount):
debit(from_acct, amount)
credit(to_acct, amount)
# audit_log("transfer", from_acct, to_acct, amount) ← 원래 있던 줄
진행
- PR 을 보여주고 “이거 승인하시겠어요?” 라고 물어요. (5분)
- AI 를 써도 된다고 명시하세요. 오히려 쓰라고 하는 게 좋아요. (10분)
- 발견한 것들을 심각도 순으로 정렬 해달라고 합니다. (5분)
채점
| 보는 것 | 상 | 하 |
|---|---|---|
| 발견 | 심은 흠의 절반 이상 |
오타·스타일만 |
| 우선순위 | 감사 로그 삭제를 1순위로 봄 |
나열만 하고 경중이 없음 |
| AI 활용 | AI 에 물어보되 결과를 검증함 |
AI 답을 그대로 읽음 |
| 질문 | “이 재시도 명세가 뭐였나요?” 라고 되물음 |
안 물어봄 |
💡 세 번째 줄이 진짜 채점 포인트예요. AI 에게 리뷰를 시키는 것 자체는 아주 좋은 행동입니다. 봐야 할 건 AI 가 놓친 걸 잡아내는지, 그리고 AI 가 지적한 것 중 헛다리를 걸러내는지 예요. AI 리뷰는 사소한 스타일 지적을 잔뜩 쏟아내는 경향이 있는데, 그걸 그대로 읽으면 신호와 잡음을 구분 못 하는 겁니다.
⚠️ 네 번째 줄도 놓치지 마세요. 명세를 되묻는 후보자는 패턴 ④(요구사항 어긋남)를 아는 사람이에요. 코드만 보고는 판단할 수 없다는 걸 아는 거죠. 실제 팀에서 가장 필요한 사람입니다.
9. 이 영역의 레드 플래그
| 신호 | 왜 걸리나 |
|---|---|
| 검증 수단이 “돌려보기” 하나 |
0층만 있는 위임형 |
| 실수 패턴을 ①② 만 말함 |
실행만 해봤지 읽지는 않았어요 |
| 못 고친 버그 이야기가 재시도뿐 |
디버깅 전략이 없습니다 |
| 자기 코드 설명을 화면 다시 읽으며 함 |
소유권이 없어요 |
| 주어가 계속 AI 임 |
1편 축 3 의 하 수준 |
10. 정리
한 문장으로 줄이면 이거예요.
AI 코드를 얼마나 많이 만들었는지가 아니라, 그중 무엇을 근거로 믿었는지를 물으세요.
그리고 이 편에서 딱 두 개만 챙긴다면 Q1(어떻게 확인하세요) 과 Q9(AI 가 못 고친 버그) 입니다. 앞의 것은 습관을 재고, 뒤의 것은 바닥 실력을 재요. 시간이 없으면 이 둘과 8장의 PR 리뷰 실기만 해도 위임형은 거의 다 걸러집니다.
일단 오늘은 여기까지…..
다음 글에서는 사고가 실제로 나는 지점을 파볼게요. 프롬프트에 붙여넣은 사내 코드, 커밋에 딸려 들어간 키, AI 가 추천한 존재하지 않는 라이브러리, 그리고 아무도 안 보는 사이 늘어나는 토큰 청구서까지 정리해 보겠습니다.
이전 글 ←: (2/5) 도구를 어떻게 굴리나 — 컨텍스트 · 규칙 파일 · 계획
다음 글 →: (4/5) 사고는 여기서 난다 — 보안 · 비용 · 라이선스 · 사내 규정