やさしい解説

Jev って、なに?

文章を書かない、おそろしく速い「判定係」です。
「当てはまる?」「どのくらい?」にだけ、数字で答えてくれます。

1. たとえ話:先生と採点係

プログラム(コード)が先生、Jev が採点係だと思ってください。

先生(コード)

  • 段取りを決める
  • データを用意する
  • 最後に集計して、順位をつける
  • 実際に何かを実行する

採点係(Jev)

  • 1問ごとに「どのくらい?」だけ答える
  • 答えは「92%」のような数字
  • 作文はしない・説明もしない
  • たくさんの問題を、いっせいに採点する

だから、ふつうのコードが苦手な「言葉の意味を読み取る」部分だけを Jev に任せて、残りはこれまでどおりコードで書けます。

2. 状況(state):審査員に見せる資料

Jev に質問するときは、判断の材料もいっしょに渡します。これを状況(state)と呼びます。審査員の前に、判定に必要な資料を並べるイメージです。

こんなふうに渡す

{
  "customer_message": "届いた冷蔵庫のドアが閉まりません",
  "order": { "item": "冷蔵庫", "days_since": 3 },
  "refund_policy": "到着後14日以内なら返品可"
}

文字列でも渡せますが、いくつかの情報があるときは、名前をつけた JSONが基本です。何がどの情報か、はっきりします。

質問は、名前で資料を指せる

質問: `order.days_since` と
`refund_policy` を見て、
この返品は認められる?

質問の中で、資料のどこを見るかを名前(パス)で示せるので、迷わず判断できます。

どのアプリが、何を状況として渡しているかは、下の「5つのアプリ」で見られます。

3. 質問は3種類だけ

聞きたいことの答えの形で、使い分けます。タブを切り替えて、 どんな答えが返ってくるか見てみてください。

「当てはまる?」を確率で答える

状況(state)

「今すぐ振り込まないと、口座が止まります!」

質問

この文は、お金を要求していますか?

答え

97%

  • はい97%
  • いいえ3%

0.5 付近は「中くらい」ではなく「どちらとも言えない」。程度を比べたいときは score を使います。

4. 実物のリクエストとレスポンス

ここまでの話を、そのままの形で見てみましょう。POST https://api.typesafe.ai/v1/systemoneに、状況(state)と質問(questions)を送ります(APIキーは Authorization: Bearer … ヘッダーで渡します)。

送るもの(リクエスト)

{
  "model": "jev-latest",
  "state": {
    "customer_message": "届いた冷蔵庫のドアが閉まりません。すぐに何とかしてください!",
    "order": {
      "item": "冷蔵庫",
      "days_since_delivery": 3
    },
    "refund_policy": "到着後14日以内なら返品できます"
  },
  "questions": {
    "category": {
      "type": "choice",
      "instructions": "`customer_message` は、どの種類の問い合わせか?",
      "criteria": {
        "repair": "壊れている・動かないので、修理や交換を求めている",
        "return": "商品を返品して返金してほしい",
        "other": "上のどれでもない"
      }
    },
    "refundable": {
      "type": "noul",
      "instructions": "`order.days_since_delivery` と `refund_policy` から見て、この注文は返品できる期間内か?"
    },
    "urgency": {
      "type": "score",
      "instructions": "`customer_message` から読み取れる、顧客の急ぎ具合は?",
      "criteria": [
        "急いでいない",
        "少し急いでいる",
        "かなり急いでいる",
        "今すぐ対応してほしい"
      ]
    }
  }
}

返ってくるもの(レスポンス)

{
  "model": "jev-1.13.0",
  "answers": {
    "category": {
      "type": "choice",
      "choice": "repair",
      "confidence": 1.0,
      "probabilities": {
        "return": 0.0,
        "other": 0.0,
        "repair": 1.0
      }
    },
    "refundable": {
      "type": "noul",
      "noul": 0.97
    },
    "urgency": {
      "type": "score",
      "score": 2.99,
      "confidence": 0.99,
      "legend": {
        "0": "急いでいない",
        "1": "少し急いでいる",
        "2": "かなり急いでいる",
        "3": "今すぐ対応してほしい"
      },
      "probabilities": {
        "0": 0.0,
        "1": 0.0,
        "2": 0.0,
        "3": 1.0
      }
    }
  },
  "usage": {
    "input_tokens": 592,
    "output_tokens": 71
  }
}

これは実際に送って返ってきた結果です。わかりやすい例だったので、確率が 0 か 1 に寄っています。迷う内容なら、確率がばらけます。

5. Jev のとくちょう

速さは、このサンプルでの実測です(探してるものだけ表示で約0.25秒、Car Picker で約0.24秒、200問のパネルで約1.5秒)。

6. 候補がたくさんあるとき、どう聞く?

「商品が何十個」「料理が何百品」のように候補が多いときの聞き方は、おもに4つあります。 どれにも共通するのは、同じ状況に対する質問は、まとめて1回で聞くことです。質問が増えるのは、状況について知りたいことが増えたときで、候補の数に 合わせて増やすわけではありません。

候補が長い文書(記事、問い合わせの全文)で、1つの state に入れきれないときは、候補ごとに1リクエストにします(公式の再ランキングの例)。

7. 5つのアプリで、どう使っている?

公式ドキュメントには、4つのパターンがあります。どのデモが、どのパターンを使っているかは、次のとおりです。

パターンひとことで使っているデモ
Speculative Fan-Out使うか分からない質問も、1回でまとめて聞くCar Picker(主)、問い合わせ振り分け、探してるものだけ表示、今夜なに作る?、ウケるかなパネル
Confidence-Gated Routing確信度で、実行 / 確認 / 人に回す を決める問い合わせ振り分け(主)、Car Picker、探してるものだけ表示(迷いの印)
Composite Scoring小さな判断を、コードの重みで合算するCar Picker(主)
Intent Routing意図を分類して、処理先に振り分ける問い合わせ振り分け

どのアプリも、同じ型で読めます。

やりたいこと → 渡す状況 → Jev に聞くこと → 流れ → コードがやること

今夜なに作る?

アプリを開く →

使っているパターンSpeculative Fan-Out

やりたいこと「疲れた」「ご飯が進む和食がいい」といった一言から、今夜の献立を決めたい。

渡す状況(state)ユーザーの状況(自由入力)と、あなたのタスク(今夜の主菜を決める)。副菜を選ぶときは、選んだ主菜も加える。料理名は、料理ごとの質問のほうに入れる。

実際に Jev に送って、返ってきた答えの例です。1回のリクエストで、次の状況(state)に対して、3問をまとめて聞いています。

状況(state)
{
  "ユーザーの状況": "疲れているので、ご飯が進む和食がいい",
  "あなたのタスク": "今夜の夜ご飯の献立(主菜)を決める"
}
聞いたことと、返ってきた答え
nould…(サバの味噌煮)

今日の夜ご飯に、この料理はふさわしいか?

この質問に入れているデータ
{
  "candidate": "サバの味噌煮"
}
  • 85%

→ ふさわしい確率は 85%(1位)

nould…(親子丼)

今日の夜ご飯に、この料理はふさわしいか?

この質問に入れているデータ
{
  "candidate": "親子丼"
}
  • 85%

→ ふさわしい確率は 85%(2位)

nould…(ぶり大根)

今日の夜ご飯に、この料理はふさわしいか?

この質問に入れているデータ
{
  "candidate": "ぶり大根"
}
  • 80%

→ ふさわしい確率は 80%(12位)

アプリ全体では:主菜196品 × 1問 = 196問を、1リクエスト(約278ms、入力9,323トークン)。副菜・汁物も同じ形で、112問を1リクエスト

コードの仕事:「はい」の確率が高い順に並べるだけです。確信度(迷いのなさ)で選ぶと、「ふさわしくない」と自信満々に答えた料理が上に来てしまうので、順位には確率を使います。

  1. 自由入力 1文
  2. 料理ごとに1問(主菜196問)を、1リクエストに並べる
  3. 「ふさわしい」の確率
  4. 確率の高い順に並べる(副菜・汁物も同じ形で1リクエスト)

ポイント「探してるものだけ表示」と同じ形です。196品に1問ずつ聞いても1リクエストで、約0.3秒・入力約9,300トークンでした。順位は「はい」の確率で付けます。確信度(迷いのなさ)で選ぶと、「ふさわしくない」と自信満々に答えた料理が上に来てしまったので、確信度は順位には使いません。

コードがやること
  • 候補の料理の一覧を持つ(Jev に献立を考えさせない。決まった候補が、今夜にふさわしいかを聞く)
  • 確率の高い順に並べ、1位の主菜に合わせて副菜・汁物をもう1回聞く

新規事業ウケるかな?パネル

アプリを開く →

使っているパターンSpeculative Fan-Out

やりたいこと新規事業のアイデアに、いろんな立場の人がどのくらい興味を持つかを眺めたい。

渡す状況(state)新規事業のアイデア文。パネリスト(人物)の紹介は、質問のほうに入れる。

実際に Jev に送って、返ってきた答えの例です。1回のリクエストで、次の状況(state)に対して、2問をまとめて聞いています。

状況(state)
{
  "新規事業のアイデア": "使わなくなった楽器を、近所の子どもに月額で貸し出すサービス"
}
聞いたことと、返ってきた答え
scorep001(1人目)

この人物は、このアイデアにどのくらい興味を持つ?

この質問に入れているデータ
{
  "人物": {
    "名前": "ステーブン・ジョーブズ",
    "紹介": "パーソナルコンピュータとスマートフォンを世に広めた起業家。製品の美しさと、ハードとソフトを統合した体験を何よりも重視する…",
    "関心領域": [
      "プロダクトデザイン",
      "消費者向け製品",
      "垂直統合",
      "ブランド体験"
    ]
  }
}
  • 0 全く興味を示さず、自分には関係のないことだと考える3%
  • 1 懐疑的で、うまくいかないだろうと考える57%
  • 2 悪くはないと思うが、自分から積極的に関わろうとは思わない30%
  • 3 関心を持ち、もっと詳しく知りたいと考える10%
  • 4 強い興味を示し、自ら関わりたいと考える0%

→ 期待値は 1.47(0〜4)

noulp001__invest

この人物は、このアイデアに自分のお金を出す?

この質問に入れているデータ
{
  "人物": {
    "名前": "ステーブン・ジョーブズ",
    "紹介": "パーソナルコンピュータとスマートフォンを世に広めた起業家。製品の美しさと、ハードとソフトを統合した体験を何よりも重視する…"
  }
}
  • 21%

→ 当てはまる確率は 21%

アプリ全体では:パネリスト 100人 × 2問 = 200問

質問に、人物の名前・紹介・関心領域を入れています。同じ形の質問を100人分作って、200問をまとめて聞きます。

  1. アイデア 1文
  2. 100人 × 2問 = 200問
  3. 興味の度合いと確率
  4. 陣地に並べる

ポイント200問を、分けずに1回で投げます。Jev はまとめて並列に答えるので、1.5秒ほどで100人分が返ってきます。速さと並列性を見せるデモです。

コードがやること
  • パネリストの一覧を持つ
  • 結果に合わせて、アバターを陣地に並べて動かす

⚠ 実在の人物がモデルでも、これは AI による推定です。本人の考えではありません。

探してるものだけ表示

アプリを開く →

使っているパターンSpeculative Fan-Out、Confidence-Gated Routing

やりたいことAmazon の検索結果には、探していない商品が混ざる。検索したものだけが出てほしい。

渡す状況(state)検索キーワードだけ。商品のタイトルは、商品ごとの質問のほうに入れる。

実際に Jev に送って、返ってきた答えの例です。1回のリクエストで、次の状況(state)に対して、3問をまとめて聞いています。

状況(state)
{
  "search_query": "ipad pro スマートキーボード"
}
聞いたことと、返ってきた答え
choicep0

この商品は、検索した人が探しているものと、どういう関係にある?

この質問に入れているデータ
{
  "candidate": {
    "title": "Apple Smart Keyboard(10.2インチiPad、10.5インチiPad Air、10.5インチiPad…"
  }
}
  • 本命 探しているものそのもの。全条件を満たす44%
  • 代わり 同じ種類だが、条件のどれかが違う56%
  • おまけ アクセサリなど、一緒に使うもの0%
  • 無関係 探しているものと関係がない0%

→ 選ばれたのは「代わり」(確信度 0.40、正解ラベルは「本命」)

choicep1

この商品は、検索した人が探しているものと、どういう関係にある?

この質問に入れているデータ
{
  "candidate": {
    "title": "ロジクール iPad Pro 12.9インチ対応 キーボード iK1272BKA ブラック バックライトキーボード付ケー…"
  }
}
  • 本命 探しているものそのもの。全条件を満たす28%
  • 代わり 同じ種類だが、条件のどれかが違う71%
  • おまけ アクセサリなど、一緒に使うもの1%
  • 無関係 探しているものと関係がない0%

→ 選ばれたのは「代わり」(確信度 0.61、正解ラベルは「代わり」)

choicep5

この商品は、検索した人が探しているものと、どういう関係にある?

この質問に入れているデータ
{
  "candidate": {
    "title": "Apple Smart Keyboard Folio (11インチ iPad Pro 第1世代用) - 日本語"
  }
}
  • 本命 探しているものそのもの。全条件を満たす71%
  • 代わり 同じ種類だが、条件のどれかが違う28%
  • おまけ アクセサリなど、一緒に使うもの1%
  • 無関係 探しているものと関係がない0%

→ 選ばれたのは「本命」(確信度 0.62、正解ラベルは「本命」)

アプリ全体では:16商品 × 1問 = 16問を、1リクエスト(約251ms)。全24キーワードでも24リクエスト

コードの仕事:本命と判定された商品を「探してるもの」として残し、それ以外には 🚫 を付けます。確信度が 0.6 未満の判定(上の例では p0 の 0.40)には「Jev が迷った」と印を付けます。0.6 未満の判定は正解率が約5割、それ以上は約8割でした。

  1. 検索キーワード 1つ
  2. 商品ごとに1問(16〜27問)を、1リクエストに並べる
  3. 確率と確信度
  4. 探してるもの(緑)と、探してないもの(🚫)。迷いは点線で表示

ポイント同じ検索キーワード(state)に対する質問を、商品ごとに1問ずつ、まとめて1回で聞きます。395商品でも24リクエストです(商品ごとに分けた場合は395回)。本命と判定された商品だけを「探してるもの」として残し、確信度が低い判定には「Jev が迷った」と印を付けます。

コードがやること
  • 商品のタイトルを質問に入れる、質問の組み立てと、受け取った確率の集計
  • 「探してるもの」かどうかの判定と、確信度による「迷い」の印(しきい値はコード側の定数)
  • 検索結果の取得(このデモでは、あらかじめ用意したデータ)

問い合わせ振り分け

アプリを開く →

使っているパターンIntent Routing、Confidence-Gated Routing、Speculative Fan-Out

やりたいことお客さんの問い合わせを分類して、自動で対応するか、確認するか、人に回すかを決めたい。

渡す状況(state)問い合わせの文、お客さんの注文と会員プラン、返金のルール。質問は、パス(`customer.orders[0]` など)で指す。

実際に Jev に送って、返ってきた答えの例です。1回のリクエストで、次の状況(state)に対して、4問をまとめて聞いています。

状況(state)
{
  "message": "イヤホンを返金してほしいです。あと、プレミアム会員も今月で解約したいです。",
  "customer": {
    "plan": "プレミアム会員(月額)",
    "orders": [
      {
        "id": "A-1001",
        "item": "ワイヤレスイヤホン",
        "status": "配達済み",
        "days_since_delivery": 6
      },
      {
        "id": "A-1002",
        "item": "モバイルバッテリー",
        "status": "発送済み(まだ届いていない)",
        "days_since_delivery": null
      }
    ]
  },
  "refund_policy": "到着後14日以内なら返品・返金できます"
}
聞いたことと、返ってきた答え
choiceintent

この顧客が、このメッセージで一番求めていること(主な用件)はどれか?(「その他」の逃げ道あり。選択肢を逆の並びにした intent_rev も同時に聞く)

  • 注文状況 注文・配送・到着について具体的に尋ねている0%
  • 返金 返品・返金・交換を具体的に求めている100%
  • 解約 会員プランや定期サービスをやめたい0%
  • 商品の質問 仕様・使い方などを質問している0%
  • クレーム 不満を伝えているが、手続きは求めていない0%
  • アカウント ログインできない・ロックされた0%
  • その他 上のどれでもない・用件が読み取れない0%

→ 選ばれたのは「返金」(確信度 1.00。逆の並びも同じ答え)

scorefrustration

顧客の、サービスに対する不満・怒りの強さは?(3段階)

  • 0 不満はない(普通の問い合わせ・依頼)94%
  • 1 不満や困惑がある(丁寧な言葉づかいのまま)6%
  • 2 強い怒り・非難(強い言葉、責める口調)0%

→ 期待値は 0.06(0〜2)、確信度 0.91

noulmultiple_requests

互いに異なる2つ以上の依頼(例: 返金と解約)を同時に求めている?

  • 98%

→ 当てはまる確率は 98%

noulrefund_in_policy

返金を求めている注文は、配達済みで、`customer.orders` の日数が `refund_policy` の期間内に収まっている?(返金の依頼のときだけ使う、先回りの質問)

  • 96%

→ 当てはまる確率は 96%

アプリ全体では:全9問を1リクエスト(下はその一部。約206ms、入力2129トークン)

コードの仕事:返金は危険度が高いので、自動で実行するには、意図の確信度 0.85 以上、かつ「期限内」の確率 0.85 以上が必要です。ここでは両方を満たしましたが、「複数の依頼」の確率が高い(98%)ので、自動実行はせず「確認する」に格下げします。注文状況の自動返信のような低リスクの処理は、0.6 以上で自動です。しきい値は画面で変えられて、変えても Jev は呼び直しません。

  1. 問い合わせ 1通
  2. 9問を一度に(意図、緊急度、不満、返金の期限内か、など)
  3. 確率と確信度
  4. 自動で実行 / 確認する / 人に回す

ポイント処理の危険度で、必要な確信度を変えます。注文状況の自動返信は 0.6 以上、返金と解約は 0.85 以上で自動です。中間は確認、低ければ人に回します。不審なメッセージと法的な脅しは、意図に関係なく人に回します。選択肢を逆の並びにした同じ質問で、順番の偏りも確かめます。

コードがやること
  • 意図に応じた処理先の選択と、危険度ごとのしきい値、確信度の「最も弱い環」の計算
  • 返金期限の計算はしない。日数は state に入れ、ルールの文と照らし合わせるだけにする
  • 実際の返金や解約は実行しない(このデモは、判定までを見せる)

ソラカー Car Picker

アプリを開く →

使っているパターンSpeculative Fan-Out、Confidence-Gated Routing、Composite Scoring

やりたいこと「家族4人で乗れるセダン、赤、自動ブレーキ」のようなふわっとした希望から、車を選びたい。

渡す状況(state)ユーザーの要望文だけ。車の情報はカタログ側にあり、Jev には渡さない。

実際に Jev に送って、返ってきた答えの例です。1回のリクエストで、次の状況(state)に対して、5問をまとめて聞いています。

状況(state)
{
  "request": "家族四人(小学生2人)で乗れるセダン、ボディカラーは赤で、自動ブレーキで止まるやつ"
}
聞いたことと、返ってきた答え
noulbodyType_stated

この人は、車のボディタイプについて希望を述べている?(「言及があるか」を別の質問にしています)

  • 98%

→ 言及している確率は 98%

choicebodyType

この人が希望しているのは、どのボディタイプ?(「言及なし」の選択肢はありません)

  • コンパクト 小さめで運転しやすいコンパクトカー・軽快な小型車0%
  • セダン セダン(トランクのある4ドアの乗用車)100%
  • ワゴン ステーションワゴン(乗用車の形のまま荷室が広い車)0%
  • SUV SUV・クロスオーバー(車高が高くアウトドア向き)0%
  • ミニバン ミニバン(スライドドアや3列シートのある背の高い車)0%

→ 選ばれたのは「セダン」

choicebodyType_reversed

同じ質問を、選択肢を逆の並びにして、もう一度聞く(順番の偏りの確認)

  • ミニバン ミニバン(スライドドアや3列シートのある背の高い車)0%
  • SUV SUV・クロスオーバー(車高が高くアウトドア向き)0%
  • ワゴン ステーションワゴン(乗用車の形のまま荷室が広い車)0%
  • セダン セダン(トランクのある4ドアの乗用車)100%
  • コンパクト 小さめで運転しやすいコンパクトカー・軽快な小型車0%

→ 選ばれたのは「セダン」

scorebudget

月額の安さを、どのくらい重視している?(3段階)

  • 0 価格や予算に触れていない、または価格より中身を重視している100%
  • 1 予算は気にしている(「手頃な」「予算内で」「コスパ」など)0%
  • 2 安さが最優先(「とにかく安く」「節約したい」「お金がない」など)0%

→ 期待値は 0(0〜2)

noulkidsOnBoard

小さな子ども(乳幼児・未就学児・小学生)が乗る?

  • 95%

→ 当てはまる確率は 95%

アプリ全体では:全30問を1リクエスト(下はその一部)

「言及があるか」(_stated)と「どの値か」を別の質問にしているので、要望に書かれていない項目を、Jev が無理に埋めません。コードは、言及の確率に応じてその項目の影響を弱めます。確信度が低い項目があれば、「ミニバン? SUV?」と聞き返し、Jev を呼び直さずに並べ直します。

  1. 要望 1文
  2. 30問を一度に
  3. 確率と確信度
  4. おすすめ順 + 迷った項目の聞き返し

ポイント「言及があるか」と「どの値か」を別の質問にします。書かれていない項目を、Jev が無理に埋めません。あとで使うかもしれない質問も最初にまとめて聞くので(投機的ファンアウト)、往復は1回です。確信度の低い項目は聞き返し、答えが決まったら Jev を呼び直さずに並べ直します。

コードがやること
  • 価格や装備などの事実は、カタログから取る(Jev に数字を作らせない)
  • 言及の確率に応じて、項目の影響を弱める。決め手になった答えのうち、一番確信度が低いものを全体の確信度にする
  • 車種が決まったら、聞いておいた答えのうち必要なものだけを使ってオプションを選ぶ。重みを変えるスライダーも、コードだけで並べ直す

8. 気をつけること

← トップへ戻る