본문으로 건너뛰기
홈
기술
기술 전체
프로그래밍68
컴퓨터 과학63
AI48
웹 개발36
인프라33
데이터31
소프트웨어 공학18
소개
← 목록으로AI › 언어 모델 › 응용

13. LLM 운영하기

목차

LLM 운영하기

개발 환경에서 한 번 좋은 답을 얻었다고 서비스가 준비된 것은 아니다. 같은 질문도 문서 버전, 모델 버전, 검색 결과, 동시 요청 수에 따라 다른 결과가 나온다. LLMOps에서는 이 변화를 재현하고, 품질과 비용을 같이 관찰하며, 문제가 생겼을 때 안전하게 이전 상태로 돌아갈 수 있어야 한다.

flowchart LR
  A[질문 및 요청 ID] --> B[입력 검증]
  B --> C[문서 검색]
  C --> D[프롬프트 구성]
  D --> E[모델 호출]
  E --> F[출력 검증]
  F --> G[응답]
  C -. 검색 시간·문서 ID .-> H[관측 데이터]
  E -. 지연·토큰 사용량 .-> H
  F -. 오류·근거 평가 .-> H

요청 한 건을 request_id로 묶으면 “느린 답변”이 검색에서 지연됐는지, 모델 호출에서 지연됐는지 분리해 볼 수 있다. 그림의 관측 데이터에는 원문 전체 대신 필요한 식별자와 집계값만 남겨 개인정보 유출을 줄인다.

버전을 한 묶음으로 관리

RAG 서비스의 결과는 모델 파일 하나로 결정되지 않는다. 최소한 아래 항목을 함께 기록한다.

항목예시
생성 모델모델 이름, 제공자, 배포 버전, 생성 매개변수
임베딩모델 버전, 벡터 차원, 정규화 방식
검색청크 규칙, 색인 버전, 상위 k, 재정렬 방식
지시문시스템 지시문과 답변 형식 버전
문서수집 시각, 원본 버전, 권한 정책

예를 들어 임베딩 모델만 교체하고 기존 문서 벡터를 그대로 두면 질문과 문서가 서로 다른 벡터 공간에 놓인다. 새 문서 색인을 별도로 구축하고, 같은 평가 질문으로 비교한 후 트래픽을 전환한다. 이전 색인은 롤백에 필요한 동안 유지한다.

오프라인 평가와 온라인 지표

배포 전에 실제 질문을 익명화해 평가 집합을 만든다. 쉬운 질문만 넣지 말고 모호한 질문, 답이 없는 질문, 오래된 문서, 권한 밖 문서, 악의적인 문서 내용도 포함한다.

  1. 검색 품질: 관련 문서가 상위 k개 안에 있는 비율(Recall@k)과 순위(MRR@k).
  2. 답변 품질: 사실 주장에 근거가 있는지, 인용이 올바른 문서를 가리키는지, 답이 없을 때 보류하는지.
  3. 서비스 품질: 성공률, 타임아웃, p50·p95 지연 시간, 초당 요청, 요청당 비용 또는 토큰 사용량.

정답 문장이 여러 형태일 수 있으므로 문자열 일치율만으로 답변 품질을 판정하지 않는다. 중요한 질문은 평가 기준과 근거 문서를 정해 사람이 표본을 검토한다. 자동 평가 모델을 쓰더라도 사람이 판정한 표본과 얼마나 일치하는지 먼저 확인한다.

온라인에서는 사용자 불만이나 재질문도 신호지만, 이것만으로 오류율을 계산하기 어렵다. 만족한 사용자는 아무 피드백을 남기지 않을 수 있다. 배포 전 평가 집합과 운영 중 샘플 검토를 함께 유지한다.

로그와 추적 설계

OpenTelemetry의 추적(trace), 지표(metric), 로그(log)를 적용하면 단계별 지연과 오류를 연결할 수 있다. 추적에는 검색, 재정렬, 모델 호출을 각각 span으로 두고, 지표에는 성공률·지연 분포·토큰 사용량을 집계한다. OpenTelemetry의 관측 가능성 설명은 이 세 신호의 역할을 정리한다.

request_id=ab12  model_version=v3  index_version=2026-01-22
retrieve_ms=35  rerank_ms=19  generate_ms=840
retrieved_chunk_ids=[refund-v2:3, shipping-v1:1]
input_tokens=540  output_tokens=86  status=ok

위 값은 로그 필드 형식 예시이며 실제 측정값이 아니다. 질문 원문, 검색 문서 전문, 인증 토큰을 로그에 기본값으로 남기면 민감한 데이터가 쌓인다. 필요한 경우에는 접근 통제와 보존 기간을 정하고, 민감 필드는 마스킹한다. 사용자 ID처럼 값 종류가 많은 필드를 메트릭 태그로 넣으면 집계 비용도 커진다. OpenTelemetry 메트릭 문서는 높은 카디널리티의 비용을 설명한다.

실패와 비용을 제한하기

모델 API가 느리거나 실패할 때는 재시도를 무한히 반복하지 않는다. 전체 요청 시간 제한, 짧은 재시도 횟수, 동시 호출 상한을 정한다. 재시도하면 동일 요청이 중복 처리될 수 있는 도구 호출은 식별자를 사용해 중복 실행을 방지한다. 트래픽이 늘면 출력 토큰 상한과 문서 청크 수를 먼저 살펴본다.

배포 순서는 다음처럼 단순하게 잡을 수 있다.

flowchart LR
  A[새 버전 구축] --> B[고정 평가 통과]
  B --> C[소량 트래픽 적용]
  C --> D{품질·지연·비용 확인}
  D -->|통과| E[점진 확대]
  D -->|실패| F[이전 버전으로 전환]

이 흐름의 핵심은 모델 이름만 되돌리는 것이 아니라 프롬프트·색인·검색 설정까지 함께 되돌리는 것이다. 문제가 난 응답은 요청 ID와 배포 버전으로 재현해 어느 단계에서 달라졌는지 확인한다.

요청 ID 하나로 장애를 따라가기

사용자가 “어제까지 답하던 환불 규정이 오늘은 없다고 나온다”고 보고했다고 하자. 먼저 그 요청 ID의 단계별 기록을 확인한다. 이전과 같은 질문이라도 문서 색인 버전이 달라졌고 검색 결과가 0건이면 생성 모델보다 색인 갱신과 권한 필터를 먼저 본다. 검색 결과에는 정답 청크가 있는데 응답이 달라졌다면 프롬프트 버전, 채팅 템플릿, 모델 버전과 생성 설정을 비교한다. 결과가 맞지만 10초 걸렸다면 검색 시간과 TTFT·출력 토큰 수를 분리한다.

요청 A: retrieve=40ms, rerank=25ms, generate=900ms, chunks=[refund-v2:3]
요청 B: retrieve=45ms, rerank=0ms, generate=130ms, chunks=[]

이 가상 로그에서 B가 더 빨리 끝난 것은 개선이 아니다. 검색 결과가 비어 있어 짧은 실패 답변을 냈을 가능성이 높다. 평균 지연 시간만 보면 품질 악화를 놓칠 수 있다. 대시보드에는 지연과 함께 검색 0건 비율, 근거 인용률, 답변 보류율을 넣는다. 보류율 증가는 모델이 정직해진 결과일 수도 있고 색인이 고장 난 결과일 수도 있으므로 요청 사례를 확인한다.

배포 단위를 파일로 고정하기

운영 버전에는 모델 이름 하나가 아니라 다음과 같은 구성 묶음을 남긴다. 예시 값은 실제 배포 설정이 아니다.

{
  "release": "rag-2026-01-22-b",
  "generation_model": "model-revision-17",
  "embedding_model": "embedding-revision-4",
  "index": "refund-index-2026-01-22",
  "chunker": "paragraph-v2",
  "prompt": "support-answer-v3",
  "top_k": 5,
  "max_output_tokens": 256
}

임베딩과 색인을 따로 전환하면 질문은 새 모델의 벡터인데 문서는 이전 모델의 벡터인 순간이 생길 수 있다. 새 색인을 준비해 검증한 뒤 요청 단위로 한 구성 묶음을 선택하도록 한다. 롤백도 이 JSON의 이전 버전으로 되돌리는 식으로 설계한다. 프롬프트와 모델만 되돌리고 색인을 그대로 두면 이전 응답을 재현할 수 없다.

비용과 안전 한도를 숫자로 정하기

입력 토큰은 시스템 지시문, 대화 이력, 검색 청크가 합쳐져 늘어난다. 예를 들어 검색 청크를 3개에서 10개로 늘리면 검색 재현율이 조금 오를 수 있지만, 모델의 입력 비용과 TTFT도 늘어난다. 청크를 많이 보낸 실험과 적게 보낸 실험을 동일 질문 집합에서 답변 충실도·보류율·지연·요청당 토큰 수로 비교한다. 토큰 비용을 금액으로 환산할 때는 사용하는 모델의 그 시점 가격과 캐시 조건을 별도로 확인한다.

상한에 걸린 요청은 조용히 잘라 답하게 하지 않는다. 문서가 너무 길면 검색 결과를 줄이거나 질문을 구체화하도록 안내한다. 모델 시간 초과에는 제한된 재시도 후 실패 상태를 기록한다. 도구가 데이터를 변경하는 경우 재시도에 요청 ID를 붙여 중복 변경을 막는다. 이런 오류·재시도·상한 기록을 trace의 관련 span에 연결하면 “왜 이 요청만 실패했는가”를 다시 분석할 수 있다.

참고 자료

같은 카테고리의 글