ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • AI 에이전트가 흔들릴 때, 모델보다 하네스를 먼저 봅니다
    AI Agent 2026. 6. 17. 20:38
    728x90
    반응형

    같은 "점수" 하나가 세 군데에 다른 이름으로 흩어져 있었습니다.

    서버 응답엔 snake_case 키로, 앱 안엔 camelCase로, 거기다 예전에 쓰던 옛날 키까지.
    그러니 한 곳을 고치면 다른 화면이 아직 옛 키를 보고 있었어요.

    처음엔 모델을 의심했습니다.
    이 모델이 코드를 잘 고치나, 저 모델이 긴 파일을 잘 읽나.
    결과가 흔들릴 때마다 이름을 갈아 끼웠어요.

    그런데 어떤 모델을 써도 이 자리에서만은 똑같이 틀렸습니다.

    그제야 알았어요.
    모델이 아니라, 데이터가 드나드는 자리가 하나로 안 정해진 게 문제였던 거죠.
    키를 하나로 못박고 — 한 의미엔 한 필드, 옛 키 동시 발행 금지 — 그러고 나서야 그 자리가 잠잠해졌습니다.

    그때부터 결과가 흔들리면 모델보다 하네스를 먼저 봐요.
    모델 주변의 작업대 말이에요.
    일이 어디로 가고(라우팅), 어디까지 건드릴 수 있고(권한), 무엇을 통과해야 끝이고(검증), 뭘 기억하는지.

    실수는 한 군데서 안 끝납니다

    제일 크게 데인 건 검증이었어요.

    한 번은 공통으로 쓰는 값 하나가 틀어졌는데, 그게 화면 수백 군데에서 가져다 쓰는 거였습니다.
    버그 하나인 줄 알고 고치러 갔다가, 같은 패턴이 평균 서너 곳, 심한 건 헬퍼 하나에서 시작한 게 수백 곳까지 퍼져 있었어요.

    그래서 지금은 버그 하나를 찾으면 반드시 같은 패턴을 grep으로 전수 훑습니다.
    한 군데만 고치고 닫으면, 나머지가 조용히 남아 다음 주에 다시 터지거든요.

    더 무서운 건 테스트가 통과해버린 경우였어요.

    이름을 대량으로 바꾼 파일을 머지했더니, 삭제했던 옛 이름이 호환용 별칭으로 조용히 되살아났습니다.
    그것도 값이 틀린 채로요.
    어떤 건 3.0이어야 하는데 2.0으로 살아났어요.

    그런데 lint도 통과하고, "아무도 안 쓰는 죽은 코드" 검사도 통과합니다.
    별칭은 문법상 멀쩡한 별개 필드고, 아무도 안 쓰니 죽은 코드라 안 걸리거든요.
    두 게이트가 다 못 잡았어요.
    결국 사람이 정의부를 눈으로 읽고서야 찾았습니다.

    그래서 작업대에 무엇을 둘지

    라우팅부터.
    일이 엉뚱한 데로 가면 똑똑한 모델도 헛심을 씁니다.
    그래서 앱이 갈 수 있는 화면·동작을 한 레지스트리에 모아 뒀어요.
    "이거 고쳐줘"가 어디로 가야 하는지가 한 곳에 있으니, 매번 새로 찾지 않죠.

    권한은 좁힐수록 리뷰가 편해요.
    작업마다 건드릴 범위를 미리 잘라 주고, 인증 가드를 건너뛰는 지름길 같은 우회로는 아예 막아 둡니다.

    검증은 "테스트 돌려"가 아니라, 무엇을 통과해야 끝인지를 못박는 거예요.
    심각한 버그는 dev에 올려 그 환경에서 재현 테스트까지 통과해야 완료로 칩니다.
    "고쳤습니다"가 아니라 "그 환경에서 다시 안 터지는 걸 확인했습니다"여야 하니까요.

    한 번은 로컬에 띄운 작은 모델한테 항목을 10개씩 묶어 조사를 시켜 봤어요.
    출력은 JSON으로 매번 멀쩡하게 돌아왔습니다.
    한 줄 한 줄에 "검증 완료"라는 딱지까지 깔끔하게 붙어서요.
    그런데 그 딱지가 가리키는 근거 — 같은 출처에서 200이 떨어진 흔적 — 이 실제로 있는지 모델 말만 믿으면 안 됐어요.
    그래서 작업대에 그 근거가 진짜 있는지만 기계적으로 다시 보는 검사를 한 칸 더 박아 뒀습니다.
    돌려 보니 모델이 "검증 완료"라고 단 줄들 중 절반 넘게가, 근거가 없는데도 그렇게 단 거였어요.
    형식은 다 통과했고요.
    똑똑하냐 아니냐가 아니라, 자기 근거를 부풀려도 그걸 잡아 줄 칸이 작업대에 있느냐였던 거죠.

    미리 안 펼치면, 같은 회귀를 네 번 봅니다

    한 번은 화면 하나를 그냥 통째로 맡겼어요.
    회귀 보고가 왔고, 고쳤더니 또 다른 회귀, 또 고쳤더니 또.
    같은 작업으로 후속 수정을 네 번 돌았습니다.

    미리 가설을 펼치고 다른 시각으로 한 번 까였으면 첫 판에 잡혔을 회귀였어요.
    그 뒤로는 한 줄짜리 단순 변경이 아니면 계획을 먼저 펼치고 한 번 적대적 리뷰를 받고 나서 일을 분배합니다.
    이것도 하네스예요.
    모델한테 "꼼꼼히 해"라고 비는 게 아니라, 통과 못 하면 못 넘어가는 문턱을 두는 거죠.

    기억도 작업대의 일부고요.
    지난번에 뭐가 실패했는지, 어떤 파일은 건드리면 안 되는지가 대화 끝자락에만 있으면 다음 작업에서 또 날아갑니다.
    거창한 문서 말고 네 줄이면 돼요.
    지금 브랜치, 수정 범위, 통과한 검증, 아직 못 본 리스크.

    모델을 바꾸기 전에

    결과가 흔들릴 때 모델을 갈아 끼우는 건 쉬운 선택이고, 가끔 진짜 도움도 됩니다.
    데이터 자리도 하나로 모았고 권한도 좁혔는데 같은 자리에서 계속 틀리면, 그때가 모델을 의심할 때예요.

    그래도 저는 이제 이름부터 바꾸지 않습니다.
    그 "검증 완료" 절반이 사실은 비어 있던 걸 본 뒤로, 모델 칸을 만지기 전에 손이 먼저 검사 칸으로 가요.
    그 자리를 안 잡은 채로 좋은 모델만 새로 얹어 봤자, 신기할 것도 없이 같은 데서 또 틀리거든요.

    이 글은 'AI 코딩 에이전트를 믿는 법' 시리즈의 한 편이에요.
    위임·검증·하네스·비용 6편을 한 번에 보려면 여기로요.

    https://datacook.tistory.com/156

     

    AI 코딩 에이전트를 믿는 법 — 위임·검증·하네스·비용 6편 정리

    AI가 "완료했습니다" 한 줄로 답할 때, 저는 더 이상 그 말을 안 믿습니다.습관처럼 diff부터 엽니다. 그래서 들킨 적도 많고요. 멀쩡한 보고 뒤에서 엉뚱한 파일이 고쳐져 있던 날, 검증이 전부 초

    datacook.tistory.com

     

    728x90
    반응형
Designed by Tistory.