대모델 애플리케이션은 왜 감사 로그를 남겨야 하는가

대모델 시스템의 중간 과정은 전통 시스템보다 훨씬 복잡하며, 최종 답변은 흔히 가장 쓸모없는 부분이다. 답변만 저장하는 것은 트러블슈팅 능력을 포기하는 것과 같다.

감사 로그가 반드시 기록해야 할 세 종류

  • 입출력 (5가지 형태)
  • 링크 정보 (ID + 실행 과정)
  • 버전 정보 (5종 버전)

그리고 안전 경계를 그어야 한다: 마스킹, 암호화, 접근 통제, 만료 정책. 또한 로그는 검색 가능하고, 재생 가능하며, 요청 링크 단위로 집계되어야 한다.

대모델 시스템의 중간 과정

사용자 입력 → 프롬프트 조립 → 검색 소환 → 도구 호출 → 모델 생성 → 결과 검증 → 안전 필터 → 사람 확인

세 가지 「밝힐 수 없는 문제」

사용자 클레임무엇을 조회할 수 있어야 하나
모델이 정보를 유출했다그것이 어떤 컨텍스트를 봤는가
Agent의 조작이 틀렸다어떤 도구를 호출하고 무슨 파라미터를 넘겼으며 도구가 무엇을 반환했는가
어제는 답했는데 오늘은 못 답한다모델 버전 / 프롬프트 버전 / 지식베이스 버전에 변화가 있었는가

1류: 입출력 (단순 전량 저장이 아니다)

  • 원시 입력
  • 세정 후 입력
  • 모델에 들어간 컨텍스트
  • 모델의 원시 출력
  • 사용자에게 반환된 최종 출력

2류: 링크 정보

기초 식별자요청 ID, 사용자 ID, 세션 ID
모델 파라미터작업 ID, 모델명, 파라미터
실행 과정도구 호출(시퀀스), 검색 히트 문서, 리랭크 결과

이 정보들은 꿰어져야 비로소 한 번의 완전한 작업을 복기할 수 있다 — 단일 필드는 의미가 없고 링크라야 의미가 있다.

3류: 버전 정보 (5종 버전)

  • 프롬프트 버전
  • 도구 Schema 버전
  • 벡터 인덱스 버전
  • 평가셋 버전
  • 정책 규칙 버전

안전 경계: 로그는 많을수록 좋은 것이 아니다

  • 다음을 원문 그대로 장기 보존해서는 안 된다: 사용자 프라이버시, 키, 계약, 주민등록번호

  • 반드시 해야 할 네 가지

    마스킹민감 필드를 원문으로 적재하지 않음
    암호화암호화 저장
    접근 통제누가 로그를 볼 수 있는지 통제
    만료 정책 / 만료 삭제무기한 보존하지 않음
  • 개발 환경은 더 상세해도 되지만 운영 환경은 민감 필드를 통제해야 한다

로그는 검색과 재생이 가능해야 한다

  • 반면 사례: 로그를 파일에 던져놓기만 하고 아무도 안 보면 가치가 매우 낮다
  • 정면 사례: 요청 링크 단위로 집계해 「어떤 답변이 도대체 무슨 일을 겪었는가」를 조회할 수 있게 할 것

정리

대모델 애플리케이션이 감사 로그를 보존하는 것은 장애 트러블슈팅, 보안 책임 추궁, 효과 재생, 버전 비교를 위함이다. 입출력, 검색 결과, 도구 호출, 모델 파라미터, 소요와 에러, 핵심 버전 정보를 기록하고, 동시에 민감 데이터에 마스킹, 암호화, 접근 통제, 만료 삭제를 적용한다. 감사 로그는 많을수록 좋은 것이 아니라, 링크를 복원할 수 있으면서도 데이터 리스크를 확대하지 않아야 한다.

핵심 통찰

  1. 관측성의 가치는 「중간 과정의 복잡도」에 비례한다 — 전통 시스템은 결과만 저장해도 되는데, 이는 입력에서 출력까지의 경로가 기본적으로 확정적이기 때문이다. 대모델 링크에는 8개의 가변 고리가 있고 각 고리가 장애 지점일 수 있으므로, 여기서 「답변만 저장」은 게으름이 아니라 구조적 실패다.
  2. 「답변」은 여러 번 고쳐 쓰인 산물이지 사실의 소스가 아니다 — 입출력을 5가지 형태로 쪼갠 것은 본질적으로 이 점을 상기시킨다: 사용자에게 반환된 그 텍스트는 이미 안전 필터와 후처리를 거쳤으므로, 그것으로 문제를 역추적하면 반드시 잘못 추론한다. 트러블슈팅은 반드시 고쳐 쓰기 이전의 계층을 가져와야 한다.
  3. 대모델 상용 사고의 제1용의자는 버전 변경이지 모델 퇴화가 아니다 — 「모델이 갑자기 멍청해진 것이 아니라 어떤 버전이 조용히 바뀐 것」이 가장 이식성 높은 판단이다. 「어제는 잘 되던 게 오늘은 안 된다」를 만나면 먼저 5종 버전 diff를 보고 나서 모델 능력을 논하라.
  4. Embedding 모델과 벡터 인덱스는 반드시 버전을 묶어야 한다 — Embedding을 바꾸고 인덱스를 재구축하지 않는 것은 소리 없이 RAG 시스템 전체를 망가뜨릴 수 있는 조작이다. 인터페이스가 에러를 내지 않고 서비스가 죽지 않으며 소환만 전부 틀린다. 이런 「조용한 장애」는 버전 로그로만 잡을 수 있다.
  5. 로그의 조직 단위는 「한 줄 한 줄의 이벤트」가 아니라 「요청 링크」여야 한다 — 링크 단위 집계가 로그를 「보관물」에서 「도구」로 바꾸는 열쇠다. 그렇지 않으면 아무리 완전히 기록해도 사람이 다시 꿰어 맞출 수 없다.
  6. 감사 로그 설계는 이중 제약 최적화 문제다 — 목적 함수는 「링크를 복원할 수 있음」이고 제약은 「데이터 리스크를 확대하지 않음」이다. 한쪽만 최적화하는 것(완전히 기록 / 적게 기록)은 둘 다 오답이며, 이것이 채점 포인트이기도 하다.
  7. 로그 레벨은 기분이 아니라 환경에 따라 달라져야 한다 — 개발 환경은 상세하게, 운영 환경은 민감 필드를 수렴시키는 것이 안전 경계를 공학화하는 최저 비용 수단이다.

엔지니어링 실전 Tips

  • 요청마다 request_id를 생성해 전 사슬로 전파하는 것이, 위의 모든 필드를 「꿰어 맞출」 수 있게 하는 전제다. 그것이 없으면 나머지 필드의 가치가 크게 떨어진다.
  • 「5종 버전」을 version snapshot 객체로 만들어 로그마다 함께 적재할 것. 각 서비스의 설정에 흩어놓지 말 것 — 그래야 사후 diff가 가능하다.
  • Embedding 모델 업그레이드는 「인덱스 재구축 + 인덱스 버전 +1」이라는 강제 프로세스를 타야 하며, 인덱스 버전을 검색 로그에 써넣어 조용한 장애를 피할 것.
  • 민감 필드는 로그를 쓰기 전에 마스킹할 것을 권장한다(적재 시 즉시 마스킹). 조회 시 마스킹은 로그가 유출되는 순간 무효가 된다.
  • 「도구 호출 시퀀스」는 도구 이름만이 아니라 파라미터와 반환값 전체를 기록할 것 — Agent류 장애의 90%는 파라미터에서 난다.
  • 만료 삭제 정책을 만들 때 데이터 종류별로 등급을 나눌 것: 링크 지표는 오래 남겨도 되지만 사용자 입력 원문이 담긴 것은 짧게 남길 것.
  • 로그 저장 비용은 Token 양에 따라 선형으로 팽창한다. 「모델에 들어간 컨텍스트」 같은 대형 필드는 샘플링하거나 참조 저장(지문 저장 + 콜드 스토리지에 원문)할 것을 권장한다.