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を「脳」にする必要はない。むしろ「手」として使うほうが安定する場面も多い。

構造に考えさせるほうがいい場合、その「構造」はコードに落としたほうが安定する。

そしてもう一つ。

去年の夏頃、自分が欲しかったものを作れた。

必要は発明の母とはこのことなり。


誰かの、何かのヒントになるかもしれない。

これはその記録でした。