表紙・紹介・目次の文字をテキストで読む
データのそばに、AIを。
アイと先輩の保守支援システム設計
制作・原作:荒川裕二(日本オラクル)
このマンガについて
保守窓口の支援システムを任された新人エンジニアの青山アイが、同じ開発チームの先輩の神宮寺と、文書検索・契約照会・AIエージェントの設計・試作を通じて AIシステムを設計する自信を得ていく物語です。
AI 機能をデータのそばに置く「インデータベースAI」と、AIエージェントを支える「ハーネス」を、最新の Oracle AI Database の機能とともに紹介します。
Qiita で公開している作者(荒川裕二)自身のブログ記事をもとに、マンガ用に構成・脚色しています。
この漫画の制作に使用した Manga Generator を公開されている月森ナギ様に感謝します。
この漫画の内容は原作者個人の経験・見解であり所属する日本オラクルを代表するものではありません。
目次
-
文書と業務データを、一つのDBで 文書の意味検索と業務データの照会を組み合わせる
-
埋め込みモデルをDBの中へ DBの中でベクトルを作る
-
顧客の範囲を守って探す チケットの顧客と機種を絞ってベクトル検索する
-
ビューで守るRAG ビューで絞った文書を根拠に、RAGで回答する
-
Select AIで、言葉からSQLへ NL2SQLで契約情報を照会する
-
Select AI Agentに道具を渡す 文書検索と契約照会をAgentのツールにする
補足ガイド
原作:荒川裕二の技術記事(Qiita) · ウェビナー「Oracle AI Jam Session」のアーカイブ動画(YouTube) · デモの公開リポジトリ
登場人物・会話・設計依頼は漫画用の創作です。企業・機種・保守手順は原記事の架空デモに基づきます。作画には生成AIを使用しています。記事の内容は私個人の経験・見解であり所属する日本オラクルを代表するものではありません。
プロローグ
この章の会話をテキストで読む
01-1
アイ: 神宮寺先輩、保守窓口の支援システムを、私が設計することになりました。
神宮寺: アイには初めてのAI案件だね。設計は僕が一緒に確認するよ。
01-2
アイ: SQLは経験があります。でも、AIには何を任せれば…。
神宮寺: まず、窓口で答えたい問い合わせから考えよう。
02-1
想定する問い合わせ
解説: サーバーの管理画面が開きません。どうしたらいいですか?
解説: 現地保守も頼めますか?
02-2
アイ: 現状の確認や操作の手順、それに、訪問できる条件の確認が必要ですね。
神宮寺: 社内の最新手順と、この機器の契約が必要だね。
02-3
問い合わせへの対応案
アイ: 根拠のある確認手順と、この機器の契約条件を一緒に答えたいです。
第1章 文書と業務データを、一つのDBで
二種類の問いから、データ基盤を選ぶ
この章の会話をテキストで読む
37-1
第1章
文書と業務データを、一つのDBで
文書の意味検索と業務データの照会を組み合わせる
03-1
神宮寺: 手順と、契約の確認には何を調べればいいかな?
03-1b
アイ: 手順は製品マニュアルなどの文章。契約は顧客や機器ごとの表ですね。
03-2
手順書:非構造化
契約表:構造化
神宮寺: 文書は問いと意味が似ているもの、契約は顧客情報などの条件が一致するものを探すことになるね。
03-3
アイ: 意味で探す検索と、条件で絞る検索。二つを組み合わせるんですね。
04-1
神宮寺: ベクトル検索なら「開かない」「固まった」「応答しない」といった似た意味の言葉も見つけられるね。
04-1b
アイ: 文字が一致するかではなく、意味が似ているかで探すからですね。
04-1c
アイ: 契約のほうも、LLMに「現地保守できますか?」と聞けば、判定してくれますか?
04-2
神宮寺: そこは注意が要るね。LLMは、同じ条件でも答えが変わることがある。
04-2b
アイ: LLMへの指示を工夫すればいいのでしょうか?
30-2
神宮寺: 指示を工夫しても、間違いや揺らぎはゼロにはならない。
神宮寺: 契約条件のように厳密さが必要な判定は、任せきりにできないんだ。
30-3
アイ: プログラムで確定的に判定させるんですね。Pythonなどですか?
神宮寺: そう。DBのビューに、CASE式で判定列を作る方法もある。
30-4
三つの条件がそろえば、現地保守の対象
解約・停止なし
契約期間内
現地保守あり
Y:現地保守の対象 N:対象外
CREATE VIEW contract_judgement AS
SELECT c.*,
CASE
WHEN c.status = 'ACTIVE'
AND TRUNC(CURRENT_DATE) BETWEEN c.start_date AND c.end_date
AND c.service_scope = 'ONSITE'
THEN 'Y' ELSE 'N'
END AS onsite_eligible
FROM contracts c;
30-5
アイ: ビューにすると、どんなメリットがありますか?
神宮寺: ルールの適用をLLMから切り離せる。同じ契約データと日付なら、結果も同じだ。
30-7
アイ: あとでAIにSQLを作らせる場合にも使えますか?
神宮寺: 使える。AIは「現地保守の対象」を判定列のYとして読めばいい。三つの条件を毎回組み立てさせずに済む。
30-9
一つの業務ルールを共通で使う
画面表示
自然言語からのSQL
AIの契約照会処理
同じビューの判定列。呼び出す場所でルールが変わらない。
30-10
アイ: 対象外の契約は、ビューから消すんですか?
神宮寺: 消さないよ。契約は残して、判定列を「N:対象外」にする。たとえば、期間内でもリモート保守だけの契約なら、現地保守は対象外だ。
30-12
神宮寺: このビューのように、LLMの外側で処理を支え、LLMと組み合わせて仕事を進める仕組みを「ハーネス」と呼ぶんだ。
30-12b
アイ: ハーネスは、どんなことをするんですか?
30-14
設計の考え方
ハーネス
LLMを呼び出し、周囲の処理とつないで仕事を進める仕組み
LLM
①
②
③
④
①指示と文脈を用意する
②道具となる処理を呼び出す
③状態と履歴を管理する
④実行を制御し、結果を検査する
30-15
アイ: LLMが意味を読み取り、回答や次の処理を考える。ハーネスが、その実行を支えるんですね。
神宮寺: そう。守るべき権限や業務ルールは、LLMの判断だけに頼らず、ハーネスの側で確かめる。
30-15b
今回の具体例
アイ: 今回なら、契約の判定はDBのビューへ。回答や処理が判定値と合うかは、コードで検査します。
神宮寺: その組み合わせが、今回のハーネスの一部になる。
DBのビュー:契約の判定値を返す
検査コード:回答や処理を判定値と照合する
38-8
設計の考え方
VIEW as a Harness
判定と範囲をビューに持たせ、AIにはビューだけを見せる
製品機能名ではなく、設計の考え方
05-0
アイ: 文書データと契約データは、どこで管理したらいいのかな?
05-1
アイ: 文書はベクトルDB、契約は業務DBに置く方法は?
神宮寺: 検索を独立して拡張できる。ただ、契約の変更や文書の公開取消を、検索側へ同期し続ける必要がある。
05-2
複製の更新が遅れると
業務DB:取消済み
検索用の複製:未反映
アイ: 解約や公開取消が伝わらなければ、案内を間違えますね。
05-3
神宮寺: Oracle AI Databaseなら、業務表とベクトルを同じDBで扱える。
神宮寺: 最新の業務表を直接使えるので、検索用の複製や同期の負担を減らせる。
38-1
製品
Oracle AI Database
業務表も、文書も、ベクトルも。一つのDBで
05-4
アイ: 同じDBにあるから、JOINやEXISTSで最新の業務表と突き合わせて、文書を絞り込めるんですね。
38-2
Oracle AI Databaseの機能
AI Vector Search
ベクトルを表の列として持ち、SQLで意味の似た文書を検索。業務表とのJOINもそのまま
SQLで検索
ベクトル列
ベクトルの近さ
31-1
鉄道会社を想定した分析例
神宮寺: 同じDBで扱えるのは、表と文書だけではない。位置情報も使う鉄道の例を見よう。
31-2
アイ: 車両タイプや期間に加えて、新潟県への進入も調べられますか?
神宮寺: タイプと期間はリレーショナル表。県への進入は、走行位置と県の地理空間情報で調べる。
31-4
神宮寺: その車両・期間の報告書で、本文に「ブレーキ」か「制動機」があるかは全文検索。
神宮寺: その中で、凍結の影響と意味が似ている報告を探すのはベクトル検索だ。
31-6
アイ: 表、地図、文章の条件を、同じDBのSQLで組み合わせられるんですね。
07-1
アイ: 私たちのシステムでも、文書の公開状態や契約情報は、最新のものを使いたいです。
アイ: 最新のデータをその場で使うため、AIをデータのそばに。今回はOracle AI Databaseを選びます。
38-6
設計の考え方
インデータベースAI
データのある場所で、AIの検索や処理を動かす
07-2
アイ: 文書を直したら、そのベクトルも作り直さないといけませんよね。
神宮寺: そうだね。だから、ベクトルをどこで、どう作るかが大事なんだ。次はそれを考えよう。
第2章 埋め込みモデルをDBの中へ
埋め込みをどこで実行するか決める
この章の会話をテキストで読む
37-2
第2章
埋め込みモデルをDBの中へ
DBの中でベクトルを作る
08-1
アイ: 文書をベクトルにするには、何を使うんですか?
神宮寺: 埋め込みモデルだよ。文書と質問を同じモデルで変換する。
08-2
埋め込みモデルとベクトル検索
文書と質問
埋め込みモデル
文書と質問のベクトル
アイ: 質問のベクトルに近い文書ベクトルを探す。Oracle AI DatabaseのAI Vector Searchで、その検索をDB内で行うんですね。
08-4
アイ: 埋め込みモデルはクラウドのAPIを使うんですか?
08-3
神宮寺: 外部APIを使うことも、DB内に埋め込みモデルをインポートすることもできる。
38-3
Oracle AI Databaseの機能
埋め込みモデルのインポート
対応するONNX形式のモデルをDBへ取り込み、文書を外へ出さずにベクトル化
32-1
埋め込みモデルを動かす場所
DB内
クラウドなどの外部API
神宮寺: 外部APIを使うと、検索対象の文書をすべて、外のモデルへ送ってベクトルにすることになる。
09-2
アイ: 回答に使う抜粋なら外のLLMへ送れます。でも、検索準備で社内文書を全部外へ出すのは避けたいです。
09-3
神宮寺: DB内でベクトル化すれば、全文書を外へ送らずに済む。
神宮寺: 変換の速度やDB負荷、同時実行数は検証しよう。
10-1
埋め込みモデルはDB内、回答生成LLMはクラウドAPI
| 処理 | 場所 | 渡すデータ |
|---|---|---|
| ベクトルへの変換 | DB内 | 文書と質問 |
| 回答の生成 | クラウドAPI | 質問と必要な文書抜粋 |
10-2
アイ: 埋め込みはDB内、回答の生成はクラウドのLLM。役割で使い分けます。
11-3
multilingual-e5-large
神宮寺: 日本語対応の著名なOSS埋め込みモデル、multilingual-e5-largeを試してみてはどうかな。
神宮寺: ONNX形式へ変換してDBに取り込めば、SQLのVECTOR_EMBEDDINGで使える。
11-1
埋め込みモデルのインポート
必要なファイル一式
Object Storage (クラウドの ファイル置き場)
DBへロード
神宮寺: 認証と権限を用意して、Object Storageからモデルをロードしよう。
11-2
アイ: これで質問文に似ている文書の検索は解決ですね?
神宮寺: 検索の準備はできたね。でも、似ている文書なら、そのまま案内に使えるかな?
第3章 顧客の範囲を守って探す
似ている文書から、案内できる文書へ
この章の会話をテキストで読む
37-3
第3章
顧客の範囲を守って探す
チケットの顧客と機種を絞ってベクトル検索する
12-1
設計の検証ケース:意味だけで検索
アイ: 「管理画面が開かない」と意味の似た文章なら、候補は見つかりそうです。
12-2
似ていても、そのまま使えない
別機種:BX-200
廃止済みの文書
アイ: あっ、別機種。それに廃止済み。これでは案内に使えません。
33-1
神宮寺: 別機種や廃止済みだけでなく、別顧客専用の文書も混ぜてはいけない。
33-1b
アイ: 同じ機種の似た症状でも、別顧客専用の手順を案内したら困りますね。
33-2
神宮寺: 今回はチケットSR001、顧客C001への回答だ。別顧客の機器や契約も混ぜない。
33-2b
アイ: 担当者が他の顧客を扱えても、1回の回答は対応中の顧客に限るんですね。
33-3
対応中のチケットから検索対象を決める
SR001:対応中のチケット
C001:問い合わせ元の顧客
DEV001:その顧客の機器
AX-100:機器の機種
33-4
アイ: この顧客に案内できる文書の範囲、機種、公開状態で絞ってから、意味の似ている順に探すんですね。
33-5
アイ: SQLに顧客の条件を付け忘れたら、どう防ぎますか?
神宮寺: 対応中の顧客だけを返すビューを使う。後でSQLをAIに作らせる場合にも役立つ。
33-6
アイ: その「対応中の顧客」は、DBへどう伝えるんですか?
神宮寺: チケットから調べた顧客IDを、このDB接続の中に保持する。
33-7
神宮寺: ビューは、接続に保持した顧客IDと、表の各行の顧客IDをWHEREで比べる。
神宮寺: だから、対応中の顧客の行だけが返るんだ。
33-8
保持した顧客IDをWHERE条件に使う
候補:C001 / DEV001
候補:C002 / DEV009
返却:C001 / DEV001
CREATE VIEW OJ41_VISIBLE_DEVICES
AS
SELECT d.*
FROM OJ41_DEVICES d
WHERE d.customer_id =
OJ41_CASE_CTX.customer_id();
SR001を開くと、この接続にC001を保持。
customer_id()がC001を返す。
WHEREでC001の行だけを返す。
33-9
アイ: では、チケットを開かずに検索したら?
神宮寺: 接続の顧客IDは最初に消しておく。未設定なら一致する行はなく、0件になる。安全な側に倒れるんだ。
33-10
アイ: 文書も、対応中の顧客が使えるものだけにしますか?
神宮寺: 公開済みの共通文書と、その顧客専用の文書に絞る。検索時には機種も指定する。
33-11
文書を回答に使える範囲
公開済み:共通文書、C001専用文書
除外:C002専用、社内限定、下書き、廃止済み
チケット未設定なら0件
残った候補を機種で絞り、ベクトル距離で比較
33-12
アイ: ビューなら、AIが顧客条件を忘れても大丈夫ですか?
神宮寺: 大丈夫。ただし、DB権限でこのビューしか読めないようにする。元の表を直接読めたら、守れないからね。
33-14
アイ: 契約が切れていたら、文書も出しませんか?
神宮寺: 許可された技術文書は案内できる。現地保守の可否とは別だよ。
33-16
アイ: テストでは、担当者の権限、別顧客、未設定のケースも確認します。
アイ: 接続に保持した顧客IDは、処理が成功しても失敗しても消去します。
15-3
アイ: 文書を探す設計はできました。次は、担当者が使える回答にしたいです。
第4章 ビューで守るRAG
ビューで許可された文書を選び、その本文を根拠に回答を構成する。
この章の会話をテキストで読む
37-4
第4章
ビューで守るRAG
ビューで絞った文書を根拠に、RAGで回答する
16-1
アイ: 毎回この資料を読み解くのは大変。確認手順をまとめられませんか?
神宮寺: 文書を質問に添えてLLMへ渡そう。RAG、検索拡張生成だ。
38-9
設計の考え方
RAG(検索拡張生成)
検索した文書を質問に添え、LLMに根拠付きで答えさせる
16-2
DB内
質問
許可された範囲
機種と距離で検索
取得本文
回答生成LLM
根拠付き回答
アイ: ビューで絞った文書をベクトル検索して、その本文を回答の根拠にするんですね。
17-3
回答例:管理画面が開かないとき(SR001/顧客C001)
電源・LAN・疎通を確認し、ログを保存します。再起動の前に影響を確認してください。(根拠:KB001) ログ収集後は、C001の運用責任者へ連絡します。現地訪問の手配案は、現地保守の対象となる契約がある場合に作成し、訪問確定には担当者の承認が必要です。(根拠:KB012)
神宮寺: 共通の手順KB001と、C001専用のKB012。両方が根拠になっているね。
17-1
KB012はC001専用の文書
KB001:共通の確認手順
KB012:C001専用・連絡と訪問の条件
アイ: KB012は、今の顧客C001専用の手順。だから回答に使えるんですね。
17-2
アイ: もし、C002専用の似た手順が、もっと距離の近い候補だったら?
神宮寺: ビューがC002専用の文書を返さないから、LLMには届かない。
神宮寺: プロンプトで頼むより確実な、VIEW as a Harnessだ。
18-1
ビューで絞ってから、LLMへ渡す
KB001:共通
KB012:C001専用
KB013:C002専用
ビュー
LLMへ
神宮寺: C002専用のKB013は、ビューが最初から返さない。LLMへ渡るのは、KB001とKB012だけだ。
19-1
アイ: 検索の範囲はビューで守り、LLMには許可された文書だけを渡す。その根拠で回答を組み立てるんですね。
19-2
神宮寺: 残った「現地保守を頼めるか」は?
19-2b
アイ: 契約ですね。自然な言葉で、対象機器の一覧も聞けるようにしたいです。
第5章 Select AIで、言葉からSQLへ
業務の言葉と、正確な判定をつなぐ
この章の会話をテキストで読む
37-5
第5章
Select AIで、言葉からSQLへ
NL2SQLで契約情報を照会する
21-0
アイ: 「この顧客の現地保守対象機器を一覧にして」のような質問ができるようにしたいです。NL2SQLの出番ですか?
21-1
神宮寺: Oracleには、自然言語からSQLを作るSelect AIがある。これを使って検討してみよう。
38-4
Oracle AI Databaseの機能
Select AI
自然言語の質問から、SQLを生成して実行
自然言語の質問
生成されたSQL
実行結果
21-2
アイの試作テスト
自然言語の質問
生成したSQLを表示 (SHOWSQL)
確認して実行・結果照合
神宮寺: まずSQLを見る。その後、実行した結果を正解と比べよう。
22-1
参照先を制限する前の試作
アイ: あれ、違う表を検索しています。名前だけでは、表の意味が伝わらないんですね。
FROM OJ41_CHUNKS
×
21-4
顧客のWHERE条件も誤り
アイ: 表を直して再試行したら、今度は別の顧客の機器が混ざりました。WHERE句の条件が違います。
22-2
神宮寺: Select AIには、参照先の制限や注釈など、生成を改善する手段がある。ビューと組み合わせよう。
21-3
アイ: 許可したビューだけを使う設定にします。列の意味も伝えられますか?
22-4
神宮寺: 列の意味は注釈で伝えられる。正しいSQLを例として教えるFeedbackも使える。
34-1
アイ: 現地保守の可否は、先ほどのビューの判定列を使えますね。
神宮寺: そう。三条件をLLMに考え直させず、判定済みの列を使おう。
34-2
改善後の生成SQL:判定列を使っている
SELECT device_id
FROM OJ41_VISIBLE_CONTRACTS
WHERE onsite_eligible = 'Y';
質問:「この顧客の現地保守対象機器を一覧にして」
このビューは顧客の範囲と、CASEの判定列をまとめたもの。
34-3
アイ: LLMは質問の意味に合う列を選ぶ。判定ルールの適用はDBに任せるんですね。
神宮寺: そう。最後に、実行結果も期待と照合しよう。
22-3
期待する結果と照合
アイ: 対象顧客だけになりました。期限切れと現地保守なしも対象外。今回のテストは期待どおりです。
23-1
神宮寺: 注釈はSQL生成を助けるもの。参照範囲を守るのは、ビューとDB権限だよ。
23-2
アイ: 自然な言葉の質問と、DBで守る条件。役割を分けて設計できました。
神宮寺: では、手順と契約を一度に聞かれたら?
第6章 Select AI Agentに道具を渡す
二つの道具で仕組みを理解し、要件に合うAgentの設計へ
この章の会話をテキストで読む
37-6
第6章
Select AI Agentに道具を渡す
文書検索と契約照会をAgentのツールにする
24-1
アイ: 手順だけ、契約だけ、両方。依頼に合わせて処理を選びたいです。
神宮寺: Agentなら、目的に応じてLLMが道具を選び、結果を見て次の処理を考える。
24-4
アイ: 道具って、システムに用意する処理のことですか?
神宮寺: そう。Agentが呼び出せる形にした処理を、ツールと呼ぶ。
25-1
アイ: NL2SQLとの関係も整理したいです。
神宮寺: 今回のAgentは、毎回SQLを作るのではなく、用意したツールを選んで呼ぶ。そのツールを見てみよう。
24-2
固定SQLを実行する二つのツール
文書検索:条件で絞って、意味の似た順
契約照会:ビューの判定列を読む
神宮寺: 文書検索も契約照会も、中身は決まったSQL。Agentは呼ぶ道具と、検索語などの引数を選ぶ。
24-5
アイ: このAgentを動かす基盤は、どこに置くんですか?
神宮寺: Select AI Agentを使おう。DB内でツールの実行や履歴を扱い、LLMとはAPIでやり取りする。
38-5
Oracle AI Databaseの機能
Select AI Agent
DBの中でツールを実行し、履歴を残すエージェント基盤
25-2
Select AI Agentの実行基盤
DB:ツール実行と履歴
クラウド:判断するLLM
アイ: 基盤はDBの中。LLMへ渡す指示・ツール定義・ツールが返す内容も設計します。
26-6
失敗例①:ツールを呼ばずに回答
アイ: 試しに動かしたら、「契約を確認しました」と答えたのに、ツールを呼んでいません!
26-7
失敗例②:実行エラーを成功扱い
神宮寺: 呼んでいても安心できない。実行に失敗したのに、成功したように答えることもある。
26-1
失敗例③:呼び出しの引数違い
アイ: DEV001の依頼なのに、DEV005を渡していました。結果の機器も違います。
26-5
アイ: LLMに「実行を確認して」と、もう一度頼めばいいですか?
神宮寺: その確認も間違えることがある。ここもハーネスの仕事だよ。
25-3
対象機器はアプリが決める
神宮寺: 対象機器は、対応中のチケットからアプリが設定する。LLMには決めさせない。
25-4
アイ: 検索語はLLMに任せても、対象機器は勝手に変えさせないんですね。
26-2
ツールの履歴で実行を確かめる
呼んだツール・引数
成功/失敗と返却内容
回答との照合
神宮寺: Select AI Agentにはツールの呼び出し履歴を参照するビューがある。記録と返却内容をコードで確かめよう。
26-3
アイ: 呼び出しなし・実行失敗・対象違いなら、成功した回答として通さない。契約値を照合する検査も用意しました。
27-1
検査を加えて、もう一度
KB001:電源・LAN・疎通の確認とログ保存
アイ: 二つのツールが正しい対象で実行され、回答も結果と一致しました。再起動前の影響確認も、回答に残っています。
27-2
契約判定と訪問承認を分ける
アイ: 現地保守の対象なら、担当者の承認を確認。対象外や不明なら、承認へ進めません。
神宮寺: 「現地保守の対象」でも、承認済みや予約済みとは限らない。そこは分けて扱おう。文書の案内は、許可された範囲で続けられる。
35-1
今回の設計での役割分担
アイ: 意味の理解はLLM、業務ルールの適用はハーネス。任せる範囲が見えてきました。
28-2
神宮寺: データのそばにAIを置き、ハーネスで守る。これがインデータベースAIの設計だよ。
28-3
今回の設計:データのそばに、AIを。
Oracle AI Database:表・文書・ベクトル・位置情報を一つのDBで
DB内の埋め込みモデル:文書を外へ送らずベクトル化
Select AI:自然言語からSQL。ビューへの権限制限と注釈を組み合わせる
Select AI Agent:DBでツールを実行し、履歴を確認。LLMとはAPI連携
ハーネス:ビュー・権限・検査コードで業務ルールと範囲を守る
28-4
アイ: はい。使えるデータも、引数も、失敗したときの扱いも。これならAgentアプリを設計できそうです!
おしまい
補足ガイド
マンガで省いたコード・設定・データは、原記事とデモのリポジトリで確認できます。各章の要点と、原記事の対応する見出しをまとめます。
第1章 文書と業務データを、一つのDBで
- 手順を探す問いは意味の検索、現地保守を頼めるかは契約の条件の照会です。性質の違う二つの問いを、同じDBのSQLで組み合わせます。
- 別の検索基盤へ複製すると、契約の変更や文書の公開取消を同期し続ける必要があります。同じDBなら、JOINやEXISTSで最新の業務表を参照できます。
- 文書を改訂したら、そのベクトルも作り直します。
- 「VIEW as a Harness」は製品機能名ではなく、判定と範囲をビューに持たせる設計の考え方です。
- 原記事:1. 文書の意味検索と業務データの照会を組み合わせる
第2章 埋め込みモデルをDBの中へ
- multilingual-e5-large をONNX形式でDBに取り込み、VECTOR_EMBEDDING で文書と質問をベクトルにします。このモデルでは、文書の先頭に「passage: 」、質問の先頭に「query: 」を付けます。
- 表には本文(chunk_text)とベクトル(embedding)の両方を保存します。RAGでLLMへ渡すのは本文です。
- 近さは VECTOR_DISTANCE の COSINE で比べ、距離の小さい順に並べます。
- DB内で動かすのは埋め込みモデルです。回答やSQLを作るLLMは外部のOCIサービスです。
- DB内の埋め込みはDBのCPU・メモリーを使います。処理量と同時実行数は、自分の環境で確かめてください。
- 原記事:2. 埋め込みモデルをDB内へ持ち込み、DBの中でベクトルを作る
- 主なコード:sql/setup/10_load_embedding_model.sql、sql/demos/00b_embedding_basics.sql
第3章 顧客の範囲を守って探す
- デモ用のPL/SQLパッケージ OJ41_CASE_CTX が、開いたチケットの顧客をDBセッションに保持します。ビューはその値で行を絞り、チケット未設定なら0件になります。
- 接続プールを使う場合は、要求ごとに設定し、終わったら消去します。
- 契約の判定列:is_active は「解約・停止なし」かつ契約期間内、onsite_eligible はそれに加えて「現地保守あり」です。対象外の契約も、理由を説明できるようビューに残します。
- マンガでは TRUNC(CURRENT_DATE) で今日の日付を使います。接続時のタイムゾーンは業務の基準(例:Asia/Tokyo)にそろえます。原記事のデモは結果を再現するため、基準日を2026-10-15に固定しています。
- 文書を案内できる条件と、現地保守を頼める条件は別です。担当者がそのチケットを扱えるかどうかの認可も、別に設計します。
- 原記事:3. チケットの顧客と機種を絞ってベクトル検索する · デモA:リレーショナルデータベースによる ベクトル検索 & JOIN & フィルタリング(機種で絞って、ベクトル距離で並べる)
- 主なコード:sql/setup/35_create_demo_tables.sql、sql/demos/01_vector_search.sql
第4章 ビューで守るRAG
- デモのRAGは、PL/SQLの OJ41_RAG.answer_question で、検索、LLMの呼び出し、返却結果の検査をまとめています。
- 回答の検査や、検索の失敗と生成の失敗の切り分けは、原記事で詳しく扱っています。
- 原記事:4. 検索した文書を根拠にRAG(検索拡張生成)で回答する · デモB:答えがある質問と、根拠が足りない質問を比べる · 検索の失敗と生成の失敗を分けて直す
- 主なコード:sql/setup/68_rag_body.sql、sql/setup/66_answer_guard_body.sql、sql/demos/01b_rag.sql
第5章 Select AIで、言葉からSQLへ
- 注釈(ANNOTATIONS)で、「現地保守の対象」が ONSITE_ELIGIBLE であるといった列の意味をLLMへ伝えます(annotations=true)。
- object_list と enforce_object_list=true で、生成SQLが参照できる表・ビューを制限します。DBユーザーの権限は、これとは別に制限します。
- showsql は生成したSQLを表示するだけです。確認してから、チケットを設定した同じセッションで実行します。
- Select AI Feedback は、正しいSQLの例を後の生成に役立てる機能です。モデルを再学習するものではありません。
- マンガの試作で起きる失敗は、設計の流れを見せるための創作です。原記事では、注釈なしと注釈ありを各3回比べています。
- 原記事:5. NL2SQL で契約情報を照会する · デモC:現地保守の対象サーバーを自然言語で調べる · 質問とデータ定義のずれに合わせてチューニングする
- 主なコード:src/webinar_demo/nl2sql_compare.py、sql/demos/02_nl2sql.sql
第6章 Select AI Agentに道具を渡す
- 構成はAgent・Taskが各1つ、Toolが2つ(文書検索・契約照会)です。ツールの中身は固定のSQLです。
- LLMはツールを選び、検索語(p_query)などの引数を組み立てます。対象機器や顧客はアプリ側で固定し、check_call() が生成された対象機器との不一致を止めます。
- USER_AI_AGENT_TOOL_HISTORY で、呼んだツール、入力、成功・失敗、返却値を確かめ、回答と照合します。
- 「現地保守の対象」は、訪問の承認や予約の完了ではありません。デモは対応案の作成までです。
- 原記事:6. 文書検索と契約照会をAgentのツールにする · デモD:契約とドキュメントに基づいた回答をエージェントで作成する · 補足:履歴と引用の確認を自動化する場合
- 主なコード:sql/setup/61_agent_context_body.sql、sql/setup/62_contract_tool.sql、sql/setup/63_knowledge_tool.sql、sql/demos/03_support_agent.sql、sql/demos/04_checked_agent.sql
試すときは
環境の準備とデモデータは、原記事のAppendix:環境準備とデモデータにあります。権限の付与、ローカル環境とモデル、デモデータとAI定義、SQLクライアントでの実行、片付けと再構築、大量ロード、デモデータの全件の順に載っています。
謝辞
この漫画の制作に使用した Manga Generator を公開されている月森ナギ様に感謝します。































































































































