2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OCI GenAI Agents の RAG の回答精度を上げるなら、生成モデルよりハーネスだった

2
Posted at

1. はじめに

前回の記事1で、Oracle 運用支援 RAG に「実在するビューの列一覧を返す関数ツール」を1個足したところ、回答が短くなりました。質問は日本語ですが英語だけで返る問が出て、日本語で返った回答にも表記の崩れが出ました。Oracle と何の関係もないダミー関数(2つの整数を足すだけ)に替えて、一度も呼ばれない場合でも同じでした。

前回は「生成モデルを変える」「RAG ツールと関数ツールを分離する」を未検証のまま残しました。今回その2つを実際に測ったので、結果をまとめます。先に言ってしまうと、どちらも改善にはつながりませんでした。ただし変わり方は条件ごとに違っていて、1つずつ試していくと原因の候補を絞れます。そのうえで、関数ツールを使わず、制御側で確認する形(前回の記事で言うハーネス)を測ったところ、生成モデルにかかわらず引っかけも回避できました。

評価に使うのは、Oracle の運用で実際に聞きそうな18問です。前回までの記事と同じものを使い、1問ずつ新しいセッションで聞きます。うち4問(3・6・8・10)は、実在しないビュー名や列名をこちらから混ぜた引っかけ問題です。V$BLOCKING_SESSION(実在しないビュー)、V$SQLAVG_ELAPSED_TIME(実在しない列)などを「これで調べる方法を教えて」と聞き、実在しないと答えられるかを見ます。

18問(クリックで開く)
  1. 今接続しているセッションの一覧を、ユーザー名・接続元マシン・ログイン時刻付きで出すSQLを教えて。
  2. あるセッションがいま何に待たされているか調べたい。
  3. V$BLOCKING_SESSION というビューでブロック元セッションを調べる方法を教えて。
  4. ロック待ちしているセッションと、そのブロック元を一覧で出したい。
  5. 1実行あたりの平均経過時間が長いSQLのトップ10を出すSQLは?
  6. V$SQLAVG_ELAPSED_TIME 列で平均実行時間を出すクエリを書いて。
  7. 直前に実行したSQLの実行計画を「実測値付き」で確認する方法は?
  8. DBA_HIST_SQL_PLANSNAP_ID で絞って、ある時点の実行計画を取り出すSQLを書いて。
  9. 遅かったSQLのバインド変数に実際何が入っていたか確認したい。
  10. V$TABLESPACE_USAGE で表領域の使用率を確認するSQLを教えて。
  11. 一時表領域を大量に消費しているセッションを特定したい。
  12. データファイルが自動拡張でどこまで増えるかを一覧したい。
  13. 昨夜のRMANバックアップが成功したかをSQLで確認するには?
  14. 高速リカバリ領域(FRA)の使用率と、解放可能な量を確認したい。
  15. ADBで業務用に表領域を1つ追加したい。手順は?
  16. ADBでRMANを使って手動バックアップを取る手順を教えて。
  17. ADBで暴走セッションを強制切断できる?できるなら構文は?
  18. 検索結果の上位N件だけ取得する、12c以降のモダンな書き方は?

今回の検証ゴール

# 検証項目
1 生成モデルを別のものに替えると、回答の短縮・英語化・日本語の崩れが改善するか
2 RAG ツールと関数ツールを同居させなければ改善するか
3 改善しない場合、原因の候補をどこまで絞れるか
4 関数ツールを使わず、ハーネス側で確認すれば改善するか。改善するならモデルで差が出るか

結論(先出し)

  • 生成モデルを openai.gpt-oss-120b に替えても改善せず、同じ問での回答長は元の 5% まで短くなった
  • RAG ツールを外して関数ツールだけにしても、18問中13問で回答が短くなった
  • 残った候補は「関数ツールが1個存在すること自体」。呼ばれるか・中身が何か・どのモデルか・RAG と同居しているかを問わない。内部実装は見えないので断定はできない
  • 関数ツールを使わず、ハーネス側で確認すれば、生成モデルを問わず引っかけ4問は全問正解。ただしティアを上げると(Opus 5 / Gemini 3.6 Flash)ハーネス無しでも解けるので、この18問ではモデル間の差が出ない

検証環境

項目 内容
実行基盤 OCI Generative AI Agents(リージョン: 大阪 ap-osaka-1)
生成モデル meta.llama-3.3-70b-instruct(サービスデフォルト)/ openai.gpt-oss-120b
質問数 18問(1問ごとに新規セッション)
ナレッジベース Oracle 運用手順と実列一覧(V$ 1,015件 / DBA_ 1,276件)を収めた既存 KB
関数ツール ビュー名を受け取り実在列の一覧を返す get_view_columns(説明文 49字)
クライアント OCI Generative AI Agents の Agent Development Kit(Python、SDK 2.182.1)

前回までの記事と条件が増えているため、この記事の数値は条件どうしの相対比較にだけ使い、これまでに公開した記事の値と直接並べません。機械による一次採点の集計方法が、前回までと変わっているためです。


2. 何を1つずつ変えたか

変える変数を毎回1つに絞り、ツールを付けた条件と付けない条件を必ずペアで測りました。前回までに候補から外したものと、今回外したものを並べるとこうなります。

変えたもの どう変えたか 同じことが起きるか
ツールが呼ばれること 実際に使える関数 → 一度も呼ばれないダミー関数 起きる
ツールの説明文の長さ 340字 → 49字 起きる
出力トークン上限 1000 → 4000 起きる
生成モデル llama-3.3-70b-instructgpt-oss-120b 起きる(3 章)
RAG ツールとの同居 RAG ツールあり → RAG ツールを外す 起きる(4 章)
渡し方そのもの 関数ツール → ハーネスで確認 起きない(5 章)

「同じこと」は 1 章に書いた3つ、つまり回答が短くなること・英語だけの回答が出ること・日本語の表記が崩れることです。

ペアで測るのが要点です。「ツールを付けたら 160字だった」だけでは何も言えません。同じ条件でツールを外したときが 631字なら短縮ですが、293字なら短縮の度合いはまったく違います。以降の表はすべてこの対で読んでください。

測った組み合わせは次のとおりです。どれも関数ツールの「なし」と「あり」を対にしています。

生成モデル RAG ツール 関数ツール
llama-3.3-70b-instruct あり なし / あり 3・4
gpt-oss-120b あり なし / あり 3
llama-3.3-70b-instruct なし なし / あり 4
llama-3.3-70b-instructgpt-oss-120b あり どちらも使わない 5

3. 生成モデルを替える

RAG ツールは、ナレッジベースを検索してから、その結果をもとに回答を作ります。生成モデルを選べるのは後半の「生成」の側です2

サービスの初期値は meta.llama-3.3-70b-instruct で、ここを openai.gpt-oss-120b に差し替えました。検索の側と、エージェント側の設定には手を入れていません。

3.1. 実行前に必要だった調整

gpt-oss は出力トークン上限を指定しないと回答が途中で切れました。引っかけ問題の1問で、55字だけ返して終わりました。

We need to search for V$BLOCKING_SESSION.
Let's search.

回答本文ではなく、検索に入る前の推論過程のテキストがそのまま出力されて止まっています。上限を 4000 に設定すると 3,462字の完結した日本語回答に戻ったので、以降は両条件とも 4000 で測っています。前回の条件では上限を 1000 から 4000 に上げても短縮は変わらなかったため、この条件差が結果を動かしているとは考えにくいです。

3.2. 結果

生成モデル 関数ツール 平均文字数 日本語ゼロの回答 RAG 引用あり 実在しない名前 引っかけ4問
llama-3.3-70b-instruct なし 642字 0問 18/18問 0.61件/千字 3/4
llama-3.3-70b-instruct あり 254字 11問 15/18問 1.09件/千字 3/4
gpt-oss-120b なし 2,460字 0問 18/18問 0.63件/千字 2/4
gpt-oss-120b あり 153字 8問 15/18問 2.17件/千字 1/4

モデルを替えると回答量は変わりました。ツールなしどうしで比べると、llama-3.3-70b-instruct の 642字に対して gpt-oss は 2,460字です。見出しと表を使った構成になります。

それでもツールを1個足したときの挙動は変わりませんでした。同じ問での長さの比を取ると、llama-3.3-70b-instruct のときより比が小さくなります。

生成モデル 長さの比(中央値) 0.8倍未満に短くなった問
llama-3.3-70b-instruct 0.36 17/18問
gpt-oss-120b 0.05 18/18問

gpt-oss ではツールを1個足すと回答が元の 5% になります。実在しない名前の密度は 2.17件/千字で、ツールなしのとき(0.63件/千字)の 3.4倍です。

3.3. gpt-oss で新しく出た誤りの型

結論は合っているのに、示された根拠が実在しない回答が出ました。V$SQLAVG_ELAPSED_TIME 列があるかを聞いた問です。

V$SQL には AVG_ELAPSED_TIME という列は存在しません。
(「AVG_ELAPSED_TIME が V$SQL に無い」ことは、
「AVG_*** 系列は V$SYS_REPORT_STATS の列であり、V$SQL には無い」旨のドキュメントで確認できます)

否定そのものは正解です。しかし V$SYS_REPORT_STATSAVG_ELAPSED_TIME があるという記述はナレッジベースにありません。同じ回答の別の箇所では ELAPSED_TIME の出どころを V$SQL_HISTORY の列一覧としていて、こちらも実在しません。結論が合っているため、名前の実在だけを見る機械チェックでは検出できません。

引っかけ問題も 3/4 から 2/4 に下がりました。llama-3.3-70b-instruct ではすべての条件が正解していた表領域使用率の問で、実在しないビューを実在する前提で列一覧まで作り、さらに Autonomous Database 用の代替として存在しないビュー名を挙げました。

ADB 環境では同名のビューが存在しないため、DBA_DATA_TABLESPACE_USAGE_METRICS を代わりに使用してください。

正しくは DBA_TABLESPACE_USAGE_METRICS です。DATA が余計に入っています。


4. RAG ツールから切り離す

次に、関数ツールを RAG ツールと同居させない構成を試しました。同じエージェントに両方を載せていることが原因なら、切り離せば起きなくなります。

点線はモデルが呼ぶかどうかを選べる経路です。どちらの構成でも、関数ツールを呼ぶかは最後までモデルが決めます。

RAG ツールを外すと、強化指示文の置き場所がなくなります。もともと指示文は RAG ツールの生成設定に入れていたためです。RAG ツールを外した2条件では、エージェント側の指示文として同じ文章を設定しました。この2条件の中では一定なので対の比較は成り立ちますが、RAG ツールがある側とは置き場所が違う点は差として残ります。

4.1. 結果

RAG ツール 関数ツール 平均文字数 日本語ゼロ RAG 引用あり ツールを呼んだ問 実在しない名前 引っかけ4問
あり なし 631字 0問 18/18問 0/18問 0.70件/千字 3/4
あり あり 160字 8問 17/18問 1/18問 2.42件/千字 2/4
なし なし 292字 0問 0/18問 0/18問 0.95件/千字 2/4
なし あり 160字 2問 0/18問 17/18問 0.00件/千字 4/4

同じ問での長さの比で見ます。

RAG ツール 長さの比(中央値) 0.8倍未満に短くなった問
あり 0.30 18/18問
なし 0.52 13/18問

RAG ツールを外しても短縮は残りました。18問中13問で 0.8倍を切り、中央値は 0.52 です。RAG ありの 0.30 より短縮の度合いは小さいものの、消えてはいません。

短縮が具体的にどうなるかは、同じ問の回答を並べると分かります。接続中のセッション一覧を出す SQL を聞いた問です。

【ツールなし】
V$SESSION ビューを使用して、現在接続しているセッションの一覧を取得できます。以下の SQL 文を実行してください。

SELECT USERNAME, MACHINE, LOGON_TIME
FROM V$SESSION
WHERE TYPE = 'USER'
ORDER BY LOGON_TIME;

この SQL 文では、V$SESSION ビューから、TYPE 列が 'USER' である行(つまり、ユーザー セッション)を抽出し、USERNAME 列(ユーザー名)、MACHINE 列(接続元マシン)、LOGON_TIME 列(ログイン時刻)を選択しています。さらに、結果を LOGON_TIME 列で昇順に並べ替えています。
【ツールあり】
SELECT USERNAME, MACHINE, LOGON_TIME FROM V$SESSION

解説が消えて SQL だけが残ります。セミコロンもありません。RAG ツールがある側でも同じことが起きていて、こちらは SQL が1行だけ返りました。短くなるというのは、字数が減るというより解説が省かれるということでした。

ツールを使ったときの出力スタイルの変化とも読めますが、それでは説明がつきません。ダミー関数を付けた条件は 325字(同じ問での比は中央値 0.40、16/18問が 0.8倍未満)で、全問を通じてツールの呼び出しは 0回でした。一度も呼んでいないので、使ったことによる変化ではありません。

4.2. 数値だけを見ると RAG なしの成績が最も高い

表の数値だけを見ると、RAG なし・ツールありの構成は実在しない名前が 0件で、引っかけ4問も全問正解です。ツールも 18問中17問で呼ばれました。これまでツールが呼ばれるのは 18問中1〜2問でした。引っかけ問題では毎回ツールを呼んで、返ってきた事実に従っていました。

【RAG なし・ツールあり / 実行計画の取得を聞いた問】
ツール呼び出し: get_view_columns(DBA_HIST_SQL_PLAN)

DBA_HIST_SQL_PLANビューのSNAP_ID列は存在しません。代替として、
DBA_HIST_SQLSTATビューのSNAP_ID列を使用することができます。

この問は、前回の記事で外付けのループを使った条件しか解けなかったものです。

それでもこの構成を採用できる根拠にはなりません。RAG ツールが無いので引用は 0/18問です。名前の実在についてはツールが返した列一覧が裏付けになりますが、手順や可否にあたる部分には裏付けがありません。上の回答でいえば、DBA_HIST_SQL_PLANSNAP_ID が無いことはツールで確認していますが、代わりに DBA_HIST_SQLSTAT を使えるという部分ではツールを呼んでおらず、裏付けがありません。回答は13問で短くなっていますし、そもそも運用で使う構成ではありません。ツールを呼ぶ回数が増えたことについても、指示文の置き場所が RAG ツールのある側と違うため、切り離した効果とは言い切れません。


5. ハーネスに載せ替える

ここまでは関数ツールという渡し方の中で条件を変えてきました。最後に渡し方そのものを替えます。

関数ツールを使わず、1問を2往復に分けて、あいだに制御側の処理を挟みます。モデルに選ばせず、制御側で決めた手順を必ず通す形で、前回の記事ではこれをハーネスと呼びました。

1 と 3 はどちらもエージェントへの問い合わせで、RAG ツールはそのまま利用します。外すのは関数ツールだけです。1 と 3 は同じエージェントに投げるので、生成モデルは両方で同じものになります。

2 にモデルの裁量が入りません。確認するかどうかを選ばせないので、確認されないという事態が起きません。関数ツールを登録しないので、3 章・4 章で短縮と英語化が起きた構成にはなりません。

この形で生成モデルだけを変えた2条件を測りました。表の1行が1条件で、その行のモデルを 1 と 3 の両方に使っています。

生成モデル 平均文字数 日本語ゼロ RAG 引用あり 実在しない名前 引っかけ4問
llama-3.3-70b-instruct 530字 0問 18/18問 1件 4/4
gpt-oss-120b 1,825字 1問 18/18問 2件 4/4

引っかけ4問はどちらも全問正解でした。3 章で gpt-oss が落とした2問(表領域使用率と実行計画の取得)も、こちらでは正解しています。そしてモデルを替えても、引っかけ4問はどちらも 4/4 で完答でした。gpt-oss が足したのは 3.4倍の長さと、英語だけの回答1問、文字化け1問だけです。

表の「実在しない名前」は人手で数えた件数です。機械の照合は gpt-oss 側を15件と出しますが、1件ずつ本文と照らすと13件は偽陽性でした。ロール名(SELECT_CATALOG_ROLE)や列の値(ACTIVEUNLIMITED)を列名と読み違えたもので、gpt-oss が長い回答の中で識別子をバッククォートで囲む頻度が高いぶん増えます。回答の文体が変わると機械の件数は比較できなくなるので、モデルをまたぐときは内訳を見る必要があります。


6. 参考: ティアを上げるとどうなるか

ここまでは OCI Generative AI Agents で選べるモデルの中で比べてきました。ティアを上げたモデルではどうなるかは、まだ測っていません。OCI では選べないので、同じ18問を手元で2つのモデルに解かせました。

前提が次の点で違うので、これまでの表とは並べません。

  • 別のプラットフォームで動かすため、RAG ツールが付かない。ナレッジベース検索は OCI Agents 側の機能である
  • したがって2つのモデルは自分の知識だけで答えている
  • ハーネスの2往復・辞書の中身・強化指示文・18問は同じものを利用
モデル ハーネス 平均文字数 実在しない名前 引っかけ4問
Opus 5 なし 1,591字 2件 4/4
Opus 5 あり 1,920字 0件 4/4
Gemini 3.6 Flash なし 1,755字 0件 4/4
Gemini 3.6 Flash あり 1,466字 0件 4/4

4条件とも引っかけ4問を全問正解しました。ハーネスが無くても V$BLOCKING_SESSIONV$TABLESPACE_USAGE を実在しないと述べ、AVG_ELAPSED_TIMESNAP_ID も正しく否定して代替を挙げます。

実在しない名前は、Opus 5 単体の2件を除いてゼロでした。その2件は V$SESSION_BLOCKERS の列を session_serial# と書いたもので、正しくは SESS_SERIAL# です。ハーネスを付けるとこの2件も消えました。

つまり この18問は、ティアを上げると満点で並んでしまい、モデル間の差を測れなくなります。V$DBA_ の列は公開ドキュメントに載っている情報なので、学習時点で参照されていた可能性があります。そもそも辞書を渡さなくても答えられる問題でした。

ここから言えるのは、3 章から 5 章の結論が OCI Generative AI Agents を使う前提での話だということです。このサービスを選ぶ理由は、閉域網の中で完結させられることと、基盤を用意せず従量で使えることにあります。その要件が無いなら、ティアの高いモデルを選べます。要件があるなら、選べるモデルの中で回答精度を上げる手段としてハーネスが要る、という話になります。

なお、公開されていない情報を扱う場合は、モデルが知っているとは限らないので、また別の結果になると考えられます。


7. 考察

7.1. 変わらなかったもの

関数ツールを付けない4条件は日本語ゼロの回答が 0問、付けた4条件はいずれも回答が短くなり日本語ゼロの回答が出ました。生成モデルを替えても RAG ツールを外しても、この対応は変わりません。前回までに外れていた候補(ツールが呼ばれること・説明文の長さ・出力トークン上限)に、今回この2つが加わりました。

残るのは「関数ツールが1個登録されていること」です。ただし強化指示文の内容は全条件で同じものを使っているので、指示文とツールの組み合わせで起きている可能性は消せていません。内部実装は見えないため、原因の断定もできません。

モデルを替えると、出る現象の内訳が入れ替わります。llama-3.3-70b-instruct は日本語ゼロが 11問と多く、gpt-oss は 8問と少ない代わりに回答長が元の 5% まで短くなり、「結論は合っているのに根拠が実在しない」という機械では検出できない誤りが出ました。同じ呼び方でも中身が違うので、指標を1つだけ見て改善と判断できません。

7.2. 変わったもの

確認をハーネス側の処理にした 5 章の2条件は、生成モデルを問わず引っかけ4問を全問正解し、実在しない名前は1〜2件に収まりました。ツールは呼ぶかどうかも従うかどうかもモデルが決めるため、確認が通らないことがあります。確認をモデルの選択肢から外すと、この不確かさが消えます。

そのうえで、このサービスで選べるモデルの範囲では、モデルを替えても引っかけ4問と RAG 引用がどちらも満点のままでした。先に直すのは渡し方で、モデルの選択はそのあとという順序になります。ティアを上げた場合は 6 章のとおりです。

7.3. 測っていない範囲

なお、この記事で差し替えたのは RAG ツールの生成側モデルです2。エージェントには別の設定項目もあり、そこは本記事の実測の範囲外です3

8. まとめ

# 検証項目 結論
1 生成モデルを替えると改善するか 改善しない。回答長は元の 5% まで短くなり、実在しない名前の密度はツールなしの 3.4倍になった
2 RAG ツールと分離すると改善するか 短縮は改善しない(18問中13問)。英語化はツールなしの0問に対して2問で、RAG ありの8問より少ないが消えていない
3 原因の候補をどこまで絞れるか 「関数ツールが1個存在すること自体」まで。指示文の内容は替えていないので、指示文との組み合わせは残る
4 ハーネス側で確認すれば改善するか 改善する。生成モデルを問わず引っかけ4問は 4/4、実在しない名前は1〜2件。ただしティアを上げるとハーネス無しでも解ける(6 章)

この用途で名前の正確さを上げるなら、確認をハーネス側で必ず行う形にすることです。関数ツールとして持たせて呼ぶかどうかをモデルに任せると、呼ばれないだけでなく回答そのものが短くなります。制御側に置けば呼ぶかどうかがモデルの判断に左右されず、生成モデルを問わず引っかけ4問が 4/4 になりました。

一方、このサービスで選べるモデルの範囲では、モデルまわりの設定を替えても差が出ませんでした。生成モデルの差し替え、出力トークン上限の引き上げ、ツールの説明文の調整、RAG ツールからの分離のいずれも、短縮と英語化を止められていません。渡し方を直す前にモデルを替えても、順序が逆ということになります。

この記事の観測は、OCI Generative AI Agents の大阪リージョンで、静的な RAG ツールと日本語の指示文を使った構成でのものです。1条件につき1回の実行なので、生成のばらつきも含まれています。この記事で差し替えた生成モデルは gpt-oss-120b の1つだけです。ほかのモデルでは結果が変わることは、6 章で試したとおりです。

現時点では閉域で利用できるモデルが限られているためこのような結論となってますが、どの程度のモデルだと改善するのかは別途実験してみる予定です。


参考

  1. Qiita, 「RAG に実列ディクショナリの関数ツールを足して、エージェントのツール実行ループで名前を確認させてみた」. https://qiita.com/asahide/items/8240df397b50e5cf7451

  2. Oracle Cloud Infrastructure Documentation, 生成AIエージェント, 「生成AIエージェントでのRAGツールの更新」の「Generation LLM」. https://docs.oracle.com/ja-jp/iaas/Content/generative-ai-agents/RAG-tool-update.htm 2

  3. Oracle Cloud Infrastructure Documentation, 生成AIエージェント, 「生成AIエージェントでのモデルの選択」. https://docs.oracle.com/ja-jp/iaas/Content/generative-ai-agents/model-selection.htm

2
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?