지난 글의 마지막 문단에서 「재기 전에는 줄이지 않는다」고 했는데, 그 재는 일이 이 글의 주제다. 그리고 비용만의 문제가 아니다.
일반적인 백엔드에서는 로그 몇 줄이면 대개 무슨 일이 있었는지 복원된다. 요청이 들어오고, 함수가 불리고, 응답이 나간다. 같은 입력이면 같은 길로 간다.
에이전트는 그렇지 않다. 같은 입력에도 다른 걸음을 밟고, 걸음 수도 다르고, 도구를 부르는 순서도 다르다. 「어제 오후에 이 고객 문의에서 왜 저런 답이 나왔나」를 묻는 순간, 남아 있는 것이 최종 응답 한 줄뿐이면 답할 방법이 없다. 다시 돌려도 같은 길로 안 간다.
한 작업을 어떻게 쪼개 남기는가
기본 단위는 세 겹이다. 작업 하나가 트레이스 하나, 걸음 하나가 구간 하나, 그 안에 모델 호출과 도구 호출이 각각 구간으로 들어간다.
이렇게 겹쳐 놓으면 두 가지가 공짜로 따라온다. 어디가 느렸는지가 길이로 보이고, 어느 걸음에서 실패해 어디서 회복했는지가 위치로 보인다. 그림의 걸음 2에서 write가 시간 초과로 죽고 걸음 3에서 다시 성공한 것이 한눈에 읽힌다.
LLM 운영 관측에서 다룬 구조와 같은 것이고, 에이전트에서 달라지는 부분은 가운데 층이다. 단발 호출에는 「걸음」이라는 것이 없으니 트레이스 안에 호출 하나만 들어간다. 에이전트에서는 걸음 층이 있어야 「몇 번째 걸음에서 방향이 틀어졌나」를 물을 수 있다.
구간마다 무엇을 붙이는가
구간에 시간만 남으면 「느렸다」까지는 알고 「왜」는 모른다. 종류마다 붙일 것이 다르다.
| 구간 | 반드시 남길 것 |
|---|---|
| 작업(트레이스) | 작업 id, 사용자·테넌트, 요청 원문, 최종 상태, 총 걸음·토큰·비용 |
| 걸음 | 걸음 번호, 이번 걸음의 목표, 결과 상태 |
| 모델 호출 | 모델 이름과 버전, 프롬프트 버전, 입력·출력 토큰, 캐시 적중, 온도 등 설정 |
| 도구 호출 | 도구 이름, 인자, 결과 크기, 성공 여부와 오류 |
모델 버전과 프롬프트 버전이 가장 자주 빠지고 가장 아쉬운 자리다. 지난주와 이번 주의 성공률이 다를 때 「모델이 바뀐 것인지 프롬프트를 고친 것인지」를 물으면, 이 둘이 안 남아 있으면 답이 없다. 프롬프트 버전 관리에서 다룬 버전 표시를 호출마다 함께 남긴다.
도구 인자도 남긴다. 「검색을 3번 했다」보다 「같은 질의를 조금씩 바꿔 3번 했다」가 훨씬 많은 것을 말해 준다. 인자 없이는 두 상태를 구분할 수 없다.
한편 입력·출력 전문을 어디까지 남길 것인가는 결정이 필요한 자리다. 다 남기면 저장 비용과 개인정보 문제가 생기고, 안 남기면 재현이 안 된다. 실무에서 자리 잡은 절충은 이렇다.
- 전문은 짧은 보존 기간(예: 2주)으로 따로 저장하고, 지표와 메타데이터는 오래 남긴다
- 개인정보는 저장 전에 마스킹한다. 마스킹한 자리는
[이름]처럼 무엇이 지워졌는지 표시가 남게 한다 - 실패한 작업은 보존 기간을 길게 잡는다. 다시 볼 확률이 압도적으로 높다
무엇을 세는가
트레이스가 개별 사건을 설명한다면 지표는 전체가 어디로 가고 있는지를 본다. 에이전트에서 실제로 쓸모 있는 것은 대략 이 정도다.
- 작업 성공률 — 「끝났다」가 아니라 「제대로 끝났다」의 비율. 이 정의를 정하는 것이 절반의 일이다
- 걸음 수 분포 — 평균 말고 분포. 오른쪽 꼬리가 길어지면 종료 판단이 흔들리고 있다는 뜻이다
- 작업당 비용의 분포 — 같은 이유로 평균이 아니라 분포다
- 도구별 실패율 — 어느 도구가 루프를 망가뜨리는지 가장 빨리 알려 준다
- 사람 개입률 — 게이트에서 거부된 비율. 지난 글에서 다뤘듯 0이거나 너무 높으면 둘 다 신호다
- 끝까지 못 간 비율 — 상한에 걸려 멈춘 작업의 비율
걸음 수 분포를 특히 권한다. 이 하나로 잡히는 문제가 많다. 평균 6걸음이던 것이 평균 6.4로 조금 오르고 95백분위가 12에서 25로 뛰었다면, 대부분은 그대로인데 어떤 종류의 요청이 루프에 빠지기 시작한 것이다. 평균만 보면 안 보인다.
알림은 비율이 아니라 변화에 건다
지표를 모아 두면 자연스럽게 알림 이야기가 나오는데, 여기서 흔한 실수가 절대 기준을 거는 것이다. 「성공률 90% 미만이면 알림」식으로 걸어 두면 처음부터 88%인 작업 종류가 하나 있어서 알림이 늘 켜져 있게 되고, 곧 아무도 안 본다.
에이전트에서 실제로 유용한 알림은 대개 변화에 걸린 것이다.
- 걸음 수 95백분위가 지난주 대비 1.5배가 됐다
- 특정 도구의 실패율이 어제 대비 3배가 됐다
- 상한에 걸려 멈춘 작업이 하루 5건을 넘었다
- 작업당 평균 비용이 이틀 연속 올랐다
마지막 것이 조용한 사고를 가장 잘 잡는다. 품질이 그대로여도 비용이 오르고 있으면 뒤에서 무언가가 늘어나고 있다는 뜻이다.
로그가 아니라 재현이 목표다
정리하면 관측의 목표는 「무슨 일이 있었는지 보는 것」이 아니라 그 상황을 다시 만들 수 있는 것이다. 다음 셋이 남아 있으면 대개 재현이 된다.
시작 상태 — 요청 원문과 그때의 시스템 프롬프트·도구 정의. 각 걸음의 입력과 출력 — 모델에 실제로 들어간 것과 나온 것. 바깥 세계의 응답 — 도구가 돌려준 것.
이 셋이 있으면 문제가 된 작업을 실험 환경에서 그대로 다시 돌려 볼 수 있고, 고친 프롬프트가 그 상황을 해결하는지도 확인할 수 있다. 그리고 그렇게 모은 실패 작업들이 그대로 에이전트 평가의 회귀 시험 자료가 된다. 관측을 제대로 하면 평가 자료가 저절로 쌓인다는 것이 이 작업의 가장 큰 이득이다.
정리
- 에이전트는 같은 입력에도 다른 길로 가므로 「다시 돌려 보기」로는 원인을 못 찾는다
- 작업 하나가 트레이스, 걸음 하나가 구간, 그 안에 모델 호출과 도구 호출을 각각 구간으로 둔다
- 걸음 층이 있어야 「몇 번째에서 틀어졌나」를 물을 수 있다. 단발 호출 관측과 달라지는 지점이다
- 모델 버전과 프롬프트 버전이 가장 자주 빠지고 가장 아쉽다. 호출마다 남긴다
- 도구 인자를 남겨야 「같은 질의를 반복하고 있다」가 보인다
- 전문은 짧게, 지표는 길게. 실패한 작업은 보존 기간을 따로 길게 잡는다
- 개인정보는 저장 전에 마스킹하되 무엇이 지워졌는지 표시를 남긴다
- 평균이 아니라 분포를 본다. 걸음 수 95백분위 하나로 잡히는 문제가 많다
- 알림은 절대 기준이 아니라 변화에 건다. 늘 켜져 있는 알림은 없는 것과 같다
- 목표는 관찰이 아니라 재현이다. 재현할 수 있으면 실패 사례가 그대로 평가 자료가 된다
읽어주셔서 감사합니다. 😊

