LLM 에이전트 관측성 구축법: 프롬프트 로그보다 trace·metric·eval을 먼저 설계하라
AI 에이전트를 프로덕션에 넣으면 가장 먼저 부딪히는 문제는 “왜 이런 답이 나왔는지 모르겠다”입니다. 단순 채팅봇은 입력과 출력만 봐도 어느 정도 디버깅이 됩니다. 하지만 에이전트는 모델 호출, 도구 호출, 검색, 파일 읽기, API 요청, 후속 판단이 이어집니다. 최종 답변만 저장하면 장애가 났을 때 원인을 찾기 어렵습니다.
Microsoft의 Agent Framework 관측성 문서는 OpenTelemetry exporter를 통해 telemetry를 원하는 백엔드로 보낼 수 있다고 설명하고, 민감 데이터가 production logs and traces에 노출될 수 있으므로 development/test에서만 활성화하라고 경고합니다. 이 지점이 핵심입니다. 에이전트 관측성은 로그를 많이 남기는 일이 아니라, 필요한 메타데이터를 안전하게 남기는 일입니다.
참고 자료: Microsoft Agent Framework observability 문서(https://learn.microsoft.com/en-us/agent-framework/agents/observability).
프롬프트 전문 저장부터 시작하면 위험하다
많은 팀이 LLM 디버깅을 시작할 때 prompt와 completion 전문을 DB에 저장합니다. 개발 환경에서는 유용합니다. 하지만 프로덕션에서는 위험합니다. 사용자 개인정보, 내부 문서, API 응답, 도구 호출 인자, 검색 결과가 그대로 들어갈 수 있습니다. 특히 에이전트는 여러 도구를 거치기 때문에 민감 정보가 어디서 섞였는지 추적하기 어렵습니다.
관측성의 기본값은 전문 저장이 아니라 메타데이터 저장이어야 합니다. 모델명, 요청 ID, 세션 ID, 토큰 수, 지연 시간, 도구명, 도구 성공 여부, 오류 코드, 평가 점수는 대부분의 장애 분석에 충분한 출발점을 제공합니다. 전문 저장은 샘플링하거나, 마스킹하거나, 개발·스테이징에서만 켜야 합니다.
실무에서는 두 단계가 좋습니다. 기본 로그에는 민감하지 않은 메타데이터만 저장합니다. 재현이 필요한 케이스는 사용자의 동의 또는 내부 정책에 따라 제한된 기간만 원문을 저장합니다. 이렇게 해야 디버깅과 개인정보 보호를 동시에 맞출 수 있습니다.
trace 구조: 하나의 답변을 여러 span으로 쪼갠다
에이전트 관측성의 핵심은 trace입니다. 사용자가 “환불 규정 알려줘”라고 물었을 때 하나의 trace 안에는 모델의 계획 수립, 문서 검색, 정책 문서 읽기, 답변 생성, 후처리 검증이 들어갑니다. 각 단계는 span으로 나눕니다.
예를 들어 trace_id는 사용자 요청 하나에 붙이고, span은 llm.plan, retrieval.search, tool.fetch_policy, llm.answer, guardrail.check처럼 구분합니다. 각 span에는 시작 시간, 종료 시간, 성공 여부, 비용 추정치, 입력·출력 토큰, 오류 메시지를 남깁니다. 이렇게 하면 “답변이 느렸다”는 문제를 검색 지연, 모델 지연, 외부 API 지연 중 하나로 좁힐 수 있습니다.
중요한 점은 span 이름을 제품 기능 기준으로 붙이는 것입니다. 단순히 call_llm_1, call_tool_2라고 저장하면 나중에 대시보드가 의미를 잃습니다. refund_policy_search, invoice_lookup, crm_update처럼 사람이 이해할 수 있는 이름을 써야 합니다.
metric: 품질·비용·지연 시간을 한 화면에 둔다
LLM 서비스 대시보드는 일반 API 대시보드와 달라야 합니다. HTTP 200 비율만 높아도 품질은 망가질 수 있습니다. 모델이 형식은 맞지만 틀린 답을 했거나, 검색 결과를 무시했거나, 비용이 너무 많이 들었을 수 있습니다. 그래서 품질, 비용, 지연 시간을 함께 봐야 합니다.
필수 metric은 요청 수, 성공률, 모델 오류율, 도구 오류율, 평균 입력 토큰, 평균 출력 토큰, p95 지연 시간, 요청당 비용, guardrail 차단률입니다. 여기에 eval 점수를 붙이면 운영 판단이 쉬워집니다. 예를 들어 p95 지연 시간은 안정적인데 eval 점수가 떨어졌다면 모델 교체나 프롬프트 변경이 원인일 수 있습니다. 비용이 급증했는데 품질 점수가 그대로라면 컨텍스트가 불필요하게 커졌을 가능성이 큽니다.
대시보드는 전체 평균보다 기능별·고객 플랜별·모델별로 나눠야 합니다. 전체 평균은 대부분의 문제를 숨깁니다. 특정 기능 하나가 토큰을 과도하게 쓰거나 특정 고객군에서 검색 실패가 나는 경우가 더 흔합니다.
eval: 운영 로그를 테스트 자산으로 되돌린다
관측성은 보는 것으로 끝나면 반쪽입니다. 프로덕션에서 발견한 실패 사례를 평가셋으로 되돌려야 합니다. 사용자가 불만을 남긴 질문, guardrail에 걸린 요청, 도구 오류가 난 요청, 비용이 비정상적으로 높았던 요청을 골든셋 후보로 저장합니다.
다만 원문을 그대로 저장하면 개인정보 문제가 생길 수 있습니다. 저장 전에 익명화, 필드 제거, 범주화가 필요합니다. 예를 들어 실제 이메일 주소는 user@example.com으로 바꾸고, 주문번호는 ORDER_ID로 치환합니다. 중요한 것은 민감값이 아니라 실패 패턴입니다.
평가셋은 세 종류로 나눌 수 있습니다. 정답이 명확한 factual set, 형식 준수 여부를 보는 schema set, 사람이 점수를 매기는 judgment set입니다. 에이전트는 도구 사용이 포함되므로 “정답 텍스트”만 보지 말고 올바른 도구를 호출했는지도 평가해야 합니다.
운영 사고를 줄이는 알림 기준
AI 에이전트 알림은 너무 많이 울리면 아무도 보지 않습니다. 알림 기준은 적게, 명확하게 잡아야 합니다. 추천 기준은 세 가지입니다. 첫째, 도구 오류율이 일정 기준을 넘을 때. 둘째, 요청당 비용이 최근 7일 평균보다 급증할 때. 셋째, eval 샘플 점수가 기준 이하로 떨어질 때입니다.
특히 비용 알림은 중요합니다. 모델 호출은 인프라 비용과 달리 코드 한 줄, 프롬프트 한 문장, 컨텍스트 정렬 변화로도 크게 달라질 수 있습니다. 토큰이 늘어난 이유가 기능 확장인지 버그인지 구분하려면 배포 버전과 prompt version을 로그에 같이 남겨야 합니다.
품질 알림은 자동 판정만 믿으면 안 됩니다. 초기에는 사람이 보는 샘플 리뷰를 섞어야 합니다. 자동 eval은 빠르지만 편향될 수 있고, 사람 평가는 느리지만 실제 사용자 관점에 가깝습니다. 둘을 같이 써야 운영 리스크가 줄어듭니다.
실행 체크리스트
- trace_id를 사용자 요청 하나에 붙이고 모델·검색·도구 호출을 span으로 분리한다.
- prompt/completion 전문 저장은 기본 OFF로 두고, 메타데이터 중심으로 시작한다.
- 로그에는 모델명, prompt version, 기능명, 토큰, 비용, 지연 시간, 도구 오류를 남긴다.
- 실패 사례를 익명화해 factual/schema/judgment 평가셋으로 되돌린다.
- 비용 급증, 도구 오류율, eval 점수 하락 3가지 알림부터 설정한다.
- 민감 데이터가 trace에 들어가는지 정기적으로 샘플 감사를 한다.