公開済み
エンジニアリング

偽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キー、モデル名を受け取り、genuinesuspiciousunverifiedの3つの判定のいずれかを、発火したルールとプローブの生の応答とともに返します。

なぜライブラリにしたのか

同じ検査が今では3か所で動いています。あなたのブラウザ上のモデルテスター、公開ランキングのための当社サーバー、そしてUnoRouterがどのアップストリーム経路を公開するかを決める同期パイプラインの中です。パターンリストのコピーが3つあれば必ずずれていきます。パッケージが1つならずれません。

意図的にアイソモーフィックにしています。Web標準APIのみ、node:のインポートなし、実行時依存はゼロです。HTTP呼び出しは外部から注入されるため、ブラウザはCORSを回避でき、サーバーはSSRF対策済みのfetchを経由できます。プロバイダーと検出器は別々のエントリーポイントなので、Anthropicの検査にGemini設定が同梱されることはありません。

4月以降の新しい点

最初の記事にあった4つの挙動プローブは今も中核です。子猫の物語、俳句、アイデンティティの質問、モデル名の質問で、今回からAnthropic、OpenAI、Gemini形式のエンドポイントに対応しました。その周りに、モデルに「あなたは誰か」と尋ねることに依存しない検査が加わっています。

  • 思考署名。Claudeはすべての思考ブロックにサーバー生成の署名を付けます。別のモデルを提供しているリレーにはそれを作れません。アイデンティティプローブはシステムプロンプトで誘導できますが、署名は誘導できません。
  • トークン計算。リレーは本物のClaudeを転送しながら、毎回input_tokensを水増しすることができます。固定の文章だけが異なる2つのプロンプトは、課金トークン数が既知の範囲内で差がつくはずで、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に署名を再検証させる方法は決定的なテストに聞こえます。私たちはそれを実装しましたが、リレー越しでは機能しません。稼働中の2つのアップストリームは、本物のブロックに対しても、署名を308バイトのランダムなbase64に置き換えた同じブロックに対しても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でissueを開いてください。

関連投稿