다른 에이전트 대시보드 대신 로컬 증거 디버거를 구축한 이유
요약
AI 에이전트의 복잡한 실패 경로를 추적하기 위해 로컬 증거 디버거인 AgentInspect를 소개합니다. 이 툴킷은 일반적인 호스팅 관측 가능성 제품과 달리, 코드 옆에서 실행 과정을 검사하고 재현 가능한 구조화된 증거(JSON Lines)를 생성하는 데 초점을 맞춥니다.
핵심 포인트
- 에이전트의 실패 경로는 복잡하여 단순 로그나 최종 응답만으로는 파악하기 어렵습니다.
- AgentInspect는 호스팅 관측 가능성 제품을 대체하지 않으며, 로컬 개발 및 검증 단계에 최적화되어 있습니다.
- 생성된 증거는 JSON Lines 형식으로 제공되어 PR 첨부, CI 재현 등 엔지니어링 워크플로우에 통합하기 용이합니다.
AI 에이전트는 깔끔하고 명확하게 실패하는 경우가 드뭅니다. 잘못된 도구를 호출하거나, 숨겨진 오류에서 복구하거나, 예상보다 훨씬 많은 토큰을 사용하거나, 제품에 의존하는 단계를 건너뛰는 방식으로 실행이 완료될 수 있습니다. 최종 텍스트는 보이지만, 그것을 생성한 경로는 종종 보이지 않습니다.
저는 에이전트 실행을 로컬에서 검사하기 위한 오픈 소스 TypeScript 툴킷인 AgentInspect를 유지 관리하고 있습니다. 이 글에서는 왜 제가 이것을 또 다른 호스팅된 에이전트 대시보드가 아니라 로컬 증거 디버거로 설계했는지, 그리고 그 선택이 어디서 도움이 되거나 의도적으로 도움을 주지 않는지를 설명합니다. 여기에 표시된 명령어와 동작은 불변의 [email protected] 릴리스를 기준으로 확인되었습니다.
'실패했다'와 '왜 그런지' 사이의 누락된 아티팩트
에이전트가 오작동할 때, 엔지니어들은 보통 다음 세 가지 아티팩트 중 하나로 시작합니다:
- 애플리케이션 로그,
- 최종 모델 응답,
- 모니터링 제품의 스크린샷.
각각 유용하지만, 어느 것도 자동으로 완전한 설명이 되지는 않습니다. 로그는 종종 서비스 전반에 걸쳐 분산되어 있고 인과관계가 아닌 시간 순서로 정렬됩니다. 최종 응답은 실행 경로를 숨깁니다. 대시보드는 실행을 명확하게 보여줄 수 있지만, 증거를 풀 리퀘스트(pull request)에 첨부하거나 CI에서 재현하거나 계정 없이 검토하기는 어려울 수 있습니다.
제가 해결하고자 했던 간극은 더 좁았습니다:
하나의 에이전트 실행을 받았을 때, 엔지니어가 그 경로를 검사하고, 명시적인 기대를 확인하며, 다른 실행과 비교하고, 검토 가능한 아티팩트로 패키징하기에 충분한 구조화된 증거를 로컬에서 포착할 수 있을까요?
그 질문은 다른 제품 경계로 이어졌습니다.
디버거는 증거를 생성하며, 운영(operations)을 대체하지 않습니다
호스팅된 관측 가능성(observability) 제품들은 영구적인 수집(ingestion), 플릿 전체 모니터링, 보존, 경고 알림 및 팀 운영을 위해 설계되었습니다. 그것들은 가치 있는 기능들입니다. AgentInspect는 이를 노트북에서 재현하려고 하는 것이 아닙니다.
이러한 대비는 의도적입니다. OpenTelemetry의 개념 문서에서는 더 광범위한 신호, 계측(instrumentation), 컨텍스트 전파(context-propagation) 및 수집 모델을 설명합니다. 프로덕션 지향적인 예시를 위해, 이 HackerNoon 가이드워크는 OpenTelemetry와 SigNoz를 사용한 다중 에이전트 관찰 가능성(observability)을 중앙 집중식 운영 질문에서 시작합니다. 여기서 제 초점은 코드 옆에 존재할 수 있는 더 작은 사전 출시 증거 루프입니다.
그 핵심 워크플로우는 의도적으로 작습니다:
agent 실행
|
v
...
이 출력물은 엔지니어링 작업과 함께 이동할 수 있는 아티팩트입니다. 개발자는 풀 리퀘스트(pull request)를 열기 전에 이를 검사할 수 있습니다. CI는 알려진 문제가 있는 궤적을 거부할 수 있습니다. 리뷰어는 전체 실행을 재현하지 않고도 번들(bundle)을 검증할 수 있습니다. 소스 트레이스(source trace)는 JSON Lines를 사용하는데, 이는 일반적인 텍스트 처리 도구에 친숙한 라인 지향의 구조화된 형식입니다.
이것이 AgentInspect가 APM, 호스팅 에이전트 관찰 가능성, 그리고 평가 플랫폼과 상호 보완적임을 의미합니다. 이 도구는 호스팅된 보존(retention), 프로덕션 알림(alerting), 프롬프트 관리, 자동 복구(automatic remediation), 또는 규정 준수 인증을 제공하지 않습니다. 이러한 경계를 설정하는 것이 중요합니다. 로컬 증거 도구는 사용자가 그것이 제공하지 않는 것을 알 때만 유용하기 때문입니다.
가장 작은 유용한 캡처 루프
루트 패키지에는 실행(run), 일반 단계(step), 도구 호출(tool call), 그리고 LLM 호출에 대한 래퍼가 포함됩니다. 최소한의 합성 예시는 다음과 같습니다:
import { inspectRun, step } from "agent-inspect";
const answer = await inspectRun(
"quickstart-support-agent",
...
이 예시는 모든 내부 작업을 자동으로 발견한다고 주장하지 않습니다. 대신 애플리케이션이 계측하는 경계(boundaries)를 기록합니다. 프레임워크 어댑터와 표준 기반 입력은 통합 작업을 줄일 수 있지만, 수동 계측(manual instrumentation)은 여전히 명시적입니다.
이러한 명시성은 증거 중심 디버깅에서 설계상의 이점입니다. 엔지니어는 어떤 작업이 이름을 붙이고 검토할 만큼 의미가 있는지 결정합니다. 그러면 트레이스는 원격 서비스에 접근할 필요 없이 읽을 수 있습니다:
로컬 파일 자체가 목표는 아닙니다. 이 로컬 파일은 여러 검토 뷰(review views)가 파생되는 근원지입니다.
한 번의 실행으로 얻을 수 있는 네 가지 엔지니어링 질문
1. 실제로 무슨 일이 일어났나요?
실행 트리 뷰(execution-tree view)는 부모-자식 관계를 재구성하고 오류, 폴백(fallbacks), 재시도(retries), 병렬 형제 요소(parallel siblings) 등을 노출합니다. 이는 단순히 타임스탬프별로 로그 라인을 정렬하는 것과는 다릅니다.
2. 실행이 우리의 명시적 계약을 충족했나요?
결정론적 검사(Deterministic checks)를 통해 필수 또는 금지된 도구, 호출 제한(call limits), 순서 제약 조건(order constraints), 실행 상태(run status), 지속 시간(duration), 토큰 상한선(token ceilings), 관찰 실패(observation failures)와 같은 속성을 확인할 수 있습니다.
npx agent-inspect check quickstart-support-agent \
--dir .agent-inspect \
--preset trajectory \
...
이것들은 의미론적 LLM 평가가 아닙니다. 이 검사들은 재현 가능한 규칙을 사용하여 명시적인 구조적 질문에 답합니다. 답변이 설득력이 있는지, 안전한지, 또는 사실적으로 정확한지는 다른 평가자가 필요할 수 있습니다.
3. 두 실행 사이에는 무엇이 바뀌었나요?
실행 차이(run diff)를 통해 첫 번째 행동 분기점(behavioral divergence), 추가되거나 제거된 단계, 출력 변경 사항, 오류, 타이밍 차이를 확인할 수 있습니다. 이는 작은 텍스트 차이만 있는 두 코드 개정판이라도 매우 다른 에이전트 트래젝토리(agent trajectories)를 생성할 수 있고, 심지어 동일한 코드가 모델이나 외부 도구가 변경될 때 서로 다른 트래젝토리를 생성할 수 있기 때문에 유용합니다.
4. 증거를 책임감 있게 공유할 수 있나요?
로컬 트레이스에는 민감한 입력(inputs), 출력(outputs), 메타데이터가 포함될 수 있습니다. AgentInspect는 최선의 노력으로 마스킹(redaction) 및 안전성 평가를 포함하며, 이후 증거 번들 워크플로우(evidence-bundle workflow)를 수행합니다:
npx agent-inspect verify-safe quickstart-support-agent \
--dir .agent-inspect
npx agent-inspect bundle quickstart-support-agent \
...
최종 명령어는 기록된 파일 해시와 매니페스트 무결성을 검증합니다. 이 과정은 디지털 서명을 생성하거나, 저작권을 확립하거나, 규제 준수를 인증하지 않습니다. 무결성 검사를 통과했다는 것은 파일들이 여전히 번들 매니페스트와 일치한다는 의미일 뿐이며, 근본적인 에이전트가 올바르다는 것을 의미하지는 않습니다.
로컬 우선(local-first) 방식이 아키텍처적 결정이었던 이유
‘로컬 우선’은 때때로 개인 정보 보호 슬로건으로 취급되기도 합니다. 하지만 여기서는 구성 가능성(composability)에 관한 것이기도 합니다.
핵심 루프를 위해 계정이 필요하지 않음
기본 워크플로우는 로컬 디렉터리와 CLI만으로 실행될 수 있습니다. 이는 단일 실패 테스트를 검사하거나 변경 사항에 증거를 첨부하려는 개발자에게 마찰을 줄여줍니다.
증거가 기존 워크플로우에 참여할 수 있음
JSONL 트레이스 및 생성된 보고서는 CI 아티팩트로 보관되거나, 풀 리퀘스트에서 검토되거나, 다른 시스템으로 전달될 수 있습니다. 증거는 하나의 UI 뒤에 갇히지 않습니다.
캡처와 내보내기는 분리된 결정임
로컬에서 기록한다고 해서 트레이스가 공유하기 안전해지는 것은 아닙니다. 소스 트레이스, 마스크 처리된 아티팩트(redacted artifact), 안전성 평가, 그리고 번들 간의 분리는 위험을 무시무과한 최종 클릭으로 취급하는 대신 가시적으로 만듭니다.
결정론은 변경 사항 근처에 있어야 함
구조적 검사는 코드와 목업(fixtures) 옆에서 실행될 때 가장 유용합니다. “검색이 생성보다 선행되어야 한다”와 같은 계약은 누군가 대시보드 이상 징후를 알아차릴 때까지 기다리지 않고 CI에서 실패할 수 있습니다.
제가 받아들인 트레이드오프(tradeoffs)
모든 경계는 복잡성뿐만 아니라 기능을 제거하기도 합니다.
AgentInspect는 프로덕션 플릿을 지속적으로 감시하지 않습니다. 어댑터가 측정되지 않은 작업을 관찰한다는 것을 보장하지도 않습니다. 그 결정론적 검사는 산문(prose)이 올바른지 여부를 판단할 수 없습니다. 안전성 스캐닝은 최선의 노력(best effort)이며, 아티팩트를 공유하는 결정권자는 여전히 인간입니다. 시간 비교는 노이즈가 많을 수 있습니다. 증거의 무결성은 증거의 진실성을 의미하지 않습니다.
그러한 한계점들은 각주가 아닙니다. 그것들이 이 도구가 사용되어야 하는 방식을 정의합니다:
- 실행 증거(execution evidence)를 사용하여 동작을 이해하고;
- 결정론적 계약(deterministic contracts)을 사용하여 안정적인 구조 불변성(structural invariants)을 확보하며;
- 답변 품질을 위해 의미론적 및 도메인 평가기(semantic and domain evaluators)를 사용하고;
- 플릿 모니터링(fleet monitoring)과 보존이 필요할 때 호스팅된 연산 도구(hosted operations tools)를 사용하며;
- 공유하기 전에 수정된(redacted) 아티팩트를 검토합니다.
에이전트 변경 사항에 대한 더 나은 검토 단위
기존 소프트웨어 검토는 코드를 중심으로 이루어집니다. 이는 코드가 동작을 강력하게 결정하기 때문입니다. 하지만 에이전트 시스템은 모델(models), 프롬프트(prompts), 도구(tools), 검색(retrieval), 외부 상태(external state), 그리고 비결정성(nondeterminism)을 이 관계에 추가합니다. 코드 차이(code diff)는 여전히 필요하지만, 더 이상 충분하지 않습니다.
제가 원하는 추가적인 검토 단위는 간결하고 구체적입니다:
change
+ 소스 차이(source diff)
+ 대표 실행(representative run)
...
이것이 에이전트를 결정론적으로 만드는 것은 아닙니다. 하지만 엔지니어링 논의를 덜 추측성 있게 만듭니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Hacker Noon AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기