AI 코딩하면서 제일 무서운 건 코드 생성보다 ‘멀쩡한 기능을 다시 깨뜨리는 것’이었습니다
첫 글에서는 코드 한 줄 못 쓰던 제가 AI를 이용해서 실제 앱을 만들고 출시하기까지의 이야기를 적었습니다.
이번에는 그 이후에 더 크게 느낀 문제를 적어보려고 합니다.
처음 AI로 개발할 때는 이런 생각을 했습니다.
“와, 설명만 하면 코드를 만들어주네?”
그런데 실제 제품을 계속 수정하고 업데이트하다 보니 생각이 완전히 바뀌었습니다.
지금 제가 가장 무섭게 보는 건 코드 생성 능력이 아닙니다.
AI가 새로운 문제를 고치면서, 이미 잘 작동하던 기능을 조용히 다시 깨뜨리는 문제입니다.
1. 새 버그는 고쳤는데, 옛날 버그가 돌아옵니다
제가 만들고 있는 TransferIQ는 해외송금, 환율, 크립토 경로 등을 비교하는 서비스입니다.
단순 계산기처럼 보일 수 있지만 실제로는 국가, 통화, 금액대, 송금사, 거래소마다 로직이 달라집니다.
최근에는 고액 송금에서 예상 스프레드가 너무 낮게 잡히는 문제가 있었습니다.
예를 들어 신흥국 통화나 10,000달러 이상의 금액에서는 실제 시장과 비교했을 때 추정치가 지나치게 낙관적으로 나오는 경우가 있었습니다.
그래서 저는 AI와 함께 이런 로직을 추가했습니다.
CORRIDOR_SPREAD_FLOOR
쉽게 말하면,
- 어떤 국가 간 송금인지
- 금액이 얼마인지
- 어떤 유형의 업체인지
에 따라 최소 스프레드 기준을 적용하는 방식입니다.
이 로직을 넣고 실제 견적과 비교하면서 어느 정도 보정했습니다.
문제는 그다음입니다.
며칠 뒤 다른 기능을 수정하면서 갑자기 이런 생각이 들었습니다.
“잠깐, 저 로직 아직 살아 있나?”
AI는 새로운 작업을 아주 잘했습니다.
그런데 큰 파일을 수정하거나 기존 함수를 재구성하는 과정에서 과거에 어렵게 만든 로직이 사라질 수 있었습니다.
더 무서운 건 앱이 정상적으로 실행된다는 점입니다.
에러도 없습니다.
화면도 열립니다.
버튼도 눌립니다.
그런데 계산 결과는 틀릴 수 있습니다.
2. “앱이 켜진다”와 “제품이 정상이다”는 완전히 다른 문제였습니다
처음에는 테스트를 이렇게 했습니다.
앱 실행
→ 화면 확인
→ 버튼 클릭
→ 에러 없으면 완료
지금은 그렇게 안 합니다.
특히 금융 관련 제품은 최소한 세 가지를 따로 봐야 한다고 느꼈습니다.
1. 앱이 실행되는가?
2. 기능이 작동하는가?
3. 결과가 여전히 맞는가?
이 셋은 완전히 다른 문제였습니다.
예를 들어 최근에는 크립토를 현지 통화로 바꾸는 off-ramp 화면에서 문제가 생겼습니다.
USDT → BRL 같은 경로에서 브라질 로컬 거래소가 보여야 하는데 일부 데이터가 undefined로 나타났습니다.
원인은 UI 자체가 아니라 데이터 구조였습니다.
기존 컴포넌트가 기대하는 필드와 새 데이터의 필드가 달랐습니다.
그래서 중간에 어댑터를 만들었습니다.
adaptOffRampRow
서로 다른 형태의 데이터를 화면이 이해할 수 있는 형태로 맞춰주는 역할입니다.
이걸 넣으니 정상적으로 해결됐습니다.
그런데 또 같은 문제가 생깁니다.
“다음에 AI가 이 파일을 크게 수정하면 이 어댑터는 살아 있을까?”
3. 결국 아주 원시적인 검증을 추가했습니다
거창한 시스템은 아닙니다.
오히려 너무 단순합니다.
빌드 전에 중요한 로직이 실제 파일 안에 남아 있는지 직접 검색합니다.
예를 들어 Windows에서는 이런 식입니다.
findstr /C:"CORRIDOR_SPREAD_FLOOR" App.js
findstr /C:"adaptOffRampRow" App.js
특정 파트너 링크나 중요한 문자열도 같이 확인합니다.
이게 대단한 테스트 방식은 아닙니다.
자동화 테스트를 대체하지도 못합니다.
하지만 혼자 제품을 만들고, AI를 강하게 활용하는 입장에서는 꽤 효과가 있었습니다.
제가 얻은 교훈은 단순했습니다.
“새 코드가 들어갔는지만 보지 말고, 중요한 옛 코드가 사라지지 않았는지도 봐야 한다.”
4. 이제는 버튼보다 실제 시나리오를 테스트합니다
지금은 빌드 전에 실제 사용 시나리오를 적어놓고 확인합니다.
예를 들면:
- USDT → BRL에서 Mercado Bitcoin, Bitso 같은 로컬 거래소가 정상 표시되는가?
- undefined가 나오지 않는가?
- KRW 경로에서 Upbit가 잘못 P2P로 분류되지 않는가?
- 10,000 USD → BRL 추정치가 실제 관찰한 견적 범위와 너무 멀지 않은가?
- 파트너 링크가 수정 과정에서 사라지지 않았는가?
- 라이트모드에서 글자가 실제로 보이는가?
이런 식입니다.
예전에는 “코드가 돌아가네?”가 끝이었습니다.
지금은 “사업 로직이 여전히 맞나?”를 봅니다.
5. AI가 코딩을 쉽게 만든 건 맞습니다
저는 여전히 개발자가 아닙니다.
본업은 핀테크, 크립토, 운영, 프로덕트 쪽에 가깝습니다.
그런 제가 AI 도움으로 모바일 앱과 웹 서비스를 만들고 실제 출시까지 간 건 분명히 AI 덕분입니다.
그런데 제품을 계속 유지하다 보니 한 가지는 확실히 느꼈습니다.
AI가 코딩을 없앤 게 아니라, 어려운 부분의 위치를 바꿨습니다.
예전에는:
“이 코드를 어떻게 작성하지?”
가 문제였다면,
지금은:
“이 수정이 다른 기능을 깨뜨리지 않았나?”
“이 결과가 실제 비즈니스 로직과 맞나?”
“AI가 왜 존재하는지 모르는 코드를 삭제하지 않았나?”
“다른 AI가 이전 AI의 결정을 뒤집지 않았나?”
이런 문제가 더 커졌습니다.
6. 여러 AI를 같이 쓰면 더 심해집니다
저는 실제로 여러 AI 도구를 번갈아 사용합니다.
한 AI가 버그를 고칩니다.
다른 AI가 리팩터링합니다.
또 다른 AI가 UI를 수정합니다.
그러다 보면 이런 상황이 생깁니다.
첫 번째 AI:
“이 함수는 반드시 필요합니다.”
두 번째 AI:
“불필요해 보여 제거했습니다.”
세 번째 AI:
“기존 동작을 복구했습니다.”
그리고 저는 가운데서 실제 제품이 맞는지 확인해야 합니다.
이 과정에서 느낀 건, AI 시대에도 결국 제품의 맥락을 가장 많이 알아야 하는 사람은 사람이라는 점이었습니다.
7. 실제 제품은 여기서 확인할 수 있습니다
위에서 적은 사례들은 전부 제가 실제로 만들고 있는 TransferIQ에서 나온 문제들입니다.
웹:
Google Play:
https://play.google.com/store/apps/details?id=com.jkim1285.TransferIQMobile
해외송금사, 환율, 크립토 경로, 현지 off-ramp 등을 비교하는 서비스입니다.
광고 목적으로 링크만 던지는 글은 쓰고 싶지 않았고, 실제로 어떤 문제를 겪었는지 최대한 구체적으로 적어봤습니다.
직접 한번 눌러보고
“이건 이상하다”
“왜 이렇게 만들었냐”
“여기는 UX가 불편하다”
같은 피드백을 주셔도 정말 도움이 됩니다.
마지막으로 제가 요즘 AI가 “수정 완료했습니다”라고 말하면 가장 먼저 드는 생각은 이겁니다.
“그래서 이번에는 뭘 깨뜨렸지?”
처음에는 웃긴 말이었는데, 요즘은 정말 빌드 전 체크리스트가 됐습니다.
AI로 개발하시는 분들은 기존 기능 회귀를 어떻게 관리하시나요?
특히 테스트 코드가 충분하지 않은 초기 프로젝트나 1인 개발에서는 어떤 방식이 가장 효과적이었는지 궁금합니다.