layaとは?日本語の問い合わせを判定させ、料金・使い方を実測した動いた
この日に実際に動かした結果です。内容の誤りに気づかれた場合はお問い合わせください。確認のうえ訂正します。
使う前に分かること
| 必要なもの | Python 3 |
|---|---|
| 動かした環境 | クラウドのサンドボックス、Ubuntu 24.04.5 LTS、Python 3.11.17、laya 0.4.0。 |
| 日本語 | 画面・文書は英語 |
| 確認日 | 2026-10-08(この日に実際に動かした) |
追記(2026-09-20): Jev 本体の承認が下りたので、同じ 40 件を Jev にも流しました。Laya と並べた表は Jev の記事 にあります。
追記(2026-10-08): 公開から3週間でスターが700台から3万超に伸び、pip で入る版も 0.3.3 から 0.4.0 に上がっていたので、同じ40件をもう一度流しました。正解の数(窓口・返金・急ぎ、質問を変えた後の今日中)はどれも前回と1件も変わりませんでした。モデルの重み自体はこの間更新されていないようです。変わったのは速さだけで、今回は GPU の無いクラウドの Linux 環境(CPU 4コア)で試したため、1件あたり 69ms だった前回(Mac の GPU)より遅くなっています。以下の本文は、この再検証の数字に置き換えています。
「返金してほしい」「まだ届かない」「ログインできない」。毎日届く問い合わせを、担当の窓口に振り分けて、急ぎのものを先に拾う。この仕事をAIにやらせたいとき、これまでは ChatGPT のような文章を書くAIに「JSONで答えて」と頼むのが普通でした。返事を待つのに数秒かかり、たまに形式を崩してきます。
TypeSafe AI の Jev は、この「判定だけ」を専門にするモデルです。文章は一切書かず、「窓口はどれか」「返金を求めているか」といった質問に、確率つきで答えだけを返します。ただ、Jev は今のところ申し込んで承認を待つ形で、すぐには触れません。
Laya は、その Jev と同じ形の質問を受け付けるオープンソースのモデルです。pip install で入って、自分のパソコンで動きます。多言語版が用意されていて、日本語も対象に入っています。
今回は、ネットショップに来そうな日本語の問い合わせを 40 件自分で書いて、「窓口」「返金を求めているか」「どのくらい急ぎか」の 3 つを Laya に判定させ、私が付けた正解と何件合うかを数えました。Laya には自分のデータで追加学習させる仕組みもありますが、そこは触っていません。入れたままの状態でどこまで当たるか、だけです。
入れて、まず1件だけ判定させる
Python が入っていれば、pip で入ります。中で PyTorch も一緒に入るので、少し時間がかかります。
python3 -m venv laya-venv
source laya-venv/bin/activate
pip install laya
入ったバージョンを見ておきます。
pip show laya
Name: laya
Version: 0.4.0
Summary: Fast, non-autoregressive System 1 decision engine with calibrated probabilities
使い方は、判定してほしい材料(state)と、質問(questions)を渡すだけです。質問は 3 種類あります。選択肢から 1 つ選ぶ choice、段階で採点する score、はい・いいえの確率を返す noul です。Jev と同じ 3 種類で、書き方もほぼ同じです。
README には Router という入口があって、渡した文章の言語を見て、英語用と多言語用のモデルを自動で選んでくれます。日本語を渡すので、これを使います。まず 1 件だけ、二重引き落としの問い合わせで試してみます。
import json, time
from laya import Router
router = Router()
state = {
"subject": "同じ注文で2回引き落とされています",
"body": "9月15日に注文した商品の代金が、クレジットカードの明細に2回載っています。1回分を返金してください。",
}
questions = {
"department": {
"type": "choice",
"instructions": "この問い合わせを担当する窓口はどれか",
"criteria": {
"billing": "請求、二重引き落とし、返金、領収書",
"shipping": "配送の遅れ、追跡番号、住所変更",
"product": "商品の仕様、サイズ、在庫、使い方",
"account": "ログインできない、パスワード、退会",
},
},
"refund_requested": {
"type": "noul",
"instructions": "お客さんは返金を求めているか",
},
"urgency": {
"type": "score",
"instructions": "どのくらい急ぎか",
"criteria": ["急がない。質問や要望", "早めの対応がほしい", "今すぐ対応が必要。金銭や期日が絡む"],
},
}
t = time.time()
result = router.predict(state, questions)
print(f"elapsed {time.time()-t:.1f}s")
print(json.dumps(result, ensure_ascii=False, indent=2))
これを first.py に保存して実行します。初回だけ、多言語版のモデル(647MB)を Hugging Face から取りに行きます。
python3 first.py
elapsed 16.2s
16 秒のほとんどはダウンロードと読み込みで、判定そのものは一瞬です(GPU の無いこの環境でも、ここは速いです)。返ってきたものの、答えの部分だけ抜き出すとこうです。
"department": {
"type": "choice",
"choice": "billing",
"probabilities": {
"billing": 0.9993,
"shipping": 0.0001,
"product": 0.0005,
"account": 0.0001
},
"confidence": 0.9953,
"refund_requested": {
"type": "noul",
"noul": 0.8857,
"confidence": 0.8857,
"urgency": {
"type": "score",
"score": 1.661,
"legend": {
"0": "急がない。質問や要望",
"1": "早めの対応がほしい",
"2": "今すぐ対応が必要。金銭や期日が絡む"
},
"probabilities": {
"0": 0.0359,
"1": 0.2672,
"2": 0.6969
},
"confidence": 0.3413,
窓口は「請求」が 99.9%、返金を求めている確率が 89%、急ぎは 3 段階の一番上が 70%。1 件目としては文句なしです。
返事の末尾には、どのモデルを選んだかの理由も付いていました。
"reason": "non-Latin script (kana, 100% of letters); the English checkpoint cannot read it",
「かなが 100% なので、英語用のモデルでは読めない。多言語版に回した」と言っています。日本語を渡すと自動でこうなるので、モデルの指定を自分で書く必要はありませんでした。
40 件を流して、何件合うか数える
1 件なら何でも当たります。そこで、ネットショップに来そうな問い合わせを 40 件書きました。窓口は請求 13 件・配送 11 件・商品 8 件・アカウント 8 件。「壊れていたので返金して」のように返金を求めるものが 7 件、「今日中に発送されると困る」のような急ぎのものが 9 件混ざっています。件名と本文を tickets.json に入れ、それぞれに私の正解(窓口・返金の有無・急ぎの 3 段階)を付けておきます。
{"id":7,"subject":"配送先を間違えました","body":"さっき注文したばかりですが、配送先が前の住所のままでした。発送前に新しい住所に変えてほしいです。今日中に発送されると困ります。","dept":"shipping","refund":false,"urgency":2}
さっきの質問をそのまま使って、40 件を順に流し、正解と比べる batch.py を書きます。返金は確率が 0.5 以上なら「求めている」、急ぎは 3 段階のうち確率が一番高い段を答えとみなします。
tickets = json.load(open("tickets.json"))
router = Router()
for t in tickets:
state = {"subject": t["subject"], "body": t["body"]}
r = router.predict(state, questions)
a = r["answers"]
dept = a["department"]["choice"]
refund = a["refund_requested"]["noul"]
urg = max(a["urgency"]["probabilities"], key=a["urgency"]["probabilities"].get)
python3 batch.py
40 行の結果の後に、集計が出ます。
窓口 33/40 返金 36/40 急ぎ 14/40
1件あたり 253ms(2件目以降の平均)
窓口は 33 件、返金は 36 件が私の正解と一致しました。急ぎは 14 件で、3 択を当てずっぽうで選んだのとほぼ同じです。 速さは 1 件 253ms。GPU の無い Linux 環境で、CPU 4コアで動かしました。40 件で 10 秒ほどです(GPU のある Mac では 1 件 69ms でした。正解の数はどちらの環境でも同じです)。
40 件の中身です。窓口の列は、外れたものだけ「Laya の答え → 私の正解」で書いています。返金と「今日中」の列は Laya が返した確率で、× は私の正解と食い違ったものです(「今日中」の列は次の節でやり直した後の数字です)。
| # | 件名 | 窓口(Laya → 私の正解) | 返金を求めている | 今日中に対応が要る |
|---|---|---|---|---|
| 1 | 同じ注文で2回引き落とされています | 請求 | 0.89 | 0.81 |
| 2 | 荷物が届きません | 配送 | 0.00 | 0.71 × |
| 3 | サイズについて | 商品 | 0.00 | 0.14 |
| 4 | ログインできない | アカウント | 0.00 | 0.99 × |
| 5 | 届いた商品が壊れていました | 配送 → 請求 | 0.80 | 0.38 |
| 6 | 領収書がほしい | 請求 | 0.55 × | 0.55 × |
| 7 | 配送先を間違えました | 配送 | 0.00 | 0.89 |
| 8 | 退会したい | アカウント | 0.64 × | 0.98 × |
| 9 | 在庫はいつ入りますか | 配送 → 商品 | 0.05 | 0.79 × |
| 10 | キャンセルして返金してください | 配送 → 請求 | 0.93 | 0.64 |
| 11 | 追跡番号を教えてください | 配送 | 0.00 | 0.81 × |
| 12 | クーポンが使えない | 請求 | 0.49 | 0.90 |
| 13 | 洗濯できますか | 商品 | 0.00 | 0.88 × |
| 14 | メールアドレスを変えたい | アカウント | 0.00 | 0.06 |
| 15 | 違う商品が届きました | 配送 | 0.88 × | 0.91 × |
| 16 | 引き落とし日はいつですか | 請求 | 0.06 | 0.37 |
| 17 | 明日までに届きますか | 配送 | 0.52 × | 0.59 |
| 18 | 二段階認証のコードが届かない | アカウント | 0.15 | 0.99 |
| 19 | 素材を教えてください | 商品 | 0.00 | 0.34 |
| 20 | 返品したい | 配送 → 請求 | 0.99 | 0.92 × |
| 21 | ポイントが付いていない | 商品 → 請求 | 0.00 | 0.34 |
| 22 | 不在票が入っていたけど再配達できない | 配送 | 0.00 | 0.50 × |
| 23 | パスワードの再設定メールが迷惑メールにも無い | アカウント | 0.00 | 0.76 × |
| 24 | ギフト包装はできますか | 請求 → 商品 | 0.09 | 0.43 |
| 25 | 注文していないのに請求が来た | 請求 | 0.92 | 0.99 |
| 26 | 海外に発送できますか | 配送 | 0.16 | 0.39 |
| 27 | アプリでログアウトされてしまう | アカウント | 0.00 | 0.40 |
| 28 | 届いた商品が写真と違う | 配送 → 請求 | 0.96 | 0.69 × |
| 29 | 発送はいつになりますか | 配送 | 0.01 | 0.30 |
| 30 | 電池は付属していますか | 商品 | 0.05 | 0.65 × |
| 31 | 分割払いにできますか | 請求 | 0.37 | 0.52 × |
| 32 | 荷物が隣の家に届いた | 配送 | 0.00 | 0.36 |
| 33 | 注文履歴が消えた | アカウント | 0.00 | 0.38 |
| 34 | 返金がまだ来ない | 請求 | 0.06 | 0.94 × |
| 35 | 色違いはありますか | 商品 | 0.00 | 0.08 |
| 36 | 今日中に発送してほしい | 配送 | 0.09 | 0.47 × |
| 37 | 名前の漢字が違う | アカウント | 0.00 | 0.53 × |
| 38 | 半分だけ返金してほしい | 請求 | 0.84 | 0.42 |
| 39 | 使い方が分からない | 商品 | 0.00 | 0.28 |
| 40 | 配送日時を指定したい | 配送 | 0.00 | 0.26 |
窓口で外れた 7 件のうち 4 件(5・10・20・28)は、「壊れていた」「返品したい」「写真と違う」を配送に回したものです。私は「返金が絡むなら請求」と決めていましたが、これはお店によって配送窓口が受ける決まりのところもあるので、Laya が変とも言い切れません。はっきり外したのは、「在庫はいつ入りますか」を配送に、「ポイントが付いていない」を商品に、「ギフト包装はできますか」を請求に回した 3 件です。
返金の 4 件の外れは、どれも確率が 0.5 前後でした。「領収書がほしい」が 0.55、「明日までに届きますか」が 0.52。お金や注文の話が出ると少し上がるようです。逆に、返金を求めている 7 件は全部 0.80 以上で、迷いなく拾っています。
急ぎの 3 段階は、ほぼ全部を「今すぐ」に寄せていました。「洗濯できますか」も「色違いはありますか」も一番上です。README にも、段階で採点する score は弱いと書いてあります。
質問の書き方を変えて、もう一度
外れ方を見て、質問を 2 か所直しました。窓口の説明文に「返品、不良品」と「配送日時」を足したのと、3 段階の急ぎをやめて「今日中に対応しないとお客さんが困るか」というはい・いいえの質問に変えたことです。Jev の使い方を解説している海外の記事に、段階評価は「中くらい」のような程度ではなく種類で分ける、迷ったら質問を分ける、とあったので、それに寄せた形です。
"billing": "請求、二重引き落とし、返金、返品、不良品、領収書",
"shipping": "配送の遅れ、追跡番号、住所変更、配送日時",
"today": {"type": "noul", "instructions": "今日中に対応しないとお客さんが困るか"},
python3 batch2.py
窓口 31/40 返金 36/40 今日中 23/40
1件あたり 284ms(2件目以降の平均)
急ぎは 14 件から 23 件に上がりましたが、それでも 40 件中 23 件です。「ログインできない」が 0.99、「返金がまだ来ない」が 0.94 で、私は急ぎに入れていません。逆に「今日中に発送してほしい」は 0.47 で、急ぎに入りませんでした。文中に「今日中」とあってもです。
窓口は、説明文に「返品、不良品」を足したのに、33 件から 31 件に下がりました。「返品したい」は配送から商品へ移っただけで請求には来ず、「クーポンが使えない」が請求からアカウントへ動いてしまいました。説明文に言葉を足せば効くという単純な話ではないようです。
利用料金
Laya は Apache 2.0 のオープンソースで、モデルも Hugging Face から無料で落ちてきます。自分のパソコンで動くので、何件流しても料金はかかりません。アカウントも API の鍵も要りませんでした。
比べる相手の Jev は、公式サイトの表示で入力 100 万トークンあたり $0.042(出力は無料)です。今回の 1 件が 300 トークン前後だったので、40 件で 0.2 円もしません。Jev の側で高いのはお金ではなく、承認を待つ時間の方です。
まとめ
窓口の振り分けと「返金を求めているか」は、日本語のまま、入れたままの Laya で 8〜9 割が私の判断と合いました。1 件 253ms(GPU無し、CPU)で、料金ゼロ。問い合わせをまず 4 つに分けて、返金の話を先に拾う、という使い方なら、そのまま置けそうです。外した 7 件のうち 4 件は「返品を配送で受けるか請求で受けるか」というお店側の決まりの話で、これは自分のデータで追加学習させる道が README に用意されています(今回は試していません)。
「どのくらい急ぎか」は当てになりませんでした。3 段階でも、はい・いいえに崩しても、6 割止まりです。急ぎの判定は Laya には任せず、「今日中」「明日」のような言葉を自分のコードで拾う方がよさそうです。Jev の解説記事にも、日付や数の比較はモデルに任せるなとあったので、この弱さは Laya に限った話ではないのかもしれません。
質問の説明文をいじると、直したかった件が直らず、別の件が動きました。質問文を変えたら、40 件を流し直して数える。この手間は省けません。逆に言えば、1 件 300ms 前後なら流し直しは数秒です。
Jev 本体が触れるようになったので、同じ 40 件を流して並べました。続きは Jev の記事 です。
確認した環境
最初の検証(2026-09-20)は Apple M3 の Mac で、PyTorch が Mac の GPU(mps)を使って動きました。2026-10-08 にバージョン 0.4.0 で再検証した時は、GPU の無いクラウドの Linux 環境(Ubuntu 24.04.5、Python 3.11.17、CPU 4コア)で動かし、正解の数は変わらず、速さだけ 1 件 69ms から 253ms(急ぎの質問を変えた後は 284ms)に変わりました。40 件の問い合わせと正解は私が書いたもので、実際の問い合わせ窓口の記録ではありません。