1. はじめに
以前、oracle/skills(Oracle が公開する実践ガイド集)を Claude Desktop の Skill に登録して、AWR 解析が「skill の有無」と「モデルの大小」でどう変わるかを記録しました。
- 前作: oracle/skills を Claude Skill に登録すると AWR 解析で何が変わるか
- そこでの結論: skill の有無がモデルサイズより解析品質に効く(特にハードパースの過大評価を補正し、確認指標を増やした)
ただ、現場のインフラは閉域環境が多く、クラウドの LLM をそのまま叩けないことがよくあります。そこで今回は、完全にローカル/閉域で完結する構成で同じことができるか試しました。OCI のノードに Ollama を入れ、oracle/skills を 自前の RAG(検索拡張生成)知識ベースにして、ローカルの小型モデルに AWR を解析させ、「RAG あり / なし」 を比べます。
- oracle/skills: https://github.com/oracle/skills
- ベクトルストアは Oracle Database 26ai の AI Vector Search(
VECTOR型)。埋め込み・生成・検索すべてlocalhostで完結します。
本記事の「Skill」は Anthropic の Agent Skills(LLM に参照させる知識・手順のまとまり)を指します。LLM が実行する関数・API(Tool / MCP ツール)とは別概念です。
検証ゴール
| # | ゴール | 確認できれば OK |
|---|---|---|
| 1 | oracle/skills を外部通信なしでローカル RAG 化できるか |
localhost の Ollama と 26ai だけで検索→出典付き回答が動く |
| 2 | RAG の有無で AWR 解析の中身がどう変わるか | 観点ごとに「何を拾えたか」で差が見える |
| 3 | 前作(クローズドモデル)の知見が閉域・ローカルでも再現するか | ハードパース補正などが RAG ありで出る |
結論(先出し)
- 今回は 同じ Qwen ファミリでサイズだけを変えて(qwen2.5:3b vs 7b)、RAG の有無と掛け合わせて観察。
- 閉域・ローカルでも、ある程度の大きさのモデル(qwen2.5:7b)+ oracle/skills(RAG) なら前作の知見が再現。
- RAG で効いたのは、ハードパースの過大評価を補正(7b・RAG ありだけが「100/秒の閾値 → 低優先」と正答。RAG なしは誤った閾値で「優先度が高い」と誤判定)。
- ただし土台の分析力(AAS 算出・原因 SQL の名指し)はモデルの大きさ次第で、qwen2.5:3b では届かず。しかも 3b は RAG で 100/秒の閾値を渡しても使いこなせず、ハードパースの補正は 7b で効果あり(=能力があって初めて RAG が活きる)。
- 3b は速いが非力/7b は skill を活かせるが遅い。品質はモデルサイズで決まり、速度は GPU で底上げできると想定。
2. 検証環境
| 項目 | 内容 |
|---|---|
| ノード | OCI VM.Standard.E5.Flex(AMD EPYC)/ 2 OCPU(4 vCPU)/ 128GB RAM / OL8.10 |
| データベース | Oracle AI Database 26ai Free(23.26.0.0.0) |
| ベクトルストア |
SKILLUSER.SKILL_CHUNKS(embedding VECTOR(1024, FLOAT32)) |
| 埋め込みモデル | Ollama bge-m3(1024 次元・多言語) |
| 生成モデル | Ollama qwen2.5:7b-instruct / qwen2.5:3b-instruct(同一ファミリでサイズ比較) |
| ランタイム | Python 3.11、python-oracledb(thin モード・Oracle Client 不要) |
| 知識ソース | oracle/skills の db/ 配下(公開リポジトリ) |
埋め込み・生成(Ollama)も DB(26ai)もすべてノード内。外部に出る通信はありません(閉域の肝)。
3. なぜ RAG なのか(構成)
oracle/skills は 100 以上の Markdown ガイドの集まりで、本来は Claude のような大きなモデルが目次を読んで自分で資料を選ぶ前提で作られています。これをローカルの小型モデルにそのまま渡すのは、コンテキスト長・指示追従の両面で無理があります。
そこで RAG(検索拡張生成) =「質問に関係する文章だけを検索して、それだけをモデルに渡す」方式にしました。小さいモデルでも、関係する正解テキストを目の前に置けば誤りが減ると想定してます。
4. ローカル RAG の作り方
4.1. 知識の取り込み(ingest)
oracle/skills を clone し、db/**/*.md を見出し単位で分割 → bge-m3 で埋め込み → 26ai の VECTOR 列へ格納します。テーブルはこんな形です。
CREATE TABLE skill_chunks (
id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
domain VARCHAR2(64),
category VARCHAR2(64),
source_file VARCHAR2(512), -- 出典mdの相対パス(回答時に提示)
section_title VARCHAR2(512),
chunk_text CLOB,
embedding VECTOR(1024, FLOAT32) -- bge-m3 の次元数
);
今回は 2,218 チャンクを投入しました。
CPU 推論なので初回 ingest は時間がかかります(実測 約 0.35 チャンク/秒=2,218 件で約 1.7 時間)。ただしこれは初回 1 回だけです。
4.2. 問い合わせ(ask)
質問を埋め込み、VECTOR_DISTANCE(コサイン距離)で近いチャンクを top-k 取得して、生成モデルに渡します。検索の核はこの SQL だけです。
SELECT source_file, section_title, chunk_text,
VECTOR_DISTANCE(embedding, :qv, COSINE) AS dist
FROM skill_chunks
ORDER BY dist
FETCH FIRST :k ROWS ONLY;
回答の最後には、ヒットした source_file(例: db/performance/awr-reports.md)を出典として並べます。外部 API は一切呼ばず、localhost:11434(Ollama)と localhost:1521(26ai)だけで完結します。
5. AWR 評価の方法
5.1. 評価対象の AWR と答え合わせの観点
今回の評価対象 AWR に含まれる主な特徴(答え合わせに使う観点)は次のとおりです。
- AAS ≈ 58.3(DB Time 3,512.67 分 ÷ Elapsed 60.23 分)に対し CPU=16 → 容量の大幅超過
- 待機は db file sequential read 79.9%(I/O 律速)+ log file sync 8.7%
- 上位 SQL
9xkm4tq1ab3df(orders×customers 結合・status 述語)が物理読み 82.4% → 索引欠如の典型 - 効率指標は健全(Soft Parse 99.66% / Execute to Parse 91.78% / Buffer Hit 97.92%)→ parse は問題ではない
- ハードパース 2.1/秒は 100/秒未満で低優先(過大評価しないのが正解)
5.2. 公平性の担保
RAG あり / なしで、同じ AWR ダイジェスト・同じ指示文・同じ生成設定(num_ctx=16384, temperature=0.2) を使います。違いは「oracle/skills の資料(context)を渡すかどうか」だけです。
ポイントは、閾値の数値(>95%、>50%、100/秒…)をプロンプトに書かないことです。「効率指標を閾値と比較して判定せよ」というタスクは両方に同じ文で与え、その閾値の知識を RAG が資料から供給するか否かを差として観察します。
5.3. 評価は「検出マトリクス」で
観点ごとに「何を拾えたか」を ○ / △ / ✗ で並べます(前作と同じ、検出項目を並べる形式にしました)。判定は正規表現ベースの簡易チェッカで機械的に行い、最終確認は本文で行っています。
6. 結果
6.1. 検出マトリクス(3b / 7b × RAG あり / なし)
同じ Qwen ファミリでサイズだけを変え、RAG の有無と掛け合わせた結果です。
| 観点 | 3b なし | 3b あり | 7b なし | 7b あり |
|---|---|---|---|---|
| I/O 律速の特定(db file sequential read 79.9%) | ○ | ○ | ○ | ○ |
| 効率指標を見て「parse は概ね健全」と判断 | ○ | ○ | ○ | ○ |
| AAS 算出+容量超過(AAS ≫ CPU=16) | ✗ | ✗ | ○ | ○ |
原因 SQL 名指し(9xkm4tq1ab3df)+索引欠如 |
△ | △ | ○ | ○ |
| ハードパース過大評価の補正(100/秒で低優先) | △ | △ | △ 誤り | ○ 正答 |
※ ハードパース行の「△ 誤り」は、ハードパースに触れてはいるが優先度判断を誤ったことを表します(7b・RAG なしは「優先度が高い」と誤判定)。
読み取れることは大きく 3 つです。
6.2. ① RAG で効いたこと: ハードパースの過大評価を補正
同じ事実(ハードパース 2.1/秒)への評価が、skill の有無で割れました。
7b・RAG なし(誤り) — 閾値を誤って過大評価:
4. ハードパース率:
- ハードパース率: 2.1%
- 一般的な閾値は5%以下とされるため、優先度が高いです。
7b・RAG あり(正答) — skill の「100/秒」閾値で正しく低優先:
4. ハードパース率
- Hard parses/sec: 2.1
- 資料によると、ハードパース率が100/sec以上は問題があるとされていますが、
このケースでは低いです。
これはまさに前作(クラウド / Haiku・Sonnet)で見た「skill は見落とし防止ではなく、過剰な対応を防ぐ」効果と同じで、閉域・ローカルの 7b で再現しました。
6.3. ② RAG で効いたこと: 出典を出せる(検証可能性)
RAG ありは、根拠にした skill ファイルを末尾に提示します。
### 参照スキル:
- db/performance/awr-reports.md
- db/sqlcl/sqlcl-awr.md
この出典提示は RAG ありのときだけ出ます。RAG なしは資料を参照しない構造のため出典を出せません。「どの skill に基づく回答か」を示せるのは RAG 固有の利点で、DBA が生成結果を鵜呑みにせず裏取りする際に効きます。
6.4. ③ モデルサイズの壁: AAS 算出・原因 SQL 名指し
一方で、RAG の有無より先に「モデルの大きさ」で決まるものもありました。
-
AAS 算出+容量超過: 7b は RAG の有無に関係なく算出(AAS ≈ 60 と出し、CPU=16 と比較して容量超過と判断)。3b は両方とも未到達で、
÷86400や÷0といった計算自体を取り違えました。 -
原因 SQL の名指し: 7b は
9xkm4tq1ab3dfを特定して索引を提案。3b は I/O と索引の一般論・SQL 文の引用どまりで SQL_ID を特定できませんでした(△)。
そして見逃せないのが、3b は RAG ありでもハードパースの補正ができなかった点です。7b・RAG ありは渡された「100/秒」の閾値を使って正しく低優先と判断しましたが、3b・RAG ありは同じ資料を渡されても「閾値(0 以上)に達しています」と取り違えました。資料を目の前に置いても、それを使いこなすには相応のモデルサイズが要る——RAG は万能の底上げではなく、一定の地力があって初めて効く、ということです。
6.5. 生成時間(CPU 実測)
| モデル | RAG あり | RAG なし |
|---|---|---|
| qwen2.5:3b-instruct | 282 秒(約 5 分) | 218 秒(約 4 分) |
| qwen2.5:7b-instruct | 675 秒(約 11 分) | 440 秒(約 7 分) |
3b は速い代わりに非力、7b は skill を活かせる代わりに遅い、という綺麗なトレードオフが出ました(RAG ありはコンテキストが増える分、生成も少し長くなります)。
7. 考察
-
前作(クローズドモデル)の核心が閉域・ローカルで再現した。 RAG ありの 7b は、ハードパースの過大評価を 100/秒 の閾値で補正し、出典を提示しました(
results/summary.md)。クラウドの大型モデルでなくても、閉域の 7b+skill で同種の効果が得られます。 - RAG の効果は「閾値知識の供給」と「出典」に集約された。 AAS 算出や原因 SQL の名指しは 7b なら RAG なしでもでき、RAG の差は出ませんでした。RAG がはっきり効いたのは、モデルが自前で持ちにくい/誤りやすい知識(具体的な閾値)と、構造上モデルにはできないこと(出典提示)でした。
-
RAG は「地力があって初めて効く」。 同じ「100/秒」の閾値資料を渡しても、3b は使いこなせずハードパースを取り違え、7b で初めて正しい低優先判断になりました(
results/summary.md)。RAG はどんなモデルも一律に底上げする魔法ではなく、一定の推論力の上に乗って初めて知識が活きる、という切り分けが見えました。 - 品質はモデルサイズ、CPU は速度のみ。 3b は AAS や原因 SQL に届かず、7b は届きました。CPU を増やしても速くなるだけで賢くはなりません。
- GPU ノードなら速度・品質の両取りが見込めます。 今回の遅さ(7b で 1 回 7〜11 分)は CPU 推論がボトルネックで、GPU なら生成は桁違いに短縮され、さらに 14b/32b などより大きいモデルを実用速度で回せるため、AAS や原因 SQL の精度も上がると考えられます(要追加検証)。
- 小型モデルの使いどころ。 3b でも「I/O 律速か」「parse は概ね健全か」程度の一次トリアージには使えました。3b で当たりを付け、7b(将来は GPU で大型モデル)で深掘り、という役割分担が現実的だと考えられます。
本検証は単一の AWR・比較的単純な負荷での結果です。複雑な AWR での傾向は別途確認が必要です。
8. まとめ
| 観点 | 結果 |
|---|---|
| 閉域でローカル RAG 化 | Ollama+26ai Vector で localhost 完結(2,218 チャンク) |
| RAG で効いたこと | ハードパース過大評価の補正 / 出典の提示(いずれも 7b で発現) |
| モデルサイズで決まること | AAS 算出・原因 SQL 名指し・RAG 知識の活用(7b で到達、3b は未到達) |
| 速度 | 3b 速いが非力 / 7b 賢いが遅い。CPU は速度のみ・GPU が本命 |
本番が閉域で、外部 LLM を持ち込めない現場でも、oracle/skills をローカルで RAG 化すれば Oracle の専門知識をオフラインで引けること、そして十分な大きさのモデルなら前作(クローズドモデル)の効果が再現することが確認できました。