ナイモノ研究所
September 18, 2026 · View on GitHub
「この世にないことば」を交互に言う、2〜4人向けの言葉遊びゲームです。スマートフォン1台を家族で回して遊べます。
ローカル起動
Node.js 22以降を使います。実行時のnpm依存はありません。
npm test
npm run build
npx wrangler dev
http://localhost:8787 を開くと、WranglerのWorkers AI bindingを使うローカルWorkerです。Workers AIの実行はCloudflareアカウントへ接続し、利用量が発生する場合があります。
npm start はAPI接続なしの付属辞書版です。辞書にない語は、家族が「セーフ/アウト」を決めて続けます。
Cloudflareへデプロイ
Wranglerでログイン済みのCloudflareアカウントを使います。
npx wrangler whoami
npm run deploy
wrangler.jsonc のWorker名は naimono-lab です。公開URLは https://naimono-lab.mocchalera.app です。Cloudflare Custom DomainとしてWorkerに紐づけるため、既存DNSや他サービスは変更しません。
Workers AI / Jev構成
wrangler.jsoncのai.binding = "AI"でenv.AIをWorkerへバインドします。typesafe/jevはCloudflareの第三者モデルなので、実行にはアカウント側のAI Gateway利用残高またはBYOKが必要です。利用できない場合も、Workerは敗北にせず再試行・手動判定へ進めます。- 現在はAI Gatewayの
defaultGatewayへTypeSafe BYOK(providertypesafe/ aliasdefault)を登録しています。キーはCloudflare Secrets Storeに保存し、ブラウザやGitへ渡しません。ローカルの.env.localは登録時だけ使う秘密ファイルです。 worker.mjsの/api/judgeがenv.AI.run("typesafe/jev", { state, questions })を呼びます。- Jevへの1回のリクエストで、全体の聞き覚え・日常語・バンドと人名・作品とキャラクター・地名と商品・専門用語・読みと表記違いの7観点と、「ことばのつぎはぎ」「文章っぽさ」をNoulで評価します。さらに未知の固有名詞を見落とす注意度をScore(0〜4)で評価し、カテゴリーと語感をChoiceで選びます。質問はそれぞれ独立した判断で、前の質問の答えを次の質問に渡す構成ではありません。
- 音声入力などに混ざる半角・全角スペースや改行は自動で除き、漢字・カタカナの表記は保持します。機械的に変換できるひらがな・カタカナの候補を同じ語の手がかりとして添えます。漢字の読みを推測で付け足したり、勝手に別の単語に訂正したりはしません。
- 漢字など読みが必要なしりとりでは、同じリクエストに「最初の音」「最後の音」のChoiceを追加します。Jevは自由文の読みを生成せず、かなの選択肢から選びます。選択確率が0.65未満・不明・不正な回答のときだけ、補助の読み入力へ戻します。かな入力は従来どおりローカルのルールを優先します。
- APIキーを使うTypeSafe直アクセスはありません。秘密情報をブラウザへ渡さず、ゲームのルールとスコア集計は共有コードで決めます。
- 総合スコアは実在の7観点・つぎはぎ・文章の最大値です(相関する回答の平均や確率の積は使いません)。どれか0.85以上ならアウト。実在が全部0.35以下、「名前かも」が0.30未満、つぎはぎ・文章もそれぞれ0.45未満なら自動セーフで、それ以外は下記の助っ人が追加確認します。つぎはぎ・文章によるアウトを「実在する」とは説明せず、固有の理由を表示します。「名前かも」は0〜4のScoreを0〜1に換算した値で、これ単独でアウトにはしません。各観点の不明・不正・欠けた回答は0扱いにせず、再試行できるエラーにします。
境界だけ、助っ人が確認
lib/pipeline.mjsがJevの即判定と境界を分け、境界だけlib/referee.mjsのモデルに1回問い合わせます。モデルにJevの結論を押し付けず、元の語・読み・機械的な表記候補を渡します。一般のAPI利用者はモデル・予算・判定を指定できません。- 初期モデルは
@cf/google/gemma-4-26b-a4b-it。思考出力を無効化し、短いJSON、出力最大256トークンを使います。FALLBACK_MODELを@cf/qwen/qwen3-30b-a3b-fp8に変えるだけで同じ契約のQwenアダプターへ切り替えられますが、今回の固有名詞検証ではGemmaを採用しました。Qwenでは/no_thinkを使います。未知のモデルは無効になり、任意の高額モデルには流しません。新モデルはアダプター・Neuron単価・語例検証を追加してから使います。 - 固有名詞は正規名と種類、複合語は全体を覆う分解、文章は構文の説明を求めます。既存名は名前自体を示し、「既存のことば・名前としての手がかり」という固定説明にします。種類を取り違えることもあるため、分類や国籍・年・経歴などの補足を事実として表示しません。回答が曖昧・不正・途中切れ、または説明が空・入力の繰り返しなら自動勝敗に使いません。不正回答は接続失敗と区別して審議を案内します。助っ人が造語と答えても、Jevの実在または名前注意度が0.65以上、つぎはぎまたは文章が0.60以上なら不一致として審議します。LLMの記憶はWeb検索の証拠ではなく、固有名詞の取りこぼしや誤認は残ります。
discussion.levelはnone / optional / required。争点があるものだけrequired、造語の一部には分類から作ったoptionalのおしゃべりのタネを表示します。任意の話題は次のターンを妨げません。手動訂正はどの結果からも可能です。- 助っ人を含めた最終勝敗と、Jevの元の数値は別フィールドです。総合点は常に表示し、内訳と助っ人の説明は折りたたみます。追加判断で勝敗が決まった場合は「助っ人も確認!」と理由を表示します。
- 追加処理は予算予約込みで最大6秒。ブラウザ側の通信全体締切はJev最大10秒と通信余裕を合わせた18秒とし、2秒以上かかる場合は中立的な待機表示(「もうひと調べ中…」)へ段階的に切り替えます。AbortSignalも渡し、時間切れ・接続失敗・予算不足は敗北にせず審議へ戻します。タイムアウトは上流の課金取消を保証しないため、失敗分の予算は返却しません。Jev自体の失敗は従来の再試行画面です。
- SQLite Durable Object
FallbackBudgetにUTC日付・呼出数・予約Neuronだけを保存します。単一の追加判定予算を調整するための小さなRPCで、AI実行や通常のJev判定をDO内に集約しません。1日300回・保守的な見積り5,000 Neuronsの先に達した方で停止。入力UTF-8バイト数+テンプレート余裕512をトークンの上限目安にし、最大出力分も事前予約します。実際の請求量とは異なります。Workers AIの無料枠は他アプリと共有なので、アカウント全体の無料利用を保証する仕組みではありません。 - モデル・判定ルール・有効設定ごとに結果をキャッシュします。追加確認の一時的な失敗は長期キャッシュしません。NodeローカルデモはJevの分岐だけを使い、実際の追加モデルと永続予算は
npx wrangler devで確認します。 - 設定変更前の状態はGitで管理。停止・ロールバックは
FALLBACK_ENABLED: "false"として再デプロイすれば、DOの記録を残して助っ人のみ停止できます。DO移行の削除やデータ削除は不要です。モデル切替後は新セッションで/api/judgeのfallback.modelと実例を確認します。 REPORT_PATH=test-results/assistant-live.json node scripts/assistant-fixtures.mjsは18語の実Jev+助っ人検証です。誤セーフ・誤アウト・審議数・待ち時間を出力します。旧基準の比較は同じJev応答への旧閾値の適用で、別の旧モデル実行ではありません。
主なゲームルール
- 既知のことばはアウト、未知の造語はセーフ、制限時間切れはアウトです。
- 「宇宙+バナナ」のように既存の意味のあることばだけをつなぐことや、「ねこが空を飛ぶ」のような文章・説明もアウト寄りに判定します。一部の音が似ているだけではつぎはぎにしません。未知の音が残る「リンゴロロン」や、音を変えた混成語「ペンギツネ」は単純なつぎはぎとは区別します。文章では、主語が造語でも文の構造を確認します。曖昧な場合は家族が決められます。
- しりとりでは、前の語の末尾から始め、「ん」で終わる語と再使用語はアウトです。
- 判定待ち・入力確認中は時間を止めます。Jevや通信のエラーは負けにせず、再試行できます。
- 音声入力は対応ブラウザだけで使えます。漢字・カタカナも聞き取ったまま送れます。スペースは自動でつめ、聞きまちがいは判定前に修正できます。文字入力・読み入力・APIも同じ空白除去を使います。Jev未接続時の漢字しりとりには補助の読み入力が必要です。
- 発見した語・カテゴリー・語感(ふわふわ、つよそう、ミステリアス、未来っぽい、ごきげん、すっとなじむ)はこのブラウザのlocalStorageに最大60個保存します。カテゴリーごとの件数・絞り込み・発見済みカテゴリー数を図鑑で確認できます。以前の記録や分類できなかった語は消さずに「これから分類」に残します。分類が欠けても存在判定やゲームは続けられます。
見える判定と検証
- 結果画面には総合スコアを常に表示します。実在の7観点・つぎはぎ・文章と「名前かも」の内訳、採用した観点、判定基準は「どうして? 判定の内訳」から開けます。手動で勝敗を変えても元のスコアを残し、上書きの説明は折りたたまず表示します。
- セーフ・アウト・確認のどの判定でも、Jevから分類・語感が届けば審判の吹き出しに「動物っぽい!」「つよそうな響き!」などを表示します。既存の分類結果に対応する演出用の文言で、追加のAI呼び出しはしません。短い弾みと紙吹雪は端末の「動きを減らす」設定で止まります。
- 分類と語感はJevの想像で、存在判定には使いません。スコアはモデルの判断値であり、存在確率やWeb検索の裏付けではありません。知らないバンドや専門語を必ず見つける保証はありません。
- ルールの境界と誤った回答は
npm test、画面・保存・スマートフォン幅はscripts/browser_smoke.pyで確認できます。 NAIMONO_BASE_URL=http://localhost:8794 npm run test:jevは、そのURLのWorkers AI経由で実Jevを呼ぶ18語の限定検証です。既存語の誤セーフと、検証用の造語のアウトを検出します。旧方式との比較値は同一応答内のexistsだけを使った判定で、別に旧版を実行した精度比較ではありません。全日本語の精度を示すベンチマークでもありません。- 判定方式のバージョンをキャッシュキーに含め、以前の単一スコアの結果が混ざらないようにしています。
NAIMONO_BASE_URL=http://127.0.0.1:8794 node scripts/word-form-fixtures.mjsは、実Jevで複合語・文章・造語・既存語の14例を確認します。プロンプト内の例と別の例の両方を含み、判定の境界を調べる小規模な検証です。
Jevの型付き質問仕様:Cloudflareモデルドキュメント / TypeSafeドキュメント。