トピック

Radeon AI PRO R9700で作った自社AIを営業・在庫・調査で実用化する実践マニュアル

AMD Radeon AI PRO R9700

 ここで使用しているローカルLLMサーバー自体の構築方法(ハードウェアの選定から、vLLMやOpen WebUIの導入手順まで)は、以下の第1回の記事で解説している。本稿はサーバーが動いている前提で進めるため、これから構築する場合はまず第1回を参照してほしい。

本記事は【基本編】/【実践編】/【付録】の3ページ構成です

1台のローカルLLMを3つの現場へ

 環境を整えたIT担当者のもとには、営業部から「社内で使う文書の型を揃えたい」、在庫管理部門から「最新の在庫をすぐ知りたい」、調査担当から「社内文書とWebを横断して調べたい」という相談が届いた。

 さてどうするべきか?その解決策には以下の3つがある。

  • 型を持たせるSkill
  • 生きたデータに触れるMCP
  • 調べ物を任せるWeb検索とRAG

 この3つを同じ1台のRadeon AI PRO R9700搭載マシンで順に試していこう。

Radeon AI PRO R9700を搭載するTSUKUMOのカスタマイズマシン(ベースに近いものはこちら)。ここでの内容はすべてこのマシンで実行している

RAGだけでは解決しない3つの相談

 IT担当者に届いた3つの相談は、社内文書を検索して答えるRAGだけでは解決できない。提案書や稟議書には自社の「型」があり、在庫数は刻々と変化していく。最新の業界動向を調べるにはWebにも目を向ける必要がある。そこで、第1回構築したローカルLLMサーバーに「型を持たせる」「生きたデータに触らせる」「探す範囲を広げる」機能を加えていく。

 社員が自然な日本語で話しかける点は変わらない。その裏側でAIがテンプレートを読み込み、DBへSQLを発行し、Webや社内文書を検索する。これを実現するのがSkill、MCP(Model Context Protocol)、Web検索だ。まず、RAG・Skill・MCPの違いを整理しておこう。

 図4は、第1回構築したRAGの土台に、今回扱う3つの機能を加える関係を示したものだ。

第1回の土台に追加する3つの機能
第1回で構築したRAGの土台(Radeon AI PRO R9700+vLLM+Open WebUI)に、Skill・MCP・Web検索を積み上げる。それぞれ営業編・在庫管理編・リサーチ編に対応する

 どの仕組みから手を付けるかの目安として、導入の規模感も先にまとめておく。

3つの仕組みの導入規模の目安
仕組み(対応する編)主な担当導入の目安
Skill(営業編)総務・人事・営業事務でも可数時間で一通り試せる
MCP(在庫管理編)情報システム部門が主導数日~1週間程度
Web検索+RAG(リサーチ編)管理者がAPIキーを設定するだけ数分~(無料枠あり)
RAG・Skill・MCPの違い
RAGSkillMCP
何を持たせるか検索対象のドキュメント(社内文書やWebページ)再利用可能な指示書・型外部処理を呼び出す手段
典型的な用途規約・マニュアルの検索、Web検索議事録・稟議書等のフォーマット統一DB・APIへのライブアクセス
実行されるか検索のみ(テキストを返す)指示書を読み込むだけ(実行はしない)実際にSQL等を実行する
実装の重さ中(ベクトルDB等が必要)軽い(UIでテキスト入力するだけ)重い(サーバー・権限設計が必要)

 後述するリサーチ編のWeb検索は、検索対象が社内文書からWebページに変わっただけで、仕組みとしてはRAGの応用だ。ここからは実践編として、まずは営業部から見ていこう。

【営業編】提案書・稟議書の「型」をSkillで揃える

 最初の相談は営業部からだ。営業担当者は日々、提案書・見積書・稟議書・取引先へのメールなど、案件のたびにさまざまな文書を作成する。中身は案件ごとに違っても、社内での「型」は大体決まっている。この型を都度先輩に聞いて回ったり、過去の資料を探して真似たりする手間は、地味だが営業活動のスピードを確実に削っている。

文書の「型」が人に付いて回る
過去の提案書を探し、書き方を先輩に聞いて回る。文書の「型」が共有されていない現場の日常だ

 IT担当者は、Open WebUIの「Skill」という機能を使って文書フォーマットの標準化を試すことにした。

Skill(スキル)とは

Open WebUIが持つ、再利用可能な「指示書」をモデルに持たせる仕組み。名前(name)・説明(description)・本文(content)をワークスペースに登録しておくと、モデルは会話の中で必要になったタイミングだけ、組み込みツールview_skillを使って本文を読み込む。あらかじめ全部をシステムプロンプトに詰め込むのではなく、必要なときだけ該当する指示書を取り出す(プログレッシブディスクロージャー)。

 この設計思想は、Anthropicが提唱するAgent Skillsとほぼ同じである。Open WebUI独自の実装だが、狙いは共通しており「モデルに大量のルールを常時持たせず、必要な分だけ読ませる」という考え方に基づいている。

 RAGが「検索して答える」、後述するMCPが「実際に処理を実行する」のに対し、Skillは「型を読み込ませてから答えさせる」という3つ目の選択肢になる。

 議事録・稟議書・提案書・メールは、内容そのものより「型」が重要な文書だ。会社ごとに書き方のルールがあり、新入社員や中途入社者はまずこの型を覚えるところから始める。ベテラン社員に聞きに行く、過去の資料を探して真似る、といった手間が積み重なっているオフィスは多いはずだ。

 ここをSkillとして用意しておけば、モデルに「新規のお客様向けに提案書を書いて」「出張申請の稟議書を書いて」と頼むだけで、自社の型に沿った下書きが得られる。書き方を教える側の負担も、覚える側の負担も減らせる。

 RAGでも同じことは一応できるが、数百文字のテンプレートのためにベクトル化・インデックス化を行なうのは大げさだ。Skillであれば、テキストを1つ登録するだけで済む。

 導入の重さも書いておくと、ワークスペースの画面でテキストを入力するだけと簡単だ。 情報システム部門を通さずとも、総務や人事、営業事務の担当者が数時間あれば一通り試せる規模の作業になる。

 検証用に、議事録テンプレート・稟議書テンプレート・メール文体ガイド・提案書テンプレートの4カテゴリでいくつか並べてみた。

登録したSkillのカテゴリと内容例
カテゴリ内容例
議事録テンプレート定例会議/プロジェクトキックオフ/顧客打ち合わせ/品質会議/経営会議/採用面接/障害対応会議/予算検討会議/ベンダー打ち合わせ/1on1面談
稟議書テンプレート備品購入/出張申請/システム導入/外部委託契約/採用稟議/交際費/研修費用/設備投資/契約更新/広告出稿
メール文体ガイド初回問い合わせ返信/謝罪/見積もり送付/進捗報告/依頼/督促/お礼/アポイント調整/クレーム対応/契約後フォロー
提案書テンプレート新規提案/価格・見積提示/競合比較訴求/導入事例引用/フォローアップ提案

 それぞれ「記載すべき項目」「トーン」「避けるべき表現」を短くまとめた内容にしている。1件ずつ手で書くのは面倒なので、カテゴリごとに1つの雛形を用意し、種類ごとの差分(名称・説明文・トーンの要点)だけをリストで与えて機械的に埋める、簡単なPythonスクリプトで生成している。

python
EMAIL_TEMPLATE = """# メール文体ガイド({title})

{desc}の際は、以下のトーン・構成を参考にしてください。

## トーン
{note}。過度にへりくだらず、対等な立場での丁寧語を基本とする。
"""

email_types = [
    ("社外・謝罪", "apology", "ミスやトラブルに対する謝罪連絡",
     "言い訳を先に書かず、まず謝罪と事実確認の意思を明確に伝える"),
    ("社外・見積もり送付", "quotation", "見積書を添付して送付する際の本文",
     "有効期限・前提条件を本文中に明記する"),
    # ...以下、同じ4項目(表示名・IDスラッグ・説明・トーン)を種類の数だけ並べる
]

skills = [
    {
        "id": f"email-{slug}",
        "name": f"メール文体ガイド({name})",
        "description": f"{desc}の際に使う文体・構成のガイド。",
        "content": EMAIL_TEMPLATE.format(title=name, desc=desc, note=note),
        "meta": {"tags": ["メール文体", name]},
    }
    for name, slug, desc, note in email_types
]

 email_typesの1行が、このループでこう変換される。

json
{
  "id": "email-apology",
  "name": "メール文体ガイド(社外・謝罪)",
  "description": "ミスやトラブルに対する謝罪連絡の際に使う文体・構成のガイド。",
  "content": "# メール文体ガイド(社外・謝罪)\n\nミスやトラブルに対する謝罪連絡の際は、以下のトーン・構成を参考にしてください。\n\n## トーン\n言い訳を先に書かず、まず謝罪と事実確認の意思を明確に伝える。過度にへりくだらず、対等な立場での丁寧語を基本とする。\n",
  "meta": { "tags": ["メール文体", "社外・謝罪"] }
}

 議事録・稟議書・提案書のテンプレートも同じ考え方で、雛形とリストを差し替えるだけだ。出来上がったJSON配列は、Open WebUIの「Import Skills」機能に読み込ませれば一括登録できる。「Import Skills」はワークスペース > Skills一覧画面の右上にあるボタンから呼び出す。

 このスクリプトの全体は、付録の「提案書・Skill生成スクリプト(完全版)」に掲載した。

IDの付け方に注意

idを省略、あるいは日本語の名前から機械的に生成しようとすると、英数字以外が削られて-095a9fのような意味のないIDになってしまう。表示名(name)は日本語のままでよいが、idはringi-travelのように内容が分かる英語スラッグを明示的に指定するのがおすすめだ。

 Skillは、モデル作成画面で個別に有効化することもできるが、件数が多いと選ぶだけでも大変なので今回は35件すべてを1つのモデルにまとめた。MCPのToolとは異なり、Skillは「読み込まれるまでは何もしない」軽量な指示書なので、業務ごとにモデルを分けてアクセス範囲を制御する必要性が薄い。すべて有効化しておいても、実際に読み込まれるのは会話の内容に応じた1~2件だけだ。

 35件を登録しても、質問に合うSkillだけが読み込まれる流れを図5に示した。

35件登録しても実際に読み込まれるのは1~2件
モデルに常時見えているのは各Skillの名前と説明だけ。質問に応じてview_skillで該当する本文だけを読み込む
Skill 35件を有効化したモデル作成画面
新しいモデル作成画面。「書式テンプレート」にSkillを35件すべて有効化しているところ

 準備ができたところで実際に試してみたい。

【質問】「出張申請の稟議書を書きたい。来月大阪の展示会に2日間出張します」

 モデルはview_skillでringi-travel(稟議書テンプレート: 出張申請)を読み込み、フォーマットに沿った下書きを提示する。件名・起案者・稟議内容の概要・金額欄・決裁ルートといった項目が、自社の型通りに埋まった状態で返ってくる。

稟議書の下書きが「自社の型」で返る
「出張申請の稟議書を書きたい」への回答。view_skillでテンプレートを読み込んだうえで下書きを生成している

 続けて、営業らしい質問も試してみる。

【質問】「新規のお客様向けに提案書を書きたい。課題はデータ入力業務が特定の担当者に属人化していること」

 モデルはproposal-new(提案書テンプレート: 新規提案)を読み込み、課題整理・提案内容・価格とスケジュール・導入後の効果、という構成で下書きを組み立てる。

提案書もテンプレートに沿って構成される
「新規のお客様向けに提案書を書きたい」への回答。提案書テンプレートを読み込んだうえで下書きを生成している

 ここまでの作業に、Dockerもデータベースもネットワーク設定も登場していない。ワークスペースでテキストを入力する(または今回のようにJSONを一括インポートする)だけで完結する。この後に説明するMCPと比べると、実装の労力は桁違いに軽い。

  ライブなデータや外部処理が不要で、「型」を持たせたいだけならSkillで十分というのが実際に触ってみての結論だ。 この読み込み・生成処理もRadeon AI PRO R9700上で完結しており、稟議書や提案書の下書き内容が外部に送信されることはない。

 出張申請の稟議書を作成するまでの応答時間は約12.5秒で、テンプレートの読み込みから長文の生成まで実用的な待ち時間に収まった。

 営業部の文書作成はSkillで効率化できた。しかし、次に在庫管理部門から届いた相談は、決まった型だけでは解決できない。今この瞬間の在庫数をAIに答えさせるには、データベースとの接続が必要になる。

【在庫管理編】「今の在庫数」をMCPでAIに答えさせる

 これまで在庫担当者に電話やチャットで聞いていた「あの商品、在庫あります?」を、AIに直接聞けるようにしたい。担当者が離席していても、営業時間外でも答えが返る仕組みを、IT担当者がMCPとMySQLを組み合わせて構築する。

在庫の問い合わせは担当者頼み
「あの商品、在庫あります?」の電話は、担当者の離席中も鳴り続ける

 SkillとMCPの違いは明確だ。Skillは「読み込むだけ」で実行はしない。MCPは実際にSQLを実行し、その場のデータを取得する。在庫数は日々変動する典型的な「生きた数値」で、「発注点を下回っている商品は?」という質問は、ドキュメントをいくら検索しても正確には答えられない。MCPでDBに直接問い合わせることで、聞いた瞬間の正確な値が返ってくる。定番ではあるが、それだけMCPの効果が分かりやすいユースケースでもある。

 Skillと違い、こちらはDB構築・MCPサーバー・権限設計が必要になる。情報システム部門が主導し、数日~1週間程度を見ておく規模の作業だ。なお、今回使用した設定ファイル一式は記事末尾の付録にまとめている。

 準備は4ステップに分けて進める。

MCP(Model Context Protocol)とは

Anthropicが提唱する、LLMと外部のツール・データソースを接続するためのオープンな標準プロトコル。LLM側は「どんなツールが使えるか」をMCPサーバーに問い合わせ、必要に応じてツールを呼び出す。データベース、ファイルシステム、Web API、社内システムなど、さまざまな対象に対応したMCPサーバーがOSSで公開されている。

vLLM側の設定に注意

MCPはFunction Callingの仕組みの上に成り立っているため、LLMサーバー側がFunction Calling(Tool Calling)に対応していないと、MCPのツールはそもそも呼ばれない。Radeon AI PRO R9700はVRAM 32GBを積んでいるため、26BクラスのモデルをFunction Callingまで含めて動かせる余裕がある。

 第1回で紹介したvLLMの起動コマンドは、Gemma 4 26B-A4B-it AWQ INT4を素の状態で立ち上げるものだったため、これに--enable-auto-tool-choiceと--tool-call-parser gemma4を追加する必要があった(対応するパーサー名はモデルによって異なり、vLLMの--tool-call-parserの一覧から選ぶ)。これを付け忘れると、モデルは「在庫データにアクセスする権限がありません」といった、ツールを使わない一般論の回答を返してしまう。

 追加後の起動コマンド全文は、付録の「vLLM起動コマンド(全文)」を参照してほしい。

準備1: 検証用データベースを作る

 検証用にMySQLでダミーデータベース「salesdb」を作成した。テーブル構成は以下の通り。

salesdbのテーブル構成
テーブル内容
products商品(SKU・商品名・カテゴリ・単価)
inventory在庫(倉庫・在庫数・発注点)

 商品はOA機器・IT機器・事務用品・家具・消耗品の5カテゴリ×10品目、計50品目を用意し、あえて8品目を発注点割れの状態にして「在庫アラート」のデモに使えるようにした。

 このダミーデータは付録の「ダミーデータの生成スクリプト」で誰でも再現できる。

検証用データベース「salesdb」のテーブル構成
productsとinventoryの2テーブル構成。50品目のうち8品目をあえて発注点割れにしている。下部は「在庫が発注点を下回っている商品を教えて」でモデルが組み立てるSQL

 テーブルを作成するSQLの全文は、付録の「ダミーDBのスキーマ定義(CREATE TABLE)」にまとめている。

準備2: MCPサーバーを読み取り専用で立てる

 今回は検証のためダミーデータを用意したが、実際の導入では既存の在庫管理DBにそのまま接続すればよい。後述の通りMCPサーバー側は読み取り専用(SELECTのみ)に絞っているため、本番のDBに直接つないでも書き込み・削除のリスクはない。

 ただし読み取り専用にしても安全が全部確保されるわけではない。SELECT権限を与えたテーブルであれば、LLMはその中身をそのまま読める。

 今回products・inventoryの2テーブルのみにSELECTを絞っているのはこのためで、たとえば人事・給与データのようなテーブルまで見える状態にしてしまうと、書き込み・削除とは別の情報漏洩リスクが残る。 接続可能なテーブルの範囲をどこまで絞るかは、読み取り専用化と同じくらい重要な設計判断だ。

 DB用のMCPサーバーはOSSで複数公開されているが、今回は読み取り専用がデフォルトで有効な@benborla29/mcp-server-mysqlを採用した。

なぜ読み取り専用にこだわるか

LLMに直接SQL実行権限を渡す以上、誤った書き込み・削除が実行されるリスクをゼロにしておく必要がある。今回は「MySQL側で読み取り専用ユーザーを作る」「MCPサーバー側でも書き込み系オペレーションを無効化する」の二重で防御している。さらに、LLMから見えるテーブルを必要最小限に絞る対策を加えた3段階の防御を図7にまとめた。

LLMにDBを触らせるときの3つの防御
MCPサーバー側で書き込み系オペレーションを無効化し、MySQL側はSELECTのみ許可、さらに見せるテーブルを在庫関連の2つに限定。読み取りのリクエストだけが3つの防御を通過してデータに届く

 MySQL側には、在庫関連テーブル(products・inventory)のSELECTのみ許可した専用ユーザーを作成する。実際にこのユーザーでDELETEを試みると、MySQL自体にERROR 1142: DELETE command deniedと拒否される。

 このユーザーを作成するGRANT文の全文は、付録の「MySQL 読み取り専用ユーザー作成SQL(GRANT文)」を参照してほしい。

 MCPサーバー側の設定にもALLOW_INSERT_OPERATION / ALLOW_UPDATE_OPERATION / ALLOW_DELETE_OPERATIONを明示的にfalseで指定し、二重に防御した。

 この設定を含む設定ファイルの全文は、付録の「mcpoの起動設定・MCPサーバー登録設定」にまとめている。

準備3: mcpoでOpen WebUIにつなぐ

 Open WebUIでMCPを使うにはmcpoを用意する必要がある。mcpoの公式Dockerイメージ(ghcr.io/open-webui/mcpo)にはNode.js/npmが同梱されており、npxで起動する形式のMCPサーバーもそのまま扱える。

 今回はMySQL・mcpo・Open WebUIの3コンテナをDocker Composeでまとめて起動する構成にした。実際に社内のMySQLに接続する場合も、DBコンテナの部分を外して接続先を実サーバーに向けるだけで、あとの構成は同じまま使い回せる。

 構成ファイルの全文は付録の「docker-compose.yml」に掲載した。

 図8に、利用者の質問がOpen WebUIとmcpoを経由してMySQLへ届き、回答が戻るまでの流れを示した。3つのコンテナの役割を分けて見ると、MCPサーバーがDBとLLMの間をどのようにつないでいるか把握しやすい。

質問がMySQLに届くまでの流れ
社員の質問はOpen WebUIからmcpoを経由してMySQLへ届く。MCPとOpenAPIの変換を担うのがmcpoだ。3コンテナはDocker Composeで一括起動し、処理はすべて社内ネットワークで完結する

 起動後、mcpoのログにSuccessfully connected to mysqlと出れば接続成功だ。/mysql/docsにアクセスすると、Swagger UI(OpenAPIの定義から自動生成される、ブラウザ上でAPIの一覧確認・試し打ちができる画面)からmysql_queryという読み取り専用のSQL実行エンドポイントが公開されていることも確認できる。

OpenAPIとは

Web API(HTTP経由で呼び出せる機能)の仕様を、機械可読な形式で記述するための標準規格。「どんなURLに」「どんな形式のデータを送ると」「どんな結果が返るか」を定義しておくことで、対応するツール同士が自動的に連携できるようになる。多くのWebサービスやSaaSが採用しており、Open WebUIもこの形式のAPIを「Tool Server」として登録・利用する設計になっている。

 一方MCPは、LLM専用に設計された別のプロトコルであり、OpenAPIとはそのままでは会話できない。両者の間を変換するのが次に説明するmcpoの役割だ。

mcpo(エムシーピーオー)とは

Open WebUIチームが開発するプロキシで、stdio(標準入出力)で動くMCPサーバーを、通常のHTTP・OpenAPI形式のAPIサーバーに変換する。Open WebUIはMCPを直接は話さず、OpenAPI形式の「Tool Server」を読み込む設計のため、両者を橋渡しする役割を担う。

 試しにcurlで直接たたいてみると、在庫が発注点を下回っている商品がJSONで返ってくる。

bash
curl -X POST -H "Authorization: Bearer (APIキー)" -H "Content-Type: application/json" \
  -d '{"sql":"SELECT product_name, stock_qty, reorder_point FROM ... WHERE stock_qty < reorder_point"}' \
  http://localhost:8000/mysql/mysql_query
# => [[{"product_name":"ラミネーター","stock_qty":14,"reorder_point":23}, ...]]

 ここでは長いSQLを省略しているが、JOINを含む完全な形は付録の「curlの例(完全版)」に掲載した。

 この時点でMCP経由のDBアクセス自体は完成している。あとはOpen WebUIから使えるようにするだけだ。

準備4: Tool Serverとして登録し、カスタムモデルを作る

 Open WebUIにTool Serverとして登録するには、Open WebUIの管理者パネル(個人アカウント設定とは別画面)から、mcpoが公開しているOpenAPIエンドポイントを登録する。

Tool Server(ツールサーバー)とは

Open WebUIの用語で、OpenAPI形式で公開されたAPIサーバーを「モデルが呼び出せる道具箱」として登録する仕組み。一度登録すれば、その道具箱に入っているツール(今回ならmysql_query)を、任意のモデルやカスタムモデルから有効・無効を切り替えて使い回せる。

OpenAPIツールサーバーの登録フォーム
管理者パネル > 設定 > 連携 画面。OpenAPIツールサーバーの追加フォーム。URLは「http://mcpo:8000/mysql」(コンテナ間通信のためサービス名で指定)。Bearerはmcpo起動時に指定したキー
Tool Server「MySQL(在庫)」の登録完了
Tool Serverとして登録が完了し、一覧に「MySQL (在庫)」が表示された状態

「接続を確認」ボタンがエラーになる場合

 このURLの登録・保存自体はサーバー側で処理されるが、画面上の「接続を確認」ボタンはブラウザから直接このURLをたたく。

 ブラウザはmcpoというホスト名をDocker内部のDNSとして解決できないため、ここだけはエラーになりやすい(保存自体は通るので実害はない)。

 気になる場合は、作業しているPCのhostsファイルに「127.0.0.1 mcpo」を追加しておくと、ブラウザからも同じ名前で解決できるようになる。なお、Windowsではメモ帳などのエディタを「管理者として実行」して開く必要がある。

hostsファイルの場所(OS別)
OS場所(パス)
macOS/etc/hosts
Linux/etc/hosts
WindowsC:¥Windows¥System32¥drivers¥etc¥hosts

 カスタムモデルの作成は、第1回のRAG編でQ&A専用モデルを作ったのと同じ要領で、DB連携済みのカスタムモデルを作成する。

カスタムモデル「在庫管理」の設定
項目内容
モデル名在庫管理
モデルIDinventory-assistant
ベースモデル接続しているLLM
Tools先ほど登録したMySQL (在庫) Tool Serverを有効化
「在庫管理」モデルにMySQLツールを有効化
新しいモデル作成画面。「在庫管理」にMySQL (在庫) Toolを有効化しているところ

試してみる

 準備ができたところで実際に試してみる。

【質問】「在庫一覧」

 モデルは登録されている商品一覧を表示した。

「在庫一覧」で全商品が返る
「在庫一覧」への回答。全商品一覧

【質問】「在庫が発注点を下回っている商品を教えて」

 モデルがmysql_queryツールを呼び出し、inventoryとproductsをJOINしたSQLを組み立てて実行、結果を自然文で要約して返す。

発注点割れの商品をSQLで抽出して回答
「在庫が発注点を下回っている商品を教えて」への回答。ツール呼び出しの様子と結果一覧

  ドキュメントの検索ではなく、その場でSQLを組み立てて実行している点がRAG・Skillとの決定的な違いだ。 データが更新されれば、次に聞いたときには最新の値が返る。「在庫が発注点を下回っている商品を教えて」と質問してから回答が出るまでの時間は約7秒だった。初回はテーブル構造を確認する問い合わせも挟んでおり、スキーマを把握したあとの会話ならさらに短縮できる。

 これでIT担当者は、文書の型に続いて在庫管理部門の「生きたデータ」もAIから利用できるようにした。最後の相談は、社内の資料だけでなく、最新の社外情報も含めて調べたいというものだ。

【リサーチ編】Web検索と社内文書RAGを組み合わせる

 3つ目の相談を受けたIT担当者が向き合うのは、社内外に散らばった情報だ。新しい業界動向を調べてレポートにまとめる、英語の技術資料やマニュアルを読んで社内向けに翻訳する、過去の報告書や議事録がどのファイルにあるか探し回る――どれも地味だが、積み重なるとそれなりに時間のかかる「調べ物」業務だ。

調べ物が業務時間を侵食する
英語のマニュアルと、置き場所の分からない過去の報告書。地味な「調べ物」が業務時間を削っていく

 営業編・在庫管理編がそれぞれ「社内の型」「生きたデータ」を扱ったのに対し、リサーチ編は「情報を探して、まとめて、必要なら翻訳する」という調べ物そのものをAIに任せる検証になる。

 Open WebUIが対応する検索バックエンドには、無料でキー不要のものも存在するが(SearXNGを自前ホストする方法や、DuckDuckGoをスクレイピング的にたたく方法など)、企業利用では利用規約上の位置付けが明確な公式APIを選びたい。

 今回は公式にライセンスされたAPIであるTavily(LLM・RAG用途向けに設計された検索API、無料枠: 月1,000クレジット、クレジットカード登録不要)を採用する。管理者パネルでAPIキーを設定するだけで済み、追加のコンテナやサーバー構築は不要だ。

 APIキーの取得手順は付録の「TavilyのAPIキー取得手順」にまとめている。

 過去の議事録・報告書・マニュアルのような「社内に散在する文書」も、リサーチ業務では頻繁に探すことになる。これは新しい仕組みではなく、第1回で使ったRAGの応用そのものだ。Open WebUIの「ナレッジ」機能に文書をアップロードしておけば、検索結果には元ファイル名の出典が付き、「どのファイルに書いてあるか」までAIが示してくれる。

 検証用に、議事録・契約書・月次報告書・英語の保守マニュアル(トラブルシューティング文書)を4点用意し、ナレッジコレクションへ登録した。月次報告書は、以降に試す内容とは無関係なものをあえて加えている。関係のない文書を誤って参照せず、適切に検索できるか確かめるためだ。

Web検索エンジンにTavilyを設定
管理者パネル > 設定 > ウェブ検索。Tavilyをエンジンに選択し、APIキーを設定したところ
「リサーチアシスタント」モデルの設定
新しいモデル作成画面。「リサーチアシスタント」にWeb検索とナレッジを設定しているところ
カスタムモデル「リサーチアシスタント」の設定
項目内容
モデル名リサーチアシスタント
モデルIDresearch-assistant
基本モデル接続しているLLM
機能Web検索/有効化
ナレッジベース用意した文書コレクションを紐付け

【質問】「大阪営業所の在庫管理システムのキックオフ会議の議事録はありますか?決定事項を教えてください」

 モデルはナレッジから該当する議事録ファイルを検索し、出典付きで内容を要約して返す。決定事項と未決事項が本文中で明確に区別されているかどうかまで踏み込んで確認してくれる点は、単純なキーワード検索にはない強みだ。

議事録の決定事項が出典付きで返る
「議事録はありますか」への回答。出典付きで返っている

 同じ仕組みは、社外に出したくない契約条件や社内規定の確認にも応用できる。試しに、業務委託契約書をナレッジに追加登録してみた。

【質問】「業務委託契約書の再委託に関する条項はどうなっていますか」

 モデルはナレッジから該当する契約書ファイルを検索し、第3条の再委託条項を出典付きで要約して返す。 社外に出せない契約条件をクラウドAIに渡さずに確認できるという点で、ローカルLLMの価値が最も分かりやすく出る使い方の1つだ。

契約書の再委託条項を出典付きで確認
「業務委託契約書の再委託に関する条項はどうなっていますか」への回答。出典付きで返っている

 続けて、英語の保守マニュアルの内容を尋ねてみる。

【質問】「コンベアのエラーコードA01が出た。英語マニュアルの該当箇所を日本語に訳して対処法を教えて」

 翻訳のための特別な設定は何もしていない。ナレッジから該当箇所を検索し、その場でLLMが日本語に翻訳しながら回答する。原因・対処手順・注意事項が、出典付きの日本語の文章として返ってくる。

英語マニュアルを翻訳しながら対処法を回答
「エラーコードA01の対処法」への回答

 こうした過去のトラブル対応記録をナレッジ化しておけば、ベテランが個人的に抱えているノウハウを、若手担当者への技術伝承としても機能させられる。

 この仕組みは翻訳が主目的の英語マニュアルに限らず、海外拠点や海外顧客とのメール対応にもそのまま使える。GPU上での処理は外部に一切出ないため、社外に見せられない社内トラブル情報を安心してナレッジ化できる。

【質問】「2026年、30B未満のローカルLLMの動向についてWebで検索してまとめて」

 Web検索を有効にしたモデルは、Tavily API経由で検索を実行し、得られた検索結果を踏まえて回答を組み立てる。回答には参照したWebページが出典として付く。社内文書のナレッジ検索と同じ「出典付きで答える」体験を、検索対象を社内からWebに広げただけで実現できる。

 この質問への応答時間は、Tavily APIへの検索リクエストを含めて約20秒だった。社内文書だけでは答えられない最新情報を、検索から要約まで一度に処理できることを考えれば、日常のリサーチにも十分使える速さだ。

Web検索を使った最新動向のまとめ
Web検索を使った回答例。Web検索をオンにする

 Skill(営業編)とMCP(在庫管理編)は完全にローカルで完結し、月額の追加コストも発生しない。一方、リサーチ編で気をつけたいのは、Web検索だけは外部の検索APIに依存することだ。

 無料枠のクエリ数には上限があるため、全社的に使う場合は利用量を見ながら有料プランへの切り替えを検討する必要がある。また、検索キーワードが外部サービスに送信される以上、社外に出したくない語句を検索させない、といった運用ルールも決めておく必要がある。社外へ送られるのは検索キーワードだけという境界を図9に示した。

社外へ送られるのは検索キーワードだけ
社内文書・在庫DB・テンプレート・LLM本体はすべてRadeon AI PRO R9700サーバー内にとどまる。外部のTavilyへ渡るのは検索キーワードのみだ

 最後に利用人数が増えてきたらどうするか、という点にも触れておきたい。1台のGPUサーバーで捌ける同時アクセス数には限りがあるため、全社規模で使うとなるとGPU性能の強化を考える場面が出てくる。

 ここで真っ先に思い浮かぶのがデュアルGPU構成や複数GPUサーバーによる負荷分散だろうが、これは複数GPU間でリクエストを振り分けるロードバランサーを組む必要があり、構築・運用コストは大企業の予算規模でないと見合わない。

  中小企業でGPU性能を底上げしたい場合は、同じ構成のマシンを複数台用意し、部署やチームごとにサーバーを分けてIPアドレスで振り分ける方が、構成がシンプルで現実的だ。 なおかつ外部のシステムインテグレータなどに頼む必要もなく、実は一番安上がりだったりする。

まとめ

 IT担当者のもとに届いた営業・在庫管理・リサーチの3つの相談は、Skill・MCP・Web検索という性質の異なる仕組みを使い分けることで解決できた。

 入口は「社員が自然な日本語で話しかけるだけ」でどれも変わらないが、裏側でAIが「テンプレートを読み込む」のか「DBに直接問い合わせる」のか「検索して調べる」のかで、必要な準備も得られる効果もまったく違う。

 3つのどれか1つで十分ということはなく、 「型を統一したいだけならSkill」「その場のデータが必要ならMCP」「調べ物や翻訳を任せたいならWeb検索+RAG」と、目的に応じて使い分けるのが現実的だ。 始めるならまずSkillからで十分だろう。手応えを感じたら、情報システム部門を巻き込んでMCPやWeb検索に着手すればいい。

どの仕組みを使うか迷ったら

以下の順に自問すると、使うべき仕組みが決まる。

1. 今この瞬間の最新データ(在庫数など)が必要か?
  → YES: MCP(在庫管理編)
2. 文書の「型」を揃えたいだけか?
  → YES: Skill(営業編)。まずはここから
3. 探したい情報はどこにあるか?
  → 社内文書:RAG(第1回)/社外・Webの情報: Web検索(リサーチ編)

 クラウドAIに社外の契約書や在庫データを渡さずに済み、月額利用料もかからないという第1回からの前提は、Web検索を除けば今回も変わっていない。IT担当者がすべての業務を一度に作り替える必要もない。 まずSkillで小さく始め、必要に応じてMCPやWeb検索へ広げればよい。 RAG・Skill・MCP・Web検索の4つが揃えば、ローカルLLMサーバーは自分の知っていることだけを答えるAIから、社内文書を検索し、型を守り、生きたデータに触れ、必要なら世の中の情報まで調べて答える、日常業務に踏み込める「使えるAI」になる。