🎧 ▶ 5분 브리핑으로 듣기
▶ 오디오북 재생 (Google Drive)
NotebookLM 오디오 개요 (AI 생성)

에이전트가 남긴 실행 기록을 학습 데이터로 쓰려는 분이라면, 파이프라인이 조용히 0을 내놓는 방식을 한 번쯤 보시는 게 낫습니다. 저희 export 도구는 실행 486건에서 Episode 468개를 냈고 전부 스키마 검증을 통과했는데, 도구를 한 번이라도 부른 실행은 학습에 쓸 수 있는 게 하나도 없었습니다.

결함의 두 종류를 형상화한 이미지: 표면의 붉은 점과, 중앙의 빈 자리 “틀린” 결함은 표면에 붉은 점처럼 보이고, “없는” 결함은 큐브 하나가 통째로 빠진 빈 자리처럼 코드를 아무리 읽어도 보이지 않습니다.

아무것도 실패하지 않았습니다

에러 로그가 없었습니다. 종료 코드는 0이었습니다. 리포트는 “468개 작성, 0개 실패”라고 찍었습니다.

문제는 그중 도구를 쓴 254개가 전부 truncated 플래그를 달고 나왔다는 것이었습니다. 그 플래그가 붙으면 검증기가 Episode 를 거부합니다. 반쪽 관측으로 학습하느니 건너뛰는 게 낫다는 규칙이고, 그 규칙은 옳습니다. 다만 여기서는 모든 관측이 반쪽이었습니다.

에이전트 오케스트레이션은 정의상 도구 실행입니다. 상위 에이전트가 하위 에이전트를 부르는 것 자체가 agent 라는 이름의 도구 호출이니까요. 그러니 오케스트레이션 궤적의 수확량은 정확히 0이었습니다.

flowchart TB T["도구를 쓴 실행 254건"] --> P["조립기: 도구 호출 기록과 결과를
학습 Episode 로 조립"] P --> L1["손실 지점 1. 저장 자리 두 개 중
컬럼만 조회, 채팅 경로 metadata 는 안 봄"] P --> L2["손실 지점 2. 화면 잘림 1000자, 결과 저장 16KiB
사이 밴드의 본문은 어디에도 없음"] P --> L3["손실 지점 3. loop_1_agent 식별자 중복
결과가 다른 호출에 부착됨"] L1 --> Z["관측이 전부 truncated"] L2 --> Z L3 --> Z Z --> R["검증기 전량 거부, 학습용 Episode 0"]

파이프라인의 손실 지점 셋. 셋 다 에러를 만들지 않고, 코드 리뷰에서는 보이지 않습니다.

핵심 개념 요약 인포그래픽 1 NotebookLM이 소스를 종합해 생성한 인포그래픽입니다.

코드를 읽어 찾은 결함 넷

먼저 코드를 읽었고 네 가지가 나왔습니다.

트레이스에 종료 사유 필드가 아예 없었습니다. 루프는 success·max_turns·timeout 같은 타입 있는 값을 만들고 있었고, 트레이스를 마무리하는 함수는 그 값을 손에 들고 있었는데, 저장 구조체에 담을 자리가 없었습니다. 631개 트레이스 중 이 문자열을 담은 게 0개였습니다.

분류기가 찾는 문자열과 방출되는 문자열이 달랐습니다. 루프는 max_turns(밑줄)를 내고 분류기는 max turns(공백)를 찾습니다. 턴 제한에 걸려 끝난 실행이 “실패 없음”으로, 그러니까 깨끗한 성공으로 나갑니다. 저희가 부정 예제로 쓰려던 바로 그 병리가 긍정 라벨을 달고 나오는 셈입니다.

결과 라벨 테이블을 조인하지 않았습니다. 402행이 들어 있는데 조립기가 읽지 않았습니다.

전체 관측을 가져오는 인터페이스가 선언되고 테스트까지 됐는데 프로덕션에서 주입된 적이 없었습니다. 호출자를 전수 조회하니 테스트 파일 네 줄이 전부였습니다.

넷 다 진짜 결함입니다. 그런데 넷을 다 고치고 다시 돌려도 수확량은 그대로 0이었습니다.

코드를 읽어서는 못 찾은 결함 셋

같은 사실을 두 곳에 쓰고 한 곳에서만 읽고 있었습니다

도구 호출 기록에는 두 개의 저장 자리가 있었습니다. 채팅 경로는 메시지 메타데이터 안에 쓰고, 채널·커넥터 경로는 전용 컬럼에 씁니다. 읽는 쪽은 컬럼만 봤습니다.

두 스키마를 행수로 세어 보고서야 알았습니다.

저장 자리 쓰는 쪽 실제 행수
unified_messages.tool_calls 컬럼 채널 경로 0
metadata->'tool_calls' 채팅 경로 22

이 배포의 트래픽은 전부 채팅이었습니다. 그러니 조립기는 “이 플랫폼에서 도구를 쓴 에이전트가 한 번도 없다” 고 본 채로 동작했습니다. 그리고 그 판단이 이상하지 않습니다. 도구를 안 부른 실행은 지극히 평범하거든요. 출력만 봐서는 버그인지 그냥 조용한 하루였는지 구분되지 않습니다.

화면 잘림이 저장까지 결정하고 있었습니다

채팅 화면은 도구 결과를 1000자에서 자릅니다. 도구 결과 저장소는 16 KiB 를 넘는 것만 따로 보관합니다. 그 사이 밴드가 문제였습니다. 1000자는 넘고 16 KiB 는 안 되는 결과는 잘렸다는 표시만 남고 본문은 어디에도 남지 않습니다.

실제 저장된 결과를 크기순으로 세워 보니 상위 15개 중 12개가 그 밴드였습니다.

화면 잘림은 화면의 문제인데 그게 플랫폼이 무엇을 기억할지까지 정하고 있었습니다.

병렬 호출의 식별자가 서로 겹쳤습니다

도구 호출 식별자를 loop_<턴>_<도구이름> 으로 만들고 있었습니다. 한 턴에 같은 도구를 두 번 부르면 두 기록이 같은 식별자를 갖습니다. 결과가 돌아올 때는 뒤에서부터 찾아 첫 번째로 맞는 것에 붙이므로, 한 기록이 다른 호출의 출력을 달고 나머지는 빈 채로 남습니다.

이건 리뷰에서 이론으로 지적받았는데 저는 코너 케이스라고 생각했습니다. 그러다 오케스트레이터를 실제로 돌리고 메시지 행을 열었습니다.

loop_1_agent   본문 없음
loop_1_agent   본문 없음
loop_1_agent   850바이트
loop_2_agent   본문 없음
loop_2_agent   751바이트

조사 세 건을 동시에 위임하면 전부 이름이 agent 입니다. 오케스트레이터에게 이건 코너 케이스가 아니라 정상 동작입니다.

식별자는 모델 응답 안에 이미 고유한 값으로 들어 있었습니다. 두 디스패치 지점 모두에서 변수에 잡혀 있었고, 콜백이 그걸 넘겨주지 않았을 뿐입니다.

결과

지표 고치기 전 고친 뒤
산출 Episode 468 468
도구를 쓴 Episode 254 256
그중 검증 통과 0 5
본문을 담은 도구 결과 0 73

같은 명령, 같은 데이터베이스, 코드만 다릅니다. 저장된 행을 결정론적으로 다시 재생하는 것이라 반복하면 그대로 나옵니다. 표본 추정이 아니어서 오차 막대도 없습니다.

5/256 이지 256/256 이 아닙니다. 나머지는 세션을 남기지 않는 임시 평가 실행이거나, 화면 잘림 수정 이전에 기록돼 본문이 복구 불가능한 행입니다. 소급해서 살릴 방법은 없습니다.

통과했다고 쓸모 있는 건 아닙니다

수집을 고치고 나서 오케스트레이터를 돌려 첫 궤적을 받았습니다. 검증기가 통과시켰습니다. 내용은 이랬습니다.

tool_result  agent   [tool_use name=clarify id=chatcmpl-tool-9043d607de913a27]
tool_result  agent   [tool_use name=clarify]
tool_result  agent   [tool_use name="clarify" id="chatcmpl-tool-837c349fe54ce5cb"]

하위 에이전트에게 사실을 조회할 수단이 없었습니다. 시나리오는 “현재 에러율”을 묻는데 그 배포에는 지표 조회 도구가 없었습니다. 8B 모델은 있지도 않은 도구를 부르려다 그 마크업을 최종 답변으로 뱉었고, 오케스트레이터는 “입력이 부족해 판정 보류”로 끝냈습니다.

검증기는 관측이 잘렸는지를 봅니다. 관측이 말이 되는지는 보지 않습니다. 스키마 검사와 내용 검사는 다른 일이고, 둘 다 필요합니다. 이걸 그대로 학습에 넣었으면 “위임하고 아무것도 못 받는다”를 가르쳤을 겁니다.

남는 것

넷은 틀린 결함이었습니다. 라벨이 잘못 붙거나 값이 비어 나옵니다. 셋은 없는 결함이었고 데이터가 애초에 도달하지 않습니다. 앞의 넷은 코드를 읽으면 보이고, 뒤의 셋은 안 보입니다.

그리고 셋은 각각 다른 증거를 요구했습니다. 하나는 두 스키마의 행수를 세어야 했고, 하나는 실제 결과의 크기 분포를 봐야 했고, 하나는 오케스트레이터를 돌려 저장된 행을 직접 열어야 했습니다. 어느 것도 코드를 더 오래 읽는다고 나오지 않습니다.

트래커에서는 그중 둘이 이미 완료 상태였습니다. 필드도 있었고 저장소도 있었습니다. 그 둘을 잇는 어댑터 한 겹만 없었을 뿐입니다.

관련 슬라이드

본문 내용을 NotebookLM(architectural_portfolio 스타일)으로 요약한 슬라이드입니다.

defects-that-are-absent-not-wrong 슬라이드 1

defects-that-are-absent-not-wrong 슬라이드 2

defects-that-are-absent-not-wrong 슬라이드 3

defects-that-are-absent-not-wrong 슬라이드 4

핵심 개념 요약 인포그래픽 2 NotebookLM이 소스를 종합해 생성한 인포그래픽입니다.

출처

에이전트 실행 트레이스와 도구 호출의 표준 관측 모델(스팬·속성)은 OpenTelemetry GenAI 규약에서, tool_use/tool_result 블록과 식별자의 의미는 Anthropic 도구 사용 문서에서 확인했습니다. 모든 링크는 2026년 8월 24일 실제 호출로 검증했습니다.

태그: agent-platform, data-pipeline, debugging, 관찰성

카테고리:

업데이트: