ApsaraDB RDS for PostgreSQL は、強力なベクトルストレージと効率的な全文検索機能を提供します。 これにより、ApsaraDB RDS for PostgreSQL は、キーワードベースの取得を実装するための取得拡張生成 (RAG) アプリケーションの理想的なベクトルデータベースとなります。
はじめに
このトピックでは、ApsaraDB RDS for PostgreSQL を使用して専用のチケットチャットボットを作成する方法の例を示し、RAG アプリケーションの作成における ApsaraDB RDS for PostgreSQL の利点を示します。 このトピックを読んだ後、以下の情報を取得できます。
手順
ApsaraDB RDS for PostgreSQL を使用して専用のチケットチャットボットを作成するには、データ処理、マルチパスリコール、マージソート、Q&A分析といういくつかの重要な手順が必要です。
データ処理
公式ドキュメント、ナレッジベース、過去のチケットからのデータを含むソースデータは、処理されて ApsaraDB RDS for PostgreSQL インスタンスに保存されます。 データ処理は、データのセグメント化と埋め込みで構成されます。
マルチパスリコール
ドキュメントキーワードベースのリコール: 類似検索を実行して、ユーザーの質問とドキュメントテーブル内のキーワードを照合し、類似度の最も高い上位 N 件のドキュメントを返します。
コンテンツキーワードベースのリコール: ドキュメントコンテンツのキーワードに基づいて類似検索を実行し、ユーザーの質問とキーワードを照合します。
BM25 ベースのリコール: 単語の頻度、単語の距離、単語が属するドキュメントモジュールの重要性に基づいて関連性スコアを統計分析し、スコアの高いコンテンツを返します。
埋め込みベースのリコール: 質問を埋め込みに変換し、そのコサイン類似度を計算してから、類似度の高いコンテンツを返します。
マージソート
逆順位融合 (RRF) アルゴリズムとオープンソースの bce-reranker-base_v1 モデルを使用して、マルチパスリコールの結果を正確にソートします。
Q&A分析
質問とその回答はデータベースに保存されます。 テストフェーズでは、Q&A パフォーマンスがスコアリングされ、さまざまな取得ポリシーの効果が評価されます。
データ処理
公式ドキュメント、ナレッジベース、過去のチケットからのデータを含むソースデータは、処理されて RDS インスタンスに保存されます。 データ処理は、データのセグメント化と埋め込みで構成されます。
データ取得
関連データは、RAG アプリケーションの目的に基づいて取得されます。 このトピックでは、ApsaraDB RDS for PostgreSQL ベースの DingTalk チケットチャットボットを例として使用して、ヘルプドキュメント、ナレッジベース、過去のチケットからデータを収集します。
データ処理
ソースデータは処理され、特定の形式で RDS インスタンスに保存されます。 たとえば、LangChain フレームワークで提供されている HTMLHeaderTextSplitter クラスを使用して、H1 や H2 などの HTML 階層に基づいてヘルプドキュメントのテキストをセグメント化できます。 データのセグメント化サイズとデータの重複サイズを指定して、テキストのセグメント化パフォーマンスを柔軟に制御できます。 詳細については、LangChain で提供されているさまざまなテキストスプリッターを参照してください。
Markdown ドキュメントを処理する必要がある場合は、MarkdownHeaderTextSplitter クラスと # や ## などのフラグを使用して階層分割を実行できます。
データストレージ
データは、ドキュメントと埋め込みという 2 つのコアテーブルに保存されます。 ドキュメントテーブルはドキュメント情報の保存に使用されます。 埋め込みテーブルは、セグメント化後に埋め込み情報を保存するために使用されます。
ドキュメントテーブル
例:
\d document Data table "public.document" Field | Type | Collation | Nullable | Default -------------------+-----------------------------+----------+----------+-------------------------------------- id | bigint | | not null | nextval('document_id_seq'::regclass) title | character varying(255) | | | url | character varying(255) | | | ''::character varying key_word | character varying(255) | | | ''::character varying tag | character varying(255) | | | ''::character varying created | timestamp without time zone | | not null | now() modified | timestamp without time zone | | not null | now() key_word_tsvector | tsvector | | | product_name | character varying(255) | | | ''::character varying Indexes: "document_pkey" PRIMARY KEY, btree (id) "document_key_word_tsvector_gin" gin (key_word_tsvector) "document_product_name_key" btree (product_name) "document_title_key" UNIQUE CONSTRAINT, btree (title) Triggers: trigger_update_tsvector BEFORE INSERT OR UPDATE ON document FOR EACH ROW EXECUTE FUNCTION update_tsvector()ドキュメントテーブル
テーブルには、id、title、url、key_word、tag、created、modified、key_word_tsvector、product_name の各フィールドが含まれています。 key_word フィールドはキーワードを示します。 created フィールドは作成時刻を示します。 modified フィールドは変更時刻を示します。 key_word_tsvector フィールドは、キーワードの重み付き tsvector 値を示します。 key_word_tsvector フィールドは、キーワードの照合と、コンテンツキーワードベースのリコールの一部として使用されます。
インデックス
インデックスには、document_pkey、document_title_key、document_product_name_key、document_key_word_tsvector_gin が含まれます。 document_pkey インデックスはプライマリキー ID のインデックスです。 document_title_key インデックスはドキュメントタイトルのインデックスです。 ドキュメントはドキュメントタイトルに基づいて更新されるため、ドキュメントタイトルは一意である必要があります。 document_product_name_key インデックスは製品名のインデックスです。 document_key_word_tsvector_gin インデックスは、tsvector 値の GIN インデックスです。 ApsaraDB RDS for PostgreSQL では、GIN インデックスが許可されています。
トリガー
ドキュメントテーブルが更新されたり、テーブルにデータが挿入されたりすると、トリガーによって key_word_tsvector 列のコンテンツが自動的に更新されます。
埋め込みテーブル
例:
\d embedding Data table "public.embedding" Field | Type | Collation | Nullable | Default -------------------+-----------------------------+----------+----------+--------------------------------------- id | bigint | | not null | nextval('embedding_id_seq'::regclass) doc_id | integer | | | '-1'::integer content_chunk | text | | not null | content_embedding | vector(1536) | | not null | created | timestamp without time zone | | not null | now() modified | timestamp without time zone | | not null | now() ts_vector_extra | tsvector | | | Indexes: "embedding_pkey" PRIMARY KEY, btree (id) "embedding_content_embedding_idx" hnsw (content_embedding vector_cosine_ops) WITH (m='16', ef_construction='64') "embedding_doc_id_key" btree (doc_id) "embedding_rumidx" rum (ts_vector_extra) Triggers: embedding_tsvector_update BEFORE INSERT OR UPDATE ON embedding FOR EACH ROW EXECUTE FUNCTION tsvector_update_trigger('ts_vector_extra', 'public.jiebacfg', 'content_chunk')埋め込みテーブル
埋め込みテーブルには、id、doc_id、content_chunk、content_embedding、created、modified、ts_vector_extra の各フィールドが含まれています。 doc_id フィールドはドキュメント ID を示します。 content_chunk フィールドは、セグメント化後のチャンクを示します。 content_embedding フィールドは、単語分割後に取得されたチャンクの埋め込みを示します。 created フィールドは作成時刻を示します。 modified フィールドは変更時刻を示します。 ts_vector_extra フィールドは、セグメント化後のチャンクの tsvector 値を示します。
インデックス
インデックスには、embedding_pkey、embedding_doc_id_key、embedding_content_embedding_idx、embedding_rumidx が含まれます。 embedding_pkey インデックスはプライマリキーのインデックスです。 embedding_doc_id_key インデックスはドキュメント ID のインデックスです。 embedding_content_embedding_idx インデックスは、content_embedding 列のベクトルインデックスです。 embedding_rumidx インデックスは、tsvector 値の RUM インデックスです。
トリガー
埋め込みテーブルが更新された場合、またはテーブルにデータが挿入された場合、トリガーによって ts_vector_extra 列のコンテンツが自動的に更新されます。
マルチパスリコール
ドキュメントキーワードベースのリコール
ドキュメントキーワードベースのリコールは、類似検索を実行して、ユーザーの質問とドキュメントテーブル内のキーワードを照合し、類似度の最も高い上位 N 件のドキュメントを返します。
ドキュメントキーワードベースのリコールでは、ApsaraDB RDS for PostgreSQL で事前に定義された GIN インデックスを使用して、RDS インスタンス内のキーワードとユーザーの質問を効率的に照合します。
ドキュメント内のキーワードを tsvector 値に変換し、tsvector 値の重みを割り当てます。
変換中は、単語分割モードを指定する必要があります。 ほとんどの場合、中国語単語分割拡張機能である pg_jieba と zhparser が使用されます。 拡張機能のインストール方法の詳細については、「拡張機能を管理する」をご参照ください。
to_tsvector 関数を使用してキーワードをセグメント化し、setweight 関数を使用してセグメント化後の文字列の重みを指定できます。 これにより、位置情報に重み情報が追加されます。 たとえば、pg_jieba 拡張機能を使用し、単語分割モードを jiebacfg に設定し、setweight 関数を使用してドキュメントキーワードの重みを A に設定します。
SELECT setweight(to_tsvector('jiebacfg', 'PostgreSQLは世界で最も先進的なオープンソースのリレーショナルデータベースです'), 'A'); setweight ------------------------------------------------------------------------------- 'postgresql':1A '世界':3A '先進':5A '的':6A 'オープンソース':7A 'リレーショナルデータベース':10A '最も':4Aユーザーの質問を tsquery 値に変換し、tsquery 値とドキュメントキーワードを照合します。
ApsaraDB RDS for PostgreSQL の全文検索機能を使用して、ユーザーの質問とドキュメントキーワードを照合します。 ステートメントの例:
SELECT id, title, url, key_word, ts_rank( key_word_tsvector, to_tsquery(replace(text(plainto_tsquery('jiebacfg', '%s')), '&', '|')) ) AS score FROM public.document WHERE key_word_tsvector @@ to_tsquery(replace(text(plainto_tsquery('jiebacfg', '%s')), '&', '|')) AND product_name = '%s' ORDER BY score DESC LIMIT 1;to_tsquery 関数
to_tsquery 関数を使用して、ユーザーの質問を tsquery 値に変換します。 例:
SELECT to_tsquery('jiebacfg', 'PostgreSQLは世界で最も先進的なオープンソースのリレーショナルデータベースです'); to_tsquery -------------------------------------------------------------------------------- 'postgresql' <2> '世界' <2> '先進' <-> 'オープンソース' <-> 'リレーショナルデータベース'<2>は 2 つの単語間の距離を示します。<->は隣接関係を示します。 たとえば、オープンソースとリレーショナルデータベースは隣接している必要があります。 また、はやでなどのストップワードは自動的に削除されます。 アンパサンド (&) は AND を、縦棒 (|) は OR を、感嘆符 (!) は NOT を示します。 重みを指定することもできます。 例:SELECT to_tsquery('jiebacfg', 'postgresql:A'); to_tsquery ---------------- 'postgresql':Ato_tsquery 関数への入力は、tsquery の演算子の要件を満たしている必要があります。 ユーザーの質問が tsquery 値に正常に変換されるようにするには、to_tsquery 関数の代わりに plainto_tsquery 関数を使用すると、無効な演算子を効果的に無視できます。 例:
SELECT to_tsquery('jiebacfg','ログ|&ヒープ'); ERROR: tsquery の構文エラー: "ログ|&ヒープ" SELECT plainto_tsquery('jiebacfg','ログ|&ヒープ'); plainto_tsquery ----------------- 'ログ' & 'ヒープ'text 関数を使用して、plainto_tsquery 関数によって返された結果をテキスト値に変換します。 次に、replace 関数を使用して
&を|に置き換えることで、一致条件を AND から OR に変換します。 例:-- plainto_tsquery 関数を使用します。 SELECT plainto_tsquery('jiebacfg', 'PostgreSQLは世界で最も先進的なオープンソースのリレーショナルデータベースです'); plainto_tsquery -------------------------------------------------------------------- 'postgresql' & '世界' & '先進' & 'オープンソース' & 'リレーショナルデータベース' -- plainto_tsquery、text、replace 関数を使用します。 SELECT replace(text(plainto_tsquery('jiebacfg', 'PostgreSQLは世界で最も先進的なオープンソースのリレーショナルデータベースです')), '&', '|'); replace -------------------------------------------------------------------- 'postgresql' | '世界' | '先進' | 'オープンソース' | 'リレーショナルデータベース' -- to_tsquery、plainto_tsquery、text、replace 関数を使用します。 SELECT to_tsquery(replace(text(plainto_tsquery('jiebacfg', 'PostgreSQLは世界で最も先進的なオープンソースのリレーショナルデータベースです')), '&', '|')); to_tsquery -------------------------------------------------------------------- 'postgresql' | '世界' | '先進' | 'オープンソース' | 'リレーショナルデータベース'pg_jieba 拡張機能のカスタム単語分割機能を使用して、カスタム単語分割メソッドを作成します。 たとえば、
リレーショナルデータベースをカスタム辞書に追加する前のテキスト分割結果は'リレーショナル' & 'データベース'で、カスタム辞書に追加した後は'リレーショナルデータベース'です。-- リレーショナルデータベース を重み 100000 でカスタム辞書 0 に自動的に追加します。 INSERT INTO jieba_user_dict VALUES ('リレーショナルデータベース',0,100000); -- カスタム辞書 0 をロードします。 最初の 0 はカスタム辞書のシーケンス番号を示し、2 番目の 0 はデフォルト辞書がロードされることを示します。 SELECT jieba_load_user_dict(0,0); jieba_load_user_dict ---------------------- -- ユーザーの質問を tsquery 値に変換します。 SELECT to_tsquery(replace(text(plainto_tsquery('jiebacfg', 'PostgreSQLは世界で最も先進的なオープンソースのリレーショナルデータベースです')), '&', '|')); to_tsquery -------------------------------------------------------------------- 'postgresql' | '世界' | '先進' | 'オープンソース' | 'リレーショナルデータベース'演算子
ApsaraDB RDS for PostgreSQL は、さまざまな 演算子 を提供して、単語分割後の tsvector 値と tsquery 値に対する操作を実行します。 たとえば、
@@を使用して、tsvector 値が tsquery 値と一致するかどうかを示すことができます。SELECT to_tsvector('jiebacfg', 'PostgreSQLは世界で最も先進的なオープンソースのリレーショナルデータベースです') @@ to_tsquery('jiebacfg', 'postgresql:A'); ?column? ---------- f SELECT setweight(to_tsvector('jiebacfg', 'PostgreSQLは世界で最も先進的なオープンソースのリレーショナルデータベースです'),'A') @@ to_tsquery('jiebacfg', 'postgresql:A'); ?column? ---------- tクエリ条件は、重み A の単語
postgresqlです。 この場合、クエリ対象の tsvector 値に単語postgresqlが含まれていても、重み A が割り当てられていないため、false が返されます。 ただし、setweight 関数を使用してクエリ対象の tsvector 値に重み A が割り当てられている場合は、true が返されます。ts_rank 関数
ts_rank 関数を使用して、tsquery 値とクエリ対象の tsvector 値の間の一致度を計算します。 たとえば、クエリ条件が
postgresql | オープンソースの場合、クエリ対象の行には、postgresqlとオープンソースキーワードの少なくとも 1 つが含まれている必要があります。 最初の文には両方のキーワードが含まれています。 そのスコアは、オープンソースキーワードのみを含む 2 番目の文よりも高くなります。 3 番目の文は、postgresqlもオープンソースも含まれていないため、@@演算子によってスキップされます。WITH sentence AS ( SELECT 'PostgreSQLは世界で最も先進的なオープンソースのリレーショナルデータベースです' AS content UNION ALL SELECT 'MySQLは広く使用されているオープンソースのリレーショナルデータベースです' UNION ALL SELECT 'MySQLは世界中で非常に人気があります' ) SELECT content, ts_rank(to_tsvector('jiebacfg', content), to_tsquery('jiebacfg', 'postgresql | オープンソース')) AS score FROM sentence WHERE to_tsvector('jiebacfg', content) @@ to_tsquery('jiebacfg', 'postgresql | オープンソース') ORDER BY score DESC; content | score --------------------------------------------+------------- PostgreSQLは世界で最も先進的なオープンソースのリレーショナルデータベースです | 0.06079271 MySQLは広く使用されているオープンソースのリレーショナルデータベースです | 0.030396355極端な場合、単語分割の問題が発生したり、入力が不正な文字を含んでいると、ドキュメントが一致しない可能性があります。 この問題を防ぐために、ApsaraDB RDS for PostgreSQL では、pg_bigm 拡張機能を使用してあいまい一致ベースの検索を実行できます。 bigm_similarity 関数を使用して、類似度の最も高いドキュメントを返すことができます。 例:
WITH sentence AS ( SELECT 'PostgreSQLは世界で最も先進的なオープンソースのリレーショナルデータベースです' AS content UNION ALL SELECT 'MySQLは広く使用されているオープンソースのリレーショナルデータベースです' UNION ALL SELECT 'MySQLは世界中で非常に人気があります' ) SELECT content, bigm_similarity(content, 'postgres | オープンソース製品') AS score FROM sentence ORDER BY score DESC; content | score --------------------------------------------+------------ PostgreSQLは世界で最も先進的なオープンソースのリレーショナルデータベースです | 0.23076923 MySQLは広く使用されているオープンソースのリレーショナルデータベースです | 0.05263158 MySQLは世界中で非常に人気があります | 0.0 (3 rows)bigm_similarity 関数は、2 つの入力テキストを、2 つの連続した文字または 2 つの単語の組み合わせである 2-gram 要素に変換します。 次に、この関数は入力テキスト間の要素の数を計算します。 有効な値: [0, 1]。 値 1 は、テキストが同じであることを示します。 セグメント化が不正確な場合、スペルミスが存在する場合、または省略形が使用されている場合は、pg_bigm 拡張機能を使用してあいまい一致ベースの検索を実行できます。 詳細については、「pg_bigm 拡張機能を使用してあいまい一致ベースのクエリを実行する」をご参照ください。
コンテンツキーワードベースのリコール
ドキュメントコンテンツを検索するには、「ドキュメントキーワードベースのリコール」で使用したのと同じ方法を使用できます。 ほとんどの場合、ドキュメントコンテンツはキーワードよりも長くなります。 全文検索を実行する場合は、RUM 拡張機能 を使用して検索を高速化することをお勧めします。 たとえば、サンプルクエリプランを使用して類似検索を実行し、ユーザーの質問とドキュメントコンテンツのキーワードを照合できます。
RUM 拡張機能は GIN インデックスに基づいており、単語の位置やタイムスタンプなどの追加情報を保存します。 次のクエリプランでは、RUM 拡張機能の実行プランを使用し、embedding_rumidx インデックスを使用し、データをフィルタリングし、類似度を計算し、結果をソートします。 すべての操作はインデックスによって完了するため、クエリの効率が保証されます。 クエリには 3.219 ミリ秒かかります。
次のクエリプランでは、冗長な ts_vector_extra 列に基づいて構築されたネイティブ GIN インデックスを使用します。 ネイティブ GIN インデックスの実行プランは、RUM 拡張機能の実行プランよりも複雑です。 ネイティブ GIN インデックスの実行プランは 2 つのプロセスを開始し、RUM のインデックススキャンの代わりにビットマップインデックススキャンを使用します。 具体的には、インデックスを使用してクエリ条件を満たすすべての行のビットマップを取得し、embedding_ts_vector_gin で指定されたインデックスを使用して関連行を特定します。 セカンダリフィルターを実行して有効な結果を検索します。 次に、Top-N アルゴリズムを使用して結果をソートし、プロセスで gather merge を実行して結果を結合します。 クエリには 14.234 ミリ秒かかります。
GIN インデックスは
to_tsvector('jiebacfg'::regconfig, content_chunk)に構築されます。 これらの GIN インデックスの実行プランは、ts_vector_extra 列に構築された GIN インデックスの実行プランと似ています。 WHERE 条件は同じで、ランキングステージに入る行数も同様です。 主な違いは ts_rank の計算にあります。 ts_rank 関数には単語の位置情報が必要です。 GIN インデックスが作成されると、位置情報は保存されません。 ts_rank 関数を使用すると、to_tsvector 関数が各行で実行されるため、時間がかかります。 クエリには 1081.547 ミリ秒かかります。
BM25 ベースのリコール
BM25 は、単語頻度 (TF) と逆文書頻度 (IDF) の影響を考慮した古典的なテキストマッチングアルゴリズムです。 TF が大きい単語は、ドキュメントに頻繁に出現し、強い関連性があることを示します。 IDF が大きい単語は、複数のドキュメントに出現し、重要度が低いことを示します。 BM25 アルゴリズムは、TF-IDF アルゴリズムを最適化し、クエリ効果を向上させるためのパラメータを導入しています。
BM25 ベースのリコールはキーワードベースの取得方法として使用され、ApsaraDB RDS for PostgreSQL のキーワードベースの取得方法と比較されます。 ApsaraDB RDS for PostgreSQL のキーワードベースの取得方法では、ts_rank などのビルトイン関数を使用し、ドキュメントの各部分における単語の頻度、単語の距離、単語の重要度を考慮します。 BM25 ベースのリコール結果は、キーワードベースの取得結果の一部と見なすことができ、取得精度を向上させます。
埋め込みベースのリコール
ApsaraDB RDS for PostgreSQL は、高次元ベクトル類似検索 (pgvector) 拡張機能と ベクトル生成 (rds_embedding) 拡張機能をサポートしています。 pgvector 拡張機能は、必要なベクトルデータ型と、ベクトル間の距離や類似度の計算などの基本的なベクトルデータ操作をサポートしています。 rds_embedding 拡張機能は、高次元テキストを埋め込みに変換するだけです。 詳細については、「pgvector 拡張機能を使用して高次元ベクトル類似検索を実行する」および「rds_embedding 拡張機能を使用してベクトルを生成する」をご参照ください。
ApsaraDB RDS for PostgreSQL では、ベクトルを配列として保存できます。 ただし、データ型はベクトル型として定義する必要があります。 ベクトル計算とランキングを実行する場合、ベクトル型のインデックスを作成しないと、全表スキャンとランキングのオーバーヘッドが大幅に増加します。
pgvector 拡張機能は、近似最近傍探索 (ANN) のための階層型ナビゲーションスモールワールド (HNSW) と反転ファイルとフラット圧縮 (IVFFlat) のインデックス作成方法をサポートしています。 HNSW インデックス作成ではデータの挿入は不要で、IVFFlat インデックス作成よりも高速なクエリ速度を実現します。 そのため、この方法では HNSW インデックス作成が使用されます。
SELECT
embedding.id,
doc_id,
content_chunk,
content_embedding <=> '%s' AS similarity
FROM
public.embedding
LEFT JOIN
document ON document.id = embedding.doc_id
WHERE
product_name = '%s'
ORDER BY
similarity
LIMIT %s;IVFFlat インデックス作成のベストプラクティスの詳細については、「ApsaraDB RDS for PostgreSQL 上に LLM 駆動の専用チャットボットを構築する」をご参照ください。
pgvector 拡張機能のパフォーマンステストの詳細については、「pgvector 拡張機能を使用して高次元ベクトル類似検索を実行する」をご参照ください。
マージソート
この方法では、RRF アルゴリズムとオープンソースの bce-reranker-base_v1 モデルを使用して、ドキュメントキーワードベースのリコール、コンテンツキーワードベースのリコール、BM25 ベースのリコール、埋め込みベースのリコールの結果を正確にソートします。
RRF アルゴリズムは理解しやすいものです。 次の式では、
は必要なドキュメントを、 はシステム 内のドキュメント のランキングを、 は定数を示します。 k は 60 または他の値に設定できます。 個のシステム内のドキュメントのランキングを合計して、最終結果を取得できます。 ランキングが高いほど、逆順で取得される値が大きくなります。 その結果、計算される RRF 値も大きくなります。 ドキュメントが複数のシステムで上位にランクされている場合、ドキュメントの RRF 値は大幅に増加します。 RRF アルゴリズムを使用すると、マルチパスリコールのチャンクを効果的にソートできます。 bce-reranker-base_v1 は、セマンティック検索結果と関連性ランキングを最適化することを目的とした、クロスランゲージセマンティック表現アルゴリズムモデルです。 このモデルは、中国語、英語、日本語、韓国語をサポートし、強力なファインランキング機能を備えています。 実際のシナリオでは、このモデルは、特に多数のチャンクをソートする必要がある場合、リコールの実行よりもファインランキングに時間がかかります。 これはセッションの流暢さに影響を与える可能性があります。 専用チケットチャットボットからの応答を高速化するには、シンプルで効率的な RRF アルゴリズムを使用して結果をソートするか、RRF ランキング後にファインランキングを実行できます。 高い精度が必要な場合は、bce-reranker-base_v1 モデルを直接使用して結果をソートできます。
Q&A分析
専用チケットチャットボットがさまざまなデータソースに応答するために、さまざまなポリシーが定義されています。 これにより、大規模モデルが呼び出されたときに prompt_content フィールドのコンテンツが予期せず処理されるのを防ぐのに役立ちます。
ナレッジベースのコンテンツは、大規模モデルが処理するための prompt_content フィールドの入力としては使用されません。 代わりに、コンテンツが直接提供されます。
公式ドキュメントのコンテンツは、取得した HTML ファイルがセグメント化され、レイアウトの問題やコンテンツの重複が発生する可能性があるため、大規模モデルによって要約およびフォーマットされます。
大規模モデルのコンテンツは、ナレッジベースと公式ドキュメントが必要な回答を提供できない場合にのみ直接提供されます。 大規模モデルは、少数のシナリオで問題を解決するために直接呼び出されます。 ほとんどの場合、大規模モデルは一般的なナレッジアシスタントとして機能します。
過去のチケットのコンテンツは、チケット名と URL のみで提供されます。
回答の各部分について、関連ドキュメントとそのリンクが提供されます。 回答に基づいて問題を解決できない場合は、元のドキュメントを確認して、より包括的で正確なコンテンツを取得することをお勧めします。
テストフェーズでは、最新の質問と回答のスコアを、現在のポリシーの有効性の予備評価として使用できます。 コードを作成して複数のポリシーを作成し、テストに基づいて最適なリコールポリシーを決定できます。
prompt = f'''以下のコンテンツを整理してフォーマットし、出力フォーマットを整理してください。
```
{prompt_content}
```
自分の能力に基づいて回答してください。私の質問は{question}です。
'''DingTalk チャットボットに接続する
Streamlit を使用して Web アプリを作成したり、DingTalk チャットボットに接続したりできます。 Web アプリは、自己テストとドキュメント管理に使用されます。 DingTalk チャットボットを使用すると、すべてのユーザーがサービスにアクセスできます。
DingTalk グループの各 Q&A セッションでは、データベースレベルで新しい接続を確立する必要があります。 頻繁な接続の確立は、時間とメモリの消費など、パフォーマンスの問題を引き起こす可能性があります。 接続がすぐに解放されない場合、接続数が上限に達し、データベースへの新しい接続を確立できなくなる可能性があります。 プロジェクトで接続プールを使用すると、短期間の接続が頻繁に発生するのを防ぐことができます。 ApsaraDB RDS for PostgreSQL のビルトイン PgBouncer 接続プール を使用することもできます。
例
この例では、マルチパスリコールを使用して、RAG における ApsaraDB RDS for PostgreSQL の強力な機能と使いやすさを説明します。 この例では、ユーザーが PostgreSQL の紹介 という質問をします。 3 つの取得方法の結果が得られます。
データを準備する
特権アカウントを使用して、必要なデータベースで次の SQL 文を実行し、pg_jieba、pgvector、RUM、rds_embedding 拡張機能をインストールします。
重要pg_jieba 拡張機能をインストールする前に、shared_preload_libraries パラメータの 値 に pg_jieba を追加する必要があります。 shared_preload_libraries パラメータの変更方法の詳細については、「ApsaraDB RDS for PostgreSQL インスタンスのパラメータを変更する」をご参照ください。
SELECT * FROM pg_extension;文を実行して、インストールされている拡張機能を表示できます。
CREATE EXTENSION IF NOT EXISTS pg_jieba; CREATE EXTENSION IF NOT EXISTS vector; CREATE EXTENSION IF NOT EXISTS rum; CREATE EXTENSION IF NOT EXISTS rds_embedding;RDS インスタンスが外部モデルにアクセスできるように、RDS インスタンスが存在する仮想プライベートクラウド (VPC) の NAT ゲートウェイを作成します。 詳細については、「rds_embedding 拡張機能を使用してベクトルを生成する」をご参照ください。
説明デフォルトでは、インターネット経由で RDS インスタンスに接続することはできません。 Alibaba Cloud ModelScope で提供されているテキスト埋め込みモデルなどの外部大規模モデルを使用する場合は、RDS インスタンスが外部モデルにアクセスできるように、RDS インスタンスが存在する VPC の NAT ゲートウェイを作成する必要があります。
必要なデータベースで次の SQL 文を実行して、doc と embed という名前のテストテーブルを作成し、テーブルのインデックスを作成します。
--doc テストテーブルとテーブルのインデックスを作成します。 DROP TABLE IF EXISTS doc; CREATE TABLE doc ( id bigserial PRIMARY KEY, title character varying(255) UNIQUE, key_word character varying(255) DEFAULT '' ); CREATE INDEX doc_gin ON doc USING GIN (to_tsvector('jiebacfg', key_word)); --embed テストテーブルとテーブルのインデックスを作成します。 DROP TABLE IF EXISTS embed; CREATE TABLE embed ( id bigserial PRIMARY KEY, doc_id integer, content text, embedding vector(1536), ts_vector_extra tsvector ); CREATE INDEX ON embed USING hnsw (embedding vector_cosine_ops) WITH ( m = 16, ef_construction = 64 );次の SQL 文を実行してトリガーを作成します。 embed テーブルの行が更新されたり、行にデータが挿入されたりすると、ts_vector_extra 列が自動的に更新されます。
-- キーワードに基づいて全文検索を実行するために、テキストを tsvector 値に変換します。 CREATE TRIGGER embed_tsvector_update BEFORE UPDATE OR INSERT ON embed FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger('ts_vector_extra', 'public.jiebacfg', 'content');次の SQL 文を実行します。 embed テーブルで挿入または更新が実行されるたびに、挿入または更新されたコンテンツに基づいて埋め込みが生成され、embedding 列に保存されます。
重要この例では、Alibaba Cloud ModelScope で提供されているテキスト埋め込みモデルが使用されています。 Alibaba Cloud ModelScope をアクティブ化し、必要な API キーを取得する必要があります。 詳細については、「API キーを取得する」をご参照ください。
-- 質問を埋め込みに変換します。 ビジネス要件に基づいて api_key パラメータを指定します。 CREATE OR REPLACE FUNCTION update_embedding() RETURNS TRIGGER AS $$ BEGIN NEW.embedding := rds_embedding.get_embedding_by_model('dashscope', 'sk-****', NEW.content)::real[]; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER set_embedding BEFORE INSERT OR UPDATE ON embed FOR EACH ROW EXECUTE FUNCTION update_embedding();テーブルにテストデータを挿入します。
INSERT INTO doc(id, title, key_word) VALUES (1, 'PostgreSQL紹介', 'PostgreSQL プラグイン'), (2, 'MySQL紹介', 'MySQL MGR'), (3, 'SQL Server紹介', 'SQL Server Microsoft'); INSERT INTO embed(doc_id, content) VALUES (1, 'PostgreSQLは、カリフォルニア大学バークレー校のコンピュータサイエンス学部で開発された POSTGRES バージョン 4.2 をベースにしたオブジェクトリレーショナルデータベース管理システム (ORDBMS) です。 POSTGRES の先進的な多くの概念は、ずっと後に一部の商用データベースシステムに登場しました'), (1, 'PostgreSQLは、最初のバークレーコードのオープンソースの後継です。 ほとんどの SQL 標準をサポートし、複雑なクエリ、外部キー、トリガー、更新可能なビュー、トランザクションの整合性、マルチバージョン同時実行制御など、多くの最新の機能を提供します。 また、PostgreSQLは、新しいデータ型、関数、演算子、集約関数、インデックスメソッド、手続き型言語などを追加するなど、さまざまな方法で拡張できます'), (1, 'また、自由なライセンスにより、誰でも私用、商用、学術研究のいずれの目的でも、PostgreSQLを無料で使用、変更、配布できます。'), (1, 'Ganos プラグインと PostGIS プラグインは、同じスキーマにインストールできません'), (1, '豊富なエコシステム: PostGIS (地理情報処理)、TimescaleDB (時系列データベース)、pg_stat_statements (パフォーマンス監視) など、さまざまなシナリオのニーズを満たすことができる、すぐに使用できるプラグインと拡張機能が多数あります'); INSERT INTO embed(doc_id, content) VALUES (2, 'MySQL という名前の由来は不明です。 10 年以上にわたり、基本ディレクトリと多数のライブラリとツールでプレフィックス「my」を使用してきました。 ただし、共同設立者の Monty Widenius の娘の名前も「My」です。 今日まで、MySQL という名前の由来は謎のままです。'), (2, 'MySQL ソフトウェアはデュアルライセンス方式を採用しています。 ユーザーは、GNU 一般公衆利用許諾契約書 (http://www.fsf.org/licenses/) の条項に基づいて MySQL ソフトウェアをオープンソース製品として使用するか、MySQL AB から標準の商用ライセンスを購入できます。 ライセンスポリシーの詳細については、http://www.mysql.com/company/legal/licensing/ を参照してください。'), (2, 'グループレプリケーション MySQL Group Replication (MGR) は、MySQL 公式が既存の Binlog レプリケーションフレームワーク上に、Paxos プロトコルに基づいて実装した分散レプリケーション形態です。 RDS MySQL クラスタシリーズインスタンスは、グループレプリケーションをサポートしています。 この記事では、レプリケーション方式をグループレプリケーションにする方法について説明します。 グループレプリケーションを使用した MySQL クラスタは、分散 Paxos プロトコルに基づいて自己管理でき、高いデータ信頼性とデータ整合性を備えています。 従来の主備レプリケーション方式と比較して、グループレプリケーションには、データの強整合性、データの強信頼性、グローバルトランザクションの強整合性という利点があります'); INSERT INTO embed(doc_id, content) VALUES (3, 'Microsoft SQL Server は、リレーショナルデータベース管理システム (RDBMS) です。 アプリケーションとツールは SQL Server インスタンスまたはデータベースに接続し、Transact-SQL (T-SQL) を使用して通信します。'), (3, 'SQL Server 2022 (16.x) は以前のバージョンに基づいて構築されており、SQL Server を開発言語、データ型、ローカルまたはクラウド環境、オペレーティングシステムオプションを提供するプラットフォームに発展させることを目的としています。'), (3, 'SQL Server はエンタープライズレベルのアプリケーションで広く使用されており、Excel や Power BI などの他の Microsoft 製品とシームレスに統合して、データ分析を容易にします');
マルチパスリコールを実行する
次の SQL 文を実行して、PostgreSQL の紹介 というクエリテキストを複数の方法で取得し、関連ドキュメントを類似度でソートします。
-- クエリ対象のテキスト。
WITH query AS (
SELECT 'PostgreSQL の紹介' AS query_text
),
-- 質問を埋め込みに変換します。 sk-**** を Alibaba Cloud ModelScope から取得した API キーに置き換えます。
query_embedding AS (
SELECT rds_embedding.get_embedding_by_model('dashscope', 'sk-****', query.query_text)::real[]::vector AS embedding
FROM query
),
-- ドキュメントキーワードに基づいて検索を実行し、ts_rank を使用して結果をソートします。 類似度が高いほどスコアが高くなります。
first_method AS (
SELECT
id,
title,
ts_rank(to_tsvector('jiebacfg', doc.key_word),
to_tsquery(replace(text(plainto_tsquery('jiebacfg', (SELECT query_text FROM query))), '&', '|'))) AS score,
'doc_key_word' AS method
FROM doc
WHERE
to_tsvector('jiebacfg', doc.key_word) @@
to_tsquery(replace(text(plainto_tsquery('jiebacfg', (SELECT query_text FROM query))), '&', '|'))
ORDER BY
score DESC
LIMIT 3
),
-- コンテンツキーワードに基づいて全文検索を実行し、RUM の <=> 演算子を使用して結果をソートします。 類似度が高いほどスコアが低くなります。
second_method AS (
SELECT
id,
doc_id,
content,
to_tsvector('jiebacfg', content) <=>
to_tsquery(replace(text(plainto_tsquery('jiebacfg', (SELECT query_text FROM query))), '&', '|')) AS score,
'content_key_word' AS method
FROM embed
WHERE
to_tsvector('jiebacfg', content) @@
to_tsquery(replace(text(plainto_tsquery('jiebacfg', (SELECT query_text FROM query))), '&', '|'))
ORDER BY
score
LIMIT 3
),
-- 埋め込みに基づいて全文検索を実行し、pgvector の <=> 演算子を使用して結果をソートします。 類似度が高いほどスコアが低くなります。
third_method AS (
SELECT
embed.id,
embed.doc_id,
embed.content,
embedding <=> (SELECT embedding FROM query_embedding LIMIT 1) AS score,
'embedding' AS method
FROM embed
ORDER BY score
LIMIT 3
)
-- 結合クエリを実行して、より多くのフィールド情報を取得します。
SELECT
first_method.title,
embed.id AS chunk_id,
SUBSTRING(embed.content FROM 1 FOR 30),
first_method.score,
first_method.method
FROM first_method
LEFT JOIN embed ON first_method.id = embed.doc_id
-- second_method フィールドの出力を結合します。
UNION
SELECT
doc.title,
second_method.id AS chunk_id,
SUBSTRING(second_method.content FROM 1 FOR 30),
second_method.score,
second_method.method
FROM second_method
LEFT JOIN doc ON second_method.doc_id = doc.id
-- third_method フィールドの出力を結合します。
UNION
SELECT
doc.title,
third_method.id AS chunk_id,
SUBSTRING(third_method.content FROM 1 FOR 30),
third_method.score,
third_method.method
FROM third_method
LEFT JOIN doc ON third_method.doc_id = doc.id
ORDER BY method, score;
出力:
title | chunk_id | substring | score | method
----------------+----------+--------------------------------------------------------------+----------------------+------------------
PostgreSQL紹介 | 3 | PostgreSQLは、最初のバークレーコードのオープンソースの後継です。 | 13.159472465515137 | content_key_word
PostgreSQL紹介 | 2 | PostgreSQLは、カリフォルニア大学バークレー校のコンピュータサイ | 16.4493408203125 | content_key_word
PostgreSQL紹介 | 4 | また、自由なライセンスにより、誰でも私用、商用、学術研究のい | 16.4493408203125 | content_key_word
PostgreSQL紹介 | 6 | 豊富なエコシステム: PostGIS (地理情報処理)、TimescaleDB | 0.020264236256480217 | doc_key_word
PostgreSQL紹介 | 5 | Ganos プラグインと PostGIS プラグインは、同じスキーマにインス | 0.020264236256480217 | doc_key_word
PostgreSQL紹介 | 3 | PostgreSQLは、最初のバークレーコードのオープンソースの後継です。 | 0.020264236256480217 | doc_key_word
PostgreSQL紹介 | 2 | PostgreSQLは、カリフォルニア大学バークレー校のコンピュータサイ | 0.020264236256480217 | doc_key_word
PostgreSQL紹介 | 4 | また、自由なライセンスにより、誰でも私用、商用、学術研究のい | 0.020264236256480217 | doc_key_word
PostgreSQL紹介 | 2 | PostgreSQLは、カリフォルニア大学バークレー校のコンピュータサイ | 0.2546271233144539 | embedding
PostgreSQL紹介 | 3 | PostgreSQLは、最初のバークレーコードのオープンソースの後継です。 | 0.28679098231865074 | embedding
PostgreSQL紹介 | 6 | 豊富なエコシステム: PostGIS (地理情報処理)、TimescaleDB | 0.41783296077761967 | embedding
関連情報
RAG における ApsaraDB RDS for PostgreSQL のベストプラクティスの詳細については、以下のトピックをご参照ください。