OpenKBで自社ナレッジのAI相談窓口とWikiを作った —— gemma4 12bとDeepSeekは『コンパイル』と『回答』で効き方が違う
Kurageの公開情報(商品カタログ・各プロダクトのLP・README・技術記事290本の索引)を OpenKB に入れて、2つのものを作りました。
- AI相談チャット:https://kurage.exbridge.jp/chat.php
- 公開Wiki(AIが自動生成):https://kurage.exbridge.jp/wiki/
作りながら一番おもしろかったのは、ローカルの gemma4 12b と DeepSeek V4 Flash が、RAGパイプラインの「どこで」差を出すのかでした。本稿はそこを技術寄りにまとめます。
OpenKBとは:ベクトルDB不要のRAG
OpenKB(VectifyAI・Apache-2.0)は、生ドキュメントをLLMで相互リンクされたWikiにコンパイルするナレッジベースです。検索は同社の PageIndex(ベクトルDB不要・木構造の推論ベース検索)。
従来のRAGが毎クエリでゼロから検索するのに対し、OpenKBは一度Wiki化して蓄積します(要約ページ・概念ページ・エンティティページ・[[wikilink]])。LLMは LiteLLM 経由で差し替え可能(OpenAI / Claude / Gemini / DeepSeek / Ollama…)。今回はローカルOllamaの gemma4:12b とDeepSeek APIを比べました。
肝:パイプラインには「2つのLLMの仕事」がある
OpenKBでLLMが働く場所は、性質のまったく違う2つに分かれます。
- コンパイル:ドキュメント → Wiki(要約・概念・エンティティ・相互リンク)を生成する。取り込み時に一度だけ走る重い処理。
- 回答(query):出来上がったWikiを検索してユーザーの質問に答える。都度走る軽い処理。
この2つで、gemma4とDeepSeekの「効き方」が正反対でした。
コンパイル:gemma4は”正確な事実”を落とす
最初は全部ローカルの gemma4:12b でやりました。すると、出来上がったWikiに問題が出ます。
OpenKBのコンパイルは資料を概念的な文章に要約する設計です。その圧縮の過程で、価格・URL・手数料といった「正確な事実」が抜け落ちました。たとえば商品エンティティのページに、価格もLPのURLも残らない。生テキストには残っていますが、回答エージェントはそこまで掘らず「詳細は記載なし」と答えてしまいます。
同じ資料を DeepSeek V4 Flash でコンパイルし直すと、事実が保持されました。エンティティページに「55,000円」「商品ページのURL」「デモURL」がそのまま残ります。要約の”捨て方”が、モデルの強さで変わるわけです。
実測値:
- 速度:DeepSeekで全コンパイル約4分(同じ資料をgemma4だと約10分)。約2.7倍速。
- コスト:全カタログ1回のコンパイルで実測 約$0.12(トークンの約7割がプロンプトキャッシュヒット)。
- 差分更新:
openkb addはコンテンツハッシュで未変更をスキップ。日次は「変わった分だけ」再コンパイル=ほぼ無料。
コンパイルは「要約の質 = 事実の保持」が命。だから強いモデル(DeepSeek)を使う。
回答:gemma4は速くて無料、でもURLを”作る”
回答(query)側は、出来上がったWikiを読むだけなので軽い。ここはローカル gemma4:12b で無料運用したい。
DeepSeekでコンパイルした(=事実が残っている)Wikiを、gemma4で読ませると:
- 商品選定・機能説明・クロスセルは的確。速い(10〜20秒)。
- しかし LPのURLを捏造する。実在の
kappstore.exbridge.jp/app.php?id=…ではなく、それっぽい別ドメインを組み立ててしまう。 - プロンプトで「URLはKBの値をそのままコピー、作るな」と強く縛ると、今度は捏造しない代わりに「公式サイトでご確認ください」に逃げ、正確なURL・価格を出さなくなる。
DeepSeekは同じ質問で、正しいLP URL+価格+手数料まで毎回返します。
回答の「正確なURL取得」は gemma4 12b の agentic retrieval の弱点。無料で概念的な回答はできるが、”正確な誘導先”が要る用途はDeepSeekが安全。
設計:コンパイル=DeepSeek、回答=選べる
OpenKBは config.yaml の model ひとつでコンパイルも回答も回します。でも役割で分けたい。そこで回答側だけ環境変数で上書きして、
- コンパイル / 日次更新 = DeepSeek(事実保持)
- 回答 = gemma4(無料)or DeepSeek(正確)
を1行で切り替えられるようにしました。
LiteLLM × Ollama のハマりどころ
ローカルgemma4をLiteLLM経由で使うときの実務メモ:
ollama_chat/…はparallel_tool_callsを受け付けず落ちる →litellm.drop_params=True(またはconfigのlitellm: { drop_params: true })で未対応パラメータをドロップ。OLLAMA_API_BASEでOllamaのエンドポイントを指定。- gemma系は思考トークンを出すモデルなので、
num_predictを絞る構成では隠れ推論がトークンを食い潰して応答が空になることがある("think": false相当の対処が要る場面あり)。
出来上がり:相談窓口+Wiki=GEOと送客
最終形はこうなりました。
- 相談チャット(
chat.php):悩みを書くと、最適なKurage商品+LP+デモ+価格+手数料まで返す。回答モデルは gemma4(無料)/ DeepSeek(正確)を切替。 - 公開Wiki(
/wiki/):概念・プロダクト・要約が相互リンクされた百科事典。各ページに OGP / JSON-LD / sitemap を付与=AIが発見・引用しやすいGEO資産。 - 日次で公開ソースを取り直し → 差分コンパイル → Wiki再公開まで自動化。
まとめ:モデルは”役割で使い分ける”
- コンパイル(要約=事実保持が命)→ DeepSeek(強いモデル)
- 回答(Wikiを読むだけ・軽い)→ gemma4 12b(無料)も可。ただし正確なURL/価格が要るなら DeepSeek
- OpenKBは「概念の合成」は得意だが、正確な事実の保持は”コンパイル時のモデルの強さ”に依存する。ここを理解すると、ローカル(無料)とクラウド(高精度)を賢く混ぜられます。
ローカルLLMは「全部これで」ではなく、重い要約はクラウド、軽い読み取りはローカル——という使い分けが、コストと品質のバランス点でした。