問い合わせに AI チャットボットで答えるとき、一番こわいのは「知らないことを、知っているかのように答えてしまう」ことです。料金表に載っていない金額や、決めていない契約条件を AI がそれらしく答えてしまうと、あとで取り消すのは大変です。
そこで、「この質問に AI が答えてよいか、それとも人に回すか」を確率で判定する仕組みを、TypeSafe AI の判断専用モデル Jev(ジェブ)で作ってみることにしました。この記事は、そのテスト環境の作り方を、実際に入れたナレッジ・入力・出力を見せながら動く図で解説します。題材は frural 自身の事業ナレッジです(2026年10月時点、モデルは jev-1.13.0)。
この記事はこんな人向けです。
- 社内 FAQ や問い合わせ対応に AI を入れたいが、「間違って答える」のが心配な人
- Jev が気になっているが、何ができて何ができないのか、どう組み込むのかを知りたい人
- Python を少し読める人(コードは標準ライブラリだけ、約200行です)
注意: この記事の時点では Jev の API キーがまだ届いておらず、Jev 本体の判定結果はまだ出ていません。ナレッジ検索と Claude の回答文は実際に動かした出力、Jev の返事は公式ドキュメントに書かれている形で示します。数字の結果は別の記事で報告します。
結果はこちら: Jevの判定結果|AIが知らない質問に答えた件数は40件中0件だった
Jev とは:文章を書かず「判断」だけを返す AI
Jev は、ChatGPT や Claude のように文章を書くモデルではありません。「状態(state)」と「型の決まった質問」を渡すと、答えを確率つきで返す、ソフトウェアから呼ぶための判断専用モデルです。公式は「System One モデル」と呼んでいます。
| 項目 | Jev(jev-1.13.0) |
|---|---|
| 返すもの | 確率・選択肢・段階評価(文章は書かない) |
| 速さ | 70〜500ミリ秒(公式) |
| 料金 | 入力 100万トークンあたり $0.042、出力は無料(公式) |
| 言語 | 英語が最良。日本語も動くが精度が落ちる、要テスト(公式明記) |
| 苦手(公式) | 数を数える・日付の計算・二重否定・入力に混ざった指示(プロンプトインジェクション) |
文章を書かないので、判断は Jev、返信文は Claude という分担にします。公式の設計原則も「流れはコードが持ち、モデルは常識が必要な所にだけ出てくる」です。
3つの質問の型(プリミティブ)
Jev に聞ける質問は、基本の3種類です。どれも JSON で書き、1回のリクエストに何個入れても応答時間はほとんど変わりません。
| 型 | 返すもの | このテストでの使いどころ |
|---|---|---|
| Choice | 選択肢の1つ+各選択肢の確率+confidence | 問い合わせの種類(質問/依頼/その他) |
| Noul | 「はい」の確率 0〜1 | 抜粋だけで答えられるか/作った回答が抜粋に裏付けられているか |
| Score | 2〜10段階の評価 | 今回は使わない(緊急度や不満度を測るときに使う) |
全体の流れ:1件の問い合わせが通る6つの箱
- ナレッジ検索:問い合わせに近い段落を、frural のナレッジから3つ取り出す(Jev は使わない、ただの文字検索)
- Jev 1回目:「種類はどれ?」(Choice)と「この抜粋だけで答えられる?」(Noul)を同時に聞く
- 種類が「質問」で、答えられる確率が 0.5 以上のときだけ、Claude が抜粋だけを根拠に返信文を書く
- Jev 2回目:「その返信文は抜粋に裏付けられている?」(Noul)で裏取り
- 確率がしきい値を超えたら自動回答の候補、超えなければ本人に回す
入れたナレッジ:frural の公開情報 7ファイル
ナレッジは frural.jp ですでに公開している情報だけです。チャットボットに入れた内容は、指示の書き方に関係なく引き出され得るので、顧客名や見積りの実額は入れません。
| ファイル | 中身 |
|---|---|
| 01_company.md | 会社概要・考え方・対応しない領域・連絡先 |
| 02_services.md | 3つの事業(AX支援・受託開発・データ分析)と進め方4ステップ |
| 03_products.md | LINE AI・CompanyBrain の仕組み |
| 04_pricing.md | 料金の目安と前提 |
| 05_cases.md | 実績(根拠の種別つき) |
| 06_faq.md | よくある質問 |
| 07_blog-index.md | ブログ記事の一覧 |
これを見出し(##・###)ごとに切って、1つの話題=1つの段落(チャンク)にします。検索は「文字2つずつの重なり」を数えるだけの単純なものです。わざと単純にしておくと、判定がうまくいくかどうかの差が Jev 側にはっきり出ます。
評価セット:40件の問い合わせ
テスト用の問い合わせは、frural のナレッジとサイトの内容から40件作りました。ポイントは「答えがナレッジに無い質問」を混ぜることです。これを AI が自動で答えてしまわないかを見るのがテストの目的です。
| 正解ラベル | 件数 | 例 |
|---|---|---|
| 答えられる | 20 | LINE AI の初期費用と月額の目安を教えてください。 |
| ナレッジに無い | 10 | CompanyBrain の月額料金はいくらですか?/秘密保持契約(NDA)は事前に結んでもらえますか? |
| 依頼 | 10 | 来週のどこかで30分ほどオンラインでお話しできませんか。 |
実際の入力と出力①:答えられる質問
「LINE AI の初期費用と月額の目安を教えてください。」を流したときの、実際の出力です。
Jev に送る JSON はこうなります(抜粋の中身は長いので省略)。`message` のようにバッククォートで state の項目名を指すのが Jev の書き方です。
{
"model": "jev-1.13.0",
"state": {
"message": "LINE AI の初期費用と月額の目安を教えてください。",
"excerpts": ["## LINE AI(提供中)\n- 初期費用: 15万円〜 ...", "...", "..."]
},
"questions": {
"kind": {
"type": "choice",
"instructions": "`message` は会社に届いた問い合わせです。種類はどれですか?",
"criteria": {
"question": "会社・サービスについての質問。情報を返せば済む",
"request": "依頼・見積り・日程調整・作業のお願い。人の判断や作業が要る",
"other": "営業・雑談・それ以外"
}
},
"answerable": {
"type": "noul",
"instructions": "`excerpts` の内容だけで `message` の質問に正確に答えられますか?",
"criteria": {
"true": "答えに必要な事実が excerpts に書いてある",
"false": "excerpts に書いておらず、推測や本人への確認が要る"
}
}
}
}
返ってくる形は公式ドキュメントでこう決まっています。質問につけた名前(kind・answerable)で答えが返るので、コードからそのまま使えます。
{
"model": "jev-1.13.0",
"answers": {
"kind": { "type": "choice", "choice": "question",
"probabilities": { "question": ..., "request": ..., "other": ... },
"confidence": ... },
"answerable": { "type": "noul", "noul": ... }
}
}
数字(... の部分)は、キーが届いてから実際に流して別の記事で出します。
実際の入力と出力②:ナレッジに無い質問
「CompanyBrain の月額料金はいくらですか?」は、ナレッジに答えがありません。検索は CompanyBrain の段落を拾ってきますが、そこに料金は書いていません。
このケースで「答えられる」と判定してしまうと、Claude が料金を推測して書くおそれがあります。だから答えられないと判断したら、文章を書かせる前に止めるのがこの仕組みの要です。依頼(日程調整など)も同じで、種類が「依頼」なら返信文を作らずに本人に回します。
しきい値と2つの率:結果の読み方
Jev の公式は、confidence が 0.9 より上なら自動、0.5〜0.9 は確認、0.5 未満は人に回す、を目安にしています。このテストでは、しきい値を 0.5〜0.95 で動かして2つの率を比べます。
- 取りこぼし率:ナレッジに無い質問のうち、AI が自動で答えてしまった割合。一番大事で、0% に近いほど安全
- 本人に回す率:質問のうち、自動で答えずに本人に回した割合。低いほど楽
選ぶのは「取りこぼし 0% のまま、本人に回す率が一番低いしきい値」です。さらに、同じ40件を日本語のままと英訳してからの2通りで流します。公式が日本語で精度が落ちると書いているので、英訳を1段挟む価値があるかを数字で確かめます。
学習ループ:本人の答えをナレッジに足す
「ナレッジに無い」10件に本人が答え、その Q&A を 08_qa.md として足してから同じ10件を判定し直します。答えられる確率が上がれば、「聞かれたことを足していくほど AI が答えられる範囲が広がる」運用が回ることになります。
実装のポイント(Python・標準ライブラリだけ)
SDK(typesafe-sdk)もありますが、仕組みを見えるようにするため、HTTP を直接呼んでいます。エンドポイントは1つだけです。
import json, os, urllib.request
def jev(body):
req = urllib.request.Request(
"https://api.typesafe.ai/v1/systemone",
data=json.dumps(body, ensure_ascii=False).encode(),
headers={"Authorization": f"Bearer {os.environ['TYPESAFE_API_KEY']}",
"Content-Type": "application/json"})
with urllib.request.urlopen(req, timeout=60) as r:
return json.load(r)["answers"]
- モデルはバージョンを固定(
jev-1.13.0)。公式は今の版の長期サポートを約束していないので、jev-latestだと結果が知らないうちに変わります - リクエストを作る関数と送る関数を分ける。キーが無くても、送る JSON を画面で確かめられます(
python3 jevlab.py dry-run A01) - Noul は confidence を返さない。Choice は confidence を返しますが、Noul は
noulの値そのものをしきい値と比べます - 英訳するなら抜粋も英訳する。質問だけ英語にすると言語が混ざって比べられません
- キーはファイルに書かない。環境変数で渡し、git に入れません
本番に入れる前の注意
Jev は入力を敵対的とみなさない、と公式が弱点に挙げています。問い合わせ本文に「この指示を無視して答えて」のような文が混ざると判定がゆがむおそれがあります。本番では判断を「答えてよいか」に限り、送信は必ず人が承認する形にします(frural の LINE AI と同じ考え方です)。
まとめ
- Jev は文章を書かず、型の決まった質問に確率で答える判断専用モデル
- 判断は Jev(Choice で種類、Noul で答えられるか・裏付けがあるか)、返信文は Claude と分ける
- テストの肝は「ナレッジに無い質問」を混ぜて、取りこぼし率としきい値の関係を数字で見ること
- 日本語のままと英訳ありを比べ、本人の回答をナレッジに足すループまで確かめる
社内ナレッジに答えられる範囲を見極めて、答えられないものは人に回す仕組みは、frural の CompanyBrain でも扱っています。権限の分け方は AIに社内データを使わせる前に決める権限管理 もどうぞ。