들어가기 전에
새로운 기능을 개발했다고 가정해보겠습니다. 이 때 이걸 개발한 개발자는 전달받은 요구사항을 바탕으로 기능을 구현했습니다. 정상적인 요청뿐만 아니라 잘못된 입력과 외부 API 호출 실패 같은 예외 상황도 처리했습니다. 테스트 코드를 작성하고 개발 환경에서 여러 번 확인했지만 특별한 문제는 발견되지 않았습니다.
그런데 이 개발자는 운영을 앞두고 아래와 같은 요청을 받게됩니다.
앞으로 발생할 수 있는 버그까지 미리 예측해서 개발해 주세요.
물론 가능하다면 서비스에 문제가 발생하기 전에 모든 오류를 찾아 수정하는 것이 가장 좋죠.
하지만 아직 만들어지지 않은 데이터와 정해지지 않은 정책, 사용자가 앞으로 기능을 어떻게 이용할지까지 개발자가 미리 알 수 있을까요? 물론 최근에는 AI가 코드를 작성하는 것뿐만 아니라 기존 코드를 분석하고, 잠재적인 문제를 설명하고, 테스트 케이스까지 만들어주고 있습니다.
자, 그렇다면 AI가 더 발전하면 아직 발생하지 않은 버그까지 미리 예측할 수 있게 되는 걸까요?
이번 글에서는 개발자가 발생 가능한 문제를 예상하는 과정과 AI가 그 과정에서 어떤 도움을 줄 수 있는지, AI가 제안한 모든 문제에 대비하는 것이 왜 항상 좋은 선택은 아닌지도 함께 알아보려 합니다.
개발자는 미래의 버그를 어떻게 예상할 수 있을까요?
외부 API를 호출해 여러 회원에게 어떤 쿠폰을 발급하는 기능을 개발한다고 가정해보겠습니다.
정상적인 상황에서는 회원 정보를 조회하고 쿠폰 발급 API를 호출하면 작업이 끝납니다.
하지만 비슷한 기능을 개발하거나 운영해본 경험이 있다면 몇 가지 상황을 함께 생각하게 되죠.
- 외부 API의 응답이 늦어질 수 있다.
- 일부 회원만 발급에 실패할 수 있다.
- 같은 작업이 여러 번 실행될 수 있다.
- API는 처리에 성공했지만 응답을 받지 못할 수 있다.
- 작업을 재실행하면서 쿠폰이 중복 발급될 수 있다.
- 데이터가 많아지면서 서버의 응답 제한 시간을 넘길 수 있다.
위 부분들은 아직 실제로 발생하지 않은 문제들이죠? 그렇다고 개발자가 이런 미래를 알고 있는 것은 아니죠.
보통은 과거에 경험한 장애와 현재 시스템의 구조를 바탕으로 비슷한 문제가 발생할 가능성들을 생각해 볼 뿐입니다.
따라서 미래의 버그를 예측한다는 표현보다는 다음과 같이 이해하는 편이 더 정확합니다.
저는 시스템에 존재하는 단서와 자신의 경험을 이용해 위험을 판단하는 편입니다. 외부 API를 사용한다면 타임아웃과 부분 실패도 생각하죠.
같은 데이터를 여러 요청이 수정한다면 동시성 문제를 생각해볼 수 있고, 작업을 재실행할 수 있다면 중복 처리 가능성을 체크해볼 수 있죠.
AI가 잠재적인 버그를 찾는 과정도 크게 다르지 않습니다.
그럼 AI는 어떤 문제를 찾을 수 있을까요?
아래와 같이 회원에게 쿠폰을 발급하는 코드가 있다고 가정해보겠습니다.
async issueCoupon(
memberNo: number,
couponNo: number,
): Promise<void> {
await this.couponClient.issue({
memberNo,
couponNo,
});
}
보시는 것처럼 코드 자체는 단순합니다. 회원번호와 쿠폰번호를 전달받아 외부 API를 호출합니다. 정상적인 요청을 한 번 실행하면 특별한 문제 없이 동작할 수 있겠죠?
만약 이 코드를 AI에게 검토해 달라고 요청하면 다음과 같은 가능성을 제안할 수 있습니다.
- 같은 요청이 두 번 들어오면 쿠폰이 중복 발급될 수 있습니다.
- 외부 API 호출에 대한 타임아웃이 필요할 수 있습니다.
- 일시적인 네트워크 오류에 대비한 재시도가 필요할 수 있습니 다.
- 재시도 과정에서 같은 요청이 다시 처리될 수 있습니다.
- 발급 결과를 저장하지 않으면 실패한 회원을 확인하기 어렵습니다.
- 외부 API가 성공한 뒤 내부 DB 저장에 실패하면 상태가 달라질 수 있습니다.
아직 발생하지 않은 문제를 마치 AI가 미리 알아낸 것처럼 보이죠? 하지만 AI는 미래의 실행 결과를 직접 확인한 것이 아니에요.
코드에서 외부 API를 호출하고 있다는 사실과 결과를 별도로 저장하지 않는 구조를 보고 비슷한 코드에서 발생할 수 있는 문제를 찾아낸 셈이죠.
그래서 AI는 이처럼 코드 안에 단서가 있는 문제를 찾는 데 유용합니다.
입력값의 경계 조건
정상적인 값만 사용하여 테스트하면 다음과 같은 조건을 놓치기 쉽습니다.
- 배열이 비어 있는 경우
- 숫자가 0이거나 음수인 경우
- 처리 가능한 최대 크기를 넘어선 경우
- 시작일이 종료일보다 늦은 경우
- 필수 값이 비어 있는 경우
- 같은 값이 여러 번 포함된 경우
AI에게 함수의 역할과 입력 조건을 함께 제공하면 이러한 경계값을 사용하는 테스트 케이스를 빠르게 만들어볼 수 있습니다.
중복 실행
웹 요청과 배치 작업은 한 번만 실행된다고 보장하기 어렵죠. 사용자가 버튼을 여러 번 누를 수 있고, 네트워크 응답이 늦어 클라이언트가 요청을 다시 보낼 수도 있습니다. 아니면 스케줄러가 중복 실행되거나 운영자가 실패한 작업을 직접 재실행할 수도 있습니다.
AI는 같은 요청이 반복되었을 때 결과가 달라지는지 확인하고, 멱등성이 필요한 지점을 제안할 수 있습니다.
동시성 문제
각각 실행했을 때 정상적인 코드도 동시에 실행되면 문제가 생길 수 있습니다.
만약 재고가 1개 남아 있는데 두 요청이 동시에 재고를 조회하면 두 요청 모두 구매 가능하다고 판단할 수 있는데 같은 회원의 등급을 여러 작업이 동시에 변경하면서 마지막 요청만 반영될 수도 있죠.
AI는 데이터를 조회한 시점과 수정한 시점 사이에 다른 요청이 개입할 수 있는지, 트랜잭션 범위가 적절한지 검토하는 데 도움을 줄 수 있습니다.
실패 경로
정상적으로 성공하는 흐름만 보면 문제가 없는 코드처럼 보일 수 있죠. 하지만 작업 중간에 오류가 발생하면 다른 결과가 만들어집니다.
- 외부 API 호출은 성공했지만 DB 저장에 실패했습니다.
- 100명의 회원 중 80명만 처리되었습니다.
- 작업이 중단된 뒤 처음부터 다시 실행되었습니다.
- 처리 결과는 남아 있지만 실패 원인은 기록되지 않았습니다.
AI는 코드의 실행 순서를 따라가며 각 단계에서 실패했을 때 어떤 상태가 남는지 확인할 수 있습니다.
하지만 AI도 알 수 없는 문제가 있습니다.
AI가 코드를 자세히 분석하더라도 제공받지 못한 정보까지 알 수는 없어요.
만약에 외부 API 문서에는 한 번의 요청에 최대 1,000건을 처리할 수 있다고 작성되어 있다고 가정해보겠습니다.
이에 개발자는 문서에 맞춰 데이터를 1,000건씩 나누어 요청했고, 개발 환경에서도 오류가 발생하지 않은 상황입니다.
하지만 실제 운영 환경에서는 한 요청에 100건 이상을 담았을 때 일부 데이터가 정상적으로 처리되지 않았을 때 이러한 동작이 문서와 코드 어디에도 나타나지 않았다면 AI가 구현 단계에서 정확하게 알아내기는 어렵습니다.
다음과 같은 문제도 마찬가지입니다.
- 개발 이후 새롭게 변경된 정책
- 문서화되지 않은 외부 시스템의 동작
- 운영 환경에만 존재하는 데이터
- 예상하지 못한 사용자의 이용 방식
- 특정 시간대에만 발생하는 트래픽 증가
- 여러 시스템의 장애가 동시에 발생하는 상황
- 인프라와 네트워크 환경에서 발생하는 일시적인 문제
AI는 제공된 코드와 문서, 로그 안에서 가능성을 찾는 것이지 컨텍스트에 없는 미래의 변화까지 정확하게 알아내는 것은 아닙니다.
물론 AI에게 더 많은 정보를 제공하면 검토할 수 있는 범위는 넓어집니다. 요구사항뿐만 아니라 데이터 구조와 외부 API 문서, 운영 로그, 과거 장애 기록을 함께 제공하면 코드만 전달했을 때보다 현실적인 문제를 찾을 가능성이 높아지겠지만 정보가 많아져도 알 수 없는 영역은 여전히 남습니다.
그렇다면 가능한 문제를 많이 찾으면 더 안전해질까요?
AI에게 잠재적인 문제를 찾아달라고 요청하면 생각보다 많은 의견을 받을 수 있습니다.
- 분산 락을 적용해야 합니다.
- 메시지 큐를 사용하는 것이 좋습니다.
- 재시도 정책이 필요합니다.
- 실패 메시지를 보관하는 별도의 큐가 필요합니다.
- 캐시와 데이터베이스의 정합성을 확인해야 합니다.
- 이벤트 소싱을 고려할 수 있습니다.
- 서버 장애에 대비한 이중화가 필요합니다.
- 여러 리전에 데이터를 복제할 수 있습니다.
각각은 특정한 상황에서 잘 알려진 유효한 방법들이죠? 그렇다면 하루에 몇 번 실행되는 내부 관리 기능에도 이 구조를 모두 적용해야 할까요?
발생할 가능성이 있다는 이유만으로 모든 방어 로직을 추가하면 코드와 시스템의 구성 요소가 늘어납니다. 개발과 테스트에 필요한 시간도 증가하고, 운영자가 이해해야 할 범위도 넓어지게 되죠. 더 중요한 점은 문제를 예방하기 위해 추가한 코드에도 버그가 생길 수 있다는 것이죠.
예를 들면 재시도를 추가하면서 같은 작업이 중복 실행될 수 있고, 캐시를 추가하면서 실제 데이터와 다른 결과가 노출될 수 있고, 분산 락을 추가하면서 락이 해제되지 않는 문제가 발생할 수도 있습니다.
문제 하나를 막기 위해 새로운 구성 요소를 여러 개 추가하면 기존에는 없었던 실패 지점도 함께 만들어게 되는 셈이죠.
그래서 가능한 문제를 많이 찾는 것과 모든 문제에 대비하는 것은 다른 일입니다.
AI는 다양한 가능성을 빠르게 제안할 수 있습니다만, 제안된 가능성이 실제 서비스에서도 중요한지는 별도로 판단해야 합니다.
그래서 발생 가능성과 영향도를 함께 봐야 합니다
잠재적인 문제를 찾았다면 바로 구현을 시작하기보다 두 가지를 먼저 확인하는 것이 좋습니다.
- 실제로 발생할 가능성이 얼마나 높은가?
- 발생했을 때 서비스에 미치는 영향이 얼마나 큰가?
발생 가능성이 높고 영향도 큰 문제라면 구현 단계에서 당연히 적극적으로 예방해야 합니다.
결제 중복 처리와 개인정보 노출, 데이터 유실처럼 한 번만 발생해도 피해가 큰 문제는 발생 가능성이 낮더라도 안전장치가 필요하죠.
하지만 반대로 발생 가능성이 낮고 영향도 작은 문제라면 복잡한 방어 구조를 추가하는 것보다 로그를 남기고 발생했을 때 처리하는 편이 나을 수 있습니다. 이를 문제 유형에 따라 대응 방법을 나누면 다음과 같습니다.
| 발생 가능성 | 영향도 | 대응 방법 |
| 높음 | 큼 | 구현 단계에서 우선적으로 예방 |
| 낮음 | 큼 | 최소한의 안전장치와 복구 절차 마련 |
| 높음 | 적음 | 단순한 방어 로직 또는 자동 복구 적용 |
| 낮음 | 적음 | 로그와 모니터링을 통해 발생 후 대응 |
여기에 복구 가능성도 함께 볼 수 있죠. 문제가 발생해도 데이터를 다시 처리할 수 있는 기능과 명확한 로그가 있다면 복잡한 예방 구조가 반드시 필요하지 않을 수 있습니다.
반대로 문제가 발생한 뒤 원래 상태로 돌릴 수 없다면 사전 검증을 더 엄격하게 적용해야 합니다.
그래서 우리는 예방하지 못한 문제에 대비해야 합니다.
모든 버그를 사전에 발견할 수 없다면 운영 중 발생한 문제를 빠르게 확인하고 복구할 수 있어야 합니다.
이를 위해 다음과 같은 장치를 마련해볼 수 있죠.
- 작업의 시작과 종료 기록
- 성공 건수와 실패 건수 수집
- 외부 API 요청과 응답 결과 기록
- 실패한 대상만 다시 처리하는 기능
- 같은 작업을 반복해도 결과가 중복되지 않는 구조
- 응답 시간과 오류 비율에 대한 모니터링
- 일정 기준을 넘었을 때 전달되는 알림
- 운영자가 확인할 수 있는 처리 이력
이러한 기능은 특정한 버그 하나만을 막기 위한 장치가 아닙니다.구현 당시 예상하지 못했던 문제가 발생하더라도 무엇이 잘못되었는지 확인하고 정상 상태로 돌아갈 수 있도록 도와주죠.
예측보다 관측과 복구가 중요하다는 말은 예방이 필요하지 않다는 뜻이 아닙니다.
당연히 예상 가능하고 피해가 큰 문제는 미리 막아야 합니다만, 모든 가능성을 코드로 차단하려 하기보다, 예방할 문제와 운영 중 발견하고 복구할 문제를 나누어야 한다는 의미입니다.
그럼 AI에게 코드 검토를 맡길 때 무엇을 물어봐야 할까요?
AI에게 단순히 “이 코드에 버그가 있는지 확인해 줘!”라고 요청하면 가능한 문제를 길게 나열할 수 있습니다. 그래서 조금 더 현실적인 결과를 얻으려면 판단 기준을 함께 제공하는 것이 좋습니다.
- 현재 기능의 사용 목적
- 예상되는 데이터 크기
- 실행 빈도
- 동시에 실행될 가능성
- 외부 시스템과 통신하는 부분
- 실패했을 때 허용할 수 있는 범위
- 반드시 보호해야 하는 데이터
- 현재 운영 환경과 제약 조건
검토 결과에도 근거를 요구할 수 있습니다.
- 문제가 발생하는 구체적인 조건은 무엇인가?
- 현재 코드에서 그 가능성을 보여주는 부분은 어디인가?
- 재현할 수 있는 테스트를 만들 수 있는가?
- 발생 가능성과 영향도는 어느 정도인가?
- 최소한의 변경으로 막을 방법은 무엇인가?
- 지금 수정하지 않는다면 어떻게 관측할 수 있는가?
이렇게 요청하면 단순히 많은 문제를 나열하는 것보다 실제로 판단할 수 있는 형태의 결과를 얻기 쉽습니다.
AI가 제안한 내용을 바로 구현하기보다 테스트로 재현할 수 있는지 먼저 확인하는 것도 중요합니다.
재현되지 않는 문제라면 현재 시스템에서 실제로 발생할 수 있는지 추가로 검토해야 합니다. 반대로 실패하는 테스트가 만들어졌다면 수정 전후의 결과도 명확하게 비교할 수 있습니다.
마치며..
AI는 미래에 발생할 버그를 정확하게 예언하는 도구는 아닙니다. 대신 현재의 코드와 요구사항을 바탕으로 사람이 놓치기 쉬운 위험을 더 넓고 빠르게 탐색하도록 도와주는 도구에 가깝습니다. 중복 실행과 동시성 문제, 경계값, 예외 처리 누락처럼 코드 안에 단서가 있는 문제는 구현 단계에서 발견할 가능성을 높일 수 있습니다.
하지만 아직 결정되지 않은 정책이나 문서화되지 않은 외부 시스템의 동작, 운영 환경에서 처음 만들어지는 상황까지 모두 알아낼 수는 없습니다. AI가 많은 잠재적 문제를 이야기한다고 해서 모든 방어 로직을 추가하는 것도 좋은 선택은 아닙니다. 발생 가능성이 낮은 문제까지 모두 대비하면 시스템이 지나치게 복잡해지고, 그 복잡성이 다시 새로운 오류의 원인이 될 수 있습니다.
결국 중요한 것은 모든 미래를 맞히는 것이 아닙니다.
발생 가능성과 영향도가 큰 문제는 미리 예방하고, 예상하지 못한 문제가 발생했을 때 빠르게 발견하고 복구할 수 있는 구조를 만드는 것이 중요합니다.
AI가 발전할수록 구현 단계에서 살펴볼 수 있는 위험의 범위는 더 넓어지겠지만 그럼에도 불구하고 어떤 위험을 받아들이고 어디까지 대비할지 결정하는 일은 여전히 개발자의 판단으로 남아 있습니다.
'AI' 카테고리의 다른 글
| [바미] GPT-6 Sol·Luna가 출시되었습니다! (0) | 2026.09.24 |
|---|---|
| [바미] 클로드 오푸스 5.5 출시 되었습니다! 코딩 성능부터 비용까지 무엇이 달라졌을까요~? (0) | 2026.09.23 |
| [바미] AI가 일을 대신해 주면 사람은 무엇을 준비해야 할까? (0) | 2026.09.10 |
| [바미] AI 에이전트 하나로 충분할까? 작업 흐름과 GraphRAG 이해하기 (0) | 2026.09.09 |
| [바미] Claude와 Figma를 연결하면 화면 디자인부터 웹페이지까지 만들 수 있을까? (0) | 2026.09.08 |