[AI Agent] LLM Observability Preview (8주차)

LLM Observability는 AI Agent가 어떤 입력을 받았고, 어떤 prompt와 context로 model을 호출했으며, 어떤 retrieval과 tool 실행을 거쳐 답변을 만들었는지 추적하는 운영 체계입니다. Evaluation이 결과를 판정한다면, Observability는 그 결과가 만들어진 과정을 다시 따라갈 수 있게 남깁니다.

[AI Agent] LLM Observability Preview (8주차)
Photo by Irina Popovich / Unsplash

개요

이번 주차까지 AI Agent 시스템을 직접 만들어봤습니다.

만들었다면 이제 제대로 동작하는지 평가해야 합니다.

RAG에서는 검색이 필요한 근거를 잘 가져왔는지, 생성된 답변이 근거를 벗어나지 않았는지, 최종 답변이 기준 정답과 맞는지를 나눠 봤습니다. RAGAS 기반의 5가지 지표입니다.

Agent는 여기서 한 단계 더 봐야 합니다. 최종 답변뿐 아니라 tool 선택, tool 인자, 실행 순서까지 평가 대상이 됩니다.

평가 vs Observability

평가는 중요합니다. 하지만 평가는 보통 한 가지 질문에 답합니다.

이 결과가 좋은가, 나쁜가?

RAGAS로 조금 더 구체화해보겠습니다.

Correctness가 낮다.
Faithfulness가 낮다.
Context Recall이 낮다.

문제는 그다음입니다. 점수가 낮게 나왔다면 바로 다음 질문으로 넘어가야 합니다.

왜 나빠졌는가?
어느 단계에서 틀어졌는가?
어떤 입력에서 반복되는가?
프롬프트 문제인가, 검색 문제인가, tool 문제인가, 모델 문제인가?
어제 배포한 변경 때문에 생긴 문제인가?

RAG 케이스에서 더 자세히 알아보겠습니다.

사용자 질문은 무엇이었는가?
최종 검색 query는 무엇이었는가?
retriever가 어떤 문서를 가져왔는가?
그 문서의 score는 얼마였는가?
LLM prompt에는 어떤 context가 들어갔는가?
model은 어떤 답변을 생성했는가?
token과 latency는 어디서 많이 발생했는가?

Evaluation이 "결과를 판정하는 일"이라면, Observability는 "그 결과가 만들어진 과정을 재현 가능하게 남기는 일"입니다.


예를 들어 고객센터 Agent가 환불 가능 여부를 틀리게 답했다고 해보겠습니다.

단순 평가 결과는 이렇게 말할 수 있습니다.

correctness: 낮음
groundedness: 낮음

하지만 운영자가 실제로 알고 싶은 것은 따로 있습니다.

주문 조회 tool을 호출했는가?
상품 카테고리를 확인했는가?
환불 정책 문서를 검색했는가?
검색 query는 적절했는가?
검색된 문서에 예외 조항이 있었는가?
LLM이 그 예외 조항을 무시했는가?

질문에 답하려면 평가 점수만으로는 부족합니다. 실행 과정이 남아 있어야 합니다. 실행 과정을 남기고 해석하는 체계가 LLM Observability입니다.


평가만으로 실패는 발견할 수 있습니다. 다만 원인을 좁히기는 어렵습니다. 반대로 trace와 metric이 남아 있으면 최종 답변이 틀렸을 때도 어느 단계에서 문제가 시작됐는지 따라갈 수 있습니다.

둘의 관계는 이렇게 보는 편이 좋습니다.

Observability가 실행 과정을 남긴다.
Evaluation이 그 실행 과정과 결과를 판정한다.
판정 결과가 다시 개선할 trace와 dataset을 만든다.
구분 Evaluation Observability
핵심 질문 좋은 결과인가 왜 그런 결과가 나왔는가
주 대상 답변, 검색 결과, tool 선택 결과 요청 전체의 실행 과정
단위 dataset row, test case, score trace, span, run, session
시점 배포 전 평가 또는 운영 중 샘플 평가 개발, 디버깅, 운영 전 과정
산출물 점수, pass/fail, 리포트 trace, logs, metrics, dashboard
쓰임 품질 비교, regression 확인 원인 분석, 재현, 모니터링

그래서 보통은 Evaluation은 Observability 안으로 들어와 있습니다.

이미 여러 프레임워크와 도구가 이 흐름을 지원합니다.

  • LangSmith
  • LangFuse
  • Arize Phoenix

LLM Observability

Observability는 시스템 밖에서 관측한 신호로 시스템 안에서 무슨 일이 일어났는지 이해하게 해주는 체계입니다. 엔지니어나 개발자 분들이라면 익숙하실거라 생각합니다.

구조를 보면 기존 애플리케이션에서는 보통 세 가지를 봅니다.

Logs
Metrics
Traces

API 서버(WAS)라면 다음을 봅니다.

요청 수
응답 시간
에러율
CPU / memory
DB latency
HTTP status code
stack trace

이 정보는 LLM 애플리케이션에서도 필요합니다. LLM 앱도 결국 서버, DB, 외부 API 위에서 동작합니다.

하지만 LLM 애플리케이션에서는 이것만으로 부족합니다.

LLM 애플리케이션에서는 서버가 성공해도 서비스는 실패할 수 있습니다.

API는 200 OK를 반환했지만 답변은 틀릴 수 있습니다.
RAG 검색은 성공했지만 엉뚱한 문서가 context로 들어갔을 수 있습니다.
Tool 호출은 성공했지만 잘못된 인자로 실행됐을 수 있습니다.
Agent는 정상 종료됐지만 불필요한 tool을 여러 번 호출했을 수 있습니다.
LLM 답변은 자연스럽지만 근거 없는 내용을 만들어냈을 수 있습니다.

LLM Observability는 이걸 채워줍니다. 그래서 LLM Observability의 관측 대상은 일반 서버보다 넓습니다.

영역 관측해야 하는 것
Request 사용자 입력, 세션, 시간
Prompt system prompt, user prompt, prompt version
Model provider, model name, parameters
Token / Cost input token, output token, 요청별 비용
Latency 전체 응답 시간, model 호출 시간, tool 호출 시간
Retrieval query, retrieved documents, score
Tool tool name, arguments, result, error
Agent Step step count, loop count, stop reason
Output final answer, finish reason
Evaluation correctness, groundedness, safety, user feedback

LLM Observability의 핵심 <Trace>

LLM Observability에서 가장 중요한 단위는 trace입니다.

하나의 요청이 시스템 내부에서 어떤 경로로 처리됐는지 보여주는 실행 기록입니다.

전통적인 웹 서비스에서도 하나의 API 요청이 들어왔을 때 어떤 service를 거치고, 어떤 DB query를 실행하고, 어떤 외부 API를 호출했는지 보면 장애 지점을 좁힐 수 있습니다.
LL

LLM에서도 같은 원리가 필요합니다만, trace 안에 들어가는 내용이 달라집니다.

일반 애플리케이션 trace가 이런 흐름을 본다면,

HTTP Request
-> API handler
-> Database query
-> External API
-> Response

LLM 애플리케이션 trace는 이런 흐름을 봅니다.

User Request
-> Prompt 구성
-> Retrieval
-> Tool call
-> LLM call
-> Guardrail
-> Final Answer

Agent라면 더 복잡해집니다.

User Request
-> Agent 판단
-> Tool A 호출
-> Observation 확인
-> Agent 재판단
-> Tool B 호출
-> Observation 확인
-> Final Answer

특히 Agent는 런타임에 다음 행동을 고릅니다.

지금 검색할 것인가?
주문 조회 tool을 먼저 호출할 것인가?
사용자에게 추가 질문을 해야 하는가?
여기서 멈추고 최종 답변을 해도 되는가?

이 판단이 매 요청마다 달라질 수 있기 때문에 trace가 필요합니다.

거듭 말씀드리지만 최종 답변만 저장하면 "무슨 답을 했는지"는 알 수 있습니다.

하지만 "왜 그 답을 했는지"는 알기 어렵습니다.

trace가 있으면 다음을 볼 수 있습니다.

질문 trace에서 보는 것
어떤 입력이 들어왔는가 user input, session id
어떤 prompt가 만들어졌는가 system prompt, user prompt, prompt version
어떤 model을 호출했는가 provider, model name, parameters
어떤 문서를 검색했는가 retrieval query, retrieved documents, score
어떤 tool을 호출했는가 tool name, arguments, result, error
어디서 시간이 걸렸는가 step latency, total latency
어디서 비용이 발생했는가 input token, output token, cost
왜 종료됐는가 stop reason, max step, final answer

용어는 도구마다 조금 다릅니다. 개념만 이해하면 충분합니다.

Trace: 사용자 요청 하나의 전체 실행 기록
Span 또는 Run: trace 안에 들어 있는 개별 작업 기록
Step: Agent가 판단하고 행동한 한 번의 단계

결국 LLM Observability의 출발점은 trace를 남기는 일입니다.

환불 Agent 실패 사례로 보는 Trace

사용자 질의:

지난주에 산 무선 이어폰 환불 가능한가요?

AI Agent:

지난주가 정확히 며칠 전인가?
어떤 상품인가?
상품 카테고리는 무엇인가?
개봉했는가?
환불 정책에서 해당 카테고리의 예외 조건은 무엇인가?

이 Agent가 사용할 수 있는 tool은 세 개라고 하겠습니다.

Tool 역할
order_lookup 주문일, 상품명, 개봉 여부 확인
product_category_lookup 상품 카테고리 확인
refund_policy_search 환불 정책 검색
일반 상품은 구매 후 14일 이내 환불 가능합니다.
개봉한 전자제품은 7일 이내만 환불 가능합니다.
상품으로 인한 이상 증상 발생시 14일 이후에도 환불 가능합니다. (접촉성 피부염 등)

그런데 Agent가 다음과 같이 실행된다면...

User Request
-> refund_policy_search("14일 환불")
-> Final Answer: 네, 구매 후 14일 이내라면 환불 가능합니다.
User Request
-> refund_policy_search("14일 환불")
-> Final Answer: 네, 구매 후 14일 이내라면 환불 가능합니다.

서버 로그만 보면 문제는 없어 보입니다.

status: 200
latency: 2.1s
error: none

최종 답변도 자연스럽습니다.

하지만 실제로는 위험한 답변입니다. 주문 정보도 확인하지 않았고, 상품 카테고리도 확인하지 않았고, 개봉 여부도 확인하지 않았기 때문입니다.

이때 평가만 보면 이렇게 나올 수 있습니다.

correctness: 낮음
groundedness: 낮음
completeness: 낮음

평가는 실패를보여줍니다. 다만 운영자가 고쳐야 하는 지점은 명확하지 않습니다.

trace가 있으면 실패를 더 구체적으로 볼 수 있습니다.

Trace: refund_agent_run_001
User Input: 지난주에 산 무선 이어폰 환불 가능한가요?

Step 1
  type: tool_call
  tool: refund_policy_search
  arguments:
    query: "14일 환불"
  result:
    document: "일반 상품은 구매 후 14일 이내 환불 가능합니다."

Step 2
  type: llm_call
  model: gpt-4.1
  input:
    user_question
    retrieved_policy
  output:
    "네, 구매 후 14일 이내라면 환불 가능합니다."

Final
  stop_reason: final_answer

이 trace를 보면 실패 원인이 선명해집니다.

order_lookup이 호출되지 않았습니다.
product_category_lookup이 호출되지 않았습니다.
refund_policy_search query가 너무 넓습니다.
위생 상품 예외 조항이 context에 들어오지 않았습니다.
LLM은 부족한 context 안에서 일반 규칙만 보고 답했습니다.

더 정확한 실패 원인은 다음에 가깝습니다.

필수 tool 누락
부정확한 retrieval query
예외 조항 context 누락
불충분한 근거 기반 단정 답변

좋은 trace는 이런 형태에 가까워야 합니다.

Trace: refund_agent_run_002
User Input: 지난주에 산 무선 이어폰 환불 가능한가요?

Step 1
  type: tool_call
  tool: order_lookup
  arguments:
    user_id: "u_123"
  result:
    product_id: "p_earbud_01"
    product_name: "무선 이어폰"
    purchased_days_ago: 8
    opened: true

Step 2
  type: tool_call
  tool: product_category_lookup
  arguments:
    product_id: "p_earbud_01"
  result:
    category: "전자제품"

Step 3
  type: tool_call
  tool: refund_policy_search
  arguments:
    query: "전자제품 개봉 후 환불"
  result:
    document: "전자 제품은 개봉 후 환불이 제한될 수 있습니다."

Step 4
  type: llm_call
  model: gpt-4.1
  output:
    "주문 정보상 무선 이어폰은 구매 8일이 지났고 개봉된 상태입니다.
    환불 정책에는 개봉 후 환불이 제한될 수 있다고 되어 있습니다.
    따라서 일반 14일 환불 기준만으로 환불 가능하다고 단정하기 어렵고,
    추가 확인이 필요합니다.

    상품을 환불하는 이유가 있으신가요?
    "

Final
  stop_reason: final_answer

Regression Dataset

운영에서는 이 실패 trace를 버리면 안 됩니다.

평가 항목 좋은 trace 기준
Tool completeness order_lookupproduct_category_lookuprefund_policy_search가 모두 호출됨
Tool order 주문 확인 후 카테고리 확인, 그 다음 정책 검색
Argument quality 검색 query가 상품 카테고리와 상태를 반영함
Groundedness 최종 답변이 tool result와 정책 문서에 근거함
Cost / latency 불필요한 반복 호출 없이 종료됨

실패 trace를 dataset에 추가하고, 이후 prompt나 tool description을 수정한 뒤 같은 케이스를 다시 실행해야 합니다.

그래야 "느낌상 좋아졌다"가 아니라 "필수 tool 누락이 줄었다", "정책 예외 조항 검색률이 올라갔다", "비용은 얼마나 늘었다"처럼 설명할 수 있습니다.

Metrics

Metrics는 가볍게 알아보겠습니다

최근 응답 속도가 느려졌는가?
특정 model에서 latency가 높아졌는가?
prompt 변경 후 token 사용량이 늘었는가?
특정 tool의 실패율이 올라갔는가?
Agent step 수가 갑자기 늘었는가?

모델의 지표 뿐만 아니라 AI Agent를 파악하기 위한 지표를 포함합니다.

Amazon Bedrock LLM Monitor
AWS Bedrock LLM model real-time performance monitoring dashboard
지표 의미 왜 보는가
TTFT 첫 토큰이 나오기까지 걸린 시간 사용자가 느끼는 첫 응답 속도
Total latency 요청부터 최종 답변까지 걸린 전체 시간 전체 응답 경험
Token usage input token, output token 비용과 context 사용량 확인
Cost per request 요청 하나당 비용 운영 비용 추적
Error rate model, retrieval, tool 실패율 안정성 확인
Step count Agent가 거친 단계 수 불필요한 반복이나 loop 확인
Quality score correctness, groundedness, user feedback 품질 추세 확인

좋은 trace는 필수 tool을 모두 호출하므로 나쁜 trace보다 latency와 cost가 늘 수 있습니다. 대신 correctness와 completeness는 올라갑니다. 운영에서는 이 균형을 같이 봐야 합니다.

다시 말해 Observability는 "정답률만 높이자"가 아닙니다.

품질은 좋아졌는가?
비용은 얼마나 늘었는가?
응답 시간은 허용 가능한가?
실패율은 줄었는가?

이것들을 모두 포함하는 내용이죠.

하지만...

LLM Observability를 이야기할 때 주의할 점도 있습니다.

민감정보와 보안입니다.

Trace를 자세히 남길수록 디버깅은 쉬워집니다. 하지만 그만큼 민감한 정보가 함께 저장될 가능성도 커집니다. LLM trace에는 일반 서버 로그보다 더 많은 내용이 들어갈 수 있습니다.

  • 사용자 개인정보
  • 사내 민감정보
  • System Prompt
  • 사용자의 자유입력 정보

고객센터 Agent라면 주문 정보, 사용자 ID, 결제 정보, 배송지, 상담 내용이죠.

사용자 질문
system prompt
retrieved context
tool arguments
tool output
final answer
evaluation result

특히 대기업이나 폐쇄적인 환경에서 원인을 찾을 수 있을 만큼, 안전하게 남기는 일이 중요합니다

  • Observability는 단순히 "많이 저장하는 것"이 아닙니다.
    • 필요한 구성만 적절하게 넘기는게 목적입니다.
어떤 필드를 저장할 것인가?
어떤 필드는 masking할 것인가?
원문 prompt와 context를 저장할 것인가?
trace 보관 기간은 얼마인가?
누가 trace를 볼 수 있는가?
실패 trace를 dataset으로 옮길 때 익명화할 것인가?

이 부분은 다음 주차의 Guardrails와 Security 주제와도 연결됩니다.

이번에는 깊게 들어가지 않겠습니다. 다만 LLM Observability를 설계할 때 trace, metrics, evaluation만이 아니라 masking, 접근 제어, 보관 기간 같은 운영 규칙도 함께 필요하다는 점을 참고해야합니다.

Reference