見出し画像

Amazon BedrockでCommand R/RとClaude3.5 Sonnetのそれぞれで拡張クエリを試す


はじめに

前回の記事ではCommand R/R+を使って検索クエリの生成(クエリ拡張)を試しました。

今回は以下の処理のうちStep1の部分に着目します。Command R/R+のsearch_queries_only: True を指定した場合と同様の検索クエリ生成をClaude3.5 Sonnetを利用して実装し、出力を比較します。

  • Step 1: 関連するドキュメントを見つけるための検索クエリを生成

  • Step 2: 生成された検索クエリを使用して、外部データ ソースから関連ドキュメントを取得

  • Step3: 取得したドキュメントを使用してインライン引用を含む応答を生成

クエリ拡張の実装

Command R/R+

search_queries_only: True を指定して、クエリ拡張を行います。入力テキストの内容に応じて検索クエリーが生成されます。生成した検索クエリをprint()で出力します。ここでは、モデルにCommand Rを指定しています。

MODEL_ID_SEARCH_QUERY = "cohere.command-r-v1:0"

def create_search_query_commandr(input_text: str):
    request_body =  {
        "message": input_text,
        "search_queries_only": True, # 検索クエリーのみを生成する
        "max_tokens": 500,
        "temperature": 0,
    }
    response = _invoke_bedrock_model(request_body, MODEL_ID_SEARCH_QUERY)
    response_body = json.loads(response["body"].read())
    search_queries = response_body["search_queries"]

    print("\n" + "*" * 80)
    print("Command Rの検索クエリ:")

    for query in search_queries:
        query_text = query.get("text")
        print(query_text)

def _invoke_bedrock_model(request_body: Dict[str, Any], model_id: str) -> Dict[str, Any]:
    return bedrock_client.invoke_model(
        body=json.dumps(request_body),
        contentType="application/json",
        accept="application/json",
        modelId=model_id,
    )

Claude3.5 Sonnet

Command R/R+の場合と異なり、生成する検索クエリの数やフォーマットはプロンプトで制御します。プロンプトは、AWSの検証記事に掲載されているも
のを参考にしました。

response_bodyに検索クエリが含まれるので、それを取り出しprint()で出力します。

MODEL_ID = "anthropic.claude-3-5-sonnet-20240620-v1:0"

def create_search_query_claude(input_text: str):
    # 生成する検索クエリの数
    n_queries = 3
    # 検索クエリの生成するためのプロンプト
    system_instruction = _create_system_instruction(n_queries)
    request_body = {
        "anthropic_version": "bedrock-2023-05-31",
        "max_tokens": 500,
        "temperature":0,
        "system": system_instruction,
        "messages": [
            {
                "role": "user",
                "content": input_text,
            },
        ],
    }
    response = _invoke_bedrock_model(request_body, MODEL_ID)
    response_body = json.loads(response["body"].read())
    search_queries = response_body["content"][0]['text'].split(',')

    print("\n" + "*" * 80)
    print("Cloude 3.5 Sonnetの検索クエリ:")

    for query_text in search_queries:
        print(query_text)


def _create_system_instruction(n_queries: int) -> str:
    return f'''
    検索エンジンに入力するクエリを最適化し、様々な角度から検索を行うことで、より適切で幅広い検索結果が得られるようにします。
    具体的には、類義語や日本語と英語の表記揺れを考慮し、多角的な視点からクエリを生成します。

    ユーザーの入力した質問文に基づいて、{n_queries}個の検索用クエリを生成してください。
    <example>タグ内にあるように、各検索用クエリは30トークン以内とし、日本語と英語を適切に混ぜて使用することで、広範囲の文書が取得できるようにしてください。

    生成されたクエリは、<format>タグ内のフォーマットに従って出力してください。
    <format>タグの内容を参考にするが、回答に<format>タグを含めないこと。

    <example>
    question: Knowledge Bases for Amazon Bedrock ではどのベクトルデータベースを使えますか?
    query 1: Knowledge Bases for Amazon Bedrock vector databases engine DB
    query 2: Amazon Bedrock ナレッジベース ベクトルエンジン vector databases DB
    query 3: Amazon Bedrock RAG 検索拡張生成 埋め込みベクトル データベース エンジン
    </example>

    <format>
    for文でクエリを取得できるようカンマで区切ってください。
    クエリには改行コードを含めないでください。
    クエリ以外の文章を含めないでください。
    </format>
    '''


def _invoke_bedrock_model(request_body: Dict[str, Any], model_id: str) -> Dict[str, Any]:
    return bedrock_client.invoke_model(
        body=json.dumps(request_body),
        contentType="application/json",
        accept="application/json",
        modelId=model_id,
    )

実装例

コード全体は以下の記事に掲載しています。

出力結果の比較

"代表的なLLMを列挙し、それぞれの特徴を箇条書きで列挙してください。"という入力を行い、出力結果を比較しました。結果は以下のとおりです。
Command Rの場合は、LLMの種類と特徴 という短い語句が出力されたのに対し、Claude3.5 Sonnetの場合はプロンプトに従い3つの検索クエリが生成されました。入力文をもとに類似する単語(日英)が並んでいます。

origin_query: 代表的なLLMを列挙し、それぞれの特徴を箇条書きで列挙してください。

********************************************************************************
Command Rの検索クエリ:
LLMの種類と特徴

********************************************************************************
Cloude 3.5 Sonnetの検索クエリ:
LLM 代表的 特徴 比較
大規模言語モデル 種類 特徴 list
AI language models comparison features GPT-4 PaLM LLaMA

Command Rの場合、モデルに cohere.command-r-v1:0 を指定しました。Command R+ (cohere.command-r-plus-v1:0)を指定すれば出力結果が豊かになるかと期待しましたが、結果は 代表的なLLM というさらに短い語句が出力されました。これらの検索クエリをつかって検索を行った場合、Cloude 3.5 Sonnetで生成したもののほうが検索精度が良さそうです。

Command R/R+を使ったクエリ拡張は、実装が手軽であるものの期待するような検索精度の向上には今一歩届かないという印象でした。

まとめ

前回の記事ではCommand R/R+で生成した検索クエリをAdvanced RAGに応用できそうだと書きましたが、検索精度を考えるとsearch_queries_onlyオプションを使わずに自前で実装したほうがよいという印象でした。
Command R/R+の使い道は検索クエリ生成だけではないので、もっと便利な使い方があると思います。


この記事が気に入ったらサポートをしてみませんか?