Clef + Ollamaでローカル「判断AI」を動かす完全ガイド|文章を生成しない決定モデルの仕組みと活用例

2026年10月1日、Cloudflareが初の自社学習モデル「Clef(クレフ)」を公開しました。Qwen3.8-27Bをベースにした27Bのオープンウェイトモデルで、ライセンスはApache 2.0、Ollamaからもすぐに使えます。

ただしClefは、ChatGPTやQwenのような「チャットAI」ではありません。文章を1文字も生成せず、「状態(state)」と「型付きの質問(questions)」を受け取って答えを確率で返す、決定モデル(Decision Model)です。そのためollama run clefで会話することはできず、使い方も一般的なLLMとはまったく異なります。

この記事では、Clefの特殊性を解説したうえで、Ollamaを使ったローカルPCへの構築手順とAPIの使い方を紹介する。日本語のチケットやレシート画像、ツール呼び出しによる検証結果と、具体的な活用例も取り上げる。


  1. Clefの概要
  2. Clefは何が「特殊」なのか|生成ではなく「判断」するAI
    1. チャットAI(LLM)との違い
    2. 「System Oneモデル」というカテゴリ
    3. 1回の順伝播で全選択肢を同時に採点する仕組み
    4. 3種類の質問タイプ
    5. confidenceは「正解率」ではない
    6. Clefにできないこと
  3. Clefの主な用途と活用例
    1. 公式が挙げる4つの用途
    2. 活用例1 問い合わせチケットの自動振り分け
    3. 活用例2 AIエージェントのガードレール(ツール呼び出しの事前チェック)
    4. 活用例3 レシート・経費精算の一次チェック(画像)
    5. 活用例4 申込書・フォームの記入漏れチェック(画像)
    6. 活用例5 レビュー・アンケートの感情スコアリング
    7. 活用例6 フィッシングメール・不審メッセージの判定
    8. 活用例7 LLMのモデルルーティング
    9. その他の活用例
    10. LLMと組み合わせる設計パターン
  4. ベンチマーク結果
  5. ClefとClef-flashの違い
  6. 必要なハードウェア
  7. Ollamaのインストール方法
    1. macOS
      1. バージョンの確認方法
    2. Windows
      1. バージョンの確認方法
    3. Linux
    4. 古いバージョンのOllamaを使っている場合
  8. Clefのインストールと起動
    1. モデルのダウンロード(ollama pull)
    2. モデル情報の確認(ollama show)
    3. ollama runでは使えない点に注意
    4. モデル一覧の確認
    5. モデルの削除
  9. APIの使い方(/v1/systemone)
    1. リクエストの項目
    2. レスポンスの構造
    3. cURLで試す(macOS / Linux)
    4. Windows(PowerShell)で試す
    5. Pythonから使う(requests)
    6. Pythonから使う(ollamaライブラリ)
    7. Pythonから使う(TypeSafe SDK)
    8. JavaScript(Node.js)から使う
    9. 画像を送る
  10. 実際に試してみた(検証結果)
    1. 検証1 問い合わせチケットの振り分け(日本語)
    2. 検証2 レビューの満足度スコア
    3. 検証3 レシート画像の判定
    4. 検証4 申込書の記入漏れチェック
    5. 検証5 AIエージェントのツール呼び出しチェック
    6. 検証6 フィッシングメールの判定
    7. 検証7 モデルルーティング
  11. 参考リンク

Clefの概要

項目内容
開発元Cloudflare
公開日2026年10月1日
ベースモデルQwen3.8-27B(バックボーンは凍結し、LoRAと判定用ヘッドを追加学習)
パラメータ数27B(+画像用プロジェクタ 約4.6億)
モデルの種類決定モデル(System Oneモデル)
入力テキスト、JSON、画像(PNG / JPEG / WebP)
出力文章ではなく、型付きの答えと確率(choice / noul / score)
判定に使えるコンテキスト64K(TypeSafe「Jev」の32Kの2倍)
1リクエストの質問数1〜64問
ライセンスApache 2.0
提供形態オープンウェイト(Ollama、Hugging Face)/Cloudflare Workers AI(ホスト版)
Ollamaの必要バージョン0.35.1以降
兄弟モデルClef-flash(9B / Qwen3.5-9Bベース、高速版)

Ollamaのモデルページでは256K context windowと表示されているが、これはベースのQwen3.8の値である。Clefが判定用に想定しているstateの長さは64Kであり、Ollamaで読み込んだ際のデフォルトのnum_ctxは16,384になっている。


Clefは何が「特殊」なのか|生成ではなく「判断」するAI

チャットAI(LLM)との違い

一般的なLLM(Qwen3.8など)Clef(決定モデル)
出力自由な文章型の決まった答え+確率
生成方法1トークンずつ順に生成(自己回帰)1回の順伝播ですべての選択肢を同時に採点(非自己回帰)
出力形式の保証プロンプト次第。JSONの形式がおかしくなることもあるスキーマ通りの答えしか返らない
確信度基本的になし(自己申告は当てにならない)選択肢ごとの確率分布が返る
速度出力が長いほど遅い出力トークンがほぼ0なので、入力の長さだけで決まる
得意なこと文章作成、要約、推論、コード生成分類、Yes/No判定、採点、振り分け、ゲート判定
できないこと特になし文章の生成、値の抽出、理由の説明、会話

LLMに「このチケットはbilling / technical / otherのどれ?」と聞くと、多くの場合は"billing"という文字列が返ってきます。しかし返ってくるのは文字列だけなので、表記ゆれや余計な説明が混ざることがあり、どの程度自信があるのかもわかりません。

Clefに同じことを聞くと、次のように選択肢ごとの確率が必ず決まった形で返ってきます。

"team": {
  "type": "choice",
  "choice": "billing",
  "probabilities": {"billing": 0.981, "technical": 0.013, "other": 0.006},
  "confidence": 0.924
}

プログラム側で文字列をパースする必要はなく、「billingの確率が0.9以上なら自動で振り分け、それ未満なら人間が確認」といったしきい値による制御をそのまま書けます。

「System Oneモデル」というカテゴリ

Clefは「System Oneモデル」と呼ばれる新しいカテゴリのモデルです。この名前は、ダニエル・カーネマンの『ファスト&スロー』に出てくる2つの思考システムに由来します。

システム1は「これは請求の問い合わせだな」のような速く直感的な判断を、システム2は「この契約の問題点を整理して説明する」のような遅く熟考を伴う推論を指します。

LLMの思考モードがシステム2だとすれば、Clefはシステム1にあたります。じっくり考えて文章を書くのではなく、決められた選択肢の中から即座に判断を下します。

このカテゴリはTypeSafe AIが2026年9月に公開したクローズドモデル「Jev」によって提唱されたもので、APIの仕様(/v1/systemoneエンドポイント)もJevに由来します。ClefはJevのAPIと完全互換ですが、オープンウェイトで手元のPCでも動かせる点がJevと大きく違います。さらにJevはテキストのみでコンテキストも32Kですが、Clefは画像入力に対応し、コンテキストは64Kあります。

Ollamaでも0.35から「Decision」という新しい機能カテゴリが追加され、現在は次の4つの決定モデルが公開されています。

モデル開発元サイズ画像入力必要なOllama
tev1Together AI0.8B / 4B×0.35.0以降
nimbleBespoke Labs9B×0.35.0以降
clef-flashCloudflare9B○0.35.1以降
clefCloudflare27B○0.35.1以降

この中でClefは最も大きく、画像も扱える「精度重視」のモデルという位置づけです。

1回の順伝播で全選択肢を同時に採点する仕組み

Cloudflareの発表によると、Clefは次のような構造になっています。

  1. ベースのQwen3.8-27B(重みは凍結)が、stateと質問を1回だけ読み込む(プレフィルのみ)
  2. 追加された小さな「スキーマヘッド」が、各質問に関係する情報を入力から拾い集める
  3. すべての質問の、すべての選択肢をまとめて同時に採点し、確率に変換する

学習ではランク256のLoRAアダプタとスキーマヘッドを同時に最適化し、損失関数にはラベル平滑化付きクロスエントロピーに加えて、Brierスコア(確率の当たり具合を測る指標)を使っています。さらにRLCD(Reinforcement Learning for Calibrated Decisions)という強化学習を補助的に用いて、確率が実際の正解率に近くなるように調整(キャリブレーション)されています。

今回の検証では、すべてのリクエストでレスポンスのoutput_tokensが0でした。Clefは文章を生成しないため、ハルシネーションで選択肢にない答えを返したり、JSONの形式がおかしくなったりすることが構造的に起きません。

3種類の質問タイプ

Clefへの質問は、次の3つの型のどれかで定義します。

型用途criteria(基準)返ってくる値
choice選択肢から1つ選ぶ選択肢名と説明のオブジェクト(2〜26個)。説明をnullにすると選択肢名がそのまま使われるchoice(最も確率の高い選択肢)、probabilities、confidence
noulYes / No判定省略可。{"true": "...", "false": "..."}で両側の意味を説明できるnoul(trueである確率。0〜1の数値)
score段階評価低い順に並べたレベルの説明の配列(2〜26段階)。0から番号が振られるscore(確率で重み付けした平均レベル)、legend、probabilities、confidence

noulはYesやNoの確率を返す型の名前です。返り値は真偽値ではなく0から1の数値なので、0.9以上をYesとするなど、しきい値を自分で決めます。

scoreの値は、各レベルの確率で重み付けした期待値です。たとえば「通常 / やや急ぎ / 緊急」の3段階ならscore = 0 × P(通常) + 1 × P(やや急ぎ) + 2 × P(緊急)となり、0.0〜2.0の小数で返ります。整数に丸められないため、「1.5以上なら優先対応」のような細かい制御ができます。

choiceの選択肢は最大26個です。同じ確率で並んだ場合は先に書いた選択肢が優先されるので、望ましい選択肢を先頭に置くのがコツです。

confidenceは「正解率」ではない

choiceとscoreにはconfidence(0〜1)が付きますが、これは確率分布がどれだけ1つの答えに集中しているかを示す値で、「答えが正しい確率」ではありません。

計算式は1 − H(p) / ln(N)(H(p)は確率分布のエントロピー、Nは選択肢の数)です。すべての選択肢が同じ確率なら0、1つの選択肢がほぼ100%なら1に近づきます。

たとえば公式の例では、緊急度のscoreが通常0.451、やや急ぎ0.353、緊急0.196と割れていて、confidenceは0.071と低くなっています。こうした判断が割れているケースを拾って人間に回すのが、confidenceの正しい使い方です。

Clefにできないこと

特殊なモデルなので、できないことも明確にしておきます。

  • 会話や文章の生成はできず、ollama run clefでチャットすることもできません
  • 値は抽出できません。レシートの「合計金額はいくら?」には答えられないため、「合計は3,000円を超えているか?」(noul)や「金額帯はどれか?」(choice)のように判断の形に言い換える必要があります
  • なぜその答えになったのか、理由の説明は返ってきません
  • 自由回答はできません。答えは必ず、こちらが用意した選択肢や段階の中から選ばれます
  • ストリーミング、ツール呼び出し、動画入力には対応していません
  • 1リクエスト内の質問はそれぞれ独立に判定されるため、前の質問の答えを次の質問に使うことはできません

Clefの主な用途と活用例

公式が挙げる4つの用途

やりたいことこちらが定義するもの返ってくるもの
リクエストの振り分け振り分け先と、それぞれの条件選ばれた振り分け先と、各振り分け先の確率
条件のチェックYes/Noの質問と、判断材料true / falseそれぞれの確率
ポリシーの適用ルールと、許可される結果テキストや画像にもとづく型付きの判定
書類の読み取りページの写真と、判定したい項目項目ごとの判定と確率

Cloudflare社内でも、Trust & Safety(不正利用の申告)の振り分け、サポートチケットのトリアージ、クローラーが良性か悪性かのボット判定などに使われているとのことです。

ここからは、日本の業務で使いやすい形にした活用例を紹介します。各例の実際の判定結果は、後半の「実際に試してみた」に載せています。

活用例1 問い合わせチケットの自動振り分け

もっとも典型的な使い方です。1回のリクエストで「担当チーム(choice)」「返金要求の有無(noul)」「緊急度(score)」をまとめて判定できます。

"questions": {
  "team": {
    "type": "choice",
    "instructions": "このチケットはどのチームが対応すべきですか?",
    "criteria": {
      "billing": "支払い・請求・返金",
      "technical": "障害・不具合・設定",
      "sales": "プラン・契約・見積もり",
      "other": "上記以外"
    }
  },
  "refund": {"type": "noul", "instructions": "顧客は明示的に返金を求めていますか?"},
  "urgency": {
    "type": "score",
    "instructions": "このチケットの緊急度は?",
    "criteria": ["通常:急ぎではない", "やや急ぎ:顧客が不便を感じている", "緊急:重要なサービスが使えない"]
  }
}

判定結果は、たとえば次のように使います。

  • teamの確率が0.9以上なら自動でキューに登録し、それ未満なら一次受付担当が確認する
  • urgencyのscoreが1.5以上ならSlackに即時通知する
  • refundが0.8以上なら返金ポリシーのテンプレートを担当者に提示する

LLMで同じことをする場合と比べると、出力形式が崩れる心配がなく、確率をそのまま業務ルールに組み込めるのが利点です。

活用例2 AIエージェントのガードレール(ツール呼び出しの事前チェック)

AIエージェントがメール送信やファイル削除などのツールを実行する直前に、その呼び出しが危険でないかをClefに判定させます。

{
  "model": "clef",
  "state": "send_email(to=\"all-customers\", subject=\"【最終通知】本日中にアカウントが停止されます\")",
  "questions": {
    "harm": {"type": "noul", "instructions": "このツール呼び出しは害を及ぼす可能性がありますか?"},
    "action": {
      "type": "choice",
      "instructions": "このツール呼び出しをどう扱うべきですか?",
      "criteria": {"allow": "そのまま実行してよい", "review": "人間の確認が必要", "block": "実行を止めるべき"}
    }
  }
}

エージェントのメインのLLMに「この操作は安全?」と聞き直すと、そのたびに数秒〜数十秒かかり、コストもかさみます。Clefは判定専用なので、GPU環境なら数百ミリ秒で「実行/確認/停止」を決められます。エージェントの各ステップにゲートを挟む用途に最適です。

活用例3 レシート・経費精算の一次チェック(画像)

Clefは画像も読めます。レシートの写真を送り、経費精算のルールに沿っているかを判定させます。

"questions": {
  "total_legible": {"type": "noul", "instructions": "合計金額は読み取れますか?"},
  "category": {
    "type": "choice",
    "instructions": "これは何の購入ですか?",
    "criteria": {"meals": "飲食・食事", "travel": "交通・宿泊", "office": "事務用品", "other": null}
  },
  "has_invoice_number": {"type": "noul", "instructions": "インボイス(適格請求書)の登録番号が記載されていますか?"},
  "over_3000": {"type": "noul", "instructions": "合計金額は3,000円を超えていますか?"}
}

前述のとおりClefは金額を読み取って返せませんが、インボイス番号の有無、上限額の超過、勘定科目の判断はできます。OCRやLLMで値を抽出する処理の前段に置き、問題のないものは自動承認し、怪しいものだけ人が確認する振り分けに活用します。

活用例4 申込書・フォームの記入漏れチェック(画像)

申込書のスキャン画像やスクリーンショットを送り、必須項目の記入漏れを判定します。AIエージェントがWebフォームを送信する前に、画面のスクリーンショットで「必須項目がすべて埋まっているか」を確認するゲートとしても使えます。

"questions": {
  "complete": {"type": "noul", "instructions": "※必須の項目はすべて記入されていますか?"},
  "doc_type": {
    "type": "choice",
    "instructions": "これは何の書類ですか?",
    "criteria": {"application": "申込書", "invoice": "請求書", "receipt": "領収書", "contract": "契約書"}
  }
}

活用例5 レビュー・アンケートの感情スコアリング

ECサイトのレビューやアンケートの自由記述を、5段階の満足度で採点する。scoreは小数で返るため、星4だが星3に近いといった微妙なニュアンスも数値で扱う。複数の観点をまとめて質問すれば、1回のリクエストで多面的に分析できる。

"questions": {
  "sentiment": {
    "type": "score",
    "instructions": "このレビューの満足度を評価してください。",
    "criteria": ["非常に不満", "不満", "普通", "満足", "非常に満足"]
  },
  "mentions_shipping": {"type": "noul", "instructions": "配送・梱包について言及していますか?"}
}

活用例6 フィッシングメール・不審メッセージの判定

stateには文字列だけでなくJSONも渡せるので、メールの差出人・件名・本文を構造化したまま判定できます。

{
  "model": "clef",
  "state": {
    "from": "[email protected]",
    "subject": "【重要】お客様のアカウントが一時停止されました",
    "body": "24時間以内に以下のURLから本人確認を行わない場合、アカウントは永久に削除されます。http://amaz0n-verify.example/login"
  },
  "questions": {
    "phishing": {"type": "noul", "instructions": "このメールはフィッシング詐欺ですか?"},
    "risk": {"type": "score", "instructions": "このメールのリスクレベルは?", "criteria": ["安全", "要注意", "危険"]}
  }
}

公式ベンチマークでも、フィッシング判定(PhishNChips)でJevの62.5に対してClefは79.6と大きく上回っています。

活用例7 LLMのモデルルーティング

ユーザーのプロンプトを見て、「軽量モデルで十分か、大型モデルが必要か」を振り分けます。簡単な質問を小さなモデルに回すことで、全体のコストと待ち時間を下げられます。

"questions": {
  "model": {
    "type": "choice",
    "instructions": "このプロンプトにはどのモデルで回答すべきですか?",
    "criteria": {
      "small": "軽量モデル(雑談・短い質問・簡単な変換)",
      "large": "大型モデル(設計・高度な推論・長いコード)"
    }
  }
}

その他の活用例

用途使い方
大量データのラベリング機械学習用データセットのアノテーションを確率付きで一次処理し、確率の低いものだけ人がラベルを付ける
LLM出力の検証別のLLMが生成した回答が「質問に答えているか」「社内規定に違反していないか」を判定する
コンテンツモデレーション投稿内容や画像が利用規約に違反していないかを判定する
ボット・不正アクセスの判定アクセスログをstateに入れ、正常なクローラーか悪性のボットかを分類する
セキュリティアラートのトリアージアラート内容から重大度(score)と対応チーム(choice)を決める

LLMと組み合わせる設計パターン

ClefはLLMの前後に置き、高速な判断レイヤーとして使います。

[1] ユーザー入力 / エージェントの行動
      ↓
[2] Clef で判断(振り分け・安全確認・条件チェック = 確率つき)
      ├─ 確率が高い → 自動処理、または適切な LLM・担当者へルーティング
      └─ 確率が低い → 人間が確認(Human-in-the-loop)
      ↓
[3] LLM で生成・推論(返信文の作成、要約、コード生成など)

「考えて書く」のはLLM、「速く決める」のはClefと役割を分けると、エージェント全体の速度・コスト・安全性をバランスよく改善できます。


ベンチマーク結果

Ollamaのモデルページに掲載されている、Clef・Clef-flash・Jevの比較です。

ベンチマーク内容ClefClef-flashJev
BFCL(case exact accuracy)関数呼び出しの判定98.598.895.8
API-Bank(accuracy)API呼び出しの判定91.993.188.2
BANKING77(macro-F1)銀行問い合わせの意図分類(77クラス)94.290.979.7
CLINC150+OOS(macro-F1)意図分類+対象外の検出97.466.889.3
Home appliance simulator家電操作コマンドの判定83.097.752.3
ANLI(macro-F1)自然言語推論69.859.174.8
RouterBench(selected quality)モデルルーティング79.779.979.9
PhishNChips(accuracy)フィッシング判定79.675.062.5
レイテンシ中央値(ms)209.338.8524.1
レイテンシp95(ms)238.6122.4536.0

業務ワークフロー(Typesafe Evals)での判定精度は次のとおりです。

ワークフローClefClef-flashJev
請求書処理64.757.161.8
カスタマーサービス76.377.076.0
セキュリティインシデント62.961.761.7
エージェントトレースの監視68.569.871.6

意図分類(BANKING77 / CLINC150)ではClefが非常に強く、特に「どれにも当てはまらない」入力の検出を含むCLINC150+OOSでは、Clef-flash(66.8)と大きな差があります。一方で、関数呼び出しや家電操作の判定では、小さなClef-flashの方が高いスコアを出しています。自然言語推論(ANLI)やエージェントトレースの監視ではJevが上回っており、Clefが万能というわけではありません。

レイテンシはGPU環境での値で、ClefはJevの約2.5倍、Clef-flashは約13倍速い結果です。


ClefとClef-flashの違い

ClefClef-flash
パラメータ数27B9B
ベースモデルQwen3.8-27BQwen3.5-9B
Ollamaのサイズ(latest)18GB(Q4_K_M)11GB(Q8_0)
レイテンシ中央値209.3ms38.8ms
向いている用途精度重視の判定、選択肢が多い分類、対象外の検出リアルタイム性重視のゲート判定、ツール呼び出しのチェック
画像入力対応対応

迷ったら、まずClefで精度を確認し、速度が足りなければClef-flashを試す順番がおすすめです。どちらもAPIは同じなので、modelの値を変えるだけで切り替えられます。


必要なハードウェア

Ollamaで公開されているClefのタグは次のとおりです。

タグ形式サイズ備考
clef:latest / clef:27b / clef:27b-q4_k_mGGUF(Q4_K_M)18GB標準。迷ったらこれ
clef:27b-q8_0GGUF(Q8_0)30GB精度重視
clef:27b-nvfp4MLX18GBApple Silicon向け
clef:27b-mxfp8MLX31GBApple Silicon向け
clef:27b-mlx-bf16MLX55GBApple Silicon向け
構成目安
GPUで快適に動かすVRAM 24GB以上(RTX 3090 / 4090 / 5090など)。VRAM 32GB以上あると余裕があります
Mac(Apple Silicon)ユニファイドメモリ32GB以上
CPUのみで動かすメインメモリ32GB以上(検証では約22GB使用)。動きますが遅いです
ストレージ空き20GB以上(Q4_K_Mの場合)

今回の検証環境(VRAM 8GBのRadeon RX 570)では、GPUに一部を載せようとして計算用バッファ(約6.6GB)を確保できず、起動に失敗しました。CPUで動かす対処法は後述します。CPUのみでの処理時間は「実際に試してみた」を参照してください。


Ollamaのインストール方法

Clefを使うにはOllama 0.35.1以降が必要です。すでにOllamaを使っている場合も、バージョンを確認してください。

macOS

必要なOSはmacOS 14 Sonoma以降です。

  1. https://ollama.com/download/macからDMGファイルをダウンロード
  2. DMGをマウントし、OllamaアプリをApplicationsフォルダにドラッグ&ドロップ
  3. アプリを起動するとメニューバーにアイコンが表示される

バージョンの確認方法

以下のコマンドを実行して、0.35.1以降のバージョンが表示されればOKです。

ollama --version

Windows

必要なOSはWindows 10以降です。

  1. https://ollama.com/downloadからEXEインストーラーをダウンロード
  2. ダウンロードした.exeファイルをダブルクリックして「Install」ボタンをクリック

バージョンの確認方法

PowerShellを開き、以下を実行します。

ollama --version
ollama version is 0.35.1

Linux

ターミナルで以下の1コマンドを実行するだけです。

curl -fsSL https://ollama.com/install.sh | sh
# サービスの状態確認
sudo systemctl status ollama

# サービスの手動起動
sudo systemctl start ollama

# インストール確認
ollama --version

古いバージョンのOllamaを使っている場合

Ollama 0.35.0未満では/v1/systemoneエンドポイント自体がなく、0.35.0でもClef(画像対応の決定モデル)は動きません。macOS / Windowsはアプリのアップデート通知から、または上記の手順でインストーラーを再実行して更新してください。Linuxはインストールコマンドを再実行すれば最新版に更新されます。


Clefのインストールと起動

モデルのダウンロード(ollama pull)

ollama pull clef

本体(約17GB)と画像用のプロジェクタ(約927MB)の2つがダウンロードされます。

高速版を使う場合は次のとおりです。

ollama pull clef-flash

モデル情報の確認(ollama show)

ollama show clef

Capabilitiesが completion (文章生成)ではなく decisionnだけになっているのが、Clefが決定モデルであることを表しています。

ollama runでは使えない点に注意

一般的なモデルと同じ感覚でollama runを実行すると、次のようにエラーになります。

ollama run clef "こんにちは"

チャット用の/api/chatやOpenAI互換APIに送っても、"clef" does not support chatというエラーが返ります。現時点ではOllamaのCLIが決定モデルに対応していないため、Clefは後述のAPI(/v1/systemone)から使います。

モデル一覧の確認

ollama list

モデルの削除

ollama rm clef

APIの使い方(/v1/systemone)

ClefはOllamaの/v1/systemoneエンドポイントから使います。判定してほしい内容をstateに、質問をquestionsに入れてPOSTするだけで、プロンプトはOllamaが組み立ててくれます。

リクエストの項目

項目必須説明
model○clef(またはclef-flash、自作の派生モデル名)
state○判定対象。文字列、またはJSONオブジェクト/配列
questions○名前付きの質問(1〜64問)。答えは同じ順番で返る
imagesBase64エンコードしたPNG / JPEG / WebPの配列。全質問で共有される。URLやdata URLは不可
keep_aliveリクエスト後にモデルをメモリに残す時間(例: "10m"、0で即アンロード、負の値で常駐)

リクエストサイズの上限は画像なしで64KiB、画像ありで32MiBで、超えると413エラーになります。入力が読み込み済みのコンテキストに収まらない場合もエラーになり、自動で切り詰められることはありません。レスポンスは1つのJSONで返り、ストリーミングには対応していません。また、クラウドモデルには対応しておらず、ローカルでのみ使えます。

レスポンスの構造

{
  "model": "clef",
  "answers": {
    "質問名": { "type": "choice", "choice": "...", "probabilities": {...}, "confidence": 0.9 },
    "質問名": { "type": "noul", "noul": 0.98 },
    "質問名": { "type": "score", "score": 1.4, "legend": {...}, "probabilities": {...}, "confidence": 0.5 }
  },
  "usage": { "input_tokens": 1204, "output_tokens": 3 }
}

usage.output_tokensは内部の採点処理で使われたトークン数で、返ってくるJSONの長さとは関係ありません。

cURLで試す(macOS / Linux)

まずは公式の最小例です。「Hello World」に挨拶が含まれるかを判定します。

curl http://localhost:11434/v1/systemone \
  -H "Content-Type: application/json" \
  -d '{
    "model": "clef",
    "state": "Hello World",
    "questions": {
      "says_hello": {
        "type": "noul",
        "instructions": "Does the state text contain a greeting?",
        "criteria": {
          "true": "The state text contains a greeting.",
          "false": "The state text does not contain a greeting."
        }
      }
    }
  }'
{"model":"clef","answers":{"says_hello":{"type":"noul","noul":0.9715005638338635}},"usage":{"input_tokens":143,"output_tokens":0}}

noulが0.97なので、「挨拶が含まれる」確率が97%という意味です。

Windows(PowerShell)で試す

Windows PowerShell 5.1ではcurlがInvoke-WebRequestの別名になっているうえ、JSON内のダブルクォートのエスケープが面倒です。そのため、JSONをファイルに保存してcurl.exeで送るのが確実です。

次の内容をrequest.jsonとしてUTF-8で保存します。

{
  "model": "clef",
  "state": "先月分の利用料が二重に引き落とされています。余分に支払った分を返金してください。",
  "questions": {
    "refund": {"type": "noul", "instructions": "顧客は明示的に返金を求めていますか?"}
  }
}
curl.exe http://localhost:11434/v1/systemone -H "Content-Type: application/json" -d "@request.json"

PowerShellの機能だけで送る場合はInvoke-RestMethodを使います。日本語を含む場合は、本文をUTF-8のバイト列にして送るのがポイントです。

$body = @{
    model     = "clef"
    state     = "1時間前から管理画面にログインできず、全店舗でPOSレジが止まっています。"
    questions = @{
        urgent = @{ type = "noul"; instructions = "このチケットは緊急ですか?" }
    }
} | ConvertTo-Json -Depth 5

$res = Invoke-RestMethod -Uri "http://localhost:11434/v1/systemone" -Method Post `
    -ContentType "application/json; charset=utf-8" `
    -Body ([System.Text.Encoding]::UTF8.GetBytes($body))

$res.answers.urgent.noul
0.9890536958877797

このコードを.ps1ファイルに保存して実行する場合は、UTF-8(BOM付き)で保存してください。Windows PowerShell 5.1はBOMなしのUTF-8ファイルを正しく読めず、日本語部分が文字化けして構文エラーになります。

Pythonから使う(requests)

Ollama専用のライブラリを使わない、もっとも汎用的な方法です。

import requests

res = requests.post(
    "http://localhost:11434/v1/systemone",
    json={
        "model": "clef",
        "state": {"ticket": "先月分の利用料が二重に引き落とされています。余分に支払った分を返金してください。"},
        "questions": {
            "team": {
                "type": "choice",
                "instructions": "このチケットはどのチームが対応すべきですか?",
                "criteria": {
                    "billing": "支払い・請求・返金",
                    "technical": "障害・不具合・設定",
                    "sales": "プラン・契約・見積もり",
                    "other": "上記以外",
                },
            },
            "refund": {"type": "noul", "instructions": "顧客は明示的に返金を求めていますか?"},
            "urgency": {
                "type": "score",
                "instructions": "このチケットの緊急度は?",
                "criteria": ["通常:急ぎではない", "やや急ぎ:顧客が不便を感じている", "緊急:重要なサービスが使えない"],
            },
        },
    },
    timeout=300,
)
answers = res.json()["answers"]

team = answers["team"]
if team["probabilities"][team["choice"]] >= 0.9:
    print(f"自動振り分け: {team['choice']}")
else:
    print("担当者が確認してください")

print("返金要求:", answers["refund"]["noul"] >= 0.8)
print("緊急度:", round(answers["urgency"]["score"], 2))

Pythonから使う(ollamaライブラリ)

Ollama公式のPythonライブラリにもsystemone()が用意されています。モデルページのREADMEには「決定モデルはPython / JavaScriptライブラリにまだ対応していない」とありますが、執筆時点(2026年10月)の最新版であるollama 0.6.3では動作することを確認しました。古いバージョンでは使えないので、更新してから試してください。

pip install -U ollama
import ollama

response = ollama.systemone(
    model="clef",
    state="Hello World",
    questions={
        "says_hello": {
            "type": "noul",
            "instructions": "Does the state text contain a greeting?",
        },
    },
)
print(response.answers["says_hello"].noul)  # 0.98...

Pythonから使う(TypeSafe SDK)

ClefはJevとAPI互換なので、TypeSafe AIの公式Python SDKの接続先をOllamaに向けるだけで使えます。SDKはAPIキーを要求しますが、Ollamaは無視するので任意の値で構いません。

pip install typesafe-sdk
# macOS / Linux
export TYPESAFE_BASE_URL=http://localhost:11434
export TYPESAFE_API_KEY=ollama
export TYPESAFE_DEFAULT_MODEL=clef
# Windows(PowerShell)
$env:TYPESAFE_BASE_URL = "http://localhost:11434"
$env:TYPESAFE_API_KEY = "ollama"
$env:TYPESAFE_DEFAULT_MODEL = "clef"
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient

questions = {
    "team": Choice(
        instructions="このチケットはどのチームが対応すべきですか?",
        criteria={"billing": "支払い・請求・返金", "technical": "障害・不具合・設定", "other": "上記以外"},
    ),
    "refund": Noul(instructions="顧客は明示的に返金を求めていますか?"),
    "urgency": Score(instructions="このチケットの緊急度は?", criteria=["通常", "やや急ぎ", "緊急"]),
}

with TypeSafeClient(timeout=120) as client:
    result = client.system_one(
        state={"ticket": "二重に請求されています。余分な支払いを返金してください。"},
        questions=questions,
    )

print(result.choices["team"].choice)   # billing
print(result.nouls["refund"].noul)     # 返金要求の確率
print(result.scores["urgency"].score)  # 緊急度(0〜2)

検証環境での出力は次のとおりです(SDK 0.7.2)。

billing
0.9881238296838182
0.9705049446446288

CPUのみで動かす場合は1リクエストに数十秒かかるため、TypeSafeClient(timeout=600)のようにタイムアウトを長めにしてください。

型付きのChoice / Noul / Scoreクラスで質問を書けるのでエディタの補完が使え、将来Jev(クラウド)とClef(ローカル)を切り替える場合も接続先を変えるだけで済みます。

JavaScript(Node.js)から使う

Node.js 18以降なら、標準のfetchでそのまま呼び出せます。

const res = await fetch("http://localhost:11434/v1/systemone", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    model: "clef",
    state: "Hello World",
    questions: {
      says_hello: { type: "noul", instructions: "Does the state text contain a greeting?" },
    },
  }),
});
const data = await res.json();
console.log(data.answers.says_hello.noul);

画像を送る

画像はBase64エンコードした文字列をimages配列に入れます。URLやdata:image/png;base64,...形式では送れません。画像を送る場合もstateは必須で、判定の文脈を書いておきます。

import base64
import requests

with open("receipt.png", "rb") as f:
    img = base64.b64encode(f.read()).decode()

res = requests.post(
    "http://localhost:11434/v1/systemone",
    json={
        "model": "clef",
        "state": "添付のレシート画像を経費精算の観点で判定してください。",
        "images": [img],
        "questions": {
            "total_legible": {"type": "noul", "instructions": "合計金額は読み取れますか?"},
            "category": {
                "type": "choice",
                "instructions": "これは何の購入ですか?",
                "criteria": {"meals": "飲食・食事", "travel": "交通・宿泊", "office": "事務用品", "other": None},
            },
            "has_invoice_number": {"type": "noul", "instructions": "インボイス(適格請求書)の登録番号が記載されていますか?"},
        },
    },
    timeout=600,
)
print(res.json()["answers"])

実際に試してみた(検証結果)

ここからは、実際にClefをローカルで動かして判定させた結果です。前半の活用例で紹介した質問をそのまま使っています。

項目内容
OSWindows 10 Pro
CPUAMD Ryzen 5 3600(6コア)
メモリ96GB
Ollama0.35.1
モデルclef(Q4_K_M)

検証1 問い合わせチケットの振り分け(日本語)

team(choice)・refund(noul)・urgency(score、0=通常 / 1=やや急ぎ / 2=緊急)の3問を同時に判定しました。

チケット本文teamrefundurgency
先月分の利用料が二重に引き落とされています。余分に支払った分を返金してください。billing(0.986)0.9870.865(やや急ぎ83.4%)
1時間前から管理画面にログインできず、全店舗でPOSレジが止まっています。至急対応お願いします!technical(0.940)0.0081.926(緊急94.2%)
来年度から50アカウントに増やしたいので、法人プランの見積もりをいただけますか。sales(0.974)0.0070.058(通常95.1%)

質問文も選択肢の説明も日本語で書きましたが、3件とも期待どおりに判定されました。「返金してください」と書かれたチケットだけrefundが0.987と高く、それ以外は0.01未満と、はっきり分かれています。

検証2 レビューの満足度スコア

sentiment(score、0=非常に不満 〜4=非常に満足)とmentions_shipping(noul)を判定しました。

レビュー本文sentimentconfidence配送への言及
音質も装着感も最高。毎日の通勤が楽しみになりました。3.840(非常に満足89.6%)0.7360.012
商品自体は普通。ただ箱が潰れて届いたのは残念。1.522(不満45.7% / 普通43.1%)0.3300.976
3日で壊れた。サポートにも繋がらないし二度と買わない。0.127(非常に不満91.5%)0.7790.011

2件目は「商品は普通、でも配送は不満」という評価が入り交じったレビューで、「不満」と「普通」に確率が割れ、confidenceも0.330と低くなりました。こうした判断が割れたものだけを人間が確認する運用を、そのまま実現できることがわかります。配送への言及も正しく検出できています。

検証3 レシート画像の判定

次のレシート画像(合計2,673円、インボイス登録番号あり)を送りました。

質問結果
合計金額は読み取れますか?(noul)0.984
これは何の購入ですか?(choice)meals(飲食)0.978
インボイスの登録番号が記載されていますか?(noul)0.981
合計金額は3,000円を超えていますか?(noul)0.019

すべて正解です。特に「3,000円を超えているか」には、合計2,673円を正しく読み取ったうえで0.019(=超えていない)と答えています。金額そのものは返せなくても、判断の形にすれば画像の中の数値も扱えることがわかります。

検証4 申込書の記入漏れチェック

「電話番号(必須)」だけが空欄の申込書と、すべて記入済みの申込書の2枚で比較しました。

画像必須項目はすべて記入済み?(noul)書類の種類(choice)
電話番号が空欄0.011application(申込書)0.933
すべて記入済み0.982application(申込書)0.942

空欄が1か所あるだけで判定がはっきり逆転しており、フォーム送信前のチェックとして十分に使える精度です。

検証5 AIエージェントのツール呼び出しチェック

ツール呼び出しharm(noul)action(choice)
send_email(to="all-customers", subject="【最終通知】本日中にアカウントが停止されます", ...)0.987block 0.982
read_file(path="docs/README.md")0.015allow 0.954
run_shell(command="rm -rf / --no-preserve-root")0.988block 0.988

全顧客への脅し文句のようなメール送信とシステムを破壊するコマンドは「block」、READMEを読むだけの操作は「allow」と、妥当な判定になりました。

検証6 フィッシングメールの判定

差出人が[email protected]、件名が「【重要】お客様のアカウントが一時停止されました」のメールをJSONで渡しました。結果はphishingが0.991、riskが1.963(危険97.3%)でした。

検証7 モデルルーティング

プロンプト判定
「ありがとう」を英語にしてsmall 0.994
決済台帳向けにシャーディングされたデータベーススキーマを設計し、整合性の担保方法も説明してlarge 0.993


参考リンク

コメント

タイトルとURLをコピーしました