2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

RAGじゃ足りなかったので、運用知識をPythonに任せるAIを作った

2
Last updated at Posted at 2026-02-12

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 を。


まず、リポジトリはこちら

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 はその結果を人間向けに整形するだけの構成

雑に生成した図なのでところどころ怪しいけれど、
概念としては正しく表現できている。こまけえことはええんやよ。

image.png


アーキテクチャ

やったことはシンプル。

この構成は、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 → 仕様 → ドキュメント

の流れが一本になった。


せっかくなので公開した

再掲だが、リポジトリはこちら。

MIT License で公開している。これは Dify 専用ツールというより、

分断されたドキュメント世界を、運用可能な構造に再コンパイルする実験

に近いと思っています。


学び

今回一番の学びはこれだ。

LLMを「脳」にする必要はない。むしろ「手」として使うほうが安定する場面も多い。

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

そしてもう一つ。

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

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


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

これはその記録でした。

付記

この記事は純粋に技術的な実装にフォーカスしたものです。
実装プロセスの観測ログ(人間とAIの距離感について)は
別記事にまとめています。

https://www.mncc.info/observation-log-20260212-ai-ops-python/

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?