RAGじゃ足りなかったので、運用知識をPythonに任せるAIを作った
Dify Enterprise を題材にした、Deterministic Core + LLM UI な構造ファーストbotの実装記録
はじめに
RAGを使ったドキュメント検索に限界を感じ、運用知識そのものをPythonで構造化するAIを作りました。
Vector DBでは解けなかった upgrade や設定差分の問題を、Deterministic Core + LLM UI という構成で解いています。
Dify Enterprise を題材にしていますが、設計パターン自体は、ドキュメント横断・アップグレード運用・複雑な設定管理など、他のEnterprise製品にもそのまま応用できます。
TL;DR
Dify Enterpriseの運用で、分断された3つのドキュメント(Helm/Enterprise/Community)を 横断検索する必要があったが、RAGでは構造推論ができないため、 SQLite FTS5 + Python で決定論的処理を行い、LLMは結果の整形のみに使うツールを作った。
→ リポジトリ: https://github.com/minacochang/dify-enterprise-docbot
こんな人におすすめ:
- Enterprise 製品の 複数docs 横断地獄にいる人
- RAG に疲れた人、RAGを試したけど精度に不満がある人
- Cursor を実務で使っていて、実務の自動化を進めたい人
Dify Enterprise、マジヤバいんすよ。
正直、かなり頭を使う。
理由は単純で、ドキュメント体系が三層に分断されているから。
まさにドキュメント・サンドイッチ。しかも各層が分厚め、というやつ。
まず、Dify Enterprise 版のドキュメント。 → こいつ
次に、Dify EnterpriseのHelm repoの release notes。→こいつ
そして、対応するCommunity 版の機能ドキュメント。→こいつ、だけでは足りなくて、Community版のコミットログまで追う必要がある。
しかも、新しいバージョンのコア機能は、中国語ドキュメントにしか書いていなかったりする。
(LangGeniusさんはもともと中国はTencent CloudのDevOpsチームにいたメンバーが作った会社!)
こんな状態なので、helm upgrade をしようとするたびに、
- Helm の変更点を読み
- values.yaml の差分を確認し
- 必要なら3つのドキュメントすべてを漁り
- 「で、結局何が変わるのか?」を自分の頭で join する
これを毎回やるのは、普通に無理ゲーだった。というかよくやってたな!!!!
なので作った。
SQLite + FTS5 + BFS + Python で、
Dify のドキュメント世界をローカルに再構築する docbot を。
まず、リポジトリはこちら
https://github.com/minacochang/dify-enterprise-docbot
MIT License で公開している。
問題は「ドキュメントが悪い」ことではなかった
先ほどのリンクを辿っていただくとわかるのだが、
Dify のドキュメントは、実は構造自体は悪くない。
- 見出しは整理されている
- 機能ごとにページは分かれている
- Helm release notes も比較的明確
問題はこれだった。
構造化はされているのに、横断検索が壊滅的
しかも世界が分断されている。
- Helm(配布の単位)
- Enterprise(運用の単位)
- Community(機能仕様の単位)
これらが別々の文脈で語られている。
つまり、運用者は常に
Enterprise のバージョンを見ながら
内部で動いている Community の世代を推測し
その機能ドキュメントを探しに行く
という二重参照を強いられる。
これは人間の脳にやらせる内容ではないよ!
RAGでは解決しなかった理由
最初は普通に考えた。
「RAG で全部突っ込めばよくないか?」
でもやってみると分かった。
RAGでは問題は解消しない。
必要なのは:
- バージョンアップのhop の計算
- Non-Skippable (=何をスキップしちゃいけないのか)の考慮
- values.yaml の意味的差分
- appVersion 単位での構造把握
つまり、構造推論なんすね。
(例えば、バージョン間の関係・依存・差分を“計算”する処理とかね)
やりたいのは検索ではなく「計算/処理」だった。
ベクトル検索は便利だけれど、
- なぜその結果になったのか追いづらい
- 再現性が弱い
- diff や upgrade 経路のような決定論的処理ができない
そこで方向を変えた。
推論は Python にやらせたろう。
LLM は表現だけに使ったろう。
Deterministic Core + LLM UI の全体像
図: Python が運用知識を決定論的に処理し、LLM はその結果を人間向けに整形するだけの構成
雑に生成した図なのでところどころ怪しいけれど、 概念としては正しく表現できている。こまけえことはええんやよ。

アーキテクチャ
やったことはシンプル。
この構成は、Deterministic Core + Generative Edge と呼べそうだ。
1. sitemap + BFS でドキュメントを完全回収
- Enterprise docs
- Helm release notes
- Community docs(zh / ja / en)
をローカルに収集する。
2. SQLite FTS5 で全文索引
- 日本語 / 中国語は CJK n-gram
- 英語は通常 FTS
- 再スコアでノイズ除去
Vector DB は使っていない。
理由は単純で、再現性と軽量さを優先したから。
3. 構造は Python で処理
- release notes → appVersion 抽出
- Non-Skippable → hop 分解
- upgrade 経路生成
- values.yaml diff の意味分類
- Helm chart の構造抽出
LLM(Cursor Agentを想定)は UI。よって、その後段で使用する。
機能を組み合わせて実行したり、Markdown を整えたり、説明を生成するだけって感じ。
知識を「雑に使える」状態になった
完成してみて一番驚いたのはここだった。
まず、Cursor Agentに適当にプロンプト入れても動く。
2.8.2から3.6.5にバージョンアップしたい。必要なインフラの作業は何?
以下が回答の全文。
Cursor回答結果
2.8.2 → 3.6.5 で必要なインフラ作業をまとめました。
Upgrade path
2.8.2 → 3.2.2 → 3.6.5
(3.2.2 は Non-Skippable のため省略不可)
Hop 1: 2.8.2 → 3.2.2
1. Helm values の更新
* 追加(103件): enterpriseAudit. を中心に新設
- デフォルト値変更(12件): api., enterprise., web., ssrfProxy.enabled, unstructured.enabled など
* 最新デフォルトに合わせて values.yaml を修正
2. プラグインマイグレーション
* 既存プラグインの互換性確認
* 必要に応じて新規プラグインを Marketplace から導入
3. Nginx Ingress ConfigMap の更新
* 既存の Nginx Ingress Controller の ConfigMap を新仕様に合わせて更新
4. enterpriseAudit の構成
* 監査ログ用の新コンポーネント
* デフォルトでは enterpriseAudit.enabled: true の想定
* 監査ログを有効にする場合は enterpriseAudit. を調整
Hop 2: 3.2.2 → 3.6.5
1. Helm values の更新
- 追加(60件): enterprise.passwordEncryptionKey, gateway.allowOrigins, global.innerApiKey, plugin_connector.github. など
* 削除(7件): 以下を削除し、代替キーへ移行
* api.innerApi.apiKey → global.innerApiKey
* enterprise.corsOrigins → gateway.allowOrigins
* enterprise.innerApi.apiKey → global.innerApiKey
* plugin_connector.apiKey, plugin_daemon.apiKey, plugin_daemon.innerApiKey, sandbox.apiKey → 新しい認証方式へ
2. Password Encryption Key の設定(必須)
* enterprise.passwordEncryptionKey の設定が必須
* オンプレミス/オフライン環境それぞれの手順に従って生成・設定
* 既存パスワードの暗号化方式変更を含むため、事前に手順確認が必要
3. セキュリティ対応(脆弱性対策)
* 3.6.5 は脆弱性対応を含む
* 影響範囲・優先度・一時的な緩和策・検証方法などを release notes で確認
作業チェックリスト
段階
作業
共通
バックアップ取得(DB・PVC・values.yaml)
Hop 1
values.yaml 更新(enterpriseAudit 等)
Hop 1
プラグインマイグレーション
Hop 1
Nginx Ingress ConfigMap 更新
Hop 1
helm upgrade 実行
Hop 2
values.yaml 更新(削除7件の移行、追加設定)
Hop 2
enterprise.passwordEncryptionKey 生成・設定
Hop 2
helm upgrade 実行
Hop 2
アプリケーション動作確認
参照リンク
* Hop 1: <https://langgenius.github.io/dify-helm/pages/3_2_2.md>
* Hop 2: <https://langgenius.github.io/dify-helm/pages/3_6_5.md>
詳細は上記の release notes を参照してください。
…神。
また、CLIとしても、
docbot upgrade --from 2.8.2 --to 3.7.5
と打てば、
- 必要な hop
- infra 作業
- 関連 release notes
- 関連 Community docs(zh-cn 含む)
がまとまって出る。
(これは将来コーディングにも使用できる可能性を持っている)
ここで重要なのは、答えを生成しているのではなく、 既に構造化された知識を整形しているだけ、という点。
だからこれは chatbot ではない。
Dify Enterpriseの運用知識・思考の外部化装置
を実装しているという状態に近い。
Enterprise と Community の橋渡し
特に辛かったのは、
Helm は Enterprise の箱
コア機能は Community ベース
という構造。
そこで、
- appVersion → domain マッピング
- domain → Community docs 自動検索
という橋を追加した。
これで、
Helm → 仕様 → ドキュメント
の流れが一本になった。
せっかくなので公開した
再掲だが、リポジトリはこちら。
https://github.com/minacochang/dify-enterprise-docbot
MIT License で公開している。これは Dify 専用ツールというより、
分断されたドキュメント世界を、運用可能な構造に再コンパイルする実験
に近いと思っています。
学び
今回一番の学びはこれだ。
LLMを「脳」にする必要はない。むしろ「手」として使うほうが安定する場面も多い。
構造に考えさせるほうがいい場合、その「構造」はコードに落としたほうが安定する。
そしてもう一つ。
去年の夏頃、自分が欲しかったものを作れた。
必要は発明の母とはこのことなり。
誰かの、何かのヒントになるかもしれない。
これはその記録でした。