tameshita新しいツールを実際に動かした記録

layaとは?日本語の問い合わせを判定させ、料金・使い方を実測した動いた

配布元: https://github.com/NandhaKishorM/laya  / 2026-10-08 時点で確認

この日に実際に動かした結果です。内容の誤りに気づかれた場合はお問い合わせください。確認のうえ訂正します。

2026-10-08 の確認以降に本体が更新されています(スターは 31429 → 33981)。最終確認: 2026-10-22

使う前に分かること

必要なもの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 件の問い合わせと正解は私が書いたもので、実際の問い合わせ窓口の記録ではありません。

おすすめのツール・サービス