2026년, 초보자가 AI 생성 코드를 신뢰하기 전에 확인해야 할 사항
요약
AI가 생성한 코드가 겉보기에 완벽하더라도 시스템의 규칙과 경계를 보존하는지 검증하는 방법론을 제시합니다. 데이터 경로의 일관성과 권한 검증 로직을 확인하여 AI 코드의 신뢰성을 확보하는 구체적인 가이드를 제공합니다.
핵심 포인트
- AI 코드는 데모(동작)와 엔지니어링(규칙 보존)을 구분하여 검토해야 함
- 기능 구현 전 사용자 계약(User Contract)을 명확히 정의할 것
- 데이터가 입력부터 저장, 로드까지 이어지는 전체 경로를 추적할 것
- UI 요소의 숨김이 아닌 서버 측의 실제 권한 검증 로직을 확인할 것
AI는 완성된 것처럼 보이는 코드를 작성할 수 있습니다
AI 지원 개발(AI-assisted development)에서 가장 위험한 순간은 명백한 오류가 발생하는 때가 아닙니다.
그것은 앱이 실행되고, 화면이 깔끔해 보이며, 그 아래의 코드가 분명히 건전할 것이라고 가정하게 되는 순간입니다.
저는 두 가지 질문을 분리하는 법을 배웠습니다:
- 이 코드가 내가 요청한 화면이나 동작을 생성할 수 있는가?
- 이 코드가 내 앱이 따라야 하는 규칙을 보존하는가?
첫 번째 질문은 데모(demo)입니다. 두 번째 질문은 엔지니어링(engineering)입니다.
AI는 그럴듯한 첫 번째 답변을 만들어내는 데 매우 능숙합니다. 하지만 시스템의 한 부분을 변경하면서 제품의 경계(boundaries)를 보존하는 데까지 자동으로 능숙한 것은 아닙니다.
그렇기 때문에 저는 기능이 제대로 작동하는 것처럼 보일 때조차, AI가 생성한 코드를 신뢰하기 전에 검토합니다.
코드가 아닌 사용자 계약(user contract)부터 시작하세요
변경사항이 반영된 파일을 열기 전에, 해당 기능이 수행해야 할 일을 한 문장으로 적으세요.
예를 들어:
로그인한 사용자는 개인 메모를 저장할 수 있으며, 페이지를 새로고침한 후에도 자신의 저장된 메모만 볼 수 있어야 한다.
이 문장은 "메모 추가"와 같은 모호한 요청보다 검토할 수 있는 더 많은 정보를 제공합니다. 여기에는 사용자, 동작, 소유권(ownership), 그리고 지속성(persistence)에 대한 기대치가 포함되어 있습니다.
그런 다음 AI에게 해당 계약의 각 부분이 어디에 구현되어 있는지 보여달라고 요청하세요:
- 사용자가 식별되는 곳은 어디인가?
- 소유권이 강제되는 곳은 어디인가?
- 메모가 저장되는 곳은 어디인가?
- 저장된 메모가 다시 로드되는 곳은 어디인가?
- 사용자가 로그아웃하면 어떤 일이 발생하는가?
- 요청이 실패하면 어떤 일이 발생하는가?
만약 답변이 이러한 경계들을 명확하게 가리키지 못한다면, 그 기능은 신뢰할 준비가 되지 않은 것입니다.
변경 사항을 신뢰하기 전에 제가 사용하는 5가지 확인 사항
1. 데이터 경로(data path) 확인
입력 필드에서 데이터베이스(database) 또는 스토리지 계층(storage layer)을 거쳐 다시 화면으로 돌아오는 데이터의 흐름을 따라가세요.
올바르게 보이는 컴포넌트(component)에서 멈추지 마세요.
질문하세요:
- 입력값이 정규화(normalized)되거나 검증(validated)되었는가?
- 모든 레이어(layer)에서 데이터 형태(data shape)가 동일한가?
- 결측치(missing value)가 빈 값(empty value)과 다르게 처리되는가?
- 저장된 레코드(record)가 실제 소스(real source)에서 로드되는가, 아니면 로컬 화면 상태(local screen state)에만 머물러 있는가?
- 오래된 필드 이름(old field name)이 조용히 빈 결과(empty result)를 생성할 수 있는가?
AI는 타입(type), 폼(form), 쿼리(query)를 세 가지 서로 다른 방식으로 업데이트할 수 있습니다. 각 변경 사항은 개별적으로는 합리적으로 보일 수 있지만, 그 사이의 경로가 끊어져 있을 수 있습니다.
저는 단순히 초록색(성공)으로 보이는 파일들의 집합이 아니라, 레이어 간의 계약(contract)을 보고 싶습니다.
2. 무엇을 할 수 있는지 허용된 권한을 확인하세요
버튼이 숨겨져 있는 것이 액션(action)이 보호되고 있는 것과 같지는 않습니다.
앱에 계정, 개인 데이터, 유료 기능, 관리자 액션 또는 공유 워크스페이스(shared workspaces)가 있다면, 실제 권한 부여(authorization) 확인 로직을 찾으세요.
질문하세요:
- 서버나 데이터베이스가 소유권(ownership)을 검증하는가?
- 사용자가 요청(request)에서 ID를 변경하여 다른 사람의 레코드를 읽을 수 있는가?
- 생성(create), 읽기(read), 수정(update), 삭제(delete) 규칙이 일관적인가?
- 액션 도중에 세션(session)이 만료되면 어떻게 되는가?
이를 검토하는 초보자 친화적인 방법은 두 개의 테스트 계정을 상상해 보는 것입니다. 만약 계정 A가 식별자(identifier)를 변경하여 계정 B의 데이터를 볼 수 있다면, UI가 올바른 메뉴를 보여준다고 해서 그 기능이 안전한 것은 아닙니다.
3. 실패 경로(failure paths)를 확인하세요
AI는 종종 해피 패스(happy path: 유효한 입력, 작동하는 네트워크, 존재하는 레코드, 예상된 응답)에 대부분의 주의를 기울입니다.
의도적으로 반대의 경우를 검토하세요.
- 요청이 타임아웃(timeout)될 때 사용자는 무엇을 보는가?
- 저장 실패가 성공으로 표시되는가?
- 사용자가 중복을 생성하지 않고 재시도할 수 있는가?
- 응답이 비어 있을 때 어떻게 되는가?
- 에러(error)가 화면에 오래된 데이터(stale data)를 남기는가?
- 모든 종료 경로(exit path)에서 로딩 상태(loading state)가 해제되는가?
기능은 한 번 작동한다고 해서 완성된 것이 아닙니다. 작동하지 않을 때 사용자가 무슨 일이 일어났는지 이해할 수 있을 때 비로소 완성된 것입니다.
4. 변경 표면(change surface)을 확인하세요
AI에게 변경된 모든 파일, 스키마 (schema), 라우트 (route), 의존성 (dependency), 권한 (permission), 그리고 환경 변수 (environment variable)를 나열해 달라고 요청하세요.
그런 다음 그 목록을 요청 사항과 비교해 보세요.
이렇게 하면 흔히 발생하는 실패 모드(failure mode)를 잡아낼 수 있습니다. 즉, 작은 기능 하나가 관련 없는 화면에서 사용되는 공유 코드를 조용히 변경해 버리는 경우를 방지할 수 있습니다.
저는 또한 다음 사항들을 확인합니다:
- 중복된 비즈니스 로직 (business rules),
- 프로젝트가 이미 해결한 문제를 해결하기 위해 도입된 새로운 의존성 (dependencies),
- 좁은 범위의 기능 구현에 섞여 들어온 광범위한 리팩토링 (refactors),
- 마이그레이션 경로 (migration path) 없이 이름이 변경된 필드들,
- 설정 오류를 숨기는 폴백 (fallback) 동작.
변경 사항이 건드리는 관련 없는 표면적 (surface area)이 넓을수록 더 많은 증거가 필요합니다. "새 화면이 잘 작동한다"는 사실이 기존 화면들이 변경 사항으로부터 안전하게 살아남았다는 증거는 아닙니다.
5. 코드가 스스로를 설명하는지 확인하세요
읽기 쉬운 코드는 그 자체로 QA (Quality Assurance) 도구입니다. 특정 함수가 무엇을 변경할 수 있는지 알 수 없다면, 자신 있게 리뷰할 수 없습니다.
명확한 이름, 작은 책임 범위, 예측 가능한 에러 처리 (error handling), 그리고 구문을 나열하기보다는 결정 이유를 설명하는 주석을 찾으세요.
AI가 커다란 함수를 생성할 때, 저는 다음과 같은 사항들을 설명해 달라고 요청합니다:
- 예상되는 입력값 (inputs),
- 수행하는 부작용 (side effects),
- 반환할 수 있는 에러 (errors),
- 읽거나 쓸 수 있는 데이터,
- 안전하지 않게 만들 수 있는 가정 (assumptions).
만약 그 설명에서 숨겨진 가정이 드러난다면, 구현을 다듬기 전에 경계 (boundary)부터 수정합니다.
제가 AI에게 줄 리뷰 프롬프트 (review prompt)
다음 내용을 시작점으로 사용할 수 있습니다:
이 사용자 계약(user contract)에 따라 변경된 코드를 검토하세요: [한 문장 작성]. 먼저 입력(input)에서 영속성(persistence)을 거쳐 표시(display)까지의 데이터 경로(data path)를 매핑하세요. 그다음 모든 권한 확인(authorization check) 항목을 나열하고, UI에 의해서만 보호되는 동작이 있는지 식별하세요. 이어서 타임아웃(timeout), 빈 값(empty), 잘못된 입력(invalid-input), 중복 제출(duplicate-submit), 만료된 세션(expired-session) 동작을 점검하세요. 변경된 모든 파일, 의존성(dependency), 스키마(schema), 라우트(route), 환경 변수(environment variable), 공유 컴포넌트(shared component)를 나열하세요. 요청된 기능 외에 이 변경 사항이 유발할 수 있는 회귀(regression)를 식별하세요. 아직 코드를 다시 작성하지 마세요. 파일과 함수별로 증거를 보고한 다음, 각 문제에 대해 가장 작고 안전한 수정 사항을 제시하세요.
중요한 지침은 "아직 코드를 다시 작성하지 마세요"입니다. 저는 다음 생성 코드 폭주(burst)가 일어나기 전에 검토를 원합니다. 그렇지 않으면 AI는 아무도 검토하지 않은 가정을 확신을 가지고 패치(patch)해 버릴 수 있습니다.
제가 증거로 사용하지 않을 것들
다음은 유용한 신호들이지만, 그 자체만으로는 충분하지 않습니다:
- 앱이 컴파일(compile)된다.
- 페이지가 제대로 보인다.
- 해피 패스(happy-path) 데모를 통과했다.
- AI가 버그를 수정했다고 말한다.
- 브라우저 콘솔(browser console)에 눈에 보이는 에러가 없다.
- 코드가 길고 상세하다.
증거는 구현(implementation)을 사용자 계약(user contract)과 연결해야 합니다. 데이터, 권한, 실패, 그리고 관련 없는 기능들이 유출될 수 있는 경계(boundaries)를 포함해야 합니다.
초보자를 위한 저의 규칙
"AI가 좋은 코드를 작성했나요?"라고 묻지 마세요.
"이 코드는 어떤 규칙을 보존할 책임이 있으며, 그것을 여전히 보존하고 있다는 어떤 증거가 있나요?"라고 물으세요.
이 질문은 당신의 역할을 바꿉니다. 당신은 더 이상 코드가 얼마나 인상적으로 보이는지로 점수를 매기는 사람이 아닙니다. 당신은 시스템이 여전히 당신이 의도한 제품처럼 동작하는지 확인하는 사람입니다.
가이드가 될 만한 시작점을 원하신다면, 제가 만든 AI App Builder Starter Prompts를 이용해 보세요. 무료로 제공됩니다. 이 프롬프트들은 빈 프롬프트 박스를 범위(scope), 아키텍처(architecture), 구현(implementation), 그리고 증거(proof)에 관한 더 구체적인 대화로 바꾸는 데 도움을 줍니다.
아이디어 구상부터 프롬프팅 (prompting), 구축 (building), QA (품질 보증), 배포 (deployment), 그리고 출시 (launch)에 이르는 더 깊은 엔드 투 엔드 (end-to-end) 경로를 위해서는, 다음 단계인 AI App Builder From Zero가 있습니다.
목표는 AI 사용을 중단하는 것이 아닙니다. AI의 속도가 당신의 기준에 부합하도록 만드는 것입니다.
저를 다음에서도 만나보실 수 있습니다:
Medium: https://medium.com/@marcusykim
DEV.to: https://dev.to/marcusykim
Website: https://marcusykim.com/blog/
X: https://x.com/marcusykim
LinkedIn: https://www.linkedin.com/in/marcusykim/
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기