15.1.2 숨겨진 기술 부채(Hidden Technical Debt): 모델보다 커지는 검증 시스템의 복잡도

15.1.2 숨겨진 기술 부채(Hidden Technical Debt): 모델보다 커지는 검증 시스템의 복잡도

구글의 연구원들이 발표한 기념비적인 논문인 “Hidden Technical Debt in Machine Learning Systems”(Sculley et al., 2015)는 머신러닝 시스템에서 실제 ’학습 코드(ML Code)’가 차지하는 비중은 전체 인프라의 극히 일부분에 불과하며, 나머지 방대한 영역이 모두 잠재적인 기술 부채(Technical Debt)의 늪이라고 지적했다.

이는 생성형 AI와 대형 언어 모델(LLM)을 활용한 현대 소프트웨어 개발에서 더욱 극단적인 형태로 나타난다. 프롬프트를 작성하고 API를 호출하는 애플리케이션의 핵심 로직(Core Logic)은 단 몇십 줄의 코드로 완성될 수 있지만, 변덕스러운 AI를 통제하기 위해 우리가 지금까지 쌓아 올린 오라클(Oracle) 검증 시스템의 복잡도는 본 애플리케이션의 크기를 아득히 초과하게 된다.

1. 검증 시스템 비대화의 엔지니어링 역설

전통적인 소프트웨어에서는 기능 구현에 들어간 시간의 약 20~30% 정도를 단위 테스트(Unit Test) 작성에 배분하는 것을 모범 사례(Best Practice)로 여겼다. 그러나 확률론적 AI를 통제하려는 순간, 이 비율은 완전히 역전된다.

챗봇이 사용자의 의도를 분석하여 사내 비즈니스 API를 호출(Tool Calling)하는 기능을 구현한다고 가정해 보자.

  • 애플리케이션 코드: LLM에게 도구 스키마(Tool Schema)를 넘겨주고 응답을 받아 실행하는 langchain 기반의 로직은 단 50줄이면 끝난다.
  • 검증 오라클 코드: 반면, 이 50줄의 코드를 신뢰하기 위해서는 수천 개의 골든 데이터셋(Golden Dataset), Pydantic을 이용한 스키마 검증기, RAG 인용(Citation) 추적 로직, 성능을 채점하는 LLM-as-a-Judge 프롬프트 파이프라인, 그리고 운영 환경에서 실패 케이스를 수집하는 섀도우 오라클(Shadow Oracle)까지, 족히 수천 줄에 달하는 인프라 코드가 조형되어야 한다.

소프트웨어 시스템에서 ’코드가 많다’는 것은 곧 그 자체가 ’거대한 빚(Debt)’임을 의미한다. 모델의 자유도를 묶기 위해 구축한 화려한 오라클 파이프라인이, 역설적으로 엔지니어링 팀의 발목을 잡는 가장 무거운 족쇄로 전락하게 되는 것이다.

2. 오라클의 복잡성이 초래하는 기술 부채의 증상 (Symptoms)

오라클 검증 시스템이 메인 비즈니스 로직보다 비대해졌을 때, 조직은 다음과 같은 치명적인 부채의 이자(Interest)를 상환해야 한다.

  1. 접착 코드(Glue Code)의 범람:
    LLM 제공자(Vendor)의 인터페이스나 라이브러리(예: OpenAI API, LlamaIndex)가 업데이트될 때마다, 기존에 구축해 둔 복잡한 정답지 파서(Parser)와 심판관 모델의 프롬프트를 연결하는 접착 코드가 연쇄적으로 붕괴한다.

  2. 다중 스키마 버전 관리의 지옥:
    비즈니스 요구사항이 변하여 반환해야 할 JSON 스키마에 필드 하나가 추가되면, 메인 로직의 프롬프트만 수정해서는 안 된다. 1차 정칙성 오라클의 Pydantic 클래스, 2차 LLM-as-a-Judge의 루브릭 파라미터, 수만 개의 Golden Dataset 내 기댓값 구조 구조를 모두 마이그레이션(Migration)해야 하는 거대한 번거로움이 발생한다.

  3. 파이프라인 지연(Pipeline Latency):
    CI/CD 환경에서 코드를 커밋(Commit)할 때마다 구동되는 오라클 테스트가 너무 무거워져, 브랜치를 머지(Merge)하기 위해선 수십 분의 API 병목(Bottleneck) 대기 시간을 견뎌야 한다. 이는 결과적으로 팀의 애자일(Agile)한 배포 주기를 완전히 파괴한다.

3. 부채를 다루는 엔지니어의 자세

이러한 ’모델보다 거대한 검증 인프라’는 AI 시대를 살아가는 소프트웨어 엔지니어가 피할 수 없는 숙명이다.

다만 이를 무책임한 파게티 코드(Spaghetti Code)로 방치하는 것과, 관리 가능한 수준의 ’레버리지(Leverage)’로 활용하는 것은 전혀 다른 문제다. 오라클 아키텍트는 맹목적으로 오라클의 층위를 두껍게 쌓기 전에, “이 검증 로직이 진정으로 비즈니스 리스크를 상쇄하는가?”, “정규식(Regex) 단 한 줄로 끝낼 수 있는 검증을 불필요하게 LLM-as-a-Judge로 처리하고 있지 않은가?“를 끊임없이 스스로에게 반문하며 시스템의 군살을 도려내야 한다.