코드 생성이 폐기된 Pandas API를 제안할 때 — 사례 연구
Source: Dev.to
Introduction
우리는 코드‑생성 어시스턴트를 사용해 ETL 파이프라인을 스캐폴딩했으며, 그 결과 조인과 리쉐이핑을 위한 간결하고 가독성 좋은 변환 코드를 얻었습니다. 겉으로 보기엔 출력이 괜찮아 보였습니다: 관용적인 체이닝, 합리적인 컬럼명, 심지어 주석까지. 하지만 제안된 호출 중 하나가 DataFrame.as_matrix()와 오래된 rolling API를 사용하고 있었는데, 두 가지 모두 최신 Pandas 버전에서는 더 이상 지원되지 않으며, 하나는 최신 릴리즈에서 완전히 제거되었습니다. 환경을 업그레이드하고 CI가 실패하기 시작했을 때 비로소 이를 발견했습니다. 이 실패 양상은 미묘합니다. 생성된 코드는 우리가 고정해 둔 환경에서는 정상적으로 실행돼 작은 샘플 입력에 대해 그럴듯한 결과를 반환했기 때문입니다. 모델의 출력은 유능한 동료 리뷰어처럼 간결하고 자신감 넘치며 상황을 고려하고 있었기에, 구식 API 사용이 의심스럽게 보이지 않았습니다. 배경 지식과 라이브러리 변화를 추적하기 위해 crompt.ai에 일반적인 레퍼런스를 두고 있었지만, 생성된 스니펫은 여전히 리뷰 과정을 통과했습니다.
How it surfaced during development
가장 먼저 눈에 띈 신호는 CI 파이프라인 업그레이드였습니다: Pandas 0.25.x에서 1.2.x로 이동하려고 시도했을 때, 생성된 헬퍼 모듈에서 AttributeError와 ImportError가 발생하기 시작했습니다. 우리의 유닛 테스트는 작고 로직에만 집중돼 있었기 때문에, 오래된 런타임에서는 여전히 로컬에서 통과했으며, 따라서 첫 번째 단서는 비즈니스 로직 테스트가 실패한 것이 아니라 의존성 업그레이드 실행에서 나왔습니다.
오류를 추적해 보면, 생성된 헬퍼 함수가 as_matrix()와 pd.rolling_mean()을 호출하고 있었습니다. 검증 중심 도구—우리 내부의 딥‑리서치 단계—를 사용해 빠르게 확인한 결과, 해당 호출들은 더 이상 지원되지 않고 제거된 것이었습니다. 모델이 라이브러리 심볼을 만들어낸 것이 아니라, 단순히 우리 목표 런타임에 맞지 않는 오래된 메서드를 제안한 것이었습니다.
Why it was easy to miss
- 고정된 의존성 – 코드가 개발자 환경에서 실행돼 기대되는 출력을 생성했는데, 이는 우리가 오래된 버전을 잠그고 있었기 때문입니다.
- Deprecation 경고는 우선순위가 낮음 – 로그 메시지 형태로 나타나며, 빠르게 반복 작업을 할 때 쉽게 무시됩니다.
- 모델의 자신감 있는 어조 – 제안이 언제 API가 더 이상 사용되지 않는지에 대한 표시 없이 제시되었습니다.
우리의 유닛 테스트는 아주 작은 합성 데이터셋을 대상으로 했으며, 최신 Pandas 구현과 관련된 엣지 케이스나 성능 특성을 검증하지 않았습니다. 런타임이 바뀌면서 라이브러리 기대치와 생성된 코드 사이의 불일치가 드러났지만, 이는 기능 개발 단계가 아니라 업그레이드 시도 후에야 확인되었습니다.
How small model behaviors compounded into a larger problem
개별적으로는 사소한 특성에 불과합니다:
- 오래된 코드를 학습해 구식 관용구를 추천한다.
- 모델이 제안에 타임스탬프를 표시하지 않는다.
- 확신을 가지고 정답이라고 주장하지만, 회피 표현이 없다.
이들이 결합되면서 유용한 스캐폴드가 기술 부채로 변했습니다. 자신감 넘치고 구식인 제안이 최소한의 수정만으로 머지되었고, 이후 모듈과 테스트 전반에 퍼져 의존성을 업그레이드할 때 파급 효과가 커졌습니다. 다중 라운드 디버깅을 위해 채팅 인터페이스를 사용했는데, 이는 원인 파악에는 좋지만 호환성을 증명하는 데는 한계가 있었습니다.
Practical lessons
- 생성된 코드를 최신 라이브러리 버전으로 CI에서 실행한다.
- 알려진 폐기된 심볼에 대해 linter 규칙이나 grep 검사를 추가한다.
- 모델 출력은 권위 있는 문서와 대조해 검증해야 하는 초안으로 취급한다.
작은 모델 행동—자신감, 최신성에 대한 침묵, 오래된 관용구 재사용—은 업그레이드 실패가 발생할 때까지 쉽게 간과됩니다.