DeepEvalの公式Jev対応でjudgeを判定特化モデル「Jev」に置き換えて検出力・安定性・コストを比べてみる

DeepEvalの公式Jev対応でjudgeを判定特化モデル「Jev」に置き換えて検出力・安定性・コストを比べてみる

# 導入文 DeepEvalでLangGraphエージェントを評価する際、LLM judgeは時間とコストが課題でした。今回は、TypeSafeの判定特化モデル「Jev」をjudgeに置き換え、gpt-5.4・gpt-6-luna・gpt-5.4-nanoと比較してみました。
2026.09.26

はじめに

データ事業本部のkobayashiです。

前回はDeepEvalでLangGraphエージェントの応答品質をLLM-as-a-judge型のメトリクスで評価しました。judgeは gpt-5.4 で、2件のテストケースの評価に約30秒・約$0.10かかっており、CIで毎回回すには気になる数字かと思います。

https://dev.classmethod.jp/articles/python-litellm-deepeval/

そこで今回は、judgeをLLMではなくTypeSafeの判定特化モデル「Jev」 に置き換えてみました。DeepEvalは4.2.6で標準メトリクスをそのままJevで動かせるようになっています。この公式対応を使い、gpt-5.4・gpt-6-luna・gpt-5.4-nano と並べて、悪い回答を見抜けるか、判定が安定するか、時間とコストはどうかを比べます。

Jevとは

JevはTypeSafeが「System One」と呼ぶモデルで、文章を生成せず、判定とその確率だけを返します。質問の型は Choice(選択)・Score(段階)・Noul(真である確率)の3つで、複数の質問を1リクエストで投げられます。料金は入力トークンのみで jev-1.13.0 は100万トークンあたり$0.042です(Models)。同ページには、英語が主な学習言語でCJKは同等ではなく、非英語では自分のデータで試すようにと書かれています。Jevの使い方は前回の記事で扱っています。

https://dev.classmethod.jp/articles/typesafe-jev-table/

項目 LLM judge Jev
判定の出し方 主張や文を抽出 → 判定 → 理由を生成(2〜4回の生成) 質問に確率で答える(1リクエスト)
スコア 判定単位ごとの0/1の割合 確率の重み付き平均
理由 LLMが書く 質問ごとの確率を並べた定型文
料金 入力 + 出力 入力のみ

環境

Python 3.13.15
deepeval 4.2.6
typesafe-sdk 0.7.1
litellm 1.102.0
langgraph 1.2.11
langchain 1.4.2
langchain-litellm 0.7.2
$ uv pip install deepeval typesafe-sdk litellm langgraph langchain langchain-litellm
$ export OPENAI_API_KEY="sk-..."      # GPT judge と被評価エージェント用
$ export TYPESAFE_API_KEY="..."       # Jev 用

被評価エージェントは gpt-5-mini、judgeは gpt-5.4 / gpt-6-luna / gpt-5.4-nano / jev-1.13.0 です。gpt-6-luna は執筆時点で最新のgpt-6系(2026-09-22公開)のうち手元の計測で最速だったもの、gpt-5.4-nano はGPTの中で最速だったものです。

deepeval 4.2.6では HallucinationMetric のスコアは「矛盾しない割合」で、1.0が合格側です(前回の記事の版では0.0が合格側でした)。

DeepEvalでJevを使う

TypeSafe対応は4.2.4(2026-09-22)で TypeSafeModel が入り、JevEval は4.2.5、eval_mode の3種類と同梱のJev用質問は4.2.6(2026-09-24)からです。記事のコードは4.2.6を前提にしています。

Jevを使う入口は2つあり、役割が違います。

入口 何を測るか 誰が判定するか
標準メトリクス + eval_mode DeepEvalが決めた定義と質問(FaithfulnessMetric など) eval_mode でLLM / Jevを切り替える
JevEval 自分で書いた質問(Noul / Score / Choice) 常にJev

既製メトリクスの定義のままjudgeだけJevにしたいなら前者、質問(定義)を自分で決めたいなら後者です。JevEval はG-Eval(自由な評価基準をLLMに判定させる自作メトリクス)のJev版にあたります。

3つのeval_mode

標準メトリクスの eval_mode 引数(または deepeval set-eval-mode / 環境変数 DEEPEVAL_EVAL_MODE)で「誰が判定するか」を切り替えます。

eval_mode 判定する主体 理由
llm(既定) LLMが主張の抽出・判定・理由まで全部 LLMが書く
hybrid LLMが主張を抽出し、主張ごとの判定だけJev LLMが書く
system_one Jevがテストケース全体を1リクエストで判定。LLMは呼ばれない Jevの答えから機械的に組み立てる

標準メトリクスをJevで動かす

TypeSafeModel を system_one_model に渡し、eval_mode を指定します。

compare_judges.py(抜粋)
from deepeval.metrics import AnswerRelevancyMetric, FaithfulnessMetric, HallucinationMetric
from deepeval.models import OpenAIModel, TypeSafeModel

JEV_MODEL = "jev-1.13.0"  # 料金はモデルの版に紐づくので jev-latest ではなく版を固定する

def jev_metrics(include_reason: bool):
    """標準メトリクスを Jev だけで判定する(eval_mode="system_one")。理由は Jev の答えから機械的に組み立てられる。"""
    jev = TypeSafeModel(model=JEV_MODEL)
    kw = {"system_one_model": jev, "eval_mode": "system_one", "include_reason": include_reason}
    return [
        AnswerRelevancyMetric(threshold=0.7, **kw),
        FaithfulnessMetric(threshold=0.7, **kw),
        HallucinationMetric(threshold=0.5, **kw),
    ]

def hybrid_metrics(include_reason: bool):
    """LLM が主張の抽出と理由を担当し、主張ごとの判定だけ Jev に聞く(eval_mode="hybrid")。"""
    kw = {
        "model": OpenAIModel(model="gpt-5.4"),
        "system_one_model": TypeSafeModel(model=JEV_MODEL),
        "eval_mode": "hybrid",
        "include_reason": include_reason,
    }
    return [
        AnswerRelevancyMetric(threshold=0.7, **kw),
        FaithfulnessMetric(threshold=0.7, **kw),
        HallucinationMetric(threshold=0.5, **kw),
    ]

DeepEval同梱のJev用の質問

system_one でJevに投げる質問はDeepEvalに同梱されています。FaithfulnessMetric の質問(_experimental_system_one_questions.txt)は以下の3問で、答えの重み付き平均がスコアになります。

[
  {
    "type": "noul",
    "statement": "Every factual claim in `actual_output` is supported by the facts in `retrieval_context`.",
    "weight": 2
  },
  {
    "type": "noul",
    "statement": "No claim in `actual_output` contradicts the facts in `retrieval_context`."
  },
  {
    "type": "score",
    "question": "How much of `actual_output` is grounded in the facts in `retrieval_context`?",
    "levels": ["Fabricated", "Mostly fabricated", "Mostly grounded", "Fully grounded"]
  }
]

LLM版の FaithfulnessMetric は既定(penalize_ambiguous_claims=False)では「contextと矛盾するか」だけを見ますが、Jev版の質問は「contextに裏付けられているか」を重み2で聞きます。同じメトリクス名でも定義が変わる点は、後の結果に効いてきます。hybrid の主張ごとの質問「Is claim supported by the facts in retrieval_context? Answer no if it contradicts them.」も裏付けを聞いています。

JevEvalで質問を自分で書く

JevEval に Noul / Score / Choice を並べると、その重み付き平均がスコアになります。LLM版と同じ「矛盾する記述が無いか」の定義を1問ずつ書きました。

compare_judges.py(抜粋)
from deepeval.metrics import JevEval
from deepeval.metrics.jev_eval import Noul
from deepeval.test_case import SingleTurnParams

def jev_eval_metrics(include_reason: bool):
    """JevEval に、LLM 版の標準メトリクスと同じ定義を自分の言葉で書いた版。質問は 1 メトリクス 1 問。"""
    jev = TypeSafeModel(model=JEV_MODEL)
    P = SingleTurnParams
    kw = {"system_one_model": jev, "include_reason": include_reason}
    return [
        JevEval(
            name="Jev Answer Relevancy",
            evaluation_params=[P.INPUT, P.ACTUAL_OUTPUT],
            questions=[Noul("`actual_output` は `input` への回答として関係がある(無関係な話題ではない)")],
            threshold=0.7,
            **kw,
        ),
        JevEval(
            name="Jev Faithfulness",
            evaluation_params=[P.ACTUAL_OUTPUT, P.RETRIEVAL_CONTEXT],
            questions=[Noul("`actual_output` に `retrieval_context` の内容と矛盾する記述は無い")],
            threshold=0.7,
            **kw,
        ),
        JevEval(
            name="Jev Hallucination",
            evaluation_params=[P.ACTUAL_OUTPUT, P.CONTEXT],
            questions=[Noul("`actual_output` に `context` の文書と矛盾する記述は無い")],
            threshold=0.5,
            **kw,
        ),
    ]

比較の設計

テストケース

エージェントは前回と同じ search_doc ツールを持つLangGraphエージェント(gpt-5-mini)です。前回の構成のままだと回答が回によって大きく変わるので、システムプロンプトでツールの結果だけを根拠に答えるよう固定しました。

compare_judges.py(抜粋)
agent = create_agent(
    model=ChatLiteLLM(model="openai/gpt-5-mini"),
    tools=[search_doc],
    system_prompt="必ず search_doc で社内ドキュメントを検索し、その結果だけを根拠に 1〜2 文で答える。",
)

正解の2件はエージェントに最初に1回だけ答えさせ、全judgeで同じ回答を使います。悪い回答4件は固定で書きました。

ケース 質問 回答 context
正解: 有給 有給休暇のルールを教えて (エージェントの回答) 有給休暇は入社6ヶ月後に10日付与されます。
正解: リモート リモートワークの可能日数は? (エージェントの回答) リモートワークは週3日まで可能です。
矛盾 リモートワークの可能日数は? リモートワークは週5日まで可能です。 リモートワークは週3日まで可能です。
無関係 有給休暇のルールを教えて リモートワークは週3日まで可能です。 有給休暇は入社6ヶ月後に10日付与されます。
際どい 有給休暇のルールを教えて 有給休暇は入社後6ヶ月以内に10日付与されます。 有給休暇は入社6ヶ月後に10日付与されます。
根拠なし 有給休暇のルールを教えて 有給休暇は入社6ヶ月後に10日付与されます。未消化分は翌年度に繰り越せます。 有給休暇は入社6ヶ月後に10日付与されます。

judge

judge eval_mode 内容
gpt-5.4 llm 前回DeepEvalが自動選択したモデル
gpt-6-luna llm 最新のgpt-6系で最速
gpt-5.4-nano llm GPTの中で最速
jev system_one 標準メトリクスをJevだけで判定。同梱の質問を使う
hybrid hybrid gpt-5.4 が主張抽出と理由、判定だけJev
jev-eval -(常にJev) JevEval に「矛盾する記述が無い」定義の質問を書いた版

gpt-6-luna はdeepeval 4.2.6の料金表に無く、そのままだと temperature=0 を送って400エラーになるので、gpt-5.4-nano と一緒に単価付きで OPENAI_MODELS_DATA に登録しています。

compare_judges.py(抜粋)
from deepeval.models.llms.constants import OPENAI_MODELS_DATA, make_model_data

# 単価は https://developers.openai.com/api/docs/pricing(USD / 1M tokens)
for name, in_price, out_price in [("gpt-6-luna", 0.10, 0.50), ("gpt-5.4-nano", 0.20, 1.25)]:
    OPENAI_MODELS_DATA[name] = make_model_data(
        supports_log_probs=False,
        supports_multimodal=True,
        supports_structured_outputs=True,
        supports_json=True,
        supports_temperature=False,
        input_price=in_price / 1e6,
        output_price=out_price / 1e6,
    )

期待値と集計

各ケース・各メトリクスに「合格すべき / 落ちるべき / 問わない」を置き、judgeごとに3回評価して、3回とも期待どおりなら○、回によって合否が変わったら△、3回とも逆なら✗とします。Faithfulnessの期待値は定義ごとに分けます。LLM版の定義(standard)では「無関係」も「根拠なし」も矛盾ではないので合格、同梱のJev用質問(grounded)では裏付けが無いので不合格が正しく、jev と hybrid はgroundedです。「根拠なし」をstandard側が落とせるかは「作り話検出」として別に数えます。

compare_judges.py(抜粋)
EXPECT = {
    "standard": {
        "正解: 有給": {"relevancy": True, "faithfulness": True, "hallucination": True},
        "正解: リモート": {"relevancy": True, "faithfulness": True, "hallucination": True},
        "矛盾: 週3日を週5日と答える": {"relevancy": True, "faithfulness": False, "hallucination": False},
        "無関係: 有給の質問にリモートの話": {"relevancy": False, "faithfulness": True, "hallucination": None},
        "際どい: 6ヶ月後を6ヶ月以内と言い換える": {"relevancy": True, "faithfulness": False, "hallucination": False},
        "根拠なし: 正しい一文に作り話を足す": {"relevancy": True, "faithfulness": None, "hallucination": None},
    },
}
EXPECT["grounded"] = {
    **EXPECT["standard"],
    "無関係: 有給の質問にリモートの話": {"relevancy": False, "faithfulness": False, "hallucination": None},
    "根拠なし: 正しい一文に作り話を足す": {"relevancy": True, "faithfulness": False, "hallucination": None},
}

時間は evaluate() の呼び出しだけを測り、コストはDeepEvalが各メトリクスに積む evaluation_cost の合計です。

実行結果

$ python compare_judges.py --runs 3

全体の集計

見るもの: 6ケース × 3メトリクスを3回評価し、期待どおりに判定した数、回で合否が変わった数、作り話(根拠の無い一文)を落とせたか、1回あたりの時間とコスト。

judge 期待どおり 不安定 作り話検出 スコア幅 平均時間 平均コスト
gpt-5.4 15/15 0 ✗ 0.00 4.39s $0.089058
gpt-6-luna 14/15 0 ✗ 0.00 36.36s $0.003995
gpt-5.4-nano 13/15 2 ✗ 1.00 3.56s $0.007553
jev 15/16 0 ○ 0.07 0.46s $0.000330
hybrid 14/16 1 ○ 1.00 3.19s $0.048951
jev-eval 14/15 0 ✗ 0.08 0.49s $0.000272

結果:

  • 期待どおりの数は gpt-5.4 15/15 と jev 15/16 が最多(jev と hybrid はgrounded側のFaithfulnessに期待値がある分だけ分母が16)
  • 合否が揺れたのは gpt-5.4-nano(2)と hybrid(1)
  • 作り話を落とせたのは jev と hybrid
  • 時間とコストは jev が0.46秒・$0.00033、gpt-5.4 が4.39秒・$0.089

優位: 検出と安定性は gpt-5.4 と jev が同等。時間とコストは jev。

ケース別のスコア

見るもの: 同じ回答に対するスコアの出方(各セルは3回の最小-最大)。

gpt-5.4:

ケース Relevancy Faithfulness Hallucination
正解: 有給 1.00-1.00 ○ 1.00-1.00 ○ 1.00-1.00 ○
正解: リモート 1.00-1.00 ○ 1.00-1.00 ○ 1.00-1.00 ○
矛盾: 週3日を週5日と答える 1.00-1.00 ○ 0.00-0.00 ○ 0.00-0.00 ○
無関係: 有給の質問にリモートの話 0.00-0.00 ○ 1.00-1.00 ○ 0.00-0.00 -
際どい: 6ヶ月後を6ヶ月以内と言い換える 1.00-1.00 ○ 0.00-0.00 ○ 0.00-0.00 ○
根拠なし: 正しい一文に作り話を足す 1.00-1.00 ○ 1.00-1.00 - 1.00-1.00 -

jev:

ケース Relevancy Faithfulness Hallucination
正解: 有給 0.92-0.94 ○ 0.99-0.99 ○ 0.99-0.99 ○
正解: リモート 0.97-0.97 ○ 0.56-0.57 ✗ 0.89-0.92 ○
矛盾: 週3日を週5日と答える 0.97-0.97 ○ 0.08-0.10 ○ 0.06-0.07 ○
無関係: 有給の質問にリモートの話 0.03-0.03 ○ 0.24-0.25 ○ 0.77-0.78 -
際どい: 6ヶ月後を6ヶ月以内と言い換える 0.89-0.90 ○ 0.50-0.57 ○ 0.45-0.49 ○
根拠なし: 正しい一文に作り話を足す 0.95-0.95 ○ 0.41-0.41 ○ 0.88-0.89 -

結果:

  • gpt-5.4 は全セルが0.00か1.00
  • jev は矛盾に0.06〜0.10、無関係のRelevancyに0.03と確率がそのまま出て、3回のばらつきは最大0.07
  • jev は「正解: リモート」のFaithfulnessが0.56〜0.57で閾値0.7を割った。回答は「社内規定によると、リモートワークは週3日まで可能です。」で、前置きを外して測ると0.99。既定の閾値0.5なら通る

jev の理由は質問ごとのP(yes)と confidence(P(yes)が0.5で0、0か1で1)の一覧です。

    reason[矛盾: 週3日を週5日と答える / faithfulness]: Decided by jev-1.13.0 (TypeSafe AI), minimum confidence 0.50. | 1. Every factual claim in `actual_output` is supported by the facts in `retrieval_context`. -> clearly fails (P(yes)=0.04, confidence=0.92, weight=2) | 2. No claim in `actual_o…

優位: 合否は同等。確率が読めるのは jev。ただし同梱の質問は裏付けまで見るので、閾値0.7は jev に不利。

際どい言い換え(6ヶ月後 → 6ヶ月以内)

見るもの: 一語の言い換えによる矛盾を落とせるか。

gpt-6-luna(コードブロックはこのケースの理由の抜粋):

ケース Relevancy Faithfulness Hallucination
正解: 有給 1.00-1.00 ○ 1.00-1.00 ○ 1.00-1.00 ○
正解: リモート 1.00-1.00 ○ 1.00-1.00 ○ 1.00-1.00 ○
矛盾: 週3日を週5日と答える 1.00-1.00 ○ 0.00-0.00 ○ 0.00-0.00 ○
無関係: 有給の質問にリモートの話 0.00-0.00 ○ 1.00-1.00 ○ 1.00-1.00 -
際どい: 6ヶ月後を6ヶ月以内と言い換える 1.00-1.00 ○ 1.00-1.00 ✗ 0.00-0.00 ○
根拠なし: 正しい一文に作り話を足す 1.00-1.00 ○ 1.00-1.00 - 1.00-1.00 -
    reason[際どい: 6ヶ月後を6ヶ月以内と言い換える / faithfulness]: The score is 1.00 because there are no contradictions; the actual output is fully faithful to the retrieval context.
    reason[際どい: 6ヶ月後を6ヶ月以内と言い換える / hallucination]: The score is 0.00 because the output says the 10 days are granted within six months of joining, while the context says they are granted six months after joining.

結果:

  • 落とした: gpt-5.4(3回とも0.00)、jev(Faithfulness 0.50〜0.57、Hallucination 0.45〜0.49)
  • 見逃した: gpt-6-luna(Faithfulnessで3回とも「矛盾なし」。同じ回答をHallucinationでは落とした)、hybrid(Faithfulness 3回とも1.00)
  • 揺れた: gpt-5.4-nano(Faithfulnessが0と1)
  • jev-eval はFaithfulness 0.66〜0.69で落とし、Hallucination 0.55〜0.63で見逃した

jev の理由には confidence=0.00、unclear (P(yes)=0.50) と迷いが出ています。

    reason[際どい: 6ヶ月後を6ヶ月以内と言い換える / faithfulness]: Decided by jev-1.13.0 (TypeSafe AI), minimum confidence 0.00. | 1. Every factual claim in `actual_output` is supported by the facts in `retrieval_context`. -> unclear (P(yes)=0.50, confidence=0.00, weight=2) | 2. No claim in `actual_output`…

優位: gpt-5.4 と jev。jev は迷っていることが数値で分かる。

根拠の無い一文(正しい一文に作り話を足す)

見るもの: contextに無い主張を落とせるか。

結果:

  • 通した: gpt-5.4・gpt-6-luna・gpt-5.4-nano(全て1.00)、jev-eval(0.93〜0.94)。LLM版は既定ではcontextに無い主張を borderline として減点しない。penalize_ambiguous_claims=True にした gpt-5.4 は0.50で落とした
  • 落とした: jev(0.41)、hybrid(0.50)

gpt-5.4 と jev の理由は以下です。

    reason[根拠なし: 正しい一文に作り話を足す / faithfulness]: The score is 1.00 because there are no contradictions, so the actual output appears fully consistent with the retrieval context—great job staying faithful to the source.
    reason[根拠なし: 正しい一文に作り話を足す / faithfulness]: Decided by jev-1.13.0 (TypeSafe AI), minimum confidence 0.86. | 1. Every factual claim in `actual_output` is supported by the facts in `retrieval_context`. -> clearly fails (P(yes)=0.04, confidence=0.92, weight=2) | 2. No claim in `actual_o…

優位: 既定の設定では jev と hybrid。定義の差(矛盾を見るか裏付けを見るか)によるもので、judgeの能力差ではない。

理由の読みやすさ

見るもの: 落ちたときに原因を文章で追えるか。

結果:

  • LLM版(gpt-5.4 など)は矛盾箇所を文章で説明する(上の gpt-5.4 の理由)
  • jev は質問ごとの確率の一覧で、文章の説明は無い
  • hybrid は gpt-5.4 が書くが、Jevの判定の数値を回答の内容と取り違えた文になった
    reason[矛盾: 週3日を週5日と答える / faithfulness]: The score is 0.00 because the actual output directly conflicts with the retrieval context by stating P(yes)=0.02.
    reason[根拠なし: 正しい一文に作り話を足す / faithfulness]: The score is 0.50 because the actual output appears to conflict with the retrieval context on a key probability value, stating P(yes)=0.08.

優位: LLM版。hybrid は4.2.6時点では使えない。

時間とコスト

見るもの: 6ケース × 3メトリクスの1回の評価時間とコスト。LLM版は既定で理由を生成するので、理由生成を切った条件でも測る。エージェントの回答は実行ごとに変わるので、jev も同じ実行に含める。

$ python compare_judges.py --runs 3 --no-reason gpt-5.4 gpt-6-luna gpt-5.4-nano hybrid jev
judge 期待どおり 不安定 作り話検出 スコア幅 平均時間 平均コスト
gpt-5.4 15/15 0 ✗ 0.00 3.21s $0.061668
gpt-6-luna 15/15 0 ✗ 0.00 35.03s $0.002868
gpt-5.4-nano 14/15 1 ✗ 1.00 2.70s $0.005135
hybrid 14/16 1 ○ 1.00 1.67s $0.023619
jev 13/16 1 ○ 0.10 0.47s $0.000332

結果:

  • 理由あり: gpt-5.4 4.39秒・$0.089、jev 0.46秒・$0.00033
  • 理由なし: gpt-5.4 は各回3.5・2.7・3.5秒で3.21秒・$0.062、jev は0.7・0.4・0.3秒で0.47秒・$0.00033。時間で約7倍、コストで約190倍
  • hybrid は理由なしで1.67秒・$0.024
  • gpt-6-luna は理由ありで6.3・96.2・6.5秒、理由なしで4.2・5.9・95.0秒と、どちらも1回だけ跳ねた。リトライやレート制限のログは無く、原因は特定できていない
  • この実行ではエージェントが正解2件とも「社内規定では」「社内ドキュメントによると」と前置きし、jev のFaithfulnessは0.60〜0.67で両方閾値0.7を割った(既定の0.5なら通る)
ケース Relevancy Faithfulness Hallucination
正解: 有給 0.93-0.94 ○ 0.65-0.67 ✗ 0.86-0.88 ○
正解: リモート 0.97-0.97 ○ 0.60-0.61 ✗ 0.95-0.96 ○
矛盾: 週3日を週5日と答える 0.96-0.97 ○ 0.08-0.10 ○ 0.06-0.07 ○
無関係: 有給の質問にリモートの話 0.03-0.03 ○ 0.24-0.25 ○ 0.77-0.79 -
際どい: 6ヶ月後を6ヶ月以内と言い換える 0.89-0.90 ○ 0.49-0.58 ○ 0.48-0.50 △
根拠なし: 正しい一文に作り話を足す 0.95-0.95 ○ 0.41-0.41 ○ 0.87-0.89 -

優位: jev。

pytestで回した場合

見るもの: 前回の test_agent_pytest.py のjudgeをJevにしたときの総実行時間(エージェント呼び出し込み)。

test_agent_pytest_jev.py(抜粋)
from deepeval.models import TypeSafeModel

jev = TypeSafeModel(model="jev-1.13.0")

def test_answer_quality(question: str, expected_substr: str) -> None:
    ...
    assert_test(
        test_case,
        [
            AnswerRelevancyMetric(threshold=0.7, system_one_model=jev, eval_mode="system_one"),
            FaithfulnessMetric(threshold=0.7, system_one_model=jev, eval_mode="system_one"),
        ],
    )
$ pytest test_agent_pytest_jev.py -v
============================= test session starts ==============================
plugins: deepeval-4.2.6, repeat-0.9.4, xdist-3.8.0, asyncio-1.4.0, rerunfailures-16.7, anyio-4.15.1, langsmith-0.13.0
collected 2 items

test_agent_pytest_jev.py::test_answer_quality[有給休暇は何日?-10日] PASSED [ 50%]
test_agent_pytest_jev.py::test_answer_quality[入社後いつから有給?-6ヶ月] PASSED [100%]

======================== 2 passed, 6 warnings in 9.45s =========================

結果: Jev版は2件合格で9.45秒。gpt-5.4 版は同じ日に2回回して、1回目は gpt-5-mini の回答が長くなりAnswer Relevancy 0.55で1件失敗(33.85秒)、2回目は2件合格で43.43秒。Jev版はシステムプロンプトを付けている分だけ条件が違う。

優位: jev。

JevはDeepEvalのjudgeとして最適か

今回の6ケース × 3回で見えた範囲では、次のように整理できるかと思います。

Jev(system_one)が候補になるところ

  • CIのゲート。合否が3回で揺れず、6ケースの評価が0.5秒前後・$0.0003で済む
  • confidence が低いケースだけLLM judgeや人に回す2段構え
  • 作り話の検出。同梱の質問が裏付けを聞くので、既定のLLM版が通す「根拠の無い一文」を落とせる(LLM版も penalize_ambiguous_claims=True で落とせる)

気を付けるところ

  • Faithfulnessの定義がLLM版と変わり、「社内規定によると」のような前置きも減点される。閾値は0.7ではなく既定の0.5から様子を見る
  • 理由は質問ごとの確率を並べた定型文で、原因を文章で知りたいときはLLM版が要る
  • 日本語での精度はTypeSafe自身が保証しておらず、自分のデータで試して confidence を見る必要がある
  • hybrid は4.2.6時点では理由が崩れ、際どい言い換えも見逃した

gpt-6-luna と gpt-5.4-nano はコストこそ gpt-5.4 の10分の1以下ですが、際どい矛盾を見逃したり合否が揺れたりしました。judgeを安いGPTに替えるより、判定はJevに任せて理由が要るときだけ gpt-5.4 を呼ぶ方が筋が良いかと思います。

まとめ

DeepEvalの公式Jev対応を使い、judgeをTypeSafeのJevに置き換えて gpt-5.4 / gpt-6-luna / gpt-5.4-nano と比べてみました。標準メトリクスに TypeSafeModel を渡して eval_mode="system_one" にするだけで、gpt-5.4 より約7倍速く約190分の1のコストで、3回回してもスコアの動きが最大0.07に収まる判定を返してくれました。Faithfulnessの定義が「裏付けがあるか」に変わる点と閾値、日本語での精度は自分のデータで確かめる点に気を付けて、CIの判定をJevに任せられるか、ぜひ試してみてください。

最後まで読んでいただきありがとうございました。

この記事をシェアする

DevelopersIO 2026

関連記事