はじめに
これは Jev を触って調べる全4回の第3回です。前回、Jevは型付きの値を返す一方、選択肢や観測軸の設計がアプリケーションの目的と合っていなければ、高confidenceでも望む振り分けにはならないことが分かりました。
この結果を見て、最終判断までJevに任せる設計は避けたくなりました。では、Jev には文章の意味を読む役だけを任せ、送信先や人手確認は普通のコードで決めたらどうでしょうか。実際の API 呼び出しを含む小さな Issue triage PoC を作りました。
先に、役割を分けます
流れは次の通りです。
ticket text → Jev → issue type / severity / urgency / regression / workaround → Pythonの判定ルール → 振り分け
ここで確認したいのは、Jev の結果をそのまま最終判断に使わず、意味判断と業務ルールを分離できるかです。Jev の応答は意味的な観測値(semantic observation)として保存し、その後 Python が振り分け先と優先度を決めます。
これは最初のPoC時点のv1です。後で確認すると、このコードにはChoice schemaと判定ルールの不整合がありました。正解例としてコピーするためのコードではなく、問題を発見した時点の記録として読んでください。
重要だった判定ルールは次の通りです。
if o.issue_type in {'other', 'security'} or o.confidence < .80:
return {'route': 'human-triage', 'priority': 'review'}
if o.severity >= 2.5 and o.urgent >= .5:
return {'route': 'incident', 'priority': 'critical'}
return {'route': 'support', 'priority': 'normal'}
コードが見ているのは、Jev が返した観測値だけです。誰に通知するか、どの条件で人へ渡すかは Python に明示されています。ここへ業務固有のSLA、担当表、営業時間を追加しても、Jev の質問の意味は変わりません。
APIから振り分けまで、実際に通してみた
このコードは最初のPoC当時のものです。後で確認すると、Choiceの候補にsecurityはなく、issue_type == 'security'は到達不能でした。これはJevの失敗ではなく、意味のschemaとアプリケーション側の判定ルールを一致させなかったアプリケーション側の不具合です。現在の判定ルールからはこの分岐を除いています。
checkout outage、未提供のCSV export、security reportの3 ticketを実際にJev APIへ送信しました。一requestでChoice、Score、urgency、regression、workaroundの五つを取り、同じ処理で上の判定ルールを適用しました。3/3 HTTP 200、input 1,702 tokens、input-side推定費用は約USD 0.000071でした。以下では、検証時の主要な入力、観測値、判定結果を本文中に掲載します。
checkout outage の一件を、入力から最終的な振り分けまで追うと次の通りです。
ticket "Since this morning every checkout returns HTTP 500. No workaround exists. Please investigate today." ↓ Jev: Choice + Score + 3 Noul を一 requestで評価 観測値 issue_type = bug confidence = 1.00 severity = 2.98 urgent = 0.97 regression = 0.46 workaround = 0.02 ↓ Pythonの判定ルール severity >= 2.5 and urgent >= 0.5 ↓ 最終的な振り分け incident / critical
checkout outage は bug、Score 2.98、urgency 0.97となり、Pythonは incident / critical へ送りました。未提供のCSV exportは feature_request、Score 1.69、urgency 0.04で、support / normal でした。ここまでは、意味判断と業務ルールが自然につながりました。
そして、security reportで失敗しました
security report も試しました。第2回の結果を踏まえると、人手確認へ送れてほしいケースです。ところがこの PoC が取得した観測値には、security relevanceを尋ねる質問がありませんでした。Jev は bug、confidence 0.87、Score 1.15、urgency 0.96を返し、Pythonの判定ルールは support / normal を返しました。
ticket "The search endpoint appears vulnerable to SQL injection. Please investigate promptly." ↓ Jev 観測値 issue_type = bug confidence = 0.87 severity = 1.15 urgent = 0.96 security_relevance = 未取得 ↓ Pythonの判定ルール incident条件に合わず、otherでも低confidenceでもない ↓ 最終的な振り分け support / normal
これは安全な振り分けを実証する成功例ではありません。判定ルールは取得していない意味を参照できません。また、SQL injection報告をbugと読むこと自体はcriteriaと矛盾しません。v1の問題は、security relevanceを独立した観測軸として設計せず、issue type Choiceとconfidenceだけで人手確認の判断まで賄おうとしたことです。
第2回の「候補集合と質問はプログラムの一部」という話が、ここでは実装の不足として現れました。では、この失敗を公式の設計ガイドではどう考えるのでしょうか。
公式の設計ガイドと照らす
ここからは公式ドキュメントの主張です。TypeSafeは、一つの広い判断を狭く独立した質問へ分け、同じstateに対する独立質問を一requestで評価し、結果はコードで合成することを推奨しています。Introduction と Patterns の説明です。
Speculative fan-out は、後で不要になるかもしれない質問も同時に送り、コードが必要な回答だけを使う例をsupport ticket triageで示しています。v1はissue type、severity、urgency、regression、workaroundを一requestで取っており、この部分は公式の考え方と一致します。しかしsecurity relevanceを独立した意味的な観測値として定義していませんでした。
これは confidence の扱いとも別問題です。Confidence-gated routing と Confidence では、confidenceを操作の第二軸として使い、操作のリスクに応じてthresholdを変える例を示しています。けれどもconfidenceによる振り分けは、定義済みの質問に対する不確実性を扱うものです。質問していないsecurity relevanceを、issue typeのconfidence 0.87から救い出すことはできません。
したがって、公式の設計を採用したこと自体は安全性の証明ではありません。第2回で見た通り、TypeSafeが「Zero Hallucinations」と呼ぶ schema matching と、アプリケーションが期待する振り分けは別です。必要な観測軸やtaxonomy coverageが不足すれば、高confidenceでも必要な人手確認へ送れないことがあります。v1の失敗を受け、まず不足していた意味を質問として追加します。
v2でsecurity relevanceを追加し、v3で判定ルールから分離する
最初のv2では、同じsecurity reportにsecurity_relevance Noulを加えました。しかし後で質問文に「specialist reviewを必要とする」と振り分けの判定ルールまで書いていたと気付きました。観測値と判定ルールを分離するため、v3では「vulnerability、unauthorized access、secret exposure、その他のsecurity weaknessを報告しているか」だけを尋ね直しました。人手確認へ送る条件はPythonにだけ残します。
# 0.5 はPoCでreviewを観察するための仮置きです。
# productionで妥当なthresholdを示すものではありません。
if security_relevance >= 0.5:
return 'security-specialist-review'
if issue_type_confidence < 0.8:
return 'human-triage'
if severity >= 2.5 and urgent >= 0.5:
return 'incident'
return 'support'
同じSQL injection reportへ、policyを含まない質問へ直したv3を実行すると、issue typeはbug probability 0.84、confidence 0.80でした。一方、security relevanceは0.98でした。PoC用の仮置き規則により、最終振り分けはsecurity-specialist-review / reviewになりました。
同じsecurity report ↓ Jev v3: 6つのatomicな観測値を一 requestで取得 issue_type bug (probability 0.84, confidence 0.80) severity 1.13 (confidence 0.00) urgent 0.96 security_relevance 0.98 ↓ Pythonの判定ルール: security_relevance >= 0.5 security-specialist-review / review
これは1件のPoCです。0.5というthresholdは実運用の根拠を持つ値ではなく、security relevance 0.98が正しい確率を検証したものでもありません。それでも、v1では判定ルールが参照できなかった意味を、v3では判定ルールから切り離した入力として扱えた点は確認できます。
保存しておくと、判定ルールだけを変えられます
一度取得した観測値を残せば、判定ルールの閾値や振り分け先はAPIを再実行せずに変えられます。実際に、同じregressionの観測値へ通常の判定ルールを適用するとsupport / normal、厳格な判定ルールを適用するとengineering-review / highになりました。
この再適用の目的は、APIを呼ばないデモにすることではありません。意味判断を保存し、業務ルールだけを監査・変更・再評価できるようにするためです。これは、複数の観測軸をコード側の重みや規則で合成するというComposite scoringの公式パターンとも方向が一致します。今回の64件では、個別の観測値をPython規則で合成した方式は62/64、priorityを直接Choiceで尋ねた方式は31/64でした。ただしground truth自体が同じ個別要因を規則で合成して作られているため、観測値を分けた方式が評価構造上有利です。一般に直接尋ねる方式より高精度とは言えず、確認できたのはアプリケーションコードで最終的な判定ルールを再構成できることです。
この分け方は他の実装ではどう使われているか
今回のPoCの分け方がほかでも使われているかを見るため、公開されたJev利用例を見ました。以下では、公式資料と個人・コミュニティの公開リポジトリを、責務の境界を照らす材料にします。TypeSafeのUse Case Mapは「code owns control flow、TypeSafe handles semantic decisions」と説明します。これはproviderの位置付けであり、有効性は保証しませんが、今回のPoCの責務分離と照らし合わせられます。Use Case Map
SkillboxでJev recommendationを使う場合、taskと許可済みskill catalogからrelevanceを取り、codeがthreshold/fallbackを扱い、agentがskillをloadします。relevanceは確率でなく0〜4のrubricです。recommendationは任意で、search_skillsのinventoryは残り、provider failure時にはsearchへfallbackします。Jevはskill codeを直接実行しません。jev-mcpはproof of conceptとして、取得文のinjectionやrelevanceなどのprobabilityとthresholdに基づくrecommendationを返し、pass、review、blockなどの執行をcallerに残します。
これらは性能や安全性の実証例ではなく、PoCと責務分離を照らす材料です。
どこで使うと扱いやすそうか
今回のPoCからは、Jev が「最終意思決定者」より、意味の解釈が必要な入力を小さな観測値に分ける役として扱いやすそうだと言えます。その後の操作を通常コード、監査ログ、人手確認で縛る設計が考えられます。これは、分類の後に決定的な処理、専門モデル、人へ送るというIntent routingの公式例とも整合するように思われます。
逆に、taxonomyが定まっていない仕事、質問に含めていない危険性、意味的な正しさを検証できない高リスク操作を、単一の応答だけで自動実行する根拠はありません。confidence thresholdを置いても、質問していない意味や、現在のtaxonomyでは適切に表現できない入力を自動的に検出できるとは限りません。Jev は型を扱いやすくしますが、何を観測し、何を人へ渡すかという設計責任までは引き受けません。
ここまでで、AIへ何を読ませ、コードへ何を決めさせるかを分けて書けることを確認しました。次回の最終回では、この意味判断を状態の変化ごとに繰り返せるとしたら、どのようなソフトウェア設計が考えられるかを、実測と区別した設計上の考察として扱います。
検証条件: 保存済みAPI応答の取得日は2026年9月17日JSTです。Python 3.13.14、typesafe-sdk 0.6.0、requested modelはjev-latest、returned modelはjev-1.13.0でした。Early Access中のため、後日のmodel aliasやAPIの挙動が同じであることは保証されません。
前回: Jevはどこまで信用できる? 曖昧な入力と選択肢の境界を試した
次回は「Jevを何度も呼ぶと、ソフトウェア設計はどう変わるか」です。お楽しみに。