우리를 믿지 마세요 — 체인을 확인하세요: AI 에이전트 판결에 대한 공개 검증
요약
본 글은 AI 에이전트가 내린 '판결(verdict)'의 신뢰성을 검증하는 방법을 설명합니다. 단순히 발급자의 주장을 믿는 것이 아니라, 외부인이 RPC 엔드포인트를 통해 온체인에서 독립적으로 재검증할 수 있는 구조적 설계가 핵심입니다. 이를 위해 자체 검증 영수증과 공개 API를 제공하여 투명한 확인 절차를 안내합니다.
핵심 포인트
- AI 에이전트 판결은 외부인이 RPC 엔드포인트를 통해 온체인에서 독립적으로 재검증 가능해야 합니다.
- 유료 응답에는 결정론적 메모 ID와 검증 영수증이 포함되어 온체인 재검증을 지원합니다.
- 공개 API (`GET /api/verify/:verdictId`)를 사용하면 판결 아티팩트, 메모 앵커 상태 등을 확인할 수 있습니다.
- 웹 페이지(`/verify`)는 JavaScript 없이도 모든 상태(Pending 등)를 명확히 표시하여 신뢰성을 높였습니다.
이 글은 원래 AgentBadge blog에 게재되었습니다.
만약 우리가 거짓말을 한다면 어떻게 될까요? 버그가 아닙니다. 그것은 거짓말입니다. 판결(verdict) 엔드포인트는 "승인됨"이라고 말하고, 서명은 우리 것이며, JSON도 올바르게 보입니다. 만약 검증이 "발급자에게 발급자가 정직한지 묻는 것"을 의미한다면, 그 답변은 구조적으로 가치가 없습니다. 유일하게 정직한 설계는 발급자의 주장이 외부인(stranger)이 RPC 엔드포인트를 통해 확인하고, 발급자를 전혀 믿지 않아도 되는 경우입니다.
저희가 평가자(evaluator)의 서명을 받는 모든 판결에 대해 제공하는 것이 바로 그것입니다. 이제 유료 응답에는 자체 검증 영수증(verification receipt) — 링크와 결정론적 메모 ID(deterministic memo id) — 이 포함되며, 그 영수증 내의 모든 주장은 저희 API를 호출하지 않는 독립적인 패키지를 통해 온체인(on-chain)에서 재검증됩니다. 만약 저희 서버가 내일 사라진다고 해도, 증명은 여전히 확인 가능합니다.
공개 API를 통해 판결을 어떻게 검증하나요?
인증 없이 GET 요청 하나만 하면 됩니다: GET /api/verify/:verdictId는 저장된 판결 아티팩트(artifact), 기계 reason_codes, 판결별 메모 앵커(memo anchor) 상태(status, memoId, txHash, blockNumber), 해시 체인(hash-chain) 상태(anchored/pending/disabled이며 오프라인 재계산을 위한 head_ref 포인터 포함), 그리고 proof_kinds 레지스트리 요약을 반환합니다. 알 수 없는 ID는 404 verdict_not_found; 가짜-유효(fake-valid)에 대해서는 절대 응답하지 않습니다.
응답은 설계상 계층적입니다. ?kind=verdict를 요청하면 판결 레이어(아티팩트 + 메모 앵커)만 반환됩니다. ?kind=anchor-head를 요청하면 체인 레이어만 반환됩니다. ?kind=witness는 implemented:false로 응답합니다. 이 종류(kind)는 레지스트리에 선언되어 있어 검증자가 배포 전에 기능 감지(feature-detect)할 수 있습니다. 등록되지 않은 종류를 요청하면 조용한 폴백(silent fallback) 대신 전체 known 목록과 함께 400 unknown_proof_kind 오류가 발생합니다.
/verify 페이지는 무엇을 하나요?
이는 사람들을 위한 동일한 확인 절차입니다: /verify에서 서버 렌더링되는 페이지가 verdict id, anchor 트랜잭션 해시, 또는 memo id를 받습니다. 이들은 모두 0x-접두사가 붙은 64-헥스 문자열이며, 앵커 역조회(anchor reverse-lookup)를 통해 사용자가 무엇을 붙여넣었는지 확인합니다. 이 페이지는 온체인 쓰기가 아직 완료되지 않은 경우 명시적인 pending 배너와 함께 판결 내용, 이유 코드, 앵커 상태, 탐색기 링크, 그리고 JSON-LD 메타데이터를 JavaScript 없이 모두 렌더링하므로 curl과 에이전트의 텍스트 브라우저에서도 작동합니다.
핵심은 정직한(honest) 상태입니다. 앵커되지 않은 판결은 절대 "유효함(valid)"이 아닌 "대기 중(pending)"으로 표시됩니다. 형식이 잘못된 ID는 400을, 형식은 올바르지만 알 수 없는 ID는 404를 반환하며, 이 페이지는 두 가지 중 어떤 상황이 발생했는지 알려줍니다.
AgentBadge를 전혀 신뢰하지 않고 어떻게 검증할 수 있나요?
독립 실행 패키지를 실행하세요. @agentbadge/verify-verdict는 자체적으로 체인과 모든 것을 재검증합니다—Arc의 0x5294E9927c3306DcBaDb03fe70b92e01cCede505에 있는 memo 컨트랙트를 사용하며, 우리의 API 호출이나 계정, 키가 필요 없습니다:
npx @agentbadge/verify-verdict 0x<verdictId-or-txHash>
# exit 0 — 모든 증명(proof) 통과
# exit 1 — 유효하지 않거나, 앵커되지 않았거나, 타입 오류 발생 (rpc_unavailable)
각 실행은 proofs[] 보고서를 생성하며, 이는 레이어별 하나의 항목으로 구성되어 있고, 각각 ok:true/false와 상세 정보를 포함합니다:
- verdict: 판결별 메모 앵커가
memoIdFor("eaas", verdictId)에 존재하며, 해당 메모 데이터는 정규화된 아티팩트 JSON의keccak256과 일치합니다 (변조 여부 확인을 위해--artifact를 통해 아티팩트를 전달하세요). - anchor-tx: 메모 이벤트가 사용자가 제공한 트랜잭션 내에 존재합니다.
- anchor-head: 주기적인 에포크 앵커가
memoIdFor("chain", "eaas-verdicts", epochSeq)에서(headHash, count, prevAnchoredHeadHash)를 바인딩하며 에포크들을 연결합니다. - chain-recompute: 체인 항목(
--entries)을 입력하면 로컬에서 이를 접어(fold) 검증합니다: 깨진 항목은firstBrokenSeq로 실패하며, 항목에 없는 판결은 정직성 오류(honest-invalid)로 실패합니다.
우리가 서명하는 모든 판결은 이슈 시점에 해당 해시 체인에 기록되며, 에포크마다 헤드가 온체인으로 플러시됩니다. 따라서 Level-2 검증기는 가장 중요한 질문에 답합니다: 서버가 보여준 것이 체인이 가지고 있는 것과 같은가?
verify-verdict 0x4af3… --artifact verdict.json --entries chain.json
# proofs: verdict ok | anchor-head ok | chain-recompute ok
# valid: true — exit 0
Proof-kind 레지스트리란 무엇인가?
검증 표면(verification surface)이 이해하는 모든 온체인 증명(on-chain proof)의 버전 관리된 열거형(enum)입니다. PROOF_KINDS_V1은 세 가지 종류 — verdict, witness, anchor-head — 를 선언하며, 각각 메모 형식(memo format), ok:true에 대한 검증기 규칙(verifier rule), 그리고 협상을 위한 specVersion을 가집니다. 이 레지스트리 자체가 계약입니다: 검증기는 무엇이 존재하는지 열거하고, 배포가 어떤 종류를 지원하는지 확인하며, 요청받은 레이어를 건너뛰는 대신 알 수 없는 종류에 대해 명확하게 실패합니다.
witness 종류는 중요한 항목입니다. 이는 메모 형식과 규칙 스텁(rule stub)과 함께 선언되지만, implemented:false를 반환합니다. 왜냐하면 witness 레이어(작업별 독립적인 증명)가 아직 배포 중이기 때문입니다. 구현되지 않은 종류들을 나열하는 레지스트리는 제3자가 오늘 미래의 표면을 기반으로 구축할 수 있게 하며, 누구나 완전한 정직성 지도(full honesty map): 현재 검증 가능한 것, 선언된 것, 그리고 우리가 일찍 주장했다면 거짓말이었을 것이 무엇인지를 볼 수 있게 합니다.
"pending"이란 무엇을 의미하며, 왜 가짜-유효(fake-valid)가 없는가?
거짓말하는 검증 표면은 아무것도 아닌 것보다 더 나쁩니다. 판결이 이슈된 후 Anchor 쓰기는 즉시 휘발성으로 처리됩니다 — 지불된 응답은 즉시 반환되고, 메모는 비동기적으로 온체인에 기록됩니다. 이것이 기록될 때까지 모든 표면은 pending을 표시합니다: API의 anchor.status, 페이지의 배너, 그리고 패키지의 verdict 증명 (ok:false, 상세 정보에는 메모 이벤트가 없음)입니다. 우리의 RPC가 다운되면, 패키지는 `VerifyError(
인라인 영수증(inline receipt)은 보류 중 상태를 눈에 띄지 않게 만드는 대신 유용하게 만듭니다. 결제 응답의 verify:{api, page, memoId} 블록에는 판결 ID로부터 계산된 결정론적 메모 ID가 포함됩니다. 따라서 클라이언트는 응답이 도착하는 즉시 두 번째 API 왕복(round-trip)을 기다릴 필요 없이 체인에서 자신만의 앵커를 폴링(polling)하기 시작할 수 있습니다.
이것은 Arc Campaign 시리즈의 C16입니다. 이전 글: The x402 Bazaar — 머신이 쇼핑할 수 있는 서비스 카탈로그. 다음 글: Never Charged for a No — 기계가 검증 가능한 거절 계약.
링크: Verify API · Verify 페이지 · openapi.yaml · llms.txt · @agentbadge/verify-verdict · AgentBadge
인증하지 마세요. 측정하세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기