フォーム読み込み中
こんにちは!TASUKI 事業部 技術研究課 庄司秀典です。
普段は、TASUKIというAIを構築するためのアノテーション、データ構造化サービスを開発しています。
生成AIの普及により、Retrieval-Augmented Generation(RAG)を活用して業務知識や独自データを検索・回答に組み込む取り組みが広がっています。しかしながら、「期待した検索結果や回答精度が得られない」という課題がしばしば相談されます。
本記事では、こうしたRAG運用上の精度課題に対処する方法を、具体的なコードや検証*を交えて解説します。データベース(DB)で関係性とメタデータを保持する「チャンキング」の設計を題材とし、その結果として回答精度が7%向上した検証と設計指針を紹介します。
*2025年6月時点での検証結果・実装となります。
生成AIやプログラミングの知識をお持ちの方
RAGの運用で「検索に失敗する/長い不要文脈が混ざる」精度課題を抱えるアプリ・データ基盤担当者
技術的な利点
従来のページ単位での分割では、文脈の粒度が粗いため、不要なノイズが混入しやすいという課題があります。一方で、分割を細かくしすぎると、本来必要な情報が失われてしまうリスクも存在します。
本記事で紹介する手法では、DB上に見出し・種類・前後関係・出典といった要素をメタデータ化することで、関連情報を適切に整理しLLMに対して過不足のない形で情報を提供することが可能になります。
本記事で使用したRAGのアーキテクチャは以下のようになります。
検証ではLLM=GPT-4.1*、embedding model=Cohere Embed 4を使用しました。
*Azure Open AI経由での利用
見出し単位でブロック化。見出し階層パスをメタデータとして保持
ファイル名、チャンク毎の前後チャンク情報をメタデータとして保持
ブロックを Text / Table / Diagram に分割
Table / Diagramの場合前後にTextがある場合は結合
チャンクごとにベクトル化
Oracle ADBにVECTOR型としてembeddingを保存
ベクトル検索で上位チャンクを取得
同ページ内の場合、前後チャンクを連結
見出しとファイル名をチャンクに付与しLLM入力を構成
チャンキングのフロー例:
CREATE TABLE rag_chunks (
chunk_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
file_name VARCHAR2(512), -- 出典(ファイル/URL)
content_type VARCHAR2(50), -- Text | Table | Diagram
prev_chunk_id NUMBER,
next_chunk_id NUMBER,
chunk_text CLOB,
metadata JSON
);
CREATE TABLE rag_embeddings (
id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
chunk_id NUMBER,
embedding VECTOR,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO RAG_EMBEDDINGS (CHUNK_ID, EMBEDDING, CREATED_AT)
SELECT
ET.EMBED_ID AS CHUNK_ID,
TO_VECTOR(ET.EMBED_VECTOR) AS EMBEDDING,
CURRENT_TIMESTAMP AS CREATED_AT
FROM
DOCUMENTATION_TAB DT,
DBMS_VECTOR_CHAIN.UTL_TO_EMBEDDINGS(
DBMS_VECTOR_CHAIN.UTL_TO_CHUNKS(
DBMS_VECTOR_CHAIN.UTL_TO_TEXT(DT.CHUNK_TEXT),
JSON('{"max": "400", "overlap": "20", "language": "JAPANESE", "normalize": "all"}')
),
JSON('{"provider": "ocigenai", "credential_name": "VECTOR_CRED", "url": "VECTOR_URI", "model": "VECTOR_MODEL"}')
) T,
JSON_TABLE(
T.COLUMN_VALUE,
'$[*]' COLUMNS (
EMBED_ID NUMBER PATH '$.embed_id',
EMBED_VECTOR CLOB PATH '$.embed_vector'
)
) ET
WHERE DT.ID = :doc_id;
SELECT SOURCE_DOC_ID
FROM {vec_table_name}
ORDER BY VECTOR_DISTANCE(EMBEDDING, TO_VECTOR(:query_embed_vector), COSINE)
FETCH EXACT FIRST :top_k ROWS ONLY
WITH cte AS (
SELECT
id,
file_name,
metadata,
text_content,
LAG(id) OVER (PARTITION BY file_name ORDER BY id) AS prev_id,
LEAD(id) OVER (PARTITION BY file_name ORDER BY id) AS next_id
FROM {doc_table_name}
)
SELECT
c.id AS current_id,
c.metadata AS current_metadata,
c.text_content AS current_text_content,
p.id AS prev_id,
p.metadata AS prev_metadata,
p.text_content AS prev_text_content,
n.id AS next_id,
n.metadata AS next_metadata,
n.text_content AS next_text_content
FROM cte c
LEFT JOIN {doc_table_name} p
ON p.id = c.prev_id
AND p.file_name = c.file_name
LEFT JOIN {doc_table_name} n
ON n.id = c.next_id
AND n.file_name = c.file_name
WHERE c.id = {doc_id}
評価データを用意し、DBチャンキングと従来手法の回答精度を検証しました。
DBチャンキング | ページチャンキング(従来手法) |
|---|---|
78% | 71% |
DBチャンキングの回答精度が7ポイント向上しました。
考えられる精度向上要因
小粒度化で意味表現が明確になり、検索精度が向上
不要箇所の排除で、ページ内ノイズ(他表の数値など)混入を抑制
前後連結で「必要最小の文脈」を補いつつ、過剰コンテキストによるハルシネーションを回避
(参考) 評価データ
下図のようなPDFに対して100問のQAを作成し検証を実施しています。
評価に使用したPDFは多くの図表を含んでおり、RAGにおいて図表の内容を問うQAの解答は難しいとされています。
評価に用いたPDFの例:
評価に用いたQAの例:
質問 | 回答 |
|---|---|
ソフトバンクの経営理念とビジョンより下層には何が位置づけられていますか? | マテリアリティ(重要課題)、成長戦略(Beyond Carrier) |
ソフトバンクの地方創生インターンでは、誰のためのインターンシップですか? | 次の時代を創る"変革リーダー"を目指す学生のためのインターンシップ |
ソフトバンクの環境マネジメント体制に関して、環境委員会下の各部門を全て教えて。 | 各事業部門, 購買部門, オフィス管理部門, CS部門, 情報システム部門, ネットワークセンター、交換局、基地局管理部門, データセンター管理部門 |
今回の記事では、DBを使用したRAGを業務システムへ適用する際の精度向上手法を紹介しました。
従来のページ単位チャンキングではノイズや文脈不足が精度低下を招いていましたが、見出しや前後関係を保持したDBチャンキングにより必要十分な文脈を確保でき、評価データでは+7ptの精度向上を確認しました。
回答精度だけでなく、DBにデータを集約して一元管理することで、権限管理や監査などの運用要件も同時に満たせるため、RAGを業務システムへ適用する際の選択肢として検討してみてはどうでしょうか。
データ構造化代行サービスで検索拡張生成(RAG)の検索精度を向上。膨大かつ多様な社内ドキュメントも、RAGへの高い知見をもったチームがデータ構造化を支援します。
Oracle Autonomous Databaseは、Oracleが提供するクラウド型データベースサービスです。機械学習を活用してパッチ適用、バックアップ、セキュリティ、チューニングを自動化し、運用負荷を軽減します。必要な時に必要な分だけ利用でき、高い可用性と拡張性を備えています。
条件に該当するページがございません