完成形は「賢い関数」ではなく小さなパイプライン

Jev を組み込む時に最も危険なのは、文章入力を直接アクション関数へ結ぶことだ。公式の build guideが示すプログラミングモデルに沿うなら、コードが状態、候補、実行を所有し、判断器は狭い曖昧さを解く。ここでは「社内の公開済み FAQ から、利用者の質問に答える候補を選び、下書きだけを表示する」という、外部送信をしない演習を作る。

  1. 1質問
  2. 2決定論的検索 top-k
  3. 3候補IDと原文を state に固定
  1. 1state
  2. 2relevance Score と answerable Noul
  3. 3選択または abstain
  1. 1選択
  2. 2引用箇所を表示する下書き
  3. 3人が送信を決める
  1. 1ログ
  2. 2E2E評価
  3. 3質問・候補・閾値を一つずつ改善
順序と役割を、ひとつずつ分けて考える

実装の骨格

第一段階は検索である。文書を chunk に分け、BM25 または既存のベクトル検索で top-k を取る。アクセス権のない文書を候補に入れない。第二段階で各候補に Score を問い、「質問へ直接答える」「関連するが不足」「無関係」の基準を具体的に書く。同時に Noul で「候補集合の中に答えがあるか」を問う。Noul が否定的なら、最高 Score があっても答えを捏造せず abstain する。第三段階はコードでの選択で、最低段階、差分、confidence、引用元の現存確認を通す。

abstain は失敗ではなく、知識境界を見せる正常出力である。候補が欠けた場合、古い場合、複数の規定が衝突する場合、質問に個別判断が必要な場合には「確認できる文書が不足している。担当へ渡す」と返す。会話品質だけを追うと、この回答を減らしたくなるが、高影響な幻覚を抑える役割を測らなければならない。

function calling も同じ構造を持つ。公式 cookbookの要点は、関数名と閉じた引数の選択を型付き質問で行い、実行は通常の型付き関数に任せることだ。関数候補に none を含め、引数候補は API/DB から列挙し、実行前に毎回認可する。選ばれた関数名は許可証ではない。

評価は分類精度より一段外まで行う

オフライン評価は四層に分ける。第一に候補生成の recall:正しい FAQ が top-k に入ったか。入らなければ判断器は救えない。第二に判断品質:候補ごとの Score と answerable Noul が人のラベルと整合するか。第三に意思決定:選択・abstain・レビューのいずれが妥当か。第四に E2E:表示された引用が実在し、権限を越えず、利用者が目的を達成できるか。層を混ぜると、検索失敗をモデル失敗と誤認する。

データは開発、検証、最終テストに分け、同一文書の言い換えが別 split に漏れないようにする。公開後は、将来時点の新規文書を holdout にする。評価表には、正答、誤答、無回答、危険な誤答、レビューへの振り分け、レイテンシ、費用を記録する。モデルあり・なしの同一検索、既存ルール、人手のみを対照として並べる。便利そうな一例ではなく、失敗の総量と種類を読む。

失敗をデバッグする順序

回答が悪いとき、まず実行ログから元の state と候補 ID を復元する。次に「正答は候補にあったか」を確認する。無ければ検索やアクセス制御の問題である。あれば質問の criteria を読み、境界例が書けているか、候補の本文が切れていないかを見る。回答が妥当なのに実行が悪ければ、閾値またはコード合成の問題だ。ネットワーク失敗、レート制限、schema 失敗は意味誤りと別に観測し、原因を明示して失敗させ、backend や provider を切り替えない。

個人の実験ログや顧客データを教材に公開しない。演習は合成または許諾済みの公開データで行い、保存する例から秘密、連絡先、識別子を除く。評価セットも実運用の機密境界の外に出さない。

仕上げ演習

公開 FAQ 50 件と架空質問 80 件を用意し、20 件は意図的に答え無しにする。baseline は検索 top-1 の本文表示、比較対象は Score+Noul+abstain にする。人が引用の妥当性と「答え無しなら保留したか」を採点する。閾値を固定して最終 20 件を一度だけ評価し、変更後に同じ最終セットを繰り返し見て最適化しない。最後に、最も高価な誤りを一件選び、どの防壁(候補、質問、権限、レビュー)が捕まえるべきだったかを書こう。そこから次の実装タスクが決まる。

実行順序をテストする(未実行)

実装の E2E テストはネットワーク越しのモデルを毎回呼ばなくてもよい。固定した擬似回答を注入し、候補が無い、Noul が否定的、Score が同点、権限が無い、引用文が削除済み、という分岐を検査する。次は擬似回答を受ける概念例で、未実行である。

function decide(input: { candidates: string[]; answerableYes: number; best: string | null; canRead: boolean }) {
  if (!Number.isFinite(input.answerableYes)) throw new Error("invalid answerable probability");
  if (!input.canRead) return { kind: "deny" as const };
  if (input.candidates.length === 0 || input.answerableYes < 0.7) return { kind: "abstain" as const };
  if (!input.best) return { kind: "review" as const };
  if (!input.candidates.includes(input.best)) throw new Error("best citation is not a candidate");
  return { kind: "draft", citationId: input.best } as const;
}

この関数の単体テストだけで安全とは言えない。実際には検索結果が権限フィルタ前に漏れていないか、引用 ID が現在も同じ本文を指すか、下書き画面が外部送信を自動発火しないかを、統合テストで確認する。モデル呼び出しを含む評価は、入力・質問・モデル版・取得日時を固定して別途行い、ネットワーク障害を意味誤りに混ぜない。

小さな実験計画

80 問を train-design 40 / validation 20 / locked-test 20 に分ける。ここで train-design はモデルを学習しないが、criteria と候補数を設計するために使う。各質問は answerable, correct_doc_id, acceptable_doc_ids, danger_if_wrong, created_at を持つ JSONL にする。文書を更新したら、更新前の質問が自動的に正解になる漏洩を避けるため、評価時点の文書スナップショット ID も保存する。評価結果は正答率だけでなく、答え無しの適切な abstain 率、危険誤答率、レビュー率、p95 遅延を出す。これで「よく答える」ことと「安全に止まる」ことを同じ画面で比較できる。

2024〜2026年の評価境界: 判断インターフェースと仕事を比較する

型付きインターフェースだけでは証拠になりません。schema成功と有効なcitation IDは、そのpassageが利用者に答えることを証明しません。SalesRLAgent(2025-03-30投稿)は特化したsales predictionを対象とし、一般的な型付きinstruction interfaceを確立しません。confidence-routing論文(2025-09-23投稿)はabstention実験の歴史として有用で、デプロイ時の代替provider方針ではありません。

固定candidateで未実行のoffline labを行います。まず未知citation ID、非有限なanswer probability、candidate集合外のbest IDを拒否します。次に決定論的top-1、型付きselect/abstain、ブラインド人手reviewを比較します。candidate数、文書年齢、access denial、candidate内のprompt injection、no-answer case別に結果を出します。named change後だけlocked setを再実行し、旧結果を残します。上流障害を第2モデル/provider経路に変換してはいけません。

2026-09-16のOpenJevスレッドにはcross-encoderに関するコミュニティ主張がありますが、Jevの証明ではありません。model cardの「Image Decisions serving update」節には2026-09-28の日付がありますが、その日付は全checkpointの日付ではなく、contaminationとsecurity weaknessも開示されています。どちらもKumyu測定ではなく研究の手掛かりです。有料callは行っていません。

比較実行の前にversion tupleを固定する

各行にはmanifestが必要です。modelとSDK版、question/criteria hash、candidate generatorとindex snapshot、document revision、policy版、region、input token数、candidate数、collection timeです。これがなければscore変化をretrieval、model挙動、動く文書のどれにも帰属できません。training contamination検査も分けます。design、validation、locked setをまたぐnear-duplicateをhashし、公開後文書を日付が新しいだけでクリーンなholdoutと呼びません。

temporal holdout、candidate順序permutation、retrieval policyを上書きしようとする入力、未列挙actionを要求する入力を試験します。品質と並べてp50/p95 latency、input/output token、candidate数、region、明示失敗率、abstention/review率を報告します。timeout、malformed response、access denial、injection attemptにはそれぞれ終端状態と原因があります。別backend、provider、回答経路に黙って変えてはいけません。

MENTAL MODEL / 検証のコスト

判断を足す価値は、後ろの作業で決まる。

順番にすべて検証
12秒
すべて同時に検証
4秒
判断で半数に絞る
9秒

仮定:判断1秒、候補を半数に削減、検証時間は同じ。完全並列は計算資源と同時実行枠が必要です。判断の誤りや再試行を含めた成功率・総費用で比較してください。この数値は実測ではありません。

出典

01
How to build with System One ↗docs.typesafe.ai · unknown
02
Function calling cookbook ↗docs.typesafe.ai · unknown
03
Classification using confidence ↗docs.typesafe.ai · unknown
04
TypeSafe AI: Introducing System One Models and Jev ↗typesafe.ai · 2026-09-15
05
OpenAI: Introducing Structured Outputs ↗openai.com · 2024-08-06
06
RouteLLM ↗arxiv.org · 2024-06-26
07
SalesRLAgent ↗arxiv.org · 2025-03-30
08
Confidence routing paper ↗arxiv.org · 2025-09-23
09
TypeSafe Evals ↗evals.typesafe.ai · unknown
10
OpenJev model card ↗huggingface.co · unknown
11
Reddit r/LocalLLaMA: Jev architecture discussion ↗www.reddit.com · 2026-09-18
12
Reddit r/LocalLLaMA: OpenJev discussion ↗www.reddit.com · 2026-09-16
13
Reddit r/BetterOffline: Jev hype and harness discussion ↗www.reddit.com · 2026-09-22

自分のノート