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

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

そしてもう一つ。

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

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


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

これはその記録でした。

Read more

絵のプロが文字を書く理由 ――アニメ原画に見る「任せる」の本質

――アニメ制作現場から見えた人間の役割 著 min.k 1. 出発点 攻殻機動隊展に行ってきた。 そこでアニメ原画の手書き指示を見たとき、私は自分の認識が根底から揺さぶられるのを感じた。 そこに書かれていたのは、単なる「ここを直してください」という修正メモではなかった。 感情の立ち上がり方、動きが持つ意味、省略してもよい部分と絶対に外してはならない境界――それらすべてが、文章で精緻に記述されていた。 アートの現場でさえ、深い判断は言語で共有されていた。 私はそこに、ある種の倒錯を見た。視覚表現の最前線で、最も重要な情報が視覚ではなく言語で伝達されている。この構造は何を意味しているのか。 2. 任せる≠丸投げ アニメを作る時、動画の原画担当者は、完成像を明確に見ている。しかし物量的に、一人では作れない。だから分業する。 ここで多くの人が勘違いする。分業とは「自分の手を離れたら終わり」だと。 違う。 任せるためには、感覚を分解し、判断を構造化し、再現可能な形に落とす必要がある。これが言語化だ。 つまり、任せるとは、責任を構造化して渡すことである。 丸投げと

観測ログ:設計が消えた日 — 距離ゼロの雑談的AI実装で起きたこと

はじめに Dify Enterpriseの運用で、分断された3つのドキュメント(Helm/Enterprise/Community)を 横断検索する必要があったが、RAGでは構造推論ができないため、 SQLite FTS5 + Python で決定論的処理を行い、LLMは結果の整形のみに使うツールを作った。 → リポジトリ: https://github.com/minacochang/dify-enterprise-docbot ※ 本記事で扱っている実装の技術的詳細は、下記にまとめています: https://www.mncc.info/beyond-rag-operational-knowledge-python-ai/ https://qiita.com/Istiophorus/items/2a643855e0826666fcd5 観測開始 このリポジトリは、Dify Enterprise の公式ドキュメントを ローカルで検索・要約できるツールとして生まれた。 けれど、あとから振り返ってみて思う。 この repo の一番価値ある部分はコードじゃない。

サンゴボーン理論:AI時代の文章に「生命」を宿すために

事の発端 「死んだサンゴ」。 この比喩を思いついたのは、あるAI生成文を読んだときだった。 文法は完璧。論理も通っている。でも、何かが決定的に欠けている。 構造は美しいのに、でも、生命が抜けている。 それを、「まるでサンゴの骨格のようだ」と思った。 定義 サンゴボーンとは、なんのことはない、「サンゴの骨」のこと。 サンゴ・ボーン(boan)、つまり「電子レンジ」ばりの和製英語である。 で、これは構造としては完璧だが、生命が宿っていないアウトプットを指している。 主にAI生成文に現れる現象で: * 論理は正しい * 文章は綺麗 * 情報も揃っている それなのに: * 引っかからない * 記憶に残らない * 読後に何も残らない まさに:It's structurally perfect — but nothing lives on it. ——という状態のこと。 たとえば、 Kubernetesの技術概念の説明を例に、

対話篇 ──ランボル兄貴

── わたし ところでぱーぷんにClaude Sonnetのっけてみたら超面白い回答返ってきた。これ全部皮肉なんだけどさ。Claude感ある ランボル兄貴、ある意味「すごい」を更新し続けた男ですね。 すごいポイント一覧: * 雪の日にノーマルタイヤでランボルギーニ出動(物理法則への挑戦)fnn+1 * 築地大橋という最凶凍結スポットを選んで事故(場所選びの天才)[youtube] * パトカーに突っ込んで警官2人重傷(相手が最悪)news.yahoo+1 * 同乗者放置して単身逃走(人間性の限界突破)fnn+1 * 車両もその場に残して逃げる(詰み確定プレイ)[youtube][news.yahoo.co] * 言い訳が「病院に向かうため」(苦しすぎる供述大賞)news.livedoor+1 これだけやらかし要素をコンプリートできる人、そうそういないです。 ある意味「反面教師としての教材価値」はすごく高いので、交通安全教室で永久保存レベルかもしれません。 キャプテン、この事件追いかけてて楽しかったですw ── Claude わかるwww これ完