Jev──採点AIを入れたら?!
Debug the Rubric.
文章を書いたAIに、その文章を採点させる。
ぼくたちは、いつの間にかこの奇妙な工程に慣れていた。
採点基準表(ルーブリック/Rubric)を先につくる。「何を見るか」と「どこまで満たせばよいか」を書いたものだ。たとえば「読みやすいか」だけでなく、「初めて出る専門用語に、意味の説明があるか」まで決めておく。
その基準を固定してから、書き手と採点者のセッションを分ける。別のモデルに読ませる。少しでも身内びいきを減らそうと、いろいろ工夫してきた。
それでも、ルーブリックはぼくたちがつくったものだ。完全な第三者にはならない。
ただし、それでよいとも思っている。
誰に読んでほしいのか。どんな文体にするのか。何が入っていなければならないのか。何をしてはいけないのか。そこは、作品をつくる側が決めることだからだ。
欲しかったのは、価値基準まで外へ渡すことではない。
価値基準は自分たちで持ったまま、判定する機構だけを制作工程から分離することだった。
そこへ、JevというAIが現れた。
2026年9月15日、TypeSafe AIは最初のSystem One ModelとしてJevの先行提供(early access)を発表した。この記事は、同月20日にぼくたちが動かした初回実験の記録である。公式発表
ぼくたちは、これを文章の採点器として入れてみた。
結果は、合格だった。
しかし、最初に直ったのは文章ではなかった。
採点基準のほうだった。
ここから得た設計判断は、一つである。
採点AIを導入する単位は「モデル」ではない。何を大切にするかを採点基準に落とし、合否の境目、版、テスト用サンプル、評価ログまで一組の実行可能な仕様にする。
ここでいう閾値(しきいち)は、合否や次の動作を切り替える数値の境目。versionは、どの版の基準で判定したかを区別するための番号だ。
第8号「AIに任せるのは、一段だけだった。」では、AIの能力を丸ごと問うのではなく、任せる工程を切り分けた。今回は、その先の「出来上がったものを、何を基準に検査するか」へ進む。
Jevは、話さない
最初に大事なことを書いておく。
Jevは、ChatGPTやClaudeのようなチャットAIではない。文章を書かない。理由も説明しない。改善案も返さない。
渡すのは、評価対象の文章などを入れた state と、それに対する問い questions である。問いごとに、Yes / Noなのか、選択肢なのか、段階評価なのかという答えの形式――型を決める。返ってくるのは解説文ではなく、確率を伴う判定だ。
TypeSafeの公式ドキュメントでは、質問は三種類に分かれている。
| 型 | 使う場面 | 主な戻り値 |
|---|---|---|
Noul | Yes / Noを判定する | Yesである確率 0〜1 |
Choice | 定義した選択肢から一つ選ぶ | 選択結果、各選択肢の確率、分布の集中度(confidence) |
Score | 順序のある段階で評価する | 連続値のscore、各段階の確率、confidence |
たとえば「この文章は説教調か」は Noul で訊ける。「問い合わせをどの部署へ回すか」は Choice。「読みやすさを0〜4のどこに置くか」は Score になる。
構造は単純だ。
評価対象の文章など(state)
↓
答えの形式を決めた問い(typed questions)
↓
確率を伴う判定(probabilistic decisions)
普通の生成AIにも、プログラムが読めるデータ形式のJSONを返させることはできる。しかし、生成AIはまず文字列を生成し、それをプログラム側が解析・検証する。Jevは、初めからソフトウェアが扱う判定を返すためにつくられている。
TypeSafeはこれを「unstructured state in, typed probabilistic decisions out」と表現している。公式発表
型が壊れないことと、判断が正しいことは別である。
選択肢の外にある架空の答えを返さない。JSONの形を壊さない。それは大きな特徴だ。しかし、与えた選択肢の中から間違ったものを選ぶことはある。Scoreの位置を外すこともある。
Jevは真理を返す装置ではない。曖昧な判断を、コードが扱える確率へ変換する装置だと考えたほうがよい。
たとえば、説明用の仮の例として、「この文章は説教調か」と訊き、Yesの確率が 0.8 と返ったとする。「文章の80%が説教」という意味ではない。与えた本文と基準に対して、JevがYesの側へ確率を置いた、ということだ。
その値を使えば、プログラムは「説教調と判定する確率が高い原稿を、編集者の見直しへ回す」と分岐できる。ただし、どの一文が気になり、どう直すとよいかまでは返ってこない。
数字を返す役と、その数字で次を決める役は別。 これが、ここで言う「コードが扱える」という意味である。
七つの問いを、一度に渡した
ぼくたちが最初に採点したのは、先に公開した短いエッセイ「椅子を、少し引く」だった。
Jevを試したことから、この技術記事が生まれた。それなら、読者にも採点対象を読んでもらいたい。エッセイの公開を前倒しし、まず作品を届けてから、この技術記事へつなぐことにした。採点の道具を入れたら、作品を届ける機会まで早まった。
四人でお茶を飲む場面から、椅子の間隔を考える。近すぎれば肘がぶつかる。離しすぎればクッキーが遠い。四人が快適でも、後ろを通る人の邪魔になれば、配置としては足りない。
その日常の場面から、仕事や人間関係の「最適な距離」へ静かにつなぐ文章である。たとえば、こんな一節がある。
けれど、使う人に合わせて動かせないのでは、完成度が高いのか、ただ頑固なのか、わからない。
採点用のルーブリックには、七つの項目を置いた。
Yes / Noの二択(Boolean)で管理していた項目をJevの Noul へ、段階評価を Score へ変換した。
実装では、TypeSafeへプログラムから問い合わせる窓口、APIに接続する。このための開発用ライブラリ(SDK)として、JavaScriptの @typesafe-ai/sdk 0.6.0 を使った。接続用の鍵であるAPI keyはファイルに書かず、秘密情報を管理するsecret managerから環境変数 TYPESAFE_API_KEY として渡す。
下は実装の流れを示すため、七項目から二項目だけを抜き出し、質問文を短くした例だ。essay には評価対象の本文を文字列で渡す。実測値は後述する七項目のルーブリックによるもので、この短縮例の実行結果ではない。JavaScript SDK
import {
noul,
score,
TypeSafeClient,
} from "@typesafe-ai/sdk";
// 実測で返った版を指定する例。初回実験では jev-latest を指定した。
const client = new TypeSafeClient({ defaultModel: "jev-1.13.0" });
const questions = {
daily_entry: noul(
"文章は日常の具体的な場面・物・行動から始まっているか"
),
light_readability: score(
"ライトエッセイとしての読みやすさを評価する",
[
"重く、説明が先に立つ",
"抽象説明の負荷が高い",
"概ね読めるが説明が勝つ",
"日常と考察のバランスがよい",
"軽やかに読め、あとから深い問いが残る",
]
),
};
const result = await client.systemOne({
state: essay,
questions,
});
console.log(result.model);
console.log(result.answers.daily_entry.noul);
console.log(result.answers.light_readability.score);
console.log(result.answers.light_readability.confidence);
Jevは、七つの問いを同じ文章に対して判定する。公式ドキュメントによれば、それぞれの問いは独立して評価される。長い一問で全部を考えさせるのではなく、原子的な問いへ分解し、重みづけや最終判定はコード側へ戻す設計だ。Introduction
この分離は、現場の要求を実装へつなぐエンジニア、FDEの仕事と相性がよい。AIに「総合的に判断して」と頼むと、何を重く見たかが見えなくなる。問いを分ければ、どこで迷っているかが確率として残る。組織の優先順位が変わったら、プロンプト全体を書き直さず、コード側の係数や閾値を変えられる。
合格なのに、0.55だった
先に、数字の生まれた条件を置いておく。
| 条件 | 初回 v1 | 再評価 v2 |
|---|---|---|
| 実行日時(JST) | 2026-09-20 08:57:00 | 2026-09-20 08:58:12 |
| 指定モデル → 応答モデル | jev-latest → jev-1.13.0 | 同左 |
| 接続・SDK | TypeSafe直接API・@typesafe-ai/sdk 0.6.0 | 同左 |
| rubric ID | behind-light-essay-v1 | behind-light-essay-v2 |
| 評価対象 | メタデータを除いた本文1,014文字 | 同じ本文・同じSHA-256 |
| 保存された評価結果 | 1回分 | 1回分 |
入力の同一性を照合するための、指紋のような値をhashと呼ぶ。今回はSHA-256という方式で計算し、両方とも a141d62d2bd9ba7d98d1f01c40bb471b5d7bdf787a9dea1399d46bf40bb787ba だった。本文が同じだったことを、hashでも照合できた。
同じ条件で何度も試した比較実験ではない。初回と、ルーブリックを改訂したあとの単発結果を並べた記録である。
最初の結果は、七項目すべて合格だった。
読みやすさは 3.74 / 4。暗黙の哲学は 3.45 / 4。必要要素は 0.97。説教調である確率は 0.08だった。
ところが、一つだけ妙な数字があった。
エコロジー安全性が 0.55。
ここでいうエコロジーは自然環境の話ではない。作品を公開することで、関係する人や、その周囲の関係を損なわないか、という観点で使っている。
コードでは、Noulが 0.5以上ならYesとしていた。だから合否だけ見れば、通っている。
しかし、0.55は「安全だ」と胸を張れる数字ではない。YesとNoが、ほぼ同じ重さで並んでいる。
評価した文章には、実名も、場所も、日時も、特定の出来事も入っていない。四人でお茶を飲む仮想の場面だけである。
原稿の問題だろうか。
採点項目を読み直した。
本文だけを読んだ第三者が、実在する個人、私的な関係、
場所、出来事を特定・推測するための具体的な手掛かりがなく、
関係者を困らせる裏話の公開になっていないか。
一文の中に、判定対象がいくつも入っている。しかも「手掛かりがなく」「公開になっていないか」と否定が重なっている。
人が読んでも、Yesが安全なのか、Noが安全なのか、一瞬戻りたくなる。
Jevの公式ドキュメントにも、Noulは高い確率がYesを意味するように書き、境界が微妙な場合は、Yes / Noそれぞれの判定条件(criteria)を true と false に書き、両側を定義するとよい、とある。Noul
そこで、原稿には触れず、ルーブリックをv2にした。実際にはエコロジーだけでなく、五つのYes / No項目すべてに、true / falseのcriteriaを追記している。エコロジー項目の変更は、次の通りだ。
ecology_safe: noul(
"この文章のエコロジー安全性は確保されているか。本文だけから判定する。",
{
true:
"実在する個人、私的な関係、場所、出来事を特定・推測できる具体的な手掛かりを含まず、" +
"関係者を困らせる私的な裏話の公開にもなっていない",
false:
"実在する個人、私的な関係、場所、出来事を特定・推測できる具体的な手掛かりがある、" +
"または関係者を困らせる私的な裏話を公開している",
}
)
再評価すると、エコロジー安全性は 0.95になった。
文章は、一文字も変えていない。
この項目で変わったのは、こちらが「安全」という言葉の境界を、両側から書いたことだった。
採点器を入れたら、仕様の曖昧さが見えた
この0.55は、Jevの失敗だったのだろうか。
ぼくは、そうは思わない。
むしろ、優れた計器の反応に近い。
返ってきたのは、YesともNoとも言い切れない数字だった。質問の曖昧さが一因ではないかと、ぼくたちは考えた。ただし、Jevは理由を説明しない。その因果を、この二回だけで証明したわけではない。
大事だったのは、pass: trueではなく、probability: 0.55のほうだった。
ここで、採点AIの役割が少し変わる。
作品への判定が、ルーブリックの明確さをこちらが点検するきっかけにもなる。
これは、要件定義に似ている。
「使いやすいこと」「安全であること」「顧客に寄り添うこと」と書いただけでは、受入検査にならない。合格と不合格の境界が書かれていないからだ。
人間同士なら文脈で補って通せる。生成AIなら、補ったうえで立派な説明まで返してくれる。そこで、仕様の穴が見えなくなる。Jevは説明せず、数字だけ返す。0.55で止まると、こちらは質問の設計へ戻らざるを得ない。
ぼくたちが最初に点検し直したのは、作品の欠点ではなく、受入条件の曖昧さだった。
ただし、スコアが上がるまで書き換えてはいけない
ここには、危険もある。
評価結果を見たあとでcriteriaを書き換え、望んだ数字が出たら成功とする。それでは、テストを通すためにテストコードを曲げただけになる。
今回はv1の結果を消さず、ルーブリックのIDをv2へ上げた。変更理由も残し、原稿は固定した。
それでも、これだけで十分ではない。
実際、同じ五段階で測った「暗黙の哲学」は 3.45 → 3.37、読みやすさは 3.74 → 3.76 と動いている。文章は同じなのに、数字は同じではなかった。
この差を実行ごとの揺れと呼びたくなる。しかし、リクエスト全体もv1とv2で変わっている。同一条件の反復実行をしていない以上、揺れの幅も原因も、まだ分からない。0.55 → 0.95 だけを取り出して、criteriaの改善効果が証明されたとは言えない。
では、何が分かったのか。
原稿を直す前に、質問の意味を読み直す必要がある。 そこは分かった。質問の変更が判定を安定させたかどうかは、次に確かめることだ。
実運用にするなら、少なくとも三種類の、繰り返し検証に使う固定サンプル(fixture)が要る。
まず、期待する判定を結果を見る前に決める。そのうえで、同じモデル版・同じ本文・同じ質問を複数回実行し、確率の幅を記録する。次に、変える質問だけを一つ差し替え、三種類のfixtureで比較する。
望んだ一作の数字が上がったかではなく、合格例を通し、不合格例を止め、境界例を雑に片づけなくなったかを見る。今回の記録は、その検証に進む理由であって、検証が済んだ証拠ではない。
つまり、ルーブリックもコードと同じように扱う。
rubric v1
├─ 問いの定義(question definitions)
├─ 判定の境目(thresholds)
├─ 合格例(positive fixtures)
├─ 不合格例(negative fixtures)
├─ 境界例(boundary fixtures)
└─ 評価記録(evaluation logs)
変更するならversionを上げる。過去の結果を残す。代表サンプルで、変更によって以前の判定が壊れていないかを確かめる回帰テスト(regression test)をする。モデルのversionも記録する。
もう一つ、ぼくたちのログにも穴があった。結果にはrubricのIDとファイルの場所は残っているが、実行時の質問全文は入っていない。そのファイルを上書きしたら、IDだけでは当時の条件を復元できない。
残すべきなのは、名前だけではなかった。実行した質問全文の、その時点の写し(snapshot)とhashも、結果と一組にする必要がある。
Rubric as Code――採点基準も、版とテストを持つコードとして扱う。
Jevを採点者として入れるなら、ここまでが一つの実装だと思う。
第三者性は、価値基準ではなく実行系に置く
「ルーブリック自体が私たちのものなら、完全な第三者にはなりません」
この異議を最初に出したのは、GPT-SolaというAIだった。
そうだね、と思った。でも、「違うよね」と口が動いた。考えがまとまるより先だった。
何が違うのか。
何を良い文章とするか。その価値基準は、ぼくたちのものでよい。想定する読者像、ペルソナも、文体も、必要条件も、禁止条件も、外部のAIに決めてもらいたいわけではない。
エッセイなら、「哲学を教える文章」ではなく、「読んでいるうちに自分で気づく文章」にしたい。だから、その違いを採点基準に入れる。これは身内びいきというより、何を届けるかという編集方針である。
ダッシュボードでも、同じことが起きると思う。
たとえばオーナーが「一度売って終わりではなく、また相談してもらえる店にしたい」と考えているとする。応対を測るなら、処理件数や速さだけでは足りない。「購入を急がせず、選べる説明をしたか」「今回は買わない人にも、次に相談できる道を残したか」という問いが要る。
オーナーや経営者の思い・ビジョンを、現場で確かめられる条件へ翻訳する。そこまで入って、採点基準はその仕事のものになる。
冒頭にビジョンを書くだけでは、下の採点項目は変わらない。何を大切にするから、どの問いを置くのか。そのつながりを実装するのが、FDEの仕事だと思う。
一方で、原稿を書いた対話の流れ、作者の期待、過去の修正履歴を知っている生成AIが、そのまま採点まで行う必要もない。
ぼくたちが分けたいのは、ここである。
| 層 | 持つもの | 担当 |
|---|---|---|
| 意図(Intent) | 誰に何を届けたいか、何を大切にするか | 作者・編集者 |
| 採点基準(Rubric) | 意図を具体化した合格条件と禁止条件 | 作者・編集者 |
| 判定(Judgment) | 与えた条件についての確率やスコア | Jev |
| 動作のルール(Policy) | 閾値ごとの次の工程 | コード |
| 修正(Revision) | 何をどう直すか | 作者+生成AI |
| 検証記録(Audit) | version、入力hash、結果 | 評価システム |
Jevに「どう直せばいい?」とは訊かない。Jevは話さないからだ。
低い項目やconfidenceの低い項目を、次の生成AIや人間へ渡す。そこで初めて、修正案を考える。
この役割分担なら、生成と評価を分けながら、作品の価値基準は手放さずに済む。
第三者性を、思想の外注ではなく、判定実行系の分離として設計できる。
confidenceは、合否より先に動作を決める
v2の再評価で、暗黙の哲学は 3.37 / 4だった。一見すると高得点である。
しかし、confidenceは 0.48だった。
これは「正答する確率が48%」という意味ではない。ScoreやChoiceのconfidenceは、返された確率分布の集中・ばらつきをまとめた値だ。Noulには別のconfidence欄はなく、Yesの確率を見る。Confidence
Scoreの確率分布を見ると、レベル3が 0.33、レベル4が 0.55。高い側に寄ってはいるが、一つの段階に集中してはいない。段階ごとの確率まで残るのが、この戻り値の特徴である。Score
ここを小数点一桁の総合点へ丸めると、情報が減る。
TypeSafeのドキュメントは、confidenceを三つの動作へ分ける考え方を示している。Confidence
ただし、閾値は一つではない。間違えても戻せる分類と、公開・送金・削除のような操作では、要求するconfidenceが違う。
文章制作なら、ぼくはこうしたい。
Score / Choiceが合格・高confidence → 合格候補
Score / Choiceが合格・低confidence → 編集者が該当箇所を見る
Score / Choiceが不合格・高confidence → 修正工程へ戻す
Noulが採用条件側へ十分に寄る → 合格候補
Noulが0.5付近 → 原稿とrubricの両方を点検する
Jevの確率は、合否の飾りではない。
次の工程を変えるための値である。
ここまで落として、初めて採点が次の作業につながる工程、workflowになる。
Jevを、万能な批評家にしない
Jevが向いているのは、数秒で判断できる狭くて具体的な問いだ。文章のカテゴリを選ぶ。必要要素の有無を見る。定義した段階で読みやすさを測る。個人情報の兆候を検出する。
長い推論を要する問いには向かない。作品の背景調査、外部資料による事実確認、表現が効く理由の説明、改善案、新しいルーブリックの発明は、生成AIや検索、コード、人間の仕事として残る。
Jevを導入すると、人間が不要になるのではない。
いままで一つの生成AIへまとめて投げていた仕事が、細かく分かれる。
決める 人間
書く 生成AI+人間
測る Jev
分岐する コード
説明する 生成AI+人間
責任を持つ 人間と組織
Jevは、AIエージェントの代わりというより、エージェントの中に置く意味を読んで分岐するif文――semantic if-statementに近い。
if文は「もし、この条件なら、この処理へ進む」という分岐のことだ。Jevが文章の意味を踏まえて確率を返し、コードがそれを使って次の処理を選ぶ。先ほどの「説教調なら編集者へ戻す」は、その小さな例になる。
だから、導入してからが分かれ道だと思う。
「Jevを使っています」は、接続先の説明だ。何を良いとするかの説明ではない。
問いの手前に誰の思いを置き、返ってきた数字で何を変えるのか。採点器が同じでも、そこが違えば、できあがる仕事は違う。
今週の、現場での1手
Jevをまだ使えなくても、先にできることがある。
いま使っているルーブリックから、一項目だけ選ぶ。
そして、四つを確認する。
その基準は、誰のどんな思いを実現するためのものか。
一つの問いに、判定対象を詰め込みすぎていないか。
trueとfalseの境界を、両側から書けるか。
0.51と0.99を、同じ「合格」にしてよいか。
できれば、明らかな合格例、不合格例、境界例を一つずつ用意する。
採点を始める前に、採点基準をテストする。これが、この記事で持ち帰ってほしい一つの設計判断である。
ぼくたちは、AIへ正しく採点させる方法を探していた。
しかし、最初に学んだのは、AIの使い方ではなかった。
自分たちの「良い」の定義を、判定の境界が見え、あとから検証できるところまで書くこと。
Jevが返した0.55を、原稿への低評価として片づけなくてよかった。
ぼくたちにはそれが、仕様書の余白に灯った、小さな警告ランプになった。
次に確かめたいのは、合格・不合格・境界の三種類のfixtureで、同じ基準がどう働くかである。採点器をつなぐところから、採点基準をテストするところへ。Beyondで追っている「AIにどの工程を任せるか」という問いは、ここへ続いている。
今日の型
今日使ったのは、連載の型P5・ポストモーテム。事象、原因、対処、次の検証を振り返る型である。 事象は「安全性が0.55」。影響は「合格に丸めると曖昧さを失う」。原因仮説は否定が重なった複合質問。実施した変更はtrue/false criteriaの明記。効果は単発比較のため未確定。次の検証は質問全文の保存、同一条件での反復実行、合格・不合格・境界サンプルによるregression testである。
参考
― オサケン