はじめに

Cloudflare が 2026年10月1日に、判定用のモデル「Clef」と「Clef-flash」を発表しました。 この記事は、2つのモデルを Workers AI から呼び出して、簡単な実験をした記録です。

公式の情報は次のページで確認できます。

前提は次のとおりです。

  • 実験はすべて 2026年10月4日に Workers AI 上で行いました。
  • 問い合わせ文と画像は、すべて架空のものです。
  • 1つの実験あたりの件数は5件前後です。結果は傾向の確認であり、精度の評価ではありません。

Clef とは

Clef は、文章や画像を読み、あらかじめ決めた選択肢の中から答えを選ぶモデルです。 Clef は文章を生成しません。 Clef は選択肢ごとの確率を返します。

ClefClef-flash
モデルID@cf/cloudflare/clef@cf/cloudflare/clef-flash
ベースモデルQwen3.8-27BQwen3.5-9B
料金(100万入力トークンあたり)$0.24$0.09
コンテキスト長65,536 トークン65,536 トークン
公式のレイテンシ(中央値)209.3 ms38.8 ms

Clef の仕組みは次のとおりです。

  1. ベースモデルが、入力全体を1回だけ読み込みます(prefill)。
  2. ベースモデルの上に追加された小さな head が、各選択肢のスコアを並列で計算します。

ベースモデルの重みは凍結されています。 学習で更新したのは、head と LoRA だけです。

質問の形式は3種類あります。

形式用途返す値
noulyes / no の質問yes の確率
choice2〜255個の選択肢から1つを選ぶ質問選んだ選択肢、選択肢ごとの確率、confidence
score2〜10段階で評価する質問確率で重み付けした期待値、段階ごとの確率

呼び出し方

Workers AI の REST API に POST します。 API トークンは、Cloudflare のダッシュボードでテンプレート「Workers AI」を選んで作成します。

curl https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/ai/run/@cf/cloudflare/clef-flash \
  -H "Authorization: Bearer $CLOUDFLARE_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d @request.json

request.json の例です。 判定したい文章を state に入れ、質問を questions に入れます。

{
  "model": "clef-flash",
  "state": "I ordered a blue mug last week, but a red one arrived. Can I exchange it?",
  "questions": {
    "is_complaint": {
      "type": "noul",
      "instructions": "Is the customer reporting a problem with their order?"
    },
    "topic": {
      "type": "choice",
      "instructions": "Which team should handle this message?",
      "criteria": {
        "shipping": "Delivery delays or tracking",
        "returns": "Returns, exchanges, or wrong items",
        "billing": "Payments, refunds, or invoices"
      }
    }
  }
}

レスポンスです。

{
  "result": {
    "model": "clef-flash",
    "answers": {
      "is_complaint": { "type": "noul", "noul": 0.9266 },
      "topic": {
        "type": "choice",
        "choice": "returns",
        "probabilities": { "shipping": 0.0019, "returns": 0.9956, "billing": 0.0025 },
        "confidence": 0.9869
      }
    },
    "usage": { "input_tokens": 262, "output_tokens": 0 }
  },
  "success": true,
  "errors": [],
  "messages": []
}

API 仕様で気をつける点は次の3つです。

  • Workers AI では、質問ごとの instructions が必須です。Hugging Face の model card では省略できると書かれています。
  • 画像は最大4枚まで送れます。形式は PNG、JPEG、WebP のいずれかで、base64 で渡します。URL は指定できません。
  • 出力トークン数は、レスポンスを確認した32回のリクエストですべて0でした。料金表にも、入力トークンあたりの金額だけが書かれています。

試したこと

EC サイトの問い合わせを、配送(shipping)・返品(returns)・請求(billing)の3つの担当に振り分ける、という場面を想定しました。 各節の折りたたみに、判定結果の全データを載せています。

共通で使った質問(choice)

英語版:

{
  "type": "choice",
  "instructions": "Which team should handle this message?",
  "criteria": {
    "shipping": "Delivery delays or tracking",
    "returns": "Returns, exchanges, or wrong items",
    "billing": "Payments, refunds, or invoices"
  }
}

日本語版:

{
  "type": "choice",
  "instructions": "このメッセージはどの担当チームが対応すべきですか。",
  "criteria": {
    "shipping": "配送の遅れや追跡",
    "returns": "返品、交換、注文と違う商品",
    "billing": "支払い、返金、請求書"
  }
}

日本語でも判定できるか

問い合わせ文5件を、次の3条件で送りました。

  • 問い合わせ文も質問も英語
  • 問い合わせ文は日本語、質問は英語
  • 問い合わせ文も質問も日本語

Clef と Clef-flash の30回すべてで、想定どおりの担当が選ばれました。 入力トークン数は165〜183で、言語による差はほとんどありませんでした。

ただし、「返品した商品の返金がまだ口座に入っていない」という問い合わせでは、条件によって確信度が変わりました。 Clef-flash に英語の問い合わせ文を送ったときは、billing の確率が 0.777 でした。 日本語の問い合わせ文を送ったときは、billing の確率が 0.917〜0.949 でした。 英語の文と日本語の文は私が別々に書いたので、ニュアンスが完全には一致していません。 差の原因が文の書き方なのか、モデルの性質なのかは切り分けていません。

使った問い合わせ文
#日本語英語想定
1青いマグを注文したのに、赤いマグが届きました。交換できますか。I ordered a blue mug, but a red one arrived. Can I exchange it?returns
2注文から10日たっても届きません。今どこにありますか。It’s been 10 days since I ordered and it still hasn’t arrived. Where is it?shipping
3同じ注文の代金が2回引き落とされています。I was charged twice for the same order.billing
4サイズが合わなかったので返品したいです。送料はかかりますか。The size didn’t fit, so I’d like to return it. Do I have to pay for shipping?returns
5返品した商品の返金がまだ口座に入っていません。I returned an item, but the refund hasn’t reached my account yet.billing

4と5は、2つの担当で迷うように作りました。

判定結果の全データ(Clef-flash)

条件の表記は「問い合わせ文の言語/質問の言語」です。

#条件選ばれた担当shippingreturnsbilling入力トークン
1英/英returns0.0010.9980.002173
1日/英returns0.0010.9970.002174
1日/日returns0.0030.9930.004183
2英/英shipping0.9930.0040.003177
2日/英shipping0.9960.0020.002172
2日/日shipping0.9950.0030.002181
3英/英billing0.0150.0430.942165
3日/英billing0.0130.0240.963167
3日/日billing0.0120.0240.964176
4英/英returns0.0020.9830.015178
4日/英returns0.0020.9770.021170
4日/日returns0.0030.9670.030179
5英/英billing0.0160.2070.777171
5日/英billing0.0090.0740.917166
5日/日billing0.0080.0430.949175
判定結果の全データ(Clef)

入力トークン数は Clef-flash と同じでした。

#条件選ばれた担当shippingreturnsbilling
1英/英returns0.0020.9970.002
1日/英returns0.0020.9960.002
1日/日returns0.0020.9950.003
2英/英shipping0.9930.0030.004
2日/英shipping0.9930.0030.004
2日/日shipping0.9920.0040.004
3英/英billing0.0040.0040.991
3日/英billing0.0050.0050.990
3日/日billing0.0050.0060.988
4英/英returns0.0040.9890.007
4日/英returns0.0030.9730.024
4日/日returns0.0040.9830.013
5英/英billing0.0060.0860.908
5日/英billing0.0040.0290.967
5日/日billing0.0040.0210.975

選択肢の順番で結果が変わるか

criteria に書く選択肢の順番を4通りに変えて送りました。 確率は、4回とも小数点以下4桁まで同じ値でした。

Hugging Face で公開されている推論コードでは、選択肢を option id の文字列順に並べ替えてからモデルに渡しています。 Workers AI でも同じ処理をしていると考えられます。 なお、時間を空けて同じ入力を送ったときも、小数点以下4桁の精度で同じ確率が返りました。

判定結果の全データ(Clef-flash)

問い合わせ文は、迷いやすい「I returned an item, but the refund hasn’t reached my account yet.」を使いました。

criteria の記述順billingreturnsshipping
shipping, returns, billing0.77720.20660.0162
shipping, returns, billing(2回目)0.77720.20660.0162
billing, returns, shipping0.77720.20660.0162
returns, billing, shipping0.77720.20660.0162

どの担当にも当てはまらない問い合わせ

「実店舗の営業時間」「求人への応募」「コーヒーの淹れ方」という、3つの担当のどれにも当てはまらない問い合わせを送りました。

問い合わせClef-flash: other なしClef-flash: other あり
実店舗の営業時間returns 0.454other 0.961
求人への応募billing 0.595other 0.989
コーヒーの淹れ方returns 0.415other 0.997

other という選択肢がない場合、Clef は既存の担当のどれかを返しました。 Clef は「該当なし」の選択肢を自動では用意しません。 other を選択肢に加えると、3件とも other に分類されました。 範囲内の問い合わせの判定は、other を加えてもほとんど変わりませんでした。

other がない場合、範囲外の問い合わせでは confidence が 0.02〜0.16 まで下がりました。 範囲内の問い合わせの confidence は 0.89 以上でした。 confidence にしきい値を設けても、範囲外を見分けられる可能性があります。

判定結果の全データ

問い合わせ文は日本語、質問は英語で送りました。 other の説明文は「Anything not covered by the options above」です。 範囲内の2件は、日本語の実験の1と3と同じ文です。

Clef-flash:

問い合わせother選ばれた担当billingotherreturnsshippingconfidence
違う色のマグが届いたなしreturns0.002-0.9970.0010.991
代金が2回引き落とされたなしbilling0.963-0.0240.0130.891
実店舗の営業時間を教えてください。なしreturns0.432-0.4540.1140.109
御社の求人に応募したいのですが、どこから申し込めますか。なしbilling0.595-0.2340.1720.156
コーヒーをおいしく淹れるコツはありますか。なしreturns0.327-0.4150.2580.019
違う色のマグが届いたありreturns0.0020.0020.9960.0010.989
代金が2回引き落とされたありbilling0.9390.0280.0210.0120.843
実店舗の営業時間を教えてください。ありother0.0210.9610.0120.0060.899
御社の求人に応募したいのですが、どこから申し込めますか。ありother0.0060.9890.0030.0020.971
コーヒーをおいしく淹れるコツはありますか。ありother0.0010.9970.0010.0010.991

Clef:

問い合わせother選ばれた担当billingotherreturnsshippingconfidence
違う色のマグが届いたなしreturns0.002-0.9960.0020.989
代金が2回引き落とされたなしbilling0.990-0.0050.0050.970
実店舗の営業時間を教えてください。なしbilling0.462-0.3350.2030.050
御社の求人に応募したいのですが、どこから申し込めますか。なしbilling0.546-0.3360.1170.138
コーヒーをおいしく淹れるコツはありますか。なしbilling0.459-0.2840.2570.036
違う色のマグが届いたありreturns0.0020.0030.9940.0020.983
代金が2回引き落とされたありbilling0.9740.0170.0040.0040.933
実店舗の営業時間を教えてください。ありother0.0050.9870.0040.0040.966
御社の求人に応募したいのですが、どこから申し込めますか。ありother0.0050.9890.0040.0030.970
コーヒーをおいしく淹れるコツはありますか。ありother0.0050.9860.0050.0040.963

1件の問い合わせに用件が複数ある場合

実際の問い合わせでは、1つのメッセージに複数の用件が書かれることがあります。 そこで、choice 1問で担当を選ばせる方法と、担当ごとに noul で「この担当への用件を含むか」を聞く方法を比べました。

表は noul の yes の確率です。

問い合わせClef-flashClef
違う色のマグが届いた+代金が2回引き落とされたreturns 0.923 / billing 0.756returns 0.961 / billing 0.952
注文が届かない+請求書の宛名を変えたいshipping 0.917 / billing 0.953shipping 0.972 / billing 0.963
1つ目が届かない+2つ目が割れていた+クーポンが適用されていないreturns 0.947 / billing 0.721 / shipping 0.181returns 0.965 / billing 0.674 / shipping 0.935

choice は確率の合計が1になるため、用件が2つあると確率が2つの担当に割れました。 片方の担当だけが選ばれる場合もありました。 noul は担当ごとに独立して確率を返すので、複数の用件を同時に判定できました。

ただし、用件が3つある問い合わせでは、Clef-flash が配送の用件を見落としました(0.181)。 Clef は同じ用件を 0.935 で判定しました。

判定結果の全データ

問い合わせ文は日本語、質問は英語です。 choice 1問と noul 3問を、1回のリクエストにまとめて送りました。 noul の質問文は「Does this message contain a request for the {担当} team ({担当の説明})?」です。

#問い合わせ文想定
1青いマグを注文したのに、赤いマグが届きました。交換できますか。returns
2青いマグを注文したのに、赤いマグが届きました。しかも代金が2回引き落とされています。returns + billing
3注文から10日たっても届きません。それと、請求書の宛名を会社名に変えてもらえますか。shipping + billing
41つ目の荷物はまだ届いていません。2つ目は割れていたので返品したいです。あと、クーポンが適用されていない気がします。shipping + returns + billing

Clef-flash:

#choice: billingchoice: returnschoice: shippingnoul: billingnoul: returnsnoul: shipping
10.0030.9950.0020.0070.9610.055
20.0720.9190.0090.7560.9230.043
30.4660.0500.4840.9530.0090.917
40.2900.6770.0330.7210.9470.181

Clef:

#choice: billingchoice: returnschoice: shippingnoul: billingnoul: returnsnoul: shipping
10.0020.9970.0010.0030.9890.006
20.1110.8790.0090.9520.9610.009
30.1960.0180.7860.9630.0070.972
40.1540.7170.1290.6740.9650.935

画像

マグカップのイラストを6枚作り、届いた商品の状態を判定させました。 問い合わせ文は「青いマグカップを注文しました。届いた商品の写真を添付します。」です。 手ぶれ風の画像は、ぼかし、二重写り、傾き、暗さ、ノイズを加えて作りました。

画像想定Clef-flashClef
青・きれい注文どおり注文どおり 0.899注文どおり 0.951
青・手ぶれ注文どおり注文どおり 0.897注文どおり 0.933
赤・きれい違う色違う色 0.974違う色 0.989
赤・手ぶれ違う色違う色 0.972違う色 0.989
割れ・きれい破損注文どおり 0.873破損 0.971
割れ・手ぶれ破損注文どおり 0.795破損 0.486(注文どおり 0.460)

色の違いは、手ぶれがあっても両方のモデルで判定できました。 小さなひびや欠けは、Clef-flash がきれいな画像でも見落としました。 Clef も、手ぶれ風の画像では「破損」と「注文どおり」の確率がほぼ半々になりました。

使った画像は写真ではなくイラストで、手ぶれの強さも1段階だけです。 画像の判定精度については、画像を専門に扱う人の検証を参考にしてください。

判定結果の全データ

画像は 512×512 ピクセルの PNG です。 入力トークン数は、どの画像でも 456 でした。

使った質問です。

{
  "type": "choice",
  "instructions": "Based on the photo, what is the condition of the delivered item compared with the order?",
  "criteria": {
    "as_ordered": "The item matches the order and is undamaged",
    "wrong_item": "A different item or a different color than ordered arrived",
    "damaged": "The item is broken, cracked, or damaged"
  }
}

Clef-flash:

画像選ばれた状態as_ordereddamagedwrong_itemconfidence
青・きれいas_ordered0.8990.0280.0730.722
青・手ぶれas_ordered0.8970.0540.0490.714
赤・きれいwrong_item0.0130.0130.9740.923
赤・手ぶれwrong_item0.0140.0140.9720.919
割れ・きれいas_ordered0.8730.0330.0950.658
割れ・手ぶれas_ordered0.7950.1350.0700.483

Clef:

画像選ばれた状態as_ordereddamagedwrong_itemconfidence
青・きれいas_ordered0.9510.0220.0270.859
青・手ぶれas_ordered0.9330.0330.0340.808
赤・きれいwrong_item0.0060.0050.9890.967
赤・手ぶれwrong_item0.0050.0050.9890.968
割れ・きれいdamaged0.0210.9710.0080.914
割れ・手ぶれdamaged0.4600.4860.0540.176

Clef と Clef-flash の速さ

日本語の実験で送った15回の往復時間の中央値は、Clef-flash が166ミリ秒、Clef が406ミリ秒でした。 この往復時間には、日本から Cloudflare のサーバーまでの通信時間が含まれています。 2つのモデルの差は約240ミリ秒で、公式の中央値の差(約170ミリ秒)に近い値でした。

往復時間の全データ(ミリ秒)

日本語の実験の15回を、送った順に並べています。

#条件Clef-flashClef
1英/英688664
1日/英542415
1日/日166528
2英/英143517
2日/英128454
2日/日125397
3英/英177815
3日/英166499
3日/日327380
4英/英541375
4日/英141240
4日/日137373
5英/英134290
5日/英144316
5日/日558406

良かった点

  • 単純な振り分けであれば、Clef-flash でも短い時間で高い確率の判定が返りました。
  • 確率が数値で返るので、しきい値を呼び出し側で決められます。
  • 日本語の問い合わせ文でも、英語と同じ程度に判定できました。日本語にしても入力トークン数はほぼ増えませんでした。
  • 1回のリクエストに複数の質問を入れられます。noul を担当の数だけ並べれば、複数の用件を1回で判定できます。
  • 推論コードが Hugging Face で公開されています。ドキュメントに書かれていない入力の並び順や、長い入力の削り方を、コードを読んで確認できました。長い入力を実際に送って確かめる実験をしなくて済んだので、とても助かりました。

気になった点

Clef を使う場合、モデルの精度と同じくらい、利用者側の設計が結果を左右します。 私は Jev を試したときにも同じ印象を持ちました。 判定系のモデルに共通する性質だと考えています。

設計で検討が必要な点は次の4つです。

  • 範囲外の入力: Clef は必ず選択肢のどれかを返します。other を自分で選択肢に加えるか、confidence にしきい値を設ける必要があります。
  • 用件が複数ある入力: choice は1つしか選べません。複数の用件がありうる場合は、担当ごとの noul を使います。用件が多い場合、Clef-flash は見落とすことがありました。
  • 長い入力: 公開されている推論コードでは、入力が上限を超えると state の末尾が削られます。会話ログを古い順に入れると、上限を超えたときに直近の発言が消えます。Workers AI で同じ動きをするかは確認していません。
  • Clef と Clef-flash の使い分け: 今回の範囲では、単純な分類は Clef-flash で十分でした。複数の用件や画像の細部を判定する場合は、Clef のほうが見落としが少なくなりました。使い分けの基準は、自分のデータで確かめる必要があります。

実際に導入する場合は、次の手順が必要になると思います。

  1. 実際の問い合わせに近いデータに正解の担当を付けて、モデルの判定と比べます。用件が複数ある場合は、担当ごとの見落としの件数も数えます。
  2. 運用を始めたあとは、担当者が振り分けを手で直した記録を集めます。その記録をもとに、選択肢の説明文やしきい値を見直します。

実装で注意する点

実験スクリプトは Claude Code に書いてもらいました。 この章は、Claude Code が実装中に引っかかった点と、仕様や推論コードを読んで注意した点をまとめたものです。 Clef を呼び出すコードを書くとき(AI に書かせるときも含む)の参考にしてください。

仕様の不明点は公開されている推論コードで確かめる

入力の並び順や、長い入力をどちらから削るかは、ブログにも model card にも書かれていませんでした。 Hugging Face のリポジトリには、推論コード(joint_schema_model.py)が公開されています。 Claude Code がこのコードを読んだ結果、次のことがわかりました。

  • モデルへの入力は、system prompt、画像、state、質問と選択肢の順に並ぶ
  • 入力が上限を超えると、state の末尾が削られる
  • choice の選択肢は id の文字列順に並べ替えられる

選択肢が並べ替えられることがコードでわかっていたので、「選択肢の順番で結果が変わるか」の実験は、Workers AI でも同じかを確かめる1回だけで済みました。 以下の項目のうち、推論コードを根拠にしているものは、その旨を書いています。

Workers AI と model card で仕様が違う

Hugging Face の model card と Workers AI の入力スキーマでは、仕様が一部違います。 Clef は発表されたばかりで、AI の学習データには仕様が含まれていません。 コードを書く前に、Workers AI の入力スキーマ(schema-input.json)を読む必要があります。

項目model cardWorkers AI
instructions省略可質問ごとに必須
画像の渡し方PIL 画像base64 のみ(URL 不可)
動画対応項目なし
入力長の上限max_length の既定値 16,38465,536 トークン

URL でモデルを指定していても、リクエストの本文に "model": "clef-flash" が必要です。

画像は PNG / JPEG / WebP だけ

画像は、{ "content_type": "image/png", "base64": "..." } の形か、data:image/png;base64,... の形で渡します。 SVG は受け付けられません。 今回は SVG でイラストを作ったので、ヘッドレスモードの Chrome でスクリーンショットを撮り、PNG に変換してから送りました。

選択肢の id もモデルへの入力になる

推論コードでは、choice の選択肢は {"description":"...","option_id":"returns"} という JSON の文字列としてモデルに渡されます。 つまり、選択肢の id の文字列も、説明文と一緒にモデルが読みます。 id を a / b / c のような意味のない文字列にするより、returns のように意味のある英単語にするほうが安全だと考えられます。 この点は推論コードから読み取ったもので、id を変えて結果を比べる実験はしていません。

選択肢は id の文字列順に並べ替えられてからモデルに渡されます。 criteria に書いた順番は結果に影響しません。

state にオブジェクトを渡すとキーが並べ替えられる

state には文字列のほか、オブジェクトや配列も渡せます。 推論コードでは、オブジェクトは json.dumps(sort_keys=True, ensure_ascii=False) で文字列に変換されます。 キーはアルファベット順に並べ替えられるので、キーの順番に意味を持たせることはできません。 ensure_ascii=False なので、日本語は \u 形式にエスケープされず、そのままの文字で入力されます。

state は末尾から削られる

推論コードでは、入力が上限を超えると、state の末尾が削られます。 質問と選択肢は削られず、質問と選択肢だけで上限を超える場合はエラーになります。 会話ログを state に入れるときは、新しい発言を先頭に置くか、長さを事前に切り詰める必要があります。 Workers AI で同じ動きをするかは確認していません。

同じリクエストの質問は互いに影響しうる

推論コードの system prompt には「すべての項目を合わせて判断する(Decide every field jointly)」と書かれています。 1回のリクエストに複数の質問を入れると、質問同士の判定が影響し合う可能性があります。 質問ごとの精度を正確に比べたい場合は、質問を別々のリクエストに分けて送るほうが確実です。

レスポンスの値の扱い

  • 確率は小数点以下4桁に丸められて返ります。
  • usage.output_tokens は、レスポンスを確認した32回のリクエストですべて0でした。
  • confidence の計算方法は公開されていません。確率が均等に近いほど低い値になりますが、最大の確率とは別の値です。しきい値に使う場合は、自分のデータで値の分布を確かめる必要があります。
  • choice は、どの選択肢にも当てはまらない入力でも、必ずどれかの選択肢を返します。

まとめ

Clef は、文章や画像を決めた選択肢に振り分ける用途で、短い時間で確率付きの判定を返すモデルでした。 日本語の問い合わせ文でも、今回の範囲では英語と同じ程度に判定できました。 一方で、範囲外の入力や複数の用件を正しく扱えるかは、選択肢と質問の設計で決まります。 導入を考える場合は、自分のデータで正解付きの評価をしてから判断するのがよいと考えています。

参考文献