メインコンテンツへスキップ
2026年9月25日
Laravel AI分類 Jev 生成AI 業務自動化

執筆:株式会社イー・トライアド

LaravelからJevを使う:型付きの判断を業務フローにつなぐ

米TypeSafe AI社のJevは、Choice(選択肢)、Score(段階評価)、 Noul/Boolean(二択)などの型付き判断を高速に回答することに特化したAIモデルです。この記事では業務連絡と経費判定を例に、Jevへの置き換えを検討する際の質問設計と、結果を確信度やPHP側の業務ルールにつなぐ方法をサンプルコードで紹介します。

LLMの構造化出力(Structured Outputs)で分類や評価を行っている処理では、Jevへの置き換えが選択肢になる場合があります。Jevは型付きの判定結果を返すよう設計されており、対象タスクによってはLLMを使う場合に比べ、API費用や応答時間を大幅に下げられることが期待できます。問い合わせの種類や担当部門、承認の要否のように、判定項目と回答形式を事前に定義できる処理が候補です。実際の削減幅や判定品質は、入力、質問数、比較対象のモデルや設定によって変わるため、同じ条件で確かめる必要があります。

問い合わせをLaravelからJevへ送り、分類結果と確信度を確認したあと、担当部門への割り当てか担当者の確認へ振り分ける流れ
Jevの分類をもとに、Laravelが担当部門への割り当てや担当者への確認を行います。

Jevは「文章を書くAI」と役割が違う

型付きで回答が返ることは、業務判断の正しさを保証するものではありません。確信度や回答値を確認し、再現性が必要なルールや副作用はアプリケーション側に残します。

処理の役割を分けると、次のようになります。

担当向いている処理例
LLM文章生成や複雑な推論要約、回答案、計画
Jev候補が決まった分類や評価担当部門の選択、緊急度、承認要否
PHPなどのプログラム再現可能な業務ルールと副作用閾値判定、権限確認、DB更新、担当割当

Jevモデルそのものの賢さについては判断系のタスクにおいてベンチマーク上はGPT-5.6 Terra相当の精度を持っているようです。

JevはLLMや通常のプログラムを置き換えるものではありません。曖昧さを含む小さな判断を受け持たせ、その結果を使う処理はアプリケーション側に残します。

サンプルコードで扱う2つの業務フロー

ここでは、業務連絡のルーティングとレシートの経費判定という2つのサンプルを紹介します。いずれもJevが型付きの判断材料を返し、業務フローを進めるかどうかはPHP側で決めます。

業務連絡のルーティング

社内の業務連絡を分類し、担当部門への振り分けにつなげるサンプルです。確信度が低い内容はレビューに送り、緊急度や承認要否に応じて別の処理へ分けます。Jevは振り分けの判断材料を出し、最終的なルート選択や承認処理はPHP側で行います。

Jevに5つの判定をまとめて送る

TypeSafe APIには、選択肢から1つを選ぶ Choice、段階を評価する Score、はい・いいえの確率を返す Noul があります。Laravel AI SDKでは、二値判定を Boolean として扱います。

業務連絡のルーティングでは、連絡の種類と担当部門、緊急度、承認フローの要否、店舗への回答の要否を1回のリクエストで分類します。以下は、メッセージから状態を作り、質問をまとめてJevへ送るコードの抜粋です。候補と評価段階はサンプル内で定義しています。

use Laravel\Ai\Classification;
use Laravel\Ai\Classification\Boolean;
use Laravel\Ai\Classification\Choice;
use Laravel\Ai\Classification\Score;

$state = [
    'channel' => $message['direction'] === 'hq_to_store' ? '本部→店舗' : '店舗→本部',
    'store' => $message['store'],
    'subject' => $message['subject'],
    'body' => $message['body'],
];

$questions = [
    'intent' => new Choice('この業務連絡の種類は何か', $intents),
    'route_to' => new Choice('この連絡はどの部門・担当が対応すべきか', $departments),
    'urgency' => new Score('この連絡の対応緊急度はどの程度か', $urgencyLevels),
    'needs_approval' => new Boolean('この連絡は申請・承認フローの起票を必要とするか', [
        'true' => '上長や本部の承認を必要とする申請・報告である',
        'false' => '承認不要の確認・質問・情報共有である',
    ]),
    'needs_reply' => new Boolean('店舗(発信元)への回答・フィードバックが必要か'),
];

$response = Classification::of($state)
    ->questions($questions)
    ->timeout(30)
    ->classify(model: 'jev-latest');

Laravel AI SDKのプロバイダー設定でJevを選び、モデル名と TYPESAFE_API_KEY を設定します。 回答は $response->answer(‘route_to’)->choice のように取り出します。

PHP側の業務ルールで振り分ける

型付きの回答でも、分類が常に正しいとは限りません。選択肢の外にある値を返さないことと、正しい部門を選ぶことは別です。サンプルでは、確信度が基準を下回ればレビューキューへ送り、緊急度や承認要否に応じて別の処理へ分けます。

  • 連絡種別または担当部門の確信度が基準未満なら、レビューキューへ送る
  • 緊急報告、または緊急度スコアが0.75以上なら、至急エスカレーションする
  • 承認要否の確率が0.6以上なら、承認フローを起票する
  • それ以外は、判定された部門へ割り当てる

次は、PHP側の分岐を簡略化した抜粋です。サンプル実装では、各分岐に画面表示用のラベルや理由も付けています。

$intent = $response->answer('intent');
$routeTo = $response->answer('route_to');
$urgency = $response->answer('urgency');
$needsApproval = $response->answer('needs_approval');

$lowConfidence = ($routeTo->confidence !== null && $routeTo->confidence < 0.45)
    || ($intent->confidence !== null && $intent->confidence < 0.40);

if ($lowConfidence) {
    return ['type' => 'review_queue'];
}

if ($intent->choice === 'urgent_report' || $urgency->normalized() >= 0.75) {
    return ['type' => 'escalate'];
}

if ($needsApproval->probability >= 0.60) {
    return ['type' => 'approval_flow'];
}

return ['type' => 'auto_assign', 'department' => $routeTo->choice];

このサンプルコードでは、確信度が null の場合は「基準未満」の分岐に入りません。実運用では、確信度を取得できない場合の扱いも含め、レビューに回す条件を明示してください。Jevの回答を使った最終判断や副作用はアプリケーション側に置き、閾値は業務と誤判定時の影響に合わせて検証します。

レシートの経費判定

レシート画像を扱う場合は、まずOCRライブラリや画像対応LLMで店名・業態・購入日時・品目・合計金額・備考を構造化して読み取ります。レシートではない画像や読み取れない画像、品目を抽出できない画像は、この段階でエラーにします。Jev自体はマルチモーダルには対応していないため、OCRで得たテキスト情報を分類に使う構成をとります。

読み取った店名、購入情報、品目、金額、備考をひとつの状態にまとめ、Jevへ5つの質問を一度に送ります。質問は購入区分(Choice、10択)、経費科目(Choice、9択)、業務関連度(Score)、経費計上可否(Boolean / Noul)、経理担当による個別確認の要否(Boolean / Noul)です。

use Laravel\Ai\Classification;
use Laravel\Ai\Classification\Boolean;
use Laravel\Ai\Classification\Choice;
use Laravel\Ai\Classification\Score;

$state = [
    'merchant' => $receipt['merchant'],
    'merchant_kind' => $receipt['merchant_kind'],
    'purchased_at' => $receipt['purchased_at'],
    'items' => collect($receipt['items'])
        ->map(fn (array $item) => "{$item['name']} ×{$item['qty']} ¥".number_format($item['price']))
        ->implode(' / '),
    'total' => '¥'.number_format($receipt['total']),
    'note' => $receipt['note'],
];

// 候補と評価段階は、社内の経費区分・規程に合わせて定義
$questions = [
    'category' => new Choice('この領収書の購入内容の区分は何か', $categories),
    'account' => new Choice('この支出が該当する経費科目は何か', $accounts),
    'business_score' => new Score('この支出の業務関連度はどの程度か', $businessLevels),
    'expensable' => new Boolean('この支出は業務経費として計上できるか', [
        'true' => '業務目的が明確で、社内規程上も経費として計上できる',
        'false' => '私用・個人消費・規程違反などで経費計上できない',
    ]),
    'needs_audit' => new Boolean('金額・用途から見て経理担当による個別確認が必要か'),
];

$response = Classification::of($state)
    ->questions($questions)
    ->timeout(30)
    ->classify(model: 'jev-latest');

回答を受け取った後は、確信度と業務ルールをPHP側で確認して振り分けます。次は decide() の分岐を短く抜き出した例です。ラベルや理由文など、画面表示用データの組み立ては省略しています。

$category = $response->answer('category');
$account = $response->answer('account');
$businessScore = $response->answer('business_score');
$expensable = $response->answer('expensable');
$needsAudit = $response->answer('needs_audit');

$lowConfidence = ($category->confidence !== null && $category->confidence < 0.40)
    || ($account->confidence !== null && $account->confidence < 0.40);

if ($lowConfidence) {
    return ['type' => 'audit'];
}

if ($expensable->probability <= 0.35 || $businessScore->normalized() <= 0.25) {
    return ['type' => 'trash'];
}

if ($needsAudit->probability >= 0.60 || $receipt['total'] >= 30_000) {
    return ['type' => 'audit'];
}

if ($expensable->probability >= 0.65 && $businessScore->normalized() >= 0.50) {
    return ['type' => 'approved'];
}

return ['type' => 'audit'];

この順序で、分類の確信度不足は査定待ちへ、経費計上可否や業務関連度が低いものはゴミ箱へ、監査判定または3万円以上の高額レシートは査定待ちへ送ります。条件を満たしたものだけ、判定された経費科目を付けて経費OKトレイへ進め、それ以外も査定待ちに回します。ここでの金額・確率の閾値はサンプルコードの値です。実際の経費規程や承認フローに合わせて設定します。

なお、この実装ではカテゴリや経費科目の確信度が null の場合、0.40未満の分岐には入りません。実運用では、確信度を取得できない場合の扱いも明示しておきます。

Jev導入前に確認しておきたいこと

入力文の書き方にばらつきがあっても、判定項目と選択肢・評価軸をあらかじめ定義できる小さな判断なら、Jevを候補にできます。判定結果をすばやく受け取り、プログラムの処理につなげたい場合に向いています。一方、長文の要約や文章生成、複雑な多段階推論にはLLM、正確な集計には通常のプログラムなど、処理に合った手段を選びます。

また、外部サービスへ送る入力内容の範囲、低確信度時の扱い、最終判断の責任者も決めておく必要があります。実データを使う場合は、データの取り扱いと利用条件を事前に確認してください。

Laravel AI SDKのClassification APIは、公式ドキュメントで実験的な機能として案内されており、マイナーバージョン間でもAPIが変わる可能性があります。導入時は、利用するSDKのバージョンと最新の公式ドキュメントを照合してください。

まとめ

JevはLLMの代わりというより、分類・評価・ルーティングなどの小さな判断を切り出して任せるためのモデルです。Jevで判定した結果を、どのように活用して業務処理として組み込むかは人が判断や設計を行い、適切にプログラミングのロジック等でハンドリングしてあげる必要があります。

AIに判断材料を出してもらい、アプリケーションが確信度と業務ルールを確認して実行する。 この役割分担が、Jevを既存の業務フローへ組み込むときの基本になります。

公式情報は、Laravel AI SDKのClassificationドキュメントとTypeSafe APIドキュメントをご覧ください。JevやLLMを用いた処理を既存業務へ取り入れる相談については、お問い合わせください。