설치
계측
각각이 실제로 발행하는 이벤트:
내부의 모든 코드는
session_id와 agent_id를 생략할 수 있습니다. 스코프는 컨텍스트 변수에 식별자를 바인딩하며, 모든 이벤트 호출이 이를 읽어오므로 함수를 통해 id를 전달할 필요가 없습니다.
세 가지 모두 with뿐만 아니라 async with에서도 동작합니다.
에이전트를 중첩하면 트리가 만들어집니다. parent_id와 깊이는 스택에서 자동으로 계산됩니다:
스코프가 닫히는 방식
agent()는 예외를 자동으로 처리합니다:
agent_end 이전에 오류가 발행되는 이유는, 대시보드가 agent_end에서 스팬을 닫고 그 이후의 이벤트는 아무것에도 귀속되지 않기 때문입니다. 취소는 실패가 아니므로 취소된 실행은 오류 목록을 오염시키지 않습니다. 예외는 항상 다시 발생됩니다. 스코프는 예외를 삼키지 않습니다.
이벤트 메서드
여섯 가지 계열에 걸쳐 열다섯 가지 메서드가 있습니다. 대부분은 쌍으로 이루어져 있으며, 여는 이벤트를 발행한 뒤 닫는 이벤트를 발행하면 SDK가 그 사이의 스팬을 측정합니다.두 가지 사람 관련 계열은 방향이 반대입니다.
두 번째 쌍은 어떤 프레임워크도 신호를 보내지 않으므로, 항상 직접 발행해야 합니다.
예시
에이전트 프레임워크 없이 OpenAI API를 사용하는 도구 호출 루프:docs/manual/examples/ 경로에 포함되어 있습니다.
스레드와 비동기
컨텍스트 변수는 asyncio 태스크에 자동으로 전파됩니다. 하지만 새 스레드는 빈 컨텍스트로 시작하기 때문에 스레드로는 자동 전파되지 않습니다.propagate()를 사용하지 않으면, 워커의 이벤트는 세션 없이 처리되는 대신 수정 방법을 알려주는 TypeError를 발생시킵니다. 이는 의도적인 동작입니다. 세션이 없는 이벤트는 인제스트에서 건너뛰어지고 200으로 응답되는데, 이는 식별자 레이어가 방지하려는 무음 실패이기 때문입니다.
어댑터 없이 프레임워크 계측하기
모든 에이전트 프레임워크는 동일한 세 가지 연결 지점을 제공합니다. 이를 매핑하면 완전한 트레이스를 얻을 수 있습니다. 출시된 네 가지 어댑터도 이것 이상을 하지 않습니다.1
실행을 괄호로 묶기
2
각 도구를 괄호로 묶기
프레임워크에서 도구 래퍼나 미들웨어라고 부르는 곳에서 처리합니다.
3
각 모델 호출을 쌍으로 처리하기
수동 계측과 자동 계측은 함께 동작합니다. 직접 작성한 스코프 안에서 실행되는 어댑터는 해당 세션에 참여하고 해당 에이전트의 하위에 위치하므로, 두 개의 트리가 아닌 하나의 트리를 얻을 수 있습니다. 지원되는 프레임워크와 함께 다른 프레임워크를 직접 계측할 때 유용합니다.
AutoGen 어댑터가 없는 이유
AutoGen 어댑터가 없는 이유
두 가지 이유가 있으며, 위의 세 가지 연결 지점이 두 경우 모두에 대한 답입니다:
autogen-core는 2025년 9월 이후 유지 관리가 중단되었습니다.- AG2는 다른 프레임워크들의 훅에 해당하는 프로세스 수준의 등록 지점을 제공하지 않기 때문에, 계측하려면 에이전트를 생성하는 모든 위치에서 래핑해야 합니다.
더 깊이 알아보기
레코딩이 실제로 동작하는 방식입니다. 시작하는 데 필요한 내용은 아닙니다.프레임워크별 레코딩의 모습
프레임워크별 레코딩의 모습
모든 레코딩은 동일한 형태를 가집니다. 스팬이 열리고, 그 안에 작업이 중첩되며, 각 열린 이벤트에 닫는 이벤트가 생깁니다.쌍이 기본 단위입니다. 각 닫는 이벤트는 SDK가 여는 이벤트부터 측정한 지속 시간을 가집니다.아래는 프레임워크별 실제 실행 결과입니다. SDK와 함께 제공되는 예시에서 캡처했으며 모델 이름은 정규화했습니다. 단 한 번의 호출에서 얼마나 많은 정보가 반환되는지 확인해 보세요.노드가 훅 쌍이 되므로, 에이전트 목록을 복잡하게 만들지 않고도 노드별 레이턴시를 얻을 수 있습니다.
- LangGraph
- CrewAI
- LlamaIndex
- Pydantic AI
- Custom agents
14 events
세션이 시작되고 끝나는 방식
세션이 시작되고 끝나는 방식
세션 종료 이벤트는 없습니다. 세션은 닫는 것이 아니라,
session_id를 공유하는 이벤트들의 그룹입니다.상태는 트레이스의 형태에서 도출됩니다:즉, 모든 쌍이 닫히면 세션이 종료됩니다. 어댑터는
agent_end를 자동으로 발행하며, 종료 시 아직 열려 있는 것들을 닫고 불완전으로 표시합니다. 충돌한 실행은 보이는 공백과 함께 done으로 정리되며 영원히 대기 상태로 남지 않습니다.이것이 세션이 두 번의 호출에 걸쳐 있을 수 있는 이유입니다. LangGraph의
interrupt()는 실행을 일시 정지하고, 루트 스팬은 의도적으로 열린 상태를 유지하며, 재개하는 호출이 그것을 닫습니다. 두 호출은 하나의 세션입니다.식별자: session_id, agent_id, 그리고 누가 생성하는가
식별자: session_id, agent_id, 그리고 누가 생성하는가
session_id와 agent_id는 모든 이벤트 메서드에서 선택 사항입니다. 생략하면 감싸는 스코프에서 해결됩니다:TypeError가 발생합니다. 세션 없는 이벤트는 인제스트에서 건너뛰어지고 200으로 응답됩니다.스코프는 컨텍스트 변수에 식별자를 바인딩합니다. 이는 asyncio 태스크에는 자동으로 전파되지만 새 스레드에는 전파되지 않으므로, 워커를 failproofai_sdk.propagate()로 감싸야 합니다.누가 어떤 id를 생성하는가
어댑터가 session_id를 해결하는 방식
첫 번째 매칭이 우선:- 명시적인
session_id옵션 - 호출별 메타데이터
- 감싸는
session()스코프 - 프레임워크 메타데이터
- 프레임워크 자체 실행 id
agent_id는 저기수성으로 유지하세요
모든 대시보드 화면의 주요 패싯이며 LowCardinality(String) 컬럼입니다. 실행별 값을 사용하면 컬럼 성능이 저하되고 필터 드롭다운에 실행마다 하나씩 항목이 쌓입니다.어댑터는 이 컬럼을 자동으로 보호합니다:실제 id는
fw_agent_id / fw_run_id에 보존되어 패싯이 되지 않으면서도 쿼리 가능합니다.이벤트 타입 목록 및 프레임워크별 기록 여부
이벤트 타입 목록 및 프레임워크별 기록 여부
위의 실행 결과를 기준으로 프레임워크별 기록 여부:
대시(—)는 프레임워크에 해당 개념이 없음을 의미합니다.
human_pause와 human_interrupt는 에이전트에 _사람_이 개입하는 것을 나타내며, 어떤 프레임워크도 신호를 보내지 않으므로 직접 발행해야 합니다.쌍, 상관관계, 지속 시간
쌍, 상관관계, 지속 시간
이벤트는 단독으로 도착하지 않습니다. 하나가 스팬을 열고, 하나가 닫으며, 닫는 이벤트는 SDK가 여는 이벤트부터 측정한 지속 시간을 가집니다.
상관관계 규칙
- 매칭되는 완료 이벤트에 동일한
tool_call_id,hook_id,pause_id,input_id를 재사용하세요. - SDK는
tool_result,hook_completed,agent_resume,human_input에 대해duration_ms를 계산합니다. 이 메서드들에 전달하면ValueError가 발생합니다. duration_ms는model_response에서 허용됩니다. 실제 프로바이더 레이턴시는 호출자만 알기 때문입니다. 정수여야 합니다. 부동소수점은 호출 시점에ValueError를 발생시킵니다. 서버가 해당 컬럼을 부호 없는 32비트 정수로 읽어 다른 값은 NULL로 저장하기 때문입니다.- 상관관계 키는 종류와 세션별로 범위가 지정되므로, 도구 호출과 훅이 같은 id를 안전하게 공유할 수 있으며, 동시 세션도 동일한 id를 충돌 없이 재사용할 수 있습니다. 에이전트별로는 범위가 지정되지 않습니다. 한 에이전트 아래서 열리고 다른 에이전트 아래서 닫히는 쌍도 여전히 상관관계를 유지합니다. 이는 다중 에이전트 프레임워크에서 일반적인 경우입니다.
request_id는model_request와model_response를 쌍으로 묶습니다. 없으면 모델 이벤트가 에이전트별 순서대로 쌍을 이루므로, 동시 호출 시 잘못된 쌍이 생깁니다.- 프로세스를 넘나드는 쌍은 다운스트림에서도 상관관계를 유지하지만, SDK는 프로세스 내 지속 시간을 계산할 수 없습니다.
- 대기 중인 맵은 최대 10,000개의 시작 이벤트를 보유하며, 가득 차면 가장 오래된 항목을 삭제합니다.
패키지 내용 및 instrument()의 프레임워크 탐지 방식
패키지 내용 및 instrument()의 프레임워크 탐지 방식
failproofai-sdk를 설치하면 네 가지 어댑터를 포함한 모든 것이 설치됩니다. extras는 어댑터가 아닌 프레임워크를 가져옵니다.import failproofai_sdk는 계약상 의존성이 없으며, --no-deps로 빌드된 wheel을 설치하는 테스트와 어떤 프레임워크도 sys.modules에 없음을 증명하는 테스트로 강제됩니다.자동 탐지는 설치된 패키지 목록이 아닌
sys.modules를 읽으므로, 설치했지만 임포트하지 않은 프레임워크는 계측되지 않으며 임의로 임포트되지도 않습니다. 현재 연결된 것을 확인하려면:CrewAI가 없는 머신에서 예외를 발생시키려면
instrument("crewai")를 호출해도 예외가 발생하지 않습니다. 경고를 로그에 남기고 ()를 반환하므로, 하나의 프레임워크가 없어도 다른 프레임워크를 계측하는 프로세스가 중단되지 않습니다.경고에는 기본 ImportError가 포함되며, 해당 메시지에 정확한 설치 명령이 나와 있습니다. 수정 방법이 숨겨지지 않고 로그에 있습니다.FAILPROOFAI_SDK_STRICT=1을 설정하세요. 이 플래그는 한 번 읽히고 캐시되므로, 실행 중에 설정하지 말고 프로세스 시작 전에 내보내세요.이벤트가 클라우드에 도달하는 방식
이벤트가 클라우드에 도달하는 방식
스풀이 안전성의 핵심입니다. 에이전트는 네트워크에서 절대 차단되지 않으며, 클라우드 장애 시 이벤트가 유실되는 대신 디렉터리가 커집니다.각 플러시는 하나의 배치 파일을 씁니다.
.tmp로 먼저 쓰고, fsync한 뒤, 원자적으로 이름을 변경합니다:.jsonl만 읽으므로 절반만 쓰인 파일을 읽을 수 없습니다. 파일명에 타임스탬프, 프로세스 id, 시퀀스 번호가 포함되어 있어 두 프로세스가 같은 밀리초에 플러시해도 충돌하지 않습니다. 큐는 10,000개 이벤트로 제한되며, 초과 시 가장 오래된 것을 삭제하고 로그를 남깁니다.데몬은 배치를 전송합니다. 열거나 다시 쓰지 않습니다.리댁션은 데몬이 자체 이벤트를 쓰는 곳에서 실행됩니다. 배치가 전송되는 곳이 아닙니다. 따라서 API 키를 포함한 프롬프트나 도구 인자는 도착 시에도 그대로입니다.이는 의도적입니다. 이것은 사용자 자신의 계측 호출이며, 전송 중에 이를 재작성하면 받은 이벤트가 발행한 이벤트와 다르게 됩니다.데몬은 각 배치를 전송 후 수 밀리초 내에 삭제하므로,
ls를 실행하면 수집기와 경쟁하게 되어 발행한 것의 일부만 보입니다. 아무것도 기록하지 않은 SDK와 구분할 수 없습니다.이벤트가 실제로 도달했는지 확인하려면 대시보드를 확인하세요. 스풀이 채워지는 것을 관찰하려면 먼저 데몬을 중지하세요.계측이 실패할 때
계측이 실패할 때
모든 콜백은 재발생만을 담당하는 래퍼 안에서 실행됩니다. 따라서 호출은 정확히 하나의
try 안에 있고, SDK가 하는 모든 것은 그 밖에서 일어납니다.기본값은 프로덕션에서는 맞고 디버깅 시에는 맞지 않습니다. “충돌하지 않았다”는 것만 증명할 수 있기 때문입니다. 삼켜진 실패를 드러내려면
FAILPROOFAI_SDK_STRICT=1을 설정하세요.자주 발생하는 문제
스팬이 끝나지 않음
스팬이 끝나지 않음
여는 이벤트에 닫는 이벤트가 없는 경우입니다.
model_request에 model_response가 없거나 tool_use에 tool_result가 없는 경우입니다. 본문에서 예외가 발생해도 쌍을 보장하는 스코프를 사용하세요. 이벤트 메서드를 직접 호출한다면 try와 finally를 사용하세요.duration_ms 전달 시 ValueError 발생
duration_ms 전달 시 ValueError 발생
매칭되는 여는 이벤트부터 측정되므로,
tool_result, hook_completed, agent_resume, human_input에서는 거부됩니다. model_response에서는 허용되며, 실제 프로바이더 레이턴시는 사용자만 알기 때문입니다. 정수여야 합니다.워커 스레드의 이벤트가 TypeError 발생
워커 스레드의 이벤트가 TypeError 발생
스레드가 컨텍스트를 상속받지 못했습니다. callable을
failproofai_sdk.propagate()로 감싸세요. 스레드와 비동기를 참고하세요.추가 필드가 사라지거나 기존 내용을 덮어씀
추가 필드가 사라지거나 기존 내용을 덮어씀
추가 필드는 마지막에 병합되므로,
model이나 outcome 같은 실제 필드와 같은 이름이면 덮어쓰고 저장된 컬럼을 변경합니다. 네임스페이스를 사용하세요. 어댑터는 fw_ 접두사를 사용합니다.에이전트 필터에 수천 개의 항목이 있음
에이전트 필터에 수천 개의 항목이 있음
agent_id는 저기수성 패싯인데 실행 id를 넣었습니다. 역할이나 노드 이름을 사용하고 실제 id는 페이로드 필드에 넣으세요.다음 단계
동작 방식
쌍, id, 세션 생명주기, 전달 방식.
트레이스 읽기
방금 캡처한 세션의 인과관계를 따라가세요.
프레임워크 어댑터
LangGraph, CrewAI, LlamaIndex, Pydantic AI.

