안전한 AI 코딩을 위한 원칙
코딩에 AI를 가장 잘 쓰는 방법은, 추측이 위험해지는 바로 그 순간에 속도를 늦추게 만드는 것입니다. AI는 낯선 코드를 설명하고, 오류를 가설로 바꾸고, 테스트를 초안으로 쓰고, diff를 리뷰하고, 리팩터링을 제안할 수 있습니다. 동시에 존재하지 않는 API를 지어내고, 숨은 의존성을 놓치고, 붙여넣은 코드 조각에 과하게 맞추고, 겉보기에는 깔끔하지만 유지하려던 동작을 바꿔 버리는 패치를 내놓기도 합니다.
이 원칙을 쓰세요. AI는 제안할 수 있지만, 결정은 저장소가 합니다. 기준이 되는 것은 코드베이스, 실패하는 재현 절차, 테스트 스위트, 런타임 로그, 제품 요구사항, 그리고 사람의 리뷰입니다. 좋은 AI 페어 프로그래머라면 이런 근거를 대체하는 대신, 그것을 바탕으로 추론하도록 도와야 합니다.
| 원칙 | 중요한 이유 | 모델에게 요청할 말 |
|---|---|---|
| 재현 먼저 | 즉흥적 패치를 막음 | "코드를 제안하기 전에 실패 동작과 근거를 다시 정리해줘." |
| 범위는 좁게 | 회귀 위험을 줄임 | "가장 작고 안전한 변경을 제안하고 손댄 파일을 나열해줘." |
| 동작 보존 | 사용자와 계약을 보호 | "이 변경이 깨면 안 되는 불변 조건을 짚어줘." |
| 테스트 필수 | 답을 검증 가능하게 함 | "수정 전에는 실패하고 후에는 통과하는 테스트를 써줘." |
| 머지 전 리뷰 | 자신만만한 실수를 잡음 | "이 diff를 정확성, 보안, 빠진 엣지 케이스 관점에서 리뷰해줘." |
이는 모델을 가리지 않고 적용됩니다. OpenAI, Anthropic을 비롯한 제공사들은 저마다 다른 성능, 컨텍스트 창 크기, 도구 사용 방식을 설명한 모델 문서를 공개합니다. 그 성능치는 유용하지만, 잘 짜인 작업 흐름을 대신하지는 못합니다. 엔지니어링 작업이라면 동료를 평가하듯 모델을 평가하세요. 빠진 맥락을 되묻는가, 불확실성을 줄여 주는가, 제약을 지키는가, 그리고 내가 검증할 수 있는 흔적을 남기는가?
디버깅 작업 흐름
믿을 만한 AI 디버깅 작업 흐름은 다섯 단계로 이루어집니다. 재현, 격리, 가설 세우기, 패치, 검증입니다. "이거 고쳐줘"로 시작하지 마세요. 근거로 시작하세요. 실패하는 명령어, 정확한 오류 메시지, 기대한 동작, 실제로 관찰된 동작, 관련 코드, 환경 정보, 그리고 문제를 일으켰을 법한 최근 변경 사항을 모델에게 주세요.
1단계, 재현 절차를 기록하세요. 백엔드 코드라면 요청, 응답, 상태 코드, 로그, 실패하는 테스트를 포함하세요. 프런트엔드 코드라면 경로, 사용자 동작, 브라우저 콘솔 오류, 네트워크 응답, 컴포넌트 상태, 필요하다면 화면 설명까지 담으세요. 빌드 문제라면 명령어, 패키지 매니저, Node 버전, 그리고 첫 실패 지점 앞뒤의 전체 오류를 넣으세요.
2단계, 코드보다 가설을 먼저 요청하세요. 신중한 모델이라면 가능성 있는 원인을 순위 매기고, 각각을 뒷받침하는 근거가 무엇인지 밝힙니다. 원인들을 서로 구분하지 못한다면, 가장 작은 진단 단계를 물어보세요. 로그 한 줄일 수도 있고, 범위를 좁힌 테스트나 타입 검사, 혹은 파일 하나 더 읽는 일일 수도 있습니다.
3단계, 가장 작은 패치를 요청하세요. 타당한 이유를 대지 못하는 한 변수 이름을 바꾸거나, 주변 코드를 다시 쓰거나, 의존성을 추가하거나, 공개 동작을 바꾸지 말라고 모델에게 못 박으세요. 근본 원인, 패치 개요, 손댄 파일, 테스트, 위험도를 함께 돌려 달라고 하세요.
4단계, 테스트를 로컬에서 돌리세요. AI의 출력은 검증 단계가 아닙니다. 검증은 동작을 실제로 증명하는 명령어나 사용자 경로입니다. 자동화된 테스트가 없다면, 먼저 회귀 테스트를 만들어 달라고 한 다음에 수정을 구현하세요.
디버깅 프롬프트:
신중한 디버깅 파트너 역할을 해줘. 아직 코드는 쓰지 마. 먼저 재현 절차, 기대한 동작, 관찰된 동작, 그리고 가장 유력한 근본 원인 세 가지를 다시 정리해줘. 각 원인을 근거에 따라 순위 매겨줘. 그다음 가장 작은 진단 단계를 제안해줘. 버그: [설명]. 명령어 또는 사용자 동작: [붙여넣기]. 오류/로그: [붙여넣기]. 관련 코드: [붙여넣기]. 제약: [스택, 건드리면 안 되는 파일, 유지해야 할 동작].
수정 프롬프트:
확인된 근본 원인을 바탕으로 가장 작고 안전한 수정을 제안해줘. 근본 원인, 바꿀 파일과 함수, 패치 개요, 수정 전에는 실패하고 후에는 통과하는 테스트, 엣지 케이스, 롤백 위험을 돌려줘. 관련 없는 코드는 리팩터링하지 마. 맥락: [붙여넣기].
코드 리뷰 작업 흐름
AI는 최초 작성자일 때보다 리뷰어일 때 더 나은 경우가 많습니다. diff를 리뷰해 달라고 하면 놓친 엣지 케이스, 보안 문제, 낡은 가정, 테스트 공백, 동작 변경을 찾아낼 수 있습니다. 핵심은 리뷰 요청을 구체적으로 만드는 것입니다. "이거 괜찮아 보여?"라고 물으면 정중한 승인이 돌아옵니다. 정확성 측면의 위험을 물으면 쓸모 있는 반론을 얻을 가능성이 높아집니다.
모델에게 diff, 의도한 동작, 관련 테스트, 그리고 제약 조건을 주세요. 유지보수성에 영향을 주지 않는 사소한 스타일은 넘어가라고 하세요. 리뷰가 우선해야 할 것은 버그이지, 보여 주기식 트집이 아닙니다.
| 리뷰 영역 | AI가 답해야 할 질문 |
|---|---|
| 정확성 | 이 diff가 요구사항을 실제로 충족하나요? |
| 회귀 위험 | 의도치 않게 바뀔 수 있는 기존 동작은? |
| 보안 | 입력, 인증, 비밀 값, 권한, 주입 위험은 처리됐나요? |
| 오류 처리 | null, 타임아웃, 재시도, 잘못된 응답, 중간 상태에서는? |
| 테스트 | 다루지 않은 동작 주장은 무엇인가요? |
| 유지보수성 | 기존 패턴을 따르고 변경이 이해하기 쉬운가요? |
코드 리뷰 프롬프트:
엄격하지만 현실적인 메인테이너처럼 이 diff를 리뷰해줘. 정확성, 회귀 위험, 보안, 엣지 케이스, 빠진 테스트에 집중해줘. 실제 유지보수 위험을 만들지 않는 사소한 스타일은 무시해줘. 문제, 우선순위, diff에서 찾은 근거, 제안하는 수정, 필요한 테스트를 표로 돌려줘. 의도한 동작: [붙여넣기]. Diff: [붙여넣기]. 기존 테스트: [붙여넣기].
위험이 큰 변경이라면 Whizi에서 모델별 수정안을 비교하는 방식을 쓰세요. 같은 리뷰 프롬프트를 두세 개 모델에 돌려 보세요. 한 모델이 문제 가능성을 짚었다면 그대로 받아들이지 말고, 그 문제가 실제 코드베이스에서 유효한지 확인하세요. 목표는 의견을 더 모으는 것이 아닙니다. 머지 전에 리뷰가 훑는 범위를 넓히는 것입니다.
리팩터링과 테스트 작업 흐름
AI와 함께하는 리팩터링이 위험한 이유는, 많은 리팩터링이 무엇이 바뀌지 않았는가로 평가되기 때문입니다. 모델은 코드를 보기 좋게 만들면서 동작, 오류 처리, 타이밍, 공개 계약을 미묘하게 바꿔 놓을 수 있습니다. 더 안전한 리팩터링은 구현에 손대기 전에 불변 조건을 먼저 정의하는 데서 시작합니다.
1단계, 리팩터링 목표를 서술하세요. 예를 들면 중복 줄이기, 큰 컴포넌트 쪼개기, 데이터 접근 분리하기, 분기 단순화하기, API 래퍼 이전하기, 테스트 용이성 높이기 같은 것들입니다. 그다음 그대로 유지되어야 할 것을 명시하세요. 공개 함수 시그니처, 라우트 동작, 이벤트 이름, 응답 형태, 애널리틱스, 권한, 접근성 동작, 성능 기대치입니다.
2단계, 단계별 계획을 요청하세요. 쓸모 있는 AI 리팩터링 계획은 되돌릴 수 있어야 합니다. 각 단계는 좁은 범위만 건드리고, 테스트를 포함하며, 동작하는 중간 상태를 남겨야 합니다. 코드가 아주 작고 테스트가 촘촘한 경우가 아니라면 한 번에 전부 다시 쓰는 방식은 피하세요.
3단계, 특성화 테스트를 작성하세요. 코드를 바꾸기 전에, 현재 동작을 파악하고 중요한 경우들을 고정해 두는 테스트를 초안으로 써 달라고 AI에 요청하세요. 이런 테스트는 의도가 불분명한 레거시 코드에서 특히 유용합니다. 일반적인 입력, 경계값 입력, 실패 경로, 그리고 리팩터링을 하게 된 이유와 연결된 회귀 사례 하나를 포함해야 합니다.
4단계, 한 번에 한 단계씩 구현하세요. 각 단계가 끝날 때마다 테스트를 돌리고 범위를 좁힌 리뷰를 요청하세요. 모델이 넓은 추상화를 제안한다면, 그 추상화가 실제 중복이나 위험을 없애는지 증명하게 하세요. 그렇지 않다면 코드는 심심하고 국소적인 편이 낫습니다.
리팩터링 계획 프롬프트:
단계별 리팩터링 계획을 만들어줘. 목표: [목표]. 현재 코드: [붙여넣기]. 제약: 공개 동작 유지, 변경량 최소화, 기존 패턴 준수, 새 의존성 추가 금지, 모든 단계는 테스트 가능하게. 불변 조건, 의존성 지도, 단계, 손댈 파일, 단계별 테스트, 롤백 위험, 리뷰 체크리스트를 돌려줘.
단위 테스트 프롬프트:
구현을 바꾸기 전에 테스트를 먼저 써줘. 여기 보이는 기존 테스트 스타일을 따라줘: [붙여넣기]. 유지해야 할 동작: [붙여넣기]. 테스트 대상 코드: [붙여넣기]. 테스트 이름, 준비 과정, 입력, 기대 결과, 그리고 각 테스트가 왜 중요한지를 돌려줘. 정상 경로, 경계 사례, 오류 사례, 회귀 사례를 포함해줘.
프롬프트 템플릿
좋은 코딩 프롬프트가 긴 이유는 화려해서가 아닙니다. 모호함을 없앨 만큼 길기 때문입니다. 모델에게는 역할, 할 일, 맥락, 제약, 출력 형식, 검증 기준이 필요합니다. 잘 통한 프롬프트는 저장해 두세요. 그래야 AI가 일회성 대화가 아니라 반복 가능한 엔지니어링 작업 흐름이 됩니다.
코드 설명 프롬프트:
프로젝트에 새로 합류한 개발자를 위해 이 코드를 설명해줘. 목적, 입력, 출력, 데이터 흐름, 의존성, 실패 모드, 그리고 신뢰도를 높여 줄 테스트를 다뤄줘. 코드에서 실제로 보이는 사실과 추측을 구분해줘. 코드: [붙여넣기].
보안 코딩 프롬프트:
이 코드의 보안 위험을 검토해줘. 인증, 권한, 주입, 비밀 값, 검증, 안전하지 않은 리다이렉트, 파일 처리, 의존성 위험, 민감 정보 노출에 집중해줘. 근거와 영향, 제안하는 수정, 테스트 또는 수동 확인 방법이 있는 문제만 돌려줘. 코드/diff: [붙여넣기].
모델 수정안 비교 프롬프트:
코딩 과제를 두고 AI 모델들을 비교하는 중이야. 제공한 맥락만 사용해줘. 근본 원인, 가장 작고 안전한 수정, 테스트, 위험, 가정, 질문을 돌려줘. 확신도를 1에서 5까지 매기고, 어떤 근거가 나오면 답이 바뀌는지 적어줘. 과제: [붙여넣기]. 맥락: [붙여넣기].
AI가 만든 코드를 받아들이기 전 QA 체크리스트:
- 모델이 과제를 정확히 다시 정리했습니다.
- 패치가 문제보다 크지 않고 작습니다.
- 공개 동작과 계약이 명시되어 있습니다.
- 테스트가 버그나 리팩터링 목표를 직접 다룹니다.
- 엣지 케이스와 실패 경로가 나열되어 있습니다.
- 보안에 민감한 입력이 검토되었습니다.
- diff가 기존 프로젝트 패턴을 따릅니다.
- 관련 테스트, 린트, 빌드, 또는 수동 재현을 직접 돌려 봤습니다.
- 사람이 최종 diff를 리뷰했습니다.
과제는 그대로 두고 수정안만 비교하고 싶을 때 Whizi가 쓸모 있습니다. 같은 디버깅 또는 리뷰 프롬프트를 여러 모델에 붙여넣고, 근거와 범위, 테스트, 위험을 기준으로 결과를 채점하세요. 모델 고르는 기준부터 잡고 싶다면 코딩용 ChatGPT 대안에서 시작하고, 요금제에서 플랜을 비교하거나, 계정 만들기로 내 코드에 이 작업 흐름을 적용해 보세요.
- 막연한 버그 설명이 아니라 실제 재현 절차로 시작하세요.
- 코드를 요청하기 전에 가설과 근거를 먼저 요청하세요.
- 가장 작고 안전한 수정을 요청하고 손댄 파일을 밝히게 하세요.
- 리팩터링 전에 바뀌면 안 되는 동작을 먼저 정의하세요.
- 패치를 믿기 전에 테스트를 쓰거나 갱신하세요.
- AI가 만든 diff를 정확성, 보안, 엣지 케이스 관점에서 리뷰하세요.
- 위험한 작업일수록 같은 프롬프트를 여러 모델에 돌리고 Whizi에서 수정안을 비교하세요.
- AI가 도운 코드는 머지하기 전에 사람의 리뷰를 거치세요.
자주 묻는 질문
코딩에 AI를 안전하게 쓰려면 어떻게 해야 하나요?
선택지와 테스트, 리뷰를 제안하는 페어 프로그래머로 AI를 쓰세요. 재현 절차에서 출발하고, 작은 패치를 요구하고, 테스트를 돌리고, 머지 전에 diff를 리뷰하세요. 생성된 코드를 자동으로 옳다고 여기지 마세요.
AI가 코드 디버깅에 도움이 되나요?
됩니다. AI는 오류와 로그, 코드를 유력한 근본 원인으로 바꿔 주는 데 유용합니다. 가장 안전한 디버깅 흐름은 가설을 먼저 요청하고, 그다음 진단 단계를, 마지막으로 가장 작은 수정과 회귀 테스트를 요청하는 것입니다.
AI가 단위 테스트를 써 줄 수 있나요?
AI는 단위 테스트 초안을 쓸 수 있지만, 동작 범위를 분명히 요구해야 합니다. 정상 경로, 경계, 오류, 회귀 사례를 요청한 다음, 그 테스트가 수정 전에는 실패하고 후에는 통과하는지 확인하세요.
코딩에 가장 좋은 AI 모델은 무엇인가요?
가장 좋은 모델은 과제와 코드베이스에 따라 달라집니다. 디버깅, 리뷰, 리팩터링에 같은 프롬프트를 여러 모델에 돌려 보고, 근거가 가장 분명하고 범위가 가장 작으며 테스트가 가장 탄탄한 답을 고르세요.