Loading the catalog…
Loading the catalog…
Langfuse 9 — 저장된 실행을 평가하고 실패를 데이터셋으로 되돌리기 이 글은 Langfuse 실습 시리즈 의 9편입니다. 배포 전 평가를 이어, 저장된 실행의 사후 평가·알림·실패 데이터셋을 연결합니다. 이 글에서 다룰 주제 이미 저장한 에이전트 출력을 다시 평가해 점수를 붙이는 방법 업무 실패와 도구 오류를 구분해 알림을 읽는 방법 Langfuse Alerts에서 로컬 HTTPS webhook까지 실제 전달 확인 실패 사례를 다음 Offline 실험의 Dataset으로 옮기는 방법 주요 단어 · Post-hoc Evaluation · Score · Alert · Webhook · NO_DATA · Feedback Loop 배포 전에 준비한 데이터셋만으로 모든 입력을 알 수는 없습니다. 실행이 쌓이면 “어떤 도구에서 오류가 있었는가”와 “에이전트의 최종 판단이 기대에 맞았는가”를 계속 확인해야 합니다. 두 질문은 서로 다른 실패를 보여 줍니다. 5편의 합성 사건 실습에는 그 차이가 드러났습니다. tool-timeout-retry 는 첫 도구 호출에서 ERROR가 있었지만 재시도 후 올바르게 진단했습니다. 반면 missing-logs 와 unknown-injection 은 모델 호출이 완료됐어도 이관해야 하는 상황을 진단 완료로 분류했습니다. 이번 글에서는 저장된 여섯 실행을 외부 Python 프로세스로 다시 평가하고, 실제 도구 ERROR에 대한 Langfuse Alert를 로컬 webhook으로 받습니다. 마지막으로 잘못된 최종 판단 두 개를 다음 실험용 Dataset에 보관합니다. 그림은 운영 개선의 전체 흐름입니다. 이번에 직접 실행한 부분은 외부 평가기의 한 번 실행, native Alert와 webhook 전달, 실패 두 건의 Dataset 저장 입니다. 새로운 요청을 계속 polling하는 상시 평가기나 native Evaluation Rule 스케줄러까지 가동한 실습으로 표현하지 않습니다. 1. 평가 경로부터 구분하기 Post-hoc 평가 는 요청이 끝나고 저장된 결과를 읽어 나중에 판정하는 방식입니다. 사용자 응답 경로에 Judge의 대기 시간을 직접 더하지 않을 수 있지만, 그만큼 점수가 늦게 나타나며 실행 시점에 위험한 동작을 막는 제어와는 구분해야 합니다. 이번 operations.py 는 이전 실행의 trace ID를 체크포인트에서 읽습니다. Langfuse Observations API로 영속 저장된 agent output을 가져오고, 그 안의 decision 을 fixture 기대값과 비교합니다. 즉 모델을 다시 호출해 다른 답변을 만든 것이 아니라 이미 기록된 답변을 재평가 했습니다. rows = observations(client, run["trace_id"]) root = next(row for row in rows if row["id"] == run["root_id"]) decision = parsed_io(root["output"])["decision"] grade = grade_output(case, decision) langfuse.create_score( name="aiops-online-contract", value=int(grade["success"]), data_type="BOOLEAN", trace_id=run["trace_id"], observation_id=run["root_id"], score_id=deterministic_score_id, ) aiops-online-contract 라는 이름은 이 실습에서 붙인 이름입니다. 이름에 online이 들어 있다고 Langfuse가 자동으로 새로운 관측을 감시하는 것은 아닙니다. 실행 경로는 external Python one-shot post-hoc evaluator; not native rule scheduler 로 결과 파일에 기록했습니다. Langfuse의 native 온라인 평가는 Evaluator에 판정 방법을 정의하고, Rule에 대상 필터와 샘플링을 연결합니다. 외부 파이프라인에서 평가한 뒤 Scores API/SDK로 보내는 방법도 지원됩니다. 이번에는 후자를 사용했습니다. 온라인 평가 경로 2. 여섯 실행의 재평가 결과 다음 값은 2026-10-05의 저장 결과를 실제로 읽어 판정한 값입니다. BOOLEAN 1 은 이 합성 fixture의 outcome·cause·증거 계약을 통과했다는 뜻입니다. 실제 환경 복구나 종합 안전성을 보장하는 점수는 아닙니다. 사건 외부 계약 점수 해석 db-saturation 1 DB 지표와 로그에 맞는 진단 upstream-slowdown 1 upstream 원인·증거 계약 통과 missing-logs 0 근거 부족 시 이관 조건을 지키지 못함 tool-timeout-retry 1 도구 재시도 후 최종 작업은 통과 outdated-runbook 1 오래된 runbook에 대해 이관 unknown-injection 0 알려진 장애 패턴이 없는데 진단으로 분류 점수는 원래 trace와 agent observation에 연결했습니다. 새로운 trace를 만들어 원래 요청과 분리하지 않았으므로, 점수를 발견한 뒤 실제 도구 호출과 모델 입력까지 되돌아갈 수 있습니다. 각 score ID는 평가기 버전 + trace ID 에서 결정적으로 만들었습니다. 이는 같은 대상을 중복 평가했을 때 다른 점수 레코드를 무한히 늘리지 않기 위한 최소 장치입니다. 실제 구현은 완료 체크포인트가 있으면 원격 데이터를 다시 만들지 않고 검증만 수행합니다. 중간 체크포인트가 불완전하면 자동으로 처음부터 재실행하지 않습니다. 3. 실패 두 건을 Dataset으로 저장 aiops-study/operational-failures Dataset에 계약 점수가 0인 두 사건만 저장했습니다. 여기서 데이터의 출처를 구분해야 합니다. 판정할 출력: Langfuse에 이미 저장된 agent observation의 decision 다음 실험에서 재현할 입력: 이전 실습 체크포인트의 input_bundle 기대값: AI 작성 보조 도구가 만든 합성 fixture의 expected 원래 실행 연결: source_trace_id , source_observation_id 잘못된 모델 응답을 기대 정답으로 복사하지 않았습니다. 다만 이 기대값도 전문가가 검수한 운영 정답은 아니므로, 실서비스에서는 담당자가 원인·원하는 행동·허용 가능한 대안을 검토하는 절차가 필요합니다. langfuse.create_dataset_item( dataset_name="aiops-study/operational-failures", id=deterministic_item_id, input=run["input_bundle"], expected_output=case["expected"], metadata={ "reference_author": "assistant-curated fixture", "failure_checks": failed_check_names, }, source_trace_id=run["trace_id"], source_observation_id=run["root_id"], ) Datasets → aiops-study → operational-failures → Items 에서 Source 열을 누르면 원본 실행으로 돌아간다. Expected Output은 모델의 틀린 답을 복사한 값이 아니라 별도로 정한 기대 판단이다. Dataset에서 항목을 열면 입력·기대값과 원래 실행을 함께 확인할 수 있습니다. missing-logs 의 기대값은 escalated / insufficient_evidence 이고, unknown-injection 도 추가 근거가 필요하므로 같은 이관 분류를 요구합니다. 실패 사례를 보관했다고 프롬프트가 고쳐진 것은 아닙니다. 다음 변경을 이 두 사건에 다시 실행하고, 기존 통과 사례도 깨지지 않는지 확인해야 개선의 한 바퀴가 끝납니다. 8편의 부분 회귀 집합이 이 실패 두 건을 대신 해결한 것으로 해석하지 않습니다. 4. 어떤 오류를 알릴 것인가 이번에 만든 native Alert는 AIOps lab — tool ERROR count 입니다. 비교 대상은 품질 점수가 아니라 observation에 기록된 도구 오류입니다. 항목 실제 설정 데이터 소스 Observations 집계 count 환경 필터 aiops-lab 타입 필터 TOOL 상태 필터 ERROR 조건 최근 1일의 개수 > 0 데이터 없음 Show severity NO_DATA 반복 알림 Off 필터의 단위에 주의합니다. 이 조건은 ERROR observation의 개수 를 셉니다. 에이전트 작업 개수도, 실패한 업무 비율도 아닙니다. 한 요청에서 tool retry가 여러 번 실패했다면 여러 관측이 집계될 수 있습니다. 이번 timeout은 fixture가 첫 metrics 조회에서 100ms 뒤 의도적으로 발생시킨 Python 예외입니다. 실제 Prometheus나 운영 데이터베이스 장애가 아닙니다. 이 관측에 ERROR가 남았고, 이어진 재시도는 성공했습니다. 최종 작업 성공과 중간 도구 오류가 동시에 존재할 수 있음을 확인하는 용도입니다. Langfuse Alerts는 Observations와 여러 자료형의 Scores를 지표로 선택할 수 있습니다. BOOLEAN 점수의 평균은 true 비율이므로 품질 통과율 알림에도 사용할 수 있습니다. 다만 이번 실습에서는 도구 ERROR 개수 알림 하나를 실제로 만들었습니다. 점수 알림도 만들었다고 확대해서 표현하지 않습니다. Alerts 공식 설명 5. Automation과 HTTPS 수신기 Alert 조건을 저장하는 일과 알림을 실제로 받는 일은 별개입니다. UI에서 Alert event를 처리하는 Automation을 만들고 Webhook action을 연결한 뒤, Alert의 notifications에서 해당 Automation을 선택했습니다. 이 실습 UI에서는 연결할 Automation을 먼저 준비해야 했습니다. 외부 메신저나 회사 시스템으로 보내지 않고 같은 Docker 네트워크의 https://aiops-webhook/alerts 로 전달합니다. 수신기는 host에 공개한 포트가 없으며, 서명 검증을 통과한 합성 alert event만 증거 파일에 기록합니다. 로컬 주소는 webhook 보안 검사에서 내부 주소로 취급되므로 특정 hostname만 허용했습니다. 인증서는 별도로 신뢰 목록에 추가했습니다. LANGFUSE_WEBHOOK_WHITELISTED_HOST: aiops-webhook NODE_EXTRA_CA_CERTS: /study/aiops-webhook-ca.crt 이 설정은 실습 hostname과 인증서에 한정합니다. TLS 검증을 전부 끄는 방식은 사용하지 않았습니다. 인증서·서명 secret은 글과 스크린샷에 노출하지 않고 별도 파일로 보관했습니다. 수신기는 요청의 원본 body bytes 와 header의 timestamp로 HMAC을 계산합니다. JSON을 예쁘게 정렬하거나 다시 직렬화한 문자열로 서명 검증을 하면 실제 전달된 bytes와 달라질 수 있습니다. const expected = crypto .createHmac("sha256", secret) .update(`${timestamp}.`) .update(rawBody) .digest("hex"); 실제 수신 코드에는 timestamp가 현재와 5분 이상 차이 나면 거절하는 검사, 상수 시간 비교, event ID 중복 제거도 넣었습니다. 같은 event가 재전송되면 두 번째 기록을 남기지 않고 성공 응답을 돌려줍니다. Langfuse webhook은 성공 응답을 받지 못하면 재시도할 수 있으므로, 수신기의 멱등성을 고려해야 합니다. Webhook 서명과 수신 확인 6. 실제 전달 확인 2026-10-05 14:08:27.971 KST에 만들어진 ALERT 이벤트를 수신기가 14:08:28.024 KST에 기록했습니다. 로컬 증거의 주요 필드는 다음과 같습니다. 표시한 두 timestamp의 차이는 이 이벤트의 기록 시점 차이이며, 일반적인 알림 전달 SLA로 사용하지 않습니다. { "received_at_utc": "2026-10-05T05:08:28.024Z", "signature_verified": true, "event": { "type": "monitor-alert", "payload": { "severity": "ALERT", "view": "observations", "window": "1d" } } } 이 값은 수동으로 흉내 낸 alert가 아니라 Langfuse에서 만든 Alert가 Automation을 거쳐 전달한 실제 event입니다. 이름에 monitor 가 남아 있는 것은 payload의 API 명칭입니다. UI의 Alerts 메뉴와 다른 제품을 뜻하지 않습니다. 운영에서는 “알림이 왔다”에서 멈추지 않고 해당 기간과 필터로 원래 observations를 엽니다. 이번에는 query-metrics 의 첫 시도와 다음 성공 시도를 함께 읽고, 최종 aiops-task-success 가 1인지 확인하면 오류의 영향 범위를 판단할 수 있습니다. 7. NO_DATA와 알림 반복 NO_DATA 는 정상과 다릅니다. 요청 자체가 없었을 수도 있고, 필터가 잘못됐거나 SDK 전송·수집 경로가 멈췄을 수도 있습니다. 따라서 없는 데이터를 자동으로 0으로 바꾸면 “오류가 없다”로 오해할 수 있습니다. 이번에는 Show severity NO_DATA 를 선택했습니다. 이는 데이터 없음 상태를 표시하되 그 이유만으로 알림을 보내지 않는 정책입니다. 요청이 반드시 들어와야 하는 서비스라면 지속적인 데이터 없음도 별도 경보 조건으로 다뤄야 합니다. Renotify=Off 는 오류가 지속되는 동안 같은 알림을 계속 보내지 않는 설정입니다. 첫 상태 전이 알림까지 막는 설정은 아닙니다. 복구 알림과 반복 알림, 데이터 없음 알림은 서로 다른 상태 변화이므로 실제 운영 정책에 맞춰 구분합니다. 전달 확인 뒤 실습 Alert를 PAUSED 로 전환했다. 학습 데이터의 오래된 오류로 알림이 다시 생기지 않도록 한 것이다. 설정과 이벤트는 남아 있으며, 다시 실험할 때 Alerts의 해당 항목에서 Resume alert를 사용한다. 8. 상시 운영으로 바꿀 때 이번 외부 평가기는 저장된 여섯 trace만 한 번 읽었습니다. 같은 구조를 운영으로 바꾸려면 데이터를 어떻게 계속 찾고, 어디까지 처리했는지 남기는 설계가 필요합니다. 준비할 것 필요한 이유 시간 범위·cursor·watermark 마지막 처리 위치를 알고 새 데이터만 이어 읽기 지연 도착 overlap 전송·수집 지연으로 나중에 나타난 관측을 누락하지 않기 평가기 버전과 멱등 ID 같은 버전의 중복 점수와 다른 버전의 재평가를 구분 평가 대상·샘플링 기록 어떤 환경·사건이 평가에서 제외됐는지 알기 평가 coverage 점수 평균이 좋아도 실제 평가가 거의 멈췄는지 확인 오류 재시도와 실패 보관 판정 실패를 좋은 점수로 취급하지 않고 다시 처리 예를 들어 통과율을 볼 때는 통과 점수 / 평가 완료 수 와 함께 평가 완료 수 / 평가 대상 수 도 봐야 합니다. 전체 요청의 어려운 부분만 평가가 실패했는데 완료된 쉬운 요청만으로 높은 점수가 보일 수 있기 때문입니다. Native Evaluation Rule을 선택하면 필터·샘플링·평가기 연결을 Langfuse에서 관리할 수 있습니다. 외부 파이프라인을 선택하면 기존 평가 코드와 자체 실행 환경을 활용할 수 있지만 cursor·중복·재시도 같은 수명주기를 직접 운영해야 합니다. 이번 예제는 두 경로의 기능이 자동으로 같아지는 것으로 설명하지 않습니다. 9. 재검증과 다음 단계 설치 환경과 실습 파일이 있는 작업 디렉터리에서 아래 명령은 새 모델 호출이나 원격 변경 없이 기록을 다시 읽습니다. docs/langfuse-study-2026-10-04/lab/.venv/bin/python \ docs/langfuse-aiops-2026-10-05/lab/operations.py --verify-only 여섯 score의 값과 연결 대상, 저장된 출력의 재계산, 실패 Dataset의 정확한 두 항목·입력·기대값·원본 연결을 확인했습니다. 다음 글의 마스킹 검사를 포함해 저장 확인 30개가 통과했습니다. 또한 불완전 checkpoint, 중복 case, 바뀐 점수, 누락된 실패 item을 거절하는 로컬 검사를 수행했습니다. 결과 파일은 evidence/operations.json , 알림 전달 기록은 evidence/webhook-events.jsonl 입니다. 실제 사용자 데이터 없이 합성 사건으로 흐름을 확인했습니다. 다음 글에서는 수집할 데이터의 범위를 줄이고, 마스킹·백업·격리 복원으로 관측 시스템 자체를 운영하는 문제를 다룹니다. 실습·공식 문서 확인: 2026-10-05. Langfuse OSS v4.50.0, Python SDK 4.16.0. 저장 후 외부 평가에서는 추가 LLM 호출을 하지 않았습니다. native 온라인 Evaluation Rules는 구성하지 않았으며 native Alert→Automation→HTTPS webhook 전달은 직접 확인했습니다. 이전: 8편 — 품질 회귀와 프롬프트 라벨 롤백 다음: 10편 — 마스킹과 백업·복원
What RADAR observed and classified to build this opportunity. It is what the source published, not a verification that the offer is still active.
[Langfuse 9] 온라인 평가·Alerts·실패 Dataset 연결하기. Langfuse 9 — 저장된 실행을 평가하고 실패를 데이터셋으로 되돌리기 이 글은 Langfuse 실습 시리즈 의 9편입니다. 배포 전 평가를 이어, 저장된 실행의 사후 평가·알림·실패 데이터셋을 연결합니다. 이 글에서 다룰 주제 이미 저장한 에이전트 출력을 다시 평가해 점수를 붙이는 방법 업무 실패와 도구 오류를 구분해 알림을 읽는 방법 Langfuse Alerts에서 로컬 HTTPS webhook까지 실제 전달 확인 실패 사례를 다음 Offline 실험의 Dataset으로 옮기는 방법 주요 단어 · Post-hoc Evaluation · Score · Alert · Webhook · NO_DATA · Feedback…
Open source