발행됨
엔지니어링

가짜 Claude 탐지기가 오픈 소스 라이브러리가 되었습니다

ai-model-verifier는 저희 모델 테스터를 움직이는 엔진으로, AGPL-3.0 라이선스로 npm에 공개했습니다. 기본 URL, 키, 모델을 넘기면 해당 엔드포인트가 판매하는 그대로의 모델을 제공하는지 알려 주며, 이제 사고 서명과 토큰 과금 검사도 포함합니다.

·4분 분량·UnoRouter 팀
엔지니어링공지

지난 4월 저희는 가짜 Claude 리셀러에 관한 수치를 공개했습니다. 8개 공급자에 걸친 183개 채널이 Kiro, Codeium, 혹은 Claude 명찰을 단 다른 모델로 응답하고 있었습니다. 이를 잡아낸 프로브는 저희 동기화 파이프라인 안에 있었습니다. 이제는 누구나 설치할 수 있는 패키지 안에 있습니다.

ai-model-verifier는 AGPL-3.0 라이선스로 npmGitHub에 있습니다. 기본 URL, API 키, 모델 이름을 받아 genuine, suspicious, unverified 세 가지 판정 중 하나를, 발동한 규칙과 프로브의 원본 응답과 함께 돌려줍니다.

왜 라이브러리인가

같은 검사가 이제 세 곳에서 실행됩니다. 브라우저의 모델 테스터, 공개 랭킹을 위한 저희 서버, 그리고 UnoRouter이 어떤 업스트림 경로를 노출할지 결정하는 동기화 파이프라인입니다. 패턴 목록 사본이 세 개면 서로 어긋나기 마련입니다. 패키지 하나면 어긋나지 않습니다.

의도적으로 아이소모픽하게 만들었습니다. 웹 표준 API만 사용하고, node: 임포트가 없으며, 런타임 의존성이 0입니다. HTTP 호출은 외부에서 주입되므로 브라우저는 CORS를 우회할 수 있고 서버는 SSRF 방어가 된 fetch를 거칠 수 있습니다. 공급자와 탐지기는 별도 진입점이라 Anthropic 검사에 Gemini 설정이 함께 번들되는 일이 없습니다.

4월 이후 달라진 점

첫 글의 네 가지 행동 프로브는 여전히 핵심입니다. 새끼 고양이 이야기, 하이쿠, 정체성 질문, 모델 이름 질문이며, 이제 Anthropic, OpenAI, Gemini 형식의 엔드포인트를 모두 지원합니다. 그 주위에 모델에게 정체를 묻는 데 의존하지 않는 검사들이 추가되었습니다.

  • 사고 서명. Claude는 모든 사고 블록에 서버가 생성한 서명을 붙입니다. 다른 모델을 제공하는 릴레이는 이를 만들 수 없습니다. 정체성 프로브는 시스템 프롬프트로 학습시킬 수 있지만 서명은 그럴 수 없습니다.
  • 토큰 회계. 릴레이는 진짜 Claude를 중계하면서도 매 호출마다 input_tokens를 부풀릴 수 있습니다. 고정된 텍스트 구간만 다른 두 프롬프트는 과금 토큰 수가 알려진 범위 안에서 차이 나야 하고, count_tokens는 과금된 값과 일치해야 하며, 출력은 max_tokens 아래에 머물러야 합니다. Opus 4.7과 4.8은 다른 토크나이저를 쓰므로 이 범위는 티어 검사 역할도 합니다.
  • 티어 불일치와 대체. Opus로 과금하고 Sonnet을 제공하는 수법은 행동 프로브를 빠져나갑니다. Sonnet도 새끼 고양이 이야기를 훌륭하게 쓰기 때문입니다. 모델 이름 프로브는 더 싼 티어를 말하는 응답을 잡아내고, 엔벨로프 검사는 요청과 다른 모델 ID를 돌려주는 엔드포인트를 잡아냅니다.
  • 응답 섞임과 언어 누출. 모든 프롬프트에는 nonce가 담깁니다. 다른 사람의 nonce를 되돌려 주는 응답은 프록시가 사용자 간 응답을 섞고 있다는 뜻입니다. 영어 프롬프트의 응답에 CJK 문자가 섞이면 중국어 모델로 대체되었다는 신호입니다.
  • 엔벨로프 메타데이터. Anthropic 형식 응답 안의 chatcmpl- ID나 Messages 응답 안의 OpenAI usage 키는 사용자와 모델 사이에 변환 계층이 있다는 뜻입니다. 판정이 아니라 관찰로 보고합니다. 저희 게이트웨이 자체가 바로 그런 계층이기 때문입니다.
  • 처리량. 큰 모델일수록 토큰당 속도가 느리므로 Opus로 과금되면서 Sonnet 속도로 도는 경로는 살펴볼 가치가 있습니다. 샘플링만 하고 임계값은 두지 않습니다. 유용한 비교는 같은 모델을 제공하는 경로들 사이의 비교이며, 그것은 호출자만 조립할 수 있습니다.

증명하지 못하는 것

유효한 서명은 진짜 Anthropic 경로가 응답했음을 증명합니다. 어느 티어인지는 증명하지 못합니다. Sonnet은 Opus로 팔려도 완벽한 서명을 돌려주므로 여기서 통과해도 티어 검사는 여전히 필요합니다. 사고 블록을 되돌려 보내 Anthropic이 서명을 재검증하게 하는 방법은 결정적인 테스트처럼 들립니다. 저희는 그것을 구현했고, 릴레이를 거치면 동작하지 않습니다. 운영 중인 업스트림 두 곳이 진짜 블록에도, 서명 자리에 무작위 base64 308바이트를 넣은 같은 블록에도 200을 돌려줬습니다. 릴레이는 그 턴을 자기 백엔드에 다시 발행하므로 아무것도 검증되지 않습니다. 이 옵션은 기본적으로 꺼져 있고 그렇게 문서화되어 있습니다.

서명 검사와 토큰 검사는 역시 AGPL인 veridrop에서 이식했으며, 그 허용 오차는 공식 API를 기준으로 보정된 것입니다. 느슨해 보이는 경계를 그대로 둔 이유는 실제 Anthropic 응답이 그 근처에 있었기 때문입니다.

사용하기

모델 테스터는 서명 검사와 토큰 검사를 포함한 전체 세트를 브라우저 안에서 실행하며, 공급자로 가는 호출 외에는 아무것도 컴퓨터 밖으로 나가지 않습니다. 랭킹 페이지는 사람들이 공유하기로 한 결과를 공개합니다. 직접 파이프라인에 넣으려면:

typescript
import { runVerification } from "ai-model-verifier";

const result = await runVerification({
  provider: "anthropic",
  baseUrl: "https://YOUR-PROVIDER",
  apiKey: process.env.YOUR_KEY,
  model: "claude-opus-4-8",
  mode: "server",
  checkSignature: true,
  checkTokenTruth: true,
});

console.log(result.verdict, result.reasons);
// "suspicious" [ "tier-mismatch: requested claude-opus-4-8, served sonnet" ]

필요한 것만 켜세요. checkSignaturecheckTokenTruth는 각각 추가 요청이 들기 때문에 요청하지 않으면 꺼진 채로 있습니다. 엔벨로프 메타데이터와 처리량은 실행이 이미 받은 응답에서 읽어 오므로 비용이 들지 않습니다.

공급자를 테스트하거나, 이 모든 것의 시작이 된 수치를 보려면 4월 글을 읽거나, 실제 엔드포인트가 잘못된 판정을 받으면 GitHub에 이슈를 열어 주세요.

관련 글