家庭内の質問に答える chatbot を作る、という発想自体がまず楽しいです。
「この部屋のエアコン、いつ替えたっけ?」とか「この前、プールのポンプを直したのはいつだっけ?」みたいな、生活の中の細かい記憶を引っ張り出してくれる相棒ですね。記事では、こうした家庭の知識を RAG で持たせています。RAG というのは、LLM が記憶だけで答えるのではなく、外部のデータベースを検索して、その結果を見ながら答える仕組みです。検索エンジン付きの賢い返事、という理解でだいたい合っています。
ただ、この人はそこで終わりません。検索対象をそのまま全部なめるのではなく、質問を先にカテゴリ分けしてから検索しているのがポイントです。たとえば「When did we replace our pool pump?」なら、先に「pool」と判定してから、そのカテゴリに合う情報だけを探しに行く。これ、地味ですがかなり筋がいいです。検索範囲を絞れれば、ノイズが減って当たりやすくなるからです。私ならここで「そんな面倒な前処理を入れなくても」と思いがちですが、実際にはこの手のひと手間が精度を支えます。
記事の本題は、そのカテゴリ分けを tiny な local LLM でどこまでできるか、という実験です。使っているのは Qwen 3:4B と Qwen 3:0.6B。4B のほうは一般的な回答役、0.6B のほうは質問の分類役です。0.6B は 6 億パラメータなので、LLM の世界ではかなり小さい部類です。ここで面白いのは、「小さいモデルでも、やる仕事を限定して訓練すれば案外いけるのでは?」という仮説を、ちゃんと検証しているところです。こういう実験、私はかなり好きです。派手な生成より、むしろこういう地味な分類のほうが実運用では効くことが多いので。
データは家庭関連の質問とカテゴリのペアが約 850 件。学習・評価・テストに 70/15/15 で分けています。たとえば gutter, water heater, irrigation, cooking, hvac といったカテゴリです。要するに「この質問は家のどの設備・話題に属するか」を当てさせるわけです。ラベル付けされたデータを食わせる、かなり王道の supervised learning です。
最初は baseline として、Qwen 0.6B に対して prompting だけで分類させています。つまり、モデル自体はそのままで、「この一覧から 1 つ選んでね」と指示するだけ。結果はかなり厳しく、131 件のテストで正解は 13 件、精度は約 10% でした。これは正直、だいぶしんどい数字です。しかも失敗の仕方がなかなか人間らしいというか、広いカテゴリに吸い寄せられたり、許可されていない新しいカテゴリ名を勝手に出したりします。たとえば electric や appliances に寄りがちで、pool や hvac を落とす。さらに apartments みたいな、そもそも一覧にない単語を返してしまうこともある。小さいモデルに「ちゃんとこの候補だけから選んで」と言っても、意外と聞いてくれないんですね。ここは妙に人間くさくて少し笑ってしまいます。
そこで fine-tuning です。Unsloth と QLoRA を使って、同じ Qwen 0.6B を家庭質問の分類に特化させます。Unsloth は local model の微調整でよく使われる open-source framework で、QLoRA はモデル全体を重く更新するのではなく、軽量な追加部分だけ学習させる方法です。大雑把に言えば「少ないコストで賢くなるように調整する」仕組みです。著者も言っていますが、こういうとき大事なのはハイパーパラメータを細かくいじることより、まず良い dataset を作ることだと思います。これはかなり同意です。モデルが賢くなるかどうかは、結局「何をどう教えたか」に強く引っ張られます。
1回目の fine-tuning で、精度は一気に約 79% まで跳ね上がります。10% から 79% は、もう別世界です。ここでの失敗は、完全に見当違いというより「惜しい」ものが増えています。たとえば hvac のつもりが ac や air の断片になったり、water heater と pool のような、意味が近いカテゴリを混同したりする。つまり、モデルは方向性はつかんだが、まだ出力の形が不安定、という感じです。
この状態、私はかなり「モデルが学んでいる」手応えを感じます。雑にゼロイチで失敗していたのが、だんだん似たものを間違えるようになる。分類器としては一歩前進です。

そして 2 回目の工夫が面白い。著者はカテゴリ名そのものを返させるのをやめて、AA, BB, CC のような 2 文字コードに置き換えました。hvac なら KK、pool なら OO といった具合です。これ、見た目は地味ですが、かなり効いています。精度は約 92% まで上がりました。
なぜ効くのかは、わりと納得感があります。カテゴリ名って、意味がかぶるんですよね。water heater も pool も「水っぽい」し、hvac も ac や air に引っ張られる。ところが 2 文字コードは意味を持たないので、モデルが余計な連想をしにくい。出力の形式を「意味のある単語」から「ただのラベル」に変えただけで、こんなに改善するのはかなり気持ちいいです。地味だけど、こういう設計変更のほうが効くことは本当に多いと思います。
とはいえ、まだ完全ではありません。特に water heater -> pool の取り違えが残っています。これは「水回り」という曖昧な意味の重なりが原因かもしれません。pool、fountain、water heater あたりは、文章の表面だけだと確かに紛らわしいです。著者もここは、訓練データをもっと細かく見直す必要がありそうだと書いています。私もこれはその通りだと思います。モデルの限界というより、ラベル設計とデータの切り方の問題がかなり大きそうです。
記事の終盤では、実際の chatbot 画面のスクリーンショットも紹介されています。吹き出しに青いカテゴリタグがついていて、そこを tiny LLM が自動で判定している、という見せ方です。こういうのはデモ映えしますし、技術の価値も伝わりやすいです。単に「精度 92% でした」より、「会話の裏側で小さいモデルが黙々とラベルを付けている」と思うと、ぐっと実感が湧きます。
個人的にこの記事でいちばん面白いのは、「大きい LLM に全部やらせる」のではなく、「小さい LLM を分類専用に鍛える」という割り切りです。LLM ブームの文脈だと、つい何でも生成させたくなりますが、実際のプロダクトでは、こういう前処理の分類器が全体の品質を支えることが多いです。しかも local で動くなら、コストやプライバシーの面でもうれしい。家の話をクラウドに投げたくない、という感覚はかなり自然ですから。
それと、最後に Logistic Regression を試した新しい実験へつながるという更新も載っています。読者から「LLM fine-tuning より、もっと単純な分類器のほうがいいのでは」というフィードバックを受けたのがきっかけだそうです。ここも健全です。AI っぽい豪華な手段に飛びつくより、まず素朴な方法を比べる。この姿勢はかなり信頼できます。実務では、だいたいシンプルな手法が強い場面も多いので、そちらの比較までやるのは賢い流れだと思います。