🏦

社外APIが使えない金融業で、社内マニュアル問い合わせAIをローカルLLM(Qwen3)で作った話

に公開

はじめに

「社内の事務マニュアルを、ChatGPTみたいに自然な言葉で聞けるようにしたい。ただしうちは金融なので、外部のAIに文書は一切出せない」——きっかけはお客様からのこんな相談でした。要件を聞いていくと、これはクラウドAPIでは詰むやつだな、と早々に分かったので、腹をくくってローカルLLMで組むことにしました。

この記事は、そのときに考えたこと・ハマったことの記録です。手順を頭から追うチュートリアルというより、「なんでこの構成にしたのか」「どこで詰まったのか」を残しておく、という趣旨で書いています。同じ「クラウド使えない縛り」で困っている人の役に立てば。

金融業の案件をやって改めて感じたのは、他の業種だとあまり気にしない制約がやたら重い、ということでした。

  • とにかく社外にデータを出せない。顧客情報はもちろん、内部規程や約款すらNG
  • 「なぜその回答になったのか」を後から説明できないと困る(監査が絡む)
  • 個人のPCにこっそり入れて運用、みたいなのは通らない。ちゃんとした基盤として据える必要がある

要するに、ChatGPT や Claude の API を叩く、という一番ラクな道が最初から塞がれている。じゃあ社内に閉じた環境で全部完結させるしかないよね、という消去法でローカルLLMに行き着いた、というのが正直なところです。


クラウドが使えない、という前提から逆算する

最初の打ち合わせで、システム部の方に「この画面って、裏でOpenAIとかに繋がってたりします?」と真顔で確認されたのが印象的でした。金融の現場だと、そのくらい「外に出るかどうか」がシビアに見られている。

なので設計は「賢いモデルをどう使うか」ではなく、「どうやって外に一切出さないか」から逆算しました。

ローカルに寄せると、文書もプロンプトも回答も社内ネットワークから一歩も出ない。ネットが切れても動くし、誰が何を聞いたかも自社のログに全部残せる。監査対応を考えると、この「全部手元にある」状態はむしろ強みでした。

代償として、サーバの調達も運用も全部自分たちで抱えることになる。ここは後半で詳しく書きます。正直、ここが一番の覚悟どころです。


モデルは Qwen3 にした

モデル選定は、いろいろ目移りしそうになるところですが、今回は Qwen3 で通しました。他のモデルと横並び比較を延々やっても案件は進まないので、早めに一本に決めた形です。

決め手はシンプルで、

  • 日本語がちゃんと読める・書ける。相手は日本語の事務マニュアルなので、ここが弱いと話にならない
  • 重みを落として自社サーバに置ける。社外に出せない要件と素直に噛み合う
  • サイズの選択肢が広くて、用途に対して過不足ないサイズを選べる
  • そしてコスパ。過剰に大きいモデルを積まなくても、RAGで検索を効かせれば十分実用になる

具体的には、最初 Qwen3-14B を 4bit 量子化(AWQ)して vLLM で動かしました。「まず14Bで様子を見て、物足りなければ上げる」くらいの気持ちでしたが、後述する通り、RAGが効いてくると14Bでも体感かなり使えたので、結局そのまま本番まで行きました。


全体構成はRAG。ただし「検索の質」が全て

やることは要するに RAG(関連文書を検索して、それを根拠にLLMに答えさせる)です。LLM単体は社内規程なんて知らないので、「関連しそうな箇所を引っ張ってきて、それを読ませて答えさせる」わけですね。

この図で個人的に一番大事だと思っているのは、外に向かう矢印が1本もないことです。お客様への説明でも、まずこの図を出して「ここに一本もインターネットへの線がないですよね」と話すと、だいたい安心してもらえました。技術より先に、この「閉じている」ことが伝わるかどうかが金融では効きます。

ベクタDBは Qdrant、埋め込みは multilingual-e5-large を使いました。このあたりは正直「動けばいい」で選んだ面もあるのですが、後から効いてくる落とし穴があったので次に書きます。


ここでハマった:日本語PDFと、似すぎた条文

RAGって図にすると綺麗なんですが、実際に組むと「検索の質」で全部決まります。そして最初、その検索がびっくりするくらい当たらなかった。原因は大きく2つでした。

PDFの表がぐちゃぐちゃに抽出される

渡された事務マニュアルの多くがPDFで、しかも表組みが多い。手数料の一覧とか、条件分岐の対応表とか。これを普通にテキスト抽出すると、表の縦横がバラバラに崩れて、意味の通らない文字列になる。当然、それを埋め込んでも検索は当たりません。

「AIが賢くならない」以前に、そもそも読ませてる元テキストが壊れてた、というオチで、これに気づくまで地味に時間を溶かしました。結局、表を含むページは抽出方法を分けて、表はできるだけ構造を保った形(Markdownの表に近い形)に整える前処理を挟むことで、だいぶマシになりました。

教訓としては、RAGの本当の敵はモデルじゃなくて前処理、というありがちなところに落ち着きました。

条文が似すぎていて、隣の条を引いてくる

もう一つが、金融のマニュアル特有の問題。条文の言い回しがどれも似ているんです。「第○条 〜については…」みたいな体裁が延々続くので、埋め込みのベクトルも近くなる。結果、質問に対して「隣の条」を引っ張ってきて、微妙に間違った回答をすることがありました。

最初はチャンク(分割単位)を固定長の512トークンで切っていたんですが、これだと条の途中でぶつ切りになって文脈が壊れる。そこで、「第○条」「別表」みたいな構造の境界で切るように変えました。あわせて、どの規程の第何条か、という見出し情報をメタデータで持たせて、回答時に出典として出すようにしました。

チャンク設計を変えただけで誤検索が体感でかなり減ったので、ここは早めに構造ベースにしておけばよかった、と反省しています。


それでも引けないから、ハイブリッド検索とリランカーを入れた

構造ベースで切るようになって誤検索はだいぶ減ったんですが、それでも「隣の条」を引くことはゼロになりませんでした。ベクトル検索は「意味が近い」ものを探すので、言い回しが似た条文ばかり並んでると、どうしても近いベクトルが並んでしまうんです。

そこで、ベクトル検索だけに頼るのをやめて、2段構えにしました。

  • BM25(キーワード検索)とのハイブリッド:条文番号とか「手数料」「解約」みたいな固有名詞は、意味より文字列の完全一致で探した方が確実に当たる。ベクトルとBM25の両方で引いて、結果をマージする
  • リランカー:マージした候補を、質問との関連度で改めて並べ直す

導入手順はざっくりこんな感じです。

  1. 質問を埋め込んでベクトル検索、同時にBM25でも検索して、それぞれ候補を出す
  2. 両方の上位を数十件マージして重複を除く
  3. クロスエンコーダ系のリランカーに「質問+候補文書」を食わせて、関連度スコアで並べ直す
  4. 上位だけをLLMに渡す

リランカーは埋め込みの「ざっくり近い」を、質問と文書を並べて読むことで「本当に関係あるか」に絞り込んでくれます。体感ですが、ハイブリッド+リランカーを入れてから「隣の条」を引くケースはかなり消えました。


「マニュアルにないことは、絶対に答えさせない」

金融でAIが一番やらかしてはいけないのは、それっぽい嘘です。「その手続きは不要です」なんて事実と違うことを堂々と言われたら、現場は大混乱します。

なので、賢く見せることよりも「知ったかぶりをさせない」ことを最優先にしました。具体的には、

  • 検索で引いてきた文書に書かれていないことは、推測で答えるなとプロンプトで強めに縛る
  • 該当が見つからなければ、「マニュアルに記載が見つかりませんでした。担当部署にご確認ください」と正直に言わせる。これを「負け」ではなく「正解」として扱う
  • 回答には必ず出典(規程名・条番号)を添える。利用者が原典で裏を取れる状態にしておく
  • そもそも検索が空振りしたら、回答を生成させない

「わからない、と言えるAI」の方が、金融では圧倒的に信頼されました。デモで「なんでも答えます」的な振る舞いをさせると逆に警戒される、というのは現場に行って初めて肌で分かった感覚です。

ただ、正直に白状すると、「絶対に答えさせない」はプロンプトだけで完璧にはできませんでした。強めに縛っても、たまに知ったかぶりが出る。最初は「プロンプトで固めればいけるだろ」と甘く見ていたんですが、何回かやらかして反省しました。

結局、プロンプトの縛りに加えて、こんなガードを重ねました。

  • 回答には必ず、取得した原文の該当箇所を引用させる。引用がない・原文に無い内容が混ざったら、その回答は出さない
  • 高リスクな質問は人に回す。金額・期日・手続きの要否みたいな「間違えたらまずい」やつはAIだけで完結させない

あと監査対応として、ログには「質問・取得した文書・投げたプロンプト・回答・出典」を全部セットで残すようにしました。監査の人が来たときに「この回答はこの条文を根拠に出ています」と、質問から回答までの流れを再現できないと困るので。加えてモデル・プロンプト・チャンク方式はバージョン管理して、どの時点の回答がどの構成で出たかを追えるようにしておきます。これがないと「いつの間にか挙動が変わってた」が監査で見つかって面倒なことになります。


動いただけじゃダメ:RAGの評価をどうやるか

これも後から痛感したんですが、RAGは「動けばいい」で作ると、あとで良し悪しを判断する物差しがないんです。モデルを変えたら良くなったのか悪くなったのか、チャンクをいじったら検索がどう変わったのか——感覚でしか分からない。金融だと「体感で大丈夫です」は通らないので、ちゃんと測る仕組みを作りました。

具体的には、ゴールデンQAセットという、あらかじめ正解を用意した質問集を作ります。現場の人に協力してもらって「この質問にはこの条文が答え」というペアを数十件ほど用意しました。これで、

  • 検索の精度:質問に対して正しい条文が上位に引っかかってくるか(ヒット率)を測る
  • 回答の正答率:最終回答が正解と合っているかを測る

この2つを、モデルやチャンク方式を変えるたびに回して、悪くなっていないかを確認するようにしています。あと、回答が「引いてきた文書からちゃんと出ているか」(勝手に話を作っていないか)も見ます。ここが怪しいと、いくら正解っぽくても金融では使えないので。

最初は「評価セット作るの面倒だな」と思って後回しにしてたんですが、これがないとモデル差し替えのときに地獄を見る。早めに作っておくべきでした。


どんな機材を買うべきか

ローカルLLMの相談で、技術の話より先に必ず出るのが「で、結局どんな機械を買えばいいの?」です。ここは実務で一番リアルに悩むところなので、少し具体的に書きます。

ノートやMacに「置く」のは、やめておいたほうがいい

先に、やらない方がいい構成をはっきりさせておきます。検証段階だとつい手近な機材でやりがちなんですが、本番を見据えると地雷です。

  • ノートPCで運用しない。デモには最高に便利ですが、複数人が日常的に使う基盤としては非力だし、持ち出される・電源切られる、で事故ります
  • 誰かのデスクトップに同居させない。その人が使ってる間は重いし、定時で電源が落ちたら全社が使えなくなる
  • Mac は今回は選びませんでした。個人の検証なら全然アリなんですが、企業として「GPUを増設したい」「資産管理・監視の仕組みに乗せたい」となると、後述のNVIDIA GPUサーバの方が圧倒的に扱いやすい

結局のところ、閉域網の中にサーバを1台きちんと据えて、みんなでそこを使う——この当たり前の形が、可用性・セキュリティ・管理のどれを取っても素直でした。

NVIDIA GPUサーバを1台。見るべきはVRAM

今回は NVIDIA L40S(48GB) を1枚積んだサーバを1台、サーバルームに据えました。Qwen3-14B の 4bit なら十分載って、数人が同時に問い合わせても待たされない程度の速度は出ています。

GPU選びで初心者がやりがちなのが「一番速いやつ」を探すことなんですが、 まず見るべきはクロックよりVRAM(GPUメモリ) です。動かしたいモデル+量子化がVRAMに収まるかどうかで、そもそも動くか動かないかが決まる。「速い遅い」はその次の話でした。

規模感で言うと、ざっくりこんな段階で考えていました。

  • スモールスタート:GPU1枚のサーバ1台。まず部署単位で試す
  • 常用:VRAMに余裕のあるGPUで、同時アクセスに耐えさせる
  • 止められない用途:サーバ2台以上で冗長化+前段にロードバランサ

作った後のほうが長い:運用の話

正直に言うと、動くものを作るところまでより、その後ちゃんと運用に乗せるところのほうが大変でした。金融だと「動いた!」で終われないので。

  • 閉域に隔離する。図で書いた「外への矢印ゼロ」を、ネットワーク設定でも物理的にも本当に担保する。ここは情シスと何度も確認しました
  • アクセス制御。部署や権限で、参照できる文書を分ける。全員が全規程を見られると困るケースがある
  • 監査ログ。いつ・誰が・何を聞いて・どの文書を根拠に・どう答えたか、を全部残す。金融の監査で効いてきます
  • 文書更新の運用。規程が改訂されたらベクタDBを作り直す。この運用フローを決めずに放置すると、古いマニュアルを根拠に堂々と間違えるAIができあがるので要注意

「作って納品して終わり」ではなく、文書更新とログ監査を回し続ける前提で設計しないと、金融では使い続けてもらえない、というのが今回の一番の学びでした。


まとめ

社外APIが使えない金融業で、社内マニュアル問い合わせAIをローカルLLM(Qwen3)で作ってみて、ざっくり言えることは、

  • ローカルLLMは「高度だから選ぶ」んじゃなくて、外に出せないから選ぶしかない。動機は消去法
  • モデルは迷わず Qwen3 に一本化。日本語とコスパで、14B+RAGでも十分戦えた
  • 敵はモデルより前処理。PDFの表崩れと条文の誤検索でしっかりハマった
  • 検索はハイブリッド検索(BM25+ベクトル)+リランカーで「隣の条」を潰す
  • 機材はノートでもMacでもなく、NVIDIA GPUサーバを閉域に1台。まずVRAMを見る
  • 一番大事なのは 「マニュアルにないことは答えさせない」 という割り切り。ただしプロンプトだけでは不十分で、人と出典確認で最後を担保
  • 品質はゴールデンQAセットで評価して、モデル・チャンク変更の劣化を検知する

「賢いAIを作る」より「嘘をつかないAIを、外に出さずに運用し続ける」ほうがずっと難しかった、というのが金融案件の実感です。


💡 ローカルLLM開発について、ご関心やご相談がございましたら、以下よりお気軽にお問い合わせください。

株式会社シャイオス お問い合わせ窓口


参考

Discussion