손님이 공들여 채운 설정이 결과에 한 글자도 반영되지 않는데, 테스트는 전부 초록불이었습니다. 남의 앱 이야기가 아니라 제가 만든 서비스 이야기입니다.
이 글 3줄 요약
- 매장 정보 폼 17칸 중 12칸이 저장만 되고 글 생성에는 한 번도 쓰이지 않았습니다. AI 모델 탓이 아니라 배선(저장한 값을 읽어 가는 길)이 끊겨 있었습니다.
- 저장 기능 테스트도, 생성 기능 테스트도 통과였습니다. "저장한 값이 생성에 들어가는가"를 보는 검사만 없었습니다.
- 코딩을 몰라도 할 수 있는 점검법이 있습니다. 칸마다 "이 값을 바꾸면 결과가 달라지나요?"를 물어보는 것입니다.
화면은 멀쩡한데 뭔가 꼬였다는 느낌
제가 운영하는 장사레이더(자영업 매장용 AI 콘텐츠·동네 신호 서비스)를 7주 동안 손보던 중이었습니다. 버그가 난 것도 아니고 화면이 깨진 것도 아닌데, "이거 뭔가 꼬였다"는 느낌이 자꾸 들었습니다. 이런 느낌이 들 때 코드를 더 고치면 보통 더 꼬입니다. 그래서 반대로 했습니다. 고치는 손을 멈추고, 코드를 읽기만 하는 전수감사(코드 전체를 빠짐없이 훑어보는 점검)를 5갈래로 나눠 동시에 돌렸습니다. 코딩 AI 도구 여러 개에게 각자 다른 구역을 맡겨 "고치지 말고 보고만 하라"고 시킨 겁니다. 나온 결론은 다른 회사 AI에게 반박 검수까지 받았습니다.
결론은 한 줄이었습니다. 화면은 안 꼬였고, 꼬인 건 "만들었다가 지운 흔적"과 "받아놓고 안 쓰는 입력"이라는 것이었습니다. 가입부터 온보딩(처음 가입한 손님에게 설정을 받는 단계), 글감 뽑기, 결과 확인, 이력까지 손님이 밟는 길에 끊긴 곳은 0곳이었습니다. 겉으로는 다 돌아갑니다. 문제는 손님이 공들여 입력한 설정이 결과에 반영되지 않는다는 점이었습니다.
17칸을 받아서 4~5칸만 쓰고 있었습니다
매장 정보 폼은 17칸을 받습니다. 영업시간, 휴무일, 가격대, 주차, 예약, 배달, 포장 여부, 타깃 손님, 피하고 싶은 주제까지. 사장님이라면 "이걸 다 넣어야 글이 내 매장답게 나오겠구나" 하고 정성껏 채우실 겁니다. 그런데 그중 12칸은 저장만 되고 글 생성에 한 번도 쓰이지 않았습니다. 생성 지시문(프롬프트, AI에게 건네는 작업 지시)에 실제로 닿는 칸은 4개 또는 5개였습니다. 집계 문서 두 개가 1칸 차이로 달라서 "또는"이라고 적습니다.
온보딩도 마찬가지였습니다. 5단계 중 4단계(말투)와 5단계(주력 채널)는 결과에 아무 영향을 주지 못했습니다.
말투 쪽이 특히 교묘했습니다. 글감 뽑기 화면의 말투 선택은 매번 "친근"으로 고정된 채 시작했습니다. 그 회차에 손님이 직접 바꾼 말투는 전달됩니다. 하지만 온보딩에서 저장한 "내 기본 말투"는 어디에서도 읽히지 않았습니다. 손님 입장에서는 "분명히 정중한 말투로 설정했는데 왜 자꾸 친근하게 나오지?"가 됩니다. 그러면 AI를 의심하게 됩니다. 사실은 AI가 그 설정을 받아 본 적이 없는데도요.
주력 채널은 더 단순했습니다. 이 설정을 읽는 코드가 0곳이었습니다. 채널 추천은 따로 고정된 표가 맡고 있었습니다. 손님이 뭘 고르든 결과가 같은 칸이 버젓이 폼에 있었던 셈입니다.
왜 이렇게 됐나: 롤백이 읽는 쪽만 지웠습니다
원인은 롤백(기능을 이전 상태로 되돌리는 것)이었습니다. 저장한 말투를 읽어 쓰던 새 홈 화면이 있었는데, 그 화면을 되돌릴 때 삭제됐습니다. 그런데 입력 폼과 DB(데이터베이스) 칸, 즉 저장하는 쪽은 그대로 살아남았습니다. 읽는 쪽만 사라지고 쓰는 쪽은 남은 겁니다. 롤백은 원래 이렇게 됩니다. 결과 화면은 눈에 보이니 지우고, 폼과 DB 칸은 "있어도 해가 되진 않겠지" 하고 두게 됩니다. 그 순간부터 그 칸은 손님에게 하는 거짓 약속이 됩니다.
같은 병의 큰 버전도 있었습니다. 근거 수집함이라는 새 부품을 코드 14,320줄과 테스트 431개 규모로 만들어 놓고, 정작 글 생성 경로는 그 코드를 0줄 읽었습니다. 그런데도 검사 6종은 전부 초록불이었고, 18일 동안 실제 결과물은 0건이었습니다. 그 코드를 걷어낸 다음 날, 기존 엔진으로 첫 실제 결과물이 나왔습니다. 만든 것과 쓰이는 것이 완전히 분리돼 있었는데 검사는 그걸 몰랐던 겁니다.
메뉴에서는 빠졌는데 주소를 직접 치면 열리는 "유령 화면·경로"도 5개(화면 4개와 처리 경로 1개) 남아 있었습니다. 반쯤 바꾸다 만 디자인 탓에 한 앱 안에 색 규칙이 2개 공존했고, 새 디자인을 쓰는 실사용 화면은 2개뿐이었습니다. 반쯤 바꾼 상태가 가장 나쁩니다. 마저 바꾸거나 걷어내거나, 둘 중 하나를 골라야 합니다.
검사는 부품을 보고, 손님은 "넣은 대로 나오나"를 봅니다
입력칸은 손님과의 약속입니다. 칸을 많이 받으면 손님은 "많이 넣을수록 결과가 좋아진다"고 믿고 시간을 씁니다. 쓰지 않을 칸이면 받지 않는 게 정직하고, 받았으면 결과에 반영해야 합니다. 폼을 줄일지 생성에 연결할지, 둘 중 하나를 정책으로 정해야 합니다. "나중에 쓸 거니까" 칸부터 만드는 건 그때까지 거짓말을 하겠다는 뜻입니다.
검사는 연결을 보증하지 않습니다. 저장 기능 테스트도 통과, 생성 기능 테스트도 통과였습니다. 하지만 "저장한 값이 생성에 들어가는가"를 보는 검사는 하나도 없었습니다. 부품별 초록불을 아무리 모아도 길이 이어졌다는 증거는 안 됩니다. 그래서 완료의 정의를 바꿨습니다. "검사 초록불"이 아니라 "실제 서비스에서 결과물 1건"입니다.
감사 결과도 반박을 받아야 정확해집니다. 처음 감사 보고서는 "말투 선택이 무시된다"고 적었습니다. 타사 AI에게 반박 검수를 시키자 "그 회차에 고른 말투는 전달된다, 문제는 저장한 기본 말투가 안 읽히는 것"으로 정정됐습니다. 화면 개수도 30개에서 실측 25개로 고쳐졌습니다. 과장된 진단은 엉뚱한 수리를 부릅니다. 처음 보고서대로 고쳤다면 멀쩡한 부분을 뜯었을 겁니다.
오늘 바로 해 볼 것: 받는 칸과 읽는 칸 대조표
외주로 만든 앱이든, 코딩 AI 도구로 직접 만든 자동화든 똑같이 적용됩니다. 손님용 서비스가 아니어도 됩니다. 직원이 매일 채우는 사내 양식에 "어디서도 안 읽히는 칸"이 있다면 같은 문제입니다.
- 손님(또는 직원)이 입력하는 모든 칸을 목록으로 뽑습니다. 가입, 온보딩, 설정 화면 전부입니다.
- 칸마다 "어디서 읽나"를 찾아 셋 중 하나로 표시합니다. 결과에 닿음, 저장만 됨, 아예 안 씀.
- "저장만 됨" 칸은 생성에 연결할지 폼에서 뺄지 정합니다. 애매하면 빼는 게 정직합니다.
- 연결하기로 한 칸은 값을 바꿔 실제로 한 번 뽑아 보고, 결과가 달라지는지 눈으로 확인합니다.
- 메뉴에 없는데 주소로 열리는 화면을 찾아 지웁니다.
- 기능을 되돌릴 때마다 1~2번을 다시 돌립니다.
- 완료 기준을 "검사 초록불"이 아니라 "실제 결과물 1건"으로 둡니다.
코드를 직접 보실 수 있는 분은 코딩 AI 도구에 아래처럼 시키면 2번까지 한 번에 나옵니다.
이 프로젝트에서 사용자가 입력하는 모든 칸(가입·온보딩·설정 화면)을 목록으로 뽑아 주세요.
칸마다 아래 셋 중 하나로 표시하고, 근거가 되는 파일 이름과 위치를 적어 주세요.
1) 결과에 닿음: 어느 코드가 이 값을 읽어 생성(또는 계산)에 쓰는지
2) 저장만 됨: 저장 코드는 있지만 읽는 코드가 없음
3) 아예 안 씀: 저장 코드도 없음
추측하지 말고 칸 이름을 코드 전체에서 검색한 결과 개수를 함께 적어 주세요.
검색 결과가 0건이면 0건이라고 그대로 적고, 코드는 고치지 마세요.
코드를 못 보시는 분도 할 수 있습니다. 설정 하나를 바꾸고 결과를 다시 뽑아 보세요. 결과가 안 달라지면 그 칸은 저장만 되는 칸입니다. 외주 개발자에게 물을 때는 이 문장 하나면 됩니다.
우리 앱에서 사용자가 입력하는 칸을 전부 적어 주시고, 칸마다 "이 값을 바꾸면 결과가 달라지는가"에 예/아니오로 답해 주세요. 아니오인 칸은 왜 받고 있는지도 같이 적어 주세요.
현장 인사이트
저장 버튼이 눌리고 "저장됐습니다"가 뜨는 것과, 그 값이 결과에 들어가는 것은 전혀 다른 일입니다. 손님은 후자만 봅니다.
이 감사에서 잘된 점도 하나 있었습니다. 거의 모든 화면이 조회 실패를 빈 화면이나 0으로 위장하지 않고 "불러오지 못했어요"와 새로고침 안내로 정직하게 보여 줬습니다. 실패를 숨기지 않는 습관은 있었던 겁니다(이 주제는 에러가 없었다고 성공은 아니다에 따로 적었습니다). 다만 그 정직함이 입력칸까지는 미치지 못했습니다. 실패를 보여 주는 것과 입력을 지키는 것은 다른 근육이라는 걸 배웠습니다.
하지 말 것
- "나중에 쓸 거니까" 입력칸부터 만들기. 쓰기 전까지는 손님에게 하는 거짓 약속입니다.
- 화면을 롤백하면서 그 화면이 읽던 설정칸과 DB 칸을 그대로 방치하기. 되돌린 뒤 "이 값을 읽는 곳이 아직 있나"를 반드시 다시 셉니다.
- 테스트가 전부 통과했다는 이유로 "입력하신 대로 반영됩니다"라고 안내하기. 그 안내는 실제 결과물로 한 번 확인한 뒤에 하셔야 합니다.
내 서비스나 사내 자동화에 비슷한 증상이 있는지 함께 들여다보고 싶으시면 아래로 연락 주세요.