Amazon Bedrock で Advanced RAG を実装してみる

# はじめに

以前の記事では､「[Amazon Kendra と Amazon Bedrock で構成した RAG システムに対する Advanced RAG 手法の精度寄与検証](https://aws.amazon.com/jp/blogs/news/verifying-the-accuracy-contribution-of-advanced-rag-methods-on-rag-systems-built-with-amazon-kendra-and-amazon-bedrock/)」の検証記事をもとに､Command R/R+とClaude3.5 Sonnetを使って検索用クエリ生成を比較しました｡

https://qiita.com/revsystem/items/80f47289a6d0050d2df5

今回は､AWSの検証記事をもとにAdvanced RAG全体の再現実装を行ってみました｡
RAGは､[Backlogヘルプセンター](https://support-ja.backlog.com/hc/ja)の記事をダウンロードし､Knowledge Bases for Amazon Bedrockで構築しました。ベクトルストアは[Pinecone](https://www.pinecone.io/)を使用しています。

AWSの検証記事のより詳細な再現実装は @ren8k さんの以下の記事がとても参考になります｡

https://qiita.com/ren8k/items/dcdb7f0c61fda384c478

:::note info
この記事をほぼ書き終えたところで以下のアップデートが発表されました｡Knowledge Bases for Amazon BedrockでAdvanced RAGがサポートされたようです｡

[Knowledge Bases for Amazon Bedrock now supports advanced RAG capabilities](
https://aws.amazon.com/jp/about-aws/whats-new/2024/07/knowledge-bases-amazon-bedrock-advanced-rag-capabilities/)

これについて､[Knowledge Bases for Amazon BedrockでサポートされたAdvanced RAGを試す](
https://qiita.com/revsystem/items/10a6666ed9ca4a5923cb) で試してみました｡

:::


# 構成図

構成は以下のとおりです｡

![構成図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61809/0670a163-a9d8-e03c-f94f-17736713873a.png)

今回の実装では､以下のステップで検索処理を行いました｡
- Step 1: ユーザー入力テキストを基にクエリ拡張により検索用クエリーを生成する
- Step 2: ユーザー入力のクエリと生成した検索用クエリーを使って検索を実行し検索結果を得る
- Step 3: ユーザー入力のクエリ検索結果を基に応答テキストを生成する

なお､AWSの検証記事にある関連度評価は省略しました｡

# 参考情報
https://aws.amazon.com/jp/blogs/news/verifying-the-accuracy-contribution-of-advanced-rag-methods-on-rag-systems-built-with-amazon-kendra-and-amazon-bedrock/

https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages.html

https://qiita.com/ren8k/items/dcdb7f0c61fda384c478

https://support-ja.backlog.com/hc/ja

# 再現実装

## 変数の設定

実行する際は､以下の項目を実際の環境に合わせて入力します｡

|変数名|値|
|-----------|------------|
|KNOWLEDGEBASE_ID|構築したKnowledge BasesのKnowledge base ID|
|MODEL_ID|言語モデルのID|
|n_queries|生成する検索用クエリの数|
|numberOfResults|ベクトルストアから返される取得結果の最大数|
|use_search_query|クエリ拡張を行うか｡Falseの場合はinput_textのみで検索を行う｡|
|input_text|質問文など|

## 使用する言語モデル
コード内ではClaude 3.5 Sonnetを使用しています｡ 速度や費用の点からClaude 3 haikuも利用したいところですが､今回の実装ではhaikuを使った場合に生成されるクエリの単語数が少なく且つ多角的にならない､あるいは意図した形にならないなど不十分な点がありました｡そのため､Claude 3.5 Sonnetを使用しています｡

この点については､プロンプトや出力内容を工夫するよりもJSONモードを利用したほうが期待した結果を得ることができます｡JSONモードについても @ren8k さんの記事がとても参考になります｡

https://qiita.com/ren8k/items/3d5f66df251703b8407e#%E5%88%A9%E7%94%A8%E4%BE%8B-2%E3%82%AF%E3%82%A8%E3%83%AA%E6%8B%A1%E5%BC%B5


## クエリ拡張を行う場合
use_search_query が True の場合､(生成する検索用クエリの数(n_queries)+input_text) * ベクトルストアから返される取得結果の最大数(numberOfResults) のデータを使い回答を生成します｡例えば、n_queries=3, numberOfResults=5の場合は合計15件の検索結果から回答を生成します。

## クエリ拡張を行わない場合
input_textの1件 * ベクトルストアから返される取得結果の最大数(numberOfResults)のデータを使い回答を生成します｡例えば、numberOfResults=5の場合は5件の検索結果から回答を生成します。

## サンプルコード
```python:app.py
import json
import logging
from typing import Any, Dict, List

import boto3

logging.basicConfig(
    format="%(asctime)s [%(levelname)s] %(message)s",
    level=logging.INFO
)

logger = logging.getLogger(__name__)

bedrock_agent_client = boto3.client("bedrock-agent-runtime")
bedrock_client = boto3.client("bedrock-runtime")

KNOWLEDGEBASE_ID = "ナレッジベースID"
MODEL_ID = "anthropic.claude-3-5-sonnet-20240620-v1:0"


def create_search_query(input_text: str) -> Dict[str, Any]:
    """
    ユーザーの入力に基づいて最適化された検索用クエリを生成する。

    Args:
        input_text (str): ユーザーの入力クエリ

    Returns:
        Dict[str, Any]: 生成されたレスポンスボディ

    Raises:
        ValueError: レスポンスのボディが空または無効なJSONの場合
    """
    n_queries = 3
    system_instruction = _create_system_instruction(n_queries)
    request_body = _create_request_body(system_instruction, input_text)
    response = _invoke_bedrock_model(request_body, MODEL_ID)
    return json.loads(response["body"].read())


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

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

    生成されたクエリは、<format>タグ内のフォーマットに従って出力してください。

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

    </example>

    <format>
    for文でクエリを取得できるようカンマで区切ってください｡
    クエリには改行コードを含めないでください｡
    生成されたクエリ以外の内容は出力しないでください｡
    </format>
    '''


def _create_request_body(system_instruction: str, input_text: str) -> Dict[str, Any]:
    return {
        "anthropic_version": "bedrock-2023-05-31",
        "max_tokens": 500,
        "system": system_instruction,
        "messages": [
            {
                "role": "user",
                "content": input_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,
    )


def retrieve_results_from_knowledge_base(search_queries: Dict[str, Any], input_text: str) -> List[Dict[str, Any]]:
    """
    Knowledge baseから検索結果を取得する。

    Args:
        search_queries (Dict[str, Any]): 検索用クエリ
        input_text (str): ユーザーの入力クエリ

    Returns:
        List[Dict[str, Any]]: 検索結果のリスト
    """
    retrieval_results = []

    if search_queries == {}:  # 検索用クエリが存在しない場合
        query_texts = [input_text]
    else:
        query_texts = search_queries["content"][0]['text'].split(',') + [input_text]

    for query_text in query_texts:
        if not query_text:
            continue

        response = bedrock_agent_client.retrieve(
            knowledgeBaseId=KNOWLEDGEBASE_ID,
            retrievalQuery={"text": query_text},
            retrievalConfiguration={
                "vectorSearchConfiguration": {"numberOfResults": 5}
            },
        )
        logging.info("search_query: %s", query_text)
        logging.debug("response: %s", response)

        retrieval_results.extend(response['retrievalResults'])

    return retrieval_results


def _create_prompt_template(context_str: str) -> str:
    return f'''
    あなたは親切で知識豊富なチャットアシスタントです。
    <excerpts>タグには、ユーザーが知りたい情報に関連する複数のドキュメントの抜粋が含まれています。
    これらの情報をもとに、ユーザーの質問に対する回答を提供してください。

    <excerpts>
    {context_str}
    </excerpts>

    まず、質問に対して<excerpts>タグ内にある情報で答えられるかを考え、<related>true</related>、
    もしくは、<related>false</related>の形式で答えてください。
    質問に答えるための情報がない場合は、「情報が不十分で回答できません」と答えてください。

    また、質問への回答は以下の点に留意してください:
    - <excerpts>タグの内容を参考にするが、回答に<excerpts>タグを含めないこと。
    - 日本語で回答すること。
    - 質問への回答は<answer></answer>タグに含めること。
    '''


def get_response_text(input_text: str, context_str) -> str:
    """
    指定されたクエリとコンテキスト文字列に基づいて、レスポンステキストを取得する。

    Args:
        input_text (str): ユーザーの入力クエリ
        context_str (str): ユーザーが知りたい情報に関連する複数のドキュメントの抜粋

    Returns:
        str: レスポンスボディ
    """
    prompt_template = _create_prompt_template(context_str)
    request_body = {
        "anthropic_version": "bedrock-2023-05-31",
        "max_tokens": 3072,
        "system": prompt_template,
        "messages": [
            {
                "role": "user",
                "content": input_text,
            },
        ],
        "temperature": 0,
    }

    logger.info("context_length: %s", len(context_str))
    response = _invoke_bedrock_model(request_body, MODEL_ID)
    response_body = json.loads(response["body"].read())
    return response_body["content"][0]["text"]


def main():
    use_search_query = True
    input_text = "ガントチャートとはどのようなものですか? プロジェクト管理での利用方法を教えてください。"
    logging.info("origin_query: %s", input_text)

    if use_search_query:
        # Step 1: ユーザー入力テキストを基に検索用クエリーを生成する
        search_queries = create_search_query(input_text)
    else:
        search_queries = {}

    # Step 2: ユーザー入力のクエリと生成した検索用クエリーで検索を実行し検索結果を得る
    retrieval_results = retrieve_results_from_knowledge_base(search_queries, input_text)

    # Step 3: ユーザー入力のクエリ検索結果を基に応答テキストを生成する
    answer = get_response_text(input_text, retrieval_results)

    logging.info('\n\n%s', "*" * 80)
    print(answer)


if __name__ == "__main__":
    main()
```

# Advanced RAGの比較
いくつかの質問を投げ、クエリ拡張の有無で結果を比較しました。temperature=0として回答のランダム性を抑えるようにしていますが、それでも毎回同じ回答が得られるとは限らないためここでは回答の一例として紹介します。

## ｢孫課題をつくることはできますか?｣
クエリ拡張の有無にかかわらず同じ内容の回答が得られました｡

### クエリ拡張なし
```terminal
2024-07-10 15:14:31,982 [INFO] origin_query: 孫課題をつくることはできますか?
2024-07-10 15:14:33,517 [INFO] search_query: 孫課題をつくることはできますか?
2024-07-10 15:14:33,517 [INFO] context_length: 5
2024-07-10 15:14:41,930 [INFO] 

********************************************************************************
<related>true</related>

<answer>
Backlogでは直接的に孫課題（三階層目の課題）を作成することはできません。しかし、擬似的に三階層で管理する方法が2つあります：

1. カテゴリーまたはマイルストーンを使用する方法：
   - 第一階層：カテゴリー（またはマイルストーン）
   - 第二階層：親課題
   - 第三階層：子課題

2. チェックリストを使用する方法：
   - 第一階層：親課題
   - 第二階層：子課題
   - 第三階層：子課題内のチェックリスト

これらの方法を使うことで、三階層の管理構造を模倣することができます。ただし、正式な「孫課題」機能はBacklogには実装されていないことに注意してください。
</answer>
```

### クエリ拡張あり
```terminal
2024-07-10 15:18:01,083 [INFO] origin_query: 孫課題をつくることはできますか?
2024-07-10 15:18:05,742 [INFO] search_query: 孫課題の作成 タスク管理システム
2024-07-10 15:18:06,324 [INFO] search_query: サブタスク 階層構造 プロジェクト管理ツール
2024-07-10 15:18:06,985 [INFO] search_query: 孫タスク ワークフロー 細分化 タスク管理アプリ機能
2024-07-10 15:18:07,464 [INFO] search_query: 孫課題をつくることはできますか?
2024-07-10 15:18:07,465 [INFO] context_length: 20
2024-07-10 15:18:17,534 [INFO] 

********************************************************************************
<related>true</related>

<answer>
Backlogでは直接孫課題を作ることはできません。Backlogの親子課題機能は2階層（親課題と子課題）までしかサポートしていません。

ただし、擬似的に3階層の管理を行う方法が2つあります：

1. カテゴリーやマイルストーンを使用する方法：
   - 第一階層：カテゴリー（もしくはマイルストーン）
   - 第二階層：親課題
   - 第三階層：子課題

2. チェックリストを使用する方法：
   - 第一階層：親課題
   - 第二階層：子課題
   - 第三階層：子課題内のチェックリスト

これらの方法を使うことで、3階層に近い管理を行うことができます。ただし、これらは正式な「孫課題」機能ではなく、あくまでも擬似的な対応策であることに注意してください。
</answer>
```

## ｢支払い方法を変更するための手続きを教えてください。｣
いずれの場合も同じ内容の回答が得られました｡クエリ拡張ありの場合は､注意点を末尾にまとめており､可読性が向上しています｡

### クエリ拡張なし
```terminal
2024-07-10 15:19:58,298 [INFO] origin_query: 支払い方法を変更するための手続きを教えてください。
2024-07-10 15:19:59,622 [INFO] search_query: 支払い方法を変更するための手続きを教えてください。
2024-07-10 15:19:59,623 [INFO] context_length: 5
2024-07-10 15:20:13,747 [INFO] 

********************************************************************************
<related>true</related>

<answer>
支払い方法を変更するための手続きは、ご利用のプランによって異なります。以下に新プランとクラシックプランの場合の手順を説明します。

1. 新プランをご利用の場合:
   - 契約管理者のアカウントでのみ変更が可能です。
   - 組織設定 > 契約 > 支払い方法と支払い期間 から変更できます。
   - 選択可能な支払い方法:
     * 銀行振込 (3・6・12ヶ月)
     * クレジットカード（1・12ヶ月)
   - 変更は次回更新分から適用されます。

2. クラシックプランをご利用の場合:
   - スペースオーナーのアカウントでのみ変更が可能です。
   - スペース設定画面から変更手続きを行います。
   - 選択可能な支払い方法:
     * 銀行振込 (3・6・12ヶ月)
     * 口座振替 (1ヶ月)
   - クレジットカード払い (1・12ヶ月)をご希望の場合は、ダッシュボード表示の「移行の開始」リンクから手続きを行います。
   - 変更は次回更新分から適用されます。

なお、支払い方法の変更の反映には数日かかる場合があります。また、すでにお支払い待ちの請求がある場合は変更できませんのでご注意ください。
</answer>
```

### クエリ拡張あり
```terminal
2024-07-10 15:21:18,692 [INFO] origin_query: 支払い方法を変更するための手続きを教えてください。
2024-07-10 15:21:24,323 [INFO] search_query: 支払い方法変更手続き クレジットカード 銀行口座
2024-07-10 15:21:24,925 [INFO] search_query: 請求 支払い方法 変更手順 アカウント設定 update payment method
2024-07-10 15:21:25,553 [INFO] search_query: 支払い設定 変更方法 クレジットカード情報 更新 billing information
2024-07-10 15:21:26,154 [INFO] search_query: 支払い方法を変更するための手続きを教えてください。
2024-07-10 15:21:26,155 [INFO] context_length: 20
2024-07-10 15:21:40,817 [INFO] 

********************************************************************************
<related>true</related>

<answer>
支払い方法を変更するための手続きは、ご利用のプランによって異なります。

新プランをご利用の場合:
1. 契約管理者のアカウントでログインします。
2. 組織設定 > 契約 > 支払い方法と支払い期間 の順に進みます。
3. 変更したい支払い方法を選択し、登録します。
4. 選択可能な支払い方法は、銀行振込(3・6・12ヶ月)またはクレジットカード(1・12ヶ月)です。

クラシックプランをご利用の場合:
1. スペースオーナーのアカウントでログインします。
2. スペース設定 > 契約 > 支払方法 の順に進みます。
3. 変更したい支払い方法を選択し、登録します。
4. 選択可能な支払い方法は、銀行振込(3・6・12ヶ月)または口座振替(1ヶ月)です。

注意点:
- 有料プランのみ設定が可能です。
- すでにお支払い待ちの請求がある場合は変更できません。
- 支払方法の変更の反映まで数日ほどかかることがあります。
- 変更は次回更新分より適用されます。

クレジットカード払いを希望する場合は、クラシックプランからの移行が必要です。その場合は、ダッシュボード表示の「移行の開始」リンクから手続きを行ってください。
</answer>
```


## ｢ガントチャートとはどのようなものですか? プロジェクト管理での利用方法を教えてください。｣
いずれの場合も同じ内容の回答が得られました｡クエリ拡張ありの場合は､なしの場合と比較し箇条書きで要点をまとめており全体的に情報が整理されている印象です｡

### クエリ拡張なし
```terminal
2024-07-10 15:23:47,508 [INFO] origin_query: ガントチャートとはどのようなものですか? プロジェクト管理での利用方法を教えてください。
2024-07-10 15:23:49,027 [INFO] search_query: ガントチャートとはどのようなものですか? プロジェクト管理での利用方法を教えてください。
2024-07-10 15:23:49,028 [INFO] context_length: 5
2024-07-10 15:24:08,115 [INFO] 

********************************************************************************
<related>true</related>

<answer>
ガントチャートは、プロジェクト管理において非常に重要なツールです。以下にガントチャートの概要と利用方法について説明します：

1. ガントチャートの概要：
   ガントチャートは、プロジェクトの計画と進捗を視覚的に表現するためのチャートです。横軸に時間、縦軸に課題や作業項目を配置し、各課題の開始日、期間、終了日を棒グラフで表示します。これにより、プロジェクト全体の進行状況を一目で把握することができます。

2. プロジェクト管理での利用方法：
   a. 課題の可視化：
      ガントチャートを使用することで、プロジェクト内の全ての課題とその期間を視覚的に表現できます。これにより、チームメンバーは各自の担当タスクと全体の進捗を容易に理解できます。

   b. スケジュール管理：
      課題の開始日、期限日を設定し、ガントチャート上で表示することで、プロジェクトのスケジュールを効果的に管理できます。

   c. 進捗管理：
      ガントチャート上で課題の状態や進捗を更新することで、リアルタイムでプロジェクトの進行状況を把握できます。

   d. リソース配分：
      担当者ごとに課題を表示することで、各メンバーの作業負荷を確認し、適切なリソース配分を行うことができます。

   e. 依存関係の把握：
      課題間の依存関係を表示することで、タスクの順序や影響を理解し、効率的なプロジェクト管理が可能になります。

   f. コミュニケーション促進：
      ガントチャートを用いてプロジェクトの状況を共有することで、チーム内のコミュニケーションを促進し、問題の早期発見や解決につながります。

Backlogのようなプロジェクト管理ツールでは、ガントチャート機能が提供されており、課題の絞り込み、担当者や状態の変更、親子課題のグルーピングなど、さまざまな機能を活用してプロジェクトを効果的に管理することができます。
</answer>
```

### クエリ拡張あり
```terminal
2024-07-10 15:25:10,089 [INFO] origin_query: ガントチャートとはどのようなものですか? プロジェクト管理での利用方法を教えてください。
2024-07-10 15:25:15,389 [INFO] search_query: ガントチャート プロジェクト管理 タスク スケジュール 可視化
2024-07-10 15:25:16,010 [INFO] search_query: Gantt chart project timeline visualization tasks dependencies
2024-07-10 15:25:16,556 [INFO] search_query: プロジェクトマネジメント ガントチャート 作成方法 活用事例 利点
2024-07-10 15:25:17,185 [INFO] search_query: ガントチャートとはどのようなものですか? プロジェクト管理での利用方法を教えてください。
2024-07-10 15:25:17,186 [INFO] context_length: 20
2024-07-10 15:25:38,735 [INFO] 

********************************************************************************
<related>true</related>

<answer>
ガントチャートは、プロジェクト管理において非常に重要なツールです。以下にガントチャートの概要と利用方法を説明します：

1. ガントチャートの概要：
   ガントチャートは、プロジェクトの課題やタスクのスケジュールを視覚的に表現するチャートです。横軸に時間、縦軸に課題を配置し、各課題の開始日、期間、終了日を棒グラフで表示します。

2. プロジェクト管理での利用方法：
   a. スケジュール管理：
      - 課題の開始日、期限日を設定し、プロジェクト全体の進捗を可視化します。
      - マイルストーンを設定することで、プロジェクトの重要な節目を明確にできます。

   b. タスクの関連性の把握：
      - 親子課題を表示することで、大きなタスクとその下位タスクの関係を理解できます。
      - 課題間の依存関係を把握し、効率的なスケジュール管理が可能になります。

   c. リソース配分：
      - 担当者ごとのタスクを確認し、適切な作業量の配分ができます。
      - チーム全体の作業バランスを調整するのに役立ちます。

   d. 進捗管理：
      - 実際の進捗状況をガントチャート上で更新し、計画との差異を視覚的に確認できます。
      - 遅延や問題が発生している箇所を早期に特定し、対策を講じることができます。

   e. コミュニケーション支援：
      - プロジェクトの状況を関係者と共有する際の有効なツールとなります。
      - 会議などでプロジェクトメンバーと進捗を確認しながら調整できます。

3. Backlogでのガントチャート機能：
   - 課題の絞り込み：種別、カテゴリー、マイルストーン、担当者で課題を絞り込んで表示できます。
   - 簡単な編集：ガントチャート上で直接、担当者や状態を変更できます。
   - グルーピング表示：親子課題やカテゴリー、マイルストーンでグルーピングして表示できます。

ガントチャートを効果的に活用することで、プロジェクトの見通しを良くし、効率的な管理が可能になります。
</answer>
```

## ｢バーンダウンチャートとは何ですか？ どのように使用しますか？｣
感覚的な物かも知れませんが､クエリ拡張なしのほうが`3. 使用方法`について丁寧に整理されている印象です｡

### クエリ拡張なし
```terminal
2024-07-10 15:41:21,592 [INFO] origin_query: バーンダウンチャートとは何ですか？ どのように使用しますか？
2024-07-10 15:41:22,848 [INFO] search_query: バーンダウンチャートとは何ですか？ どのように使用しますか？
2024-07-10 15:41:22,848 [INFO] context_length: 5
2024-07-10 15:41:43,802 [INFO] 

********************************************************************************
<related>true</related>

<answer>
バーンダウンチャートは、プロジェクト管理において非常に有用なツールです。以下にその概要と使用方法を説明します：

1. バーンダウンチャートの定義：
バーンダウンチャートは、「期限までに全ての作業を消化できるのか？」を一目で確認できるグラフです。縦軸に「作業量」、横軸に「時間」を割り当て、残りの作業量をグラフ表示します。時間が経過するにつれて作業量が減少するため、通常は右肩下がりのグラフになります。

2. チャートの構成要素：
バーンダウンチャートには3つの主要な線があります：
- 実績線：実際の進捗を示し、その日時点での残りの作業量を表します。
- 計画線：課題に設定された「期限日」と「予定時間」に基づいて表示されます。
- 理想線：全作業量を期間で平均した理想的な進捗を示します。

3. 使用方法：
a) チャートの有効化：
   - プロジェクトの基本設定で「チャートを使用する」を有効にします。
   - スタンダードプラン以上のプランで使用可能です。

b) 期間の設定：
   - マイルストーンの「開始日」と「終了日」を設定します。
   - 推奨期間は1週間〜1ヶ月半程度です。

c) 課題の計画反映：
   - 課題登録時に「マイルストーン」「期限日」「予定時間」を入力します。
   - これらの情報が計画線に反映されます。

d) 進捗の反映：
   - 課題を完了すると、設定された「予定時間」分だけ実績線が下がります。
   - 正確なチャートのために、「予定時間」の入力を推奨します。

4. チャートの解釈：
- 実績線が計画線より下にある場合、プロジェクトは予定通りに進行しています。
- 実績線が計画線より上にある場合、プロジェクトに遅れが生じています。

バーンダウンチャートを効果的に使用することで、プロジェクトの進捗を視覚的に把握し、必要に応じて計画を調整することができます。
</answer>
```

### クエリ拡張あり
```terminal
2024-07-10 15:44:22,101 [INFO] origin_query: バーンダウンチャートとは何ですか？ どのように使用しますか？
2024-07-10 15:44:27,163 [INFO] search_query: バーンダウンチャート スクラム アジャイル 進捗管理 可視化
2024-07-10 15:44:27,984 [INFO] search_query: Burndown chart project management 残作業量 時系列 グラフ
2024-07-10 15:44:28,592 [INFO] search_query: プロジェクト管理 バーンダウングラフ 作業進捗 予測 実績比較
2024-07-10 15:44:29,190 [INFO] search_query: バーンダウンチャートとは何ですか？ どのように使用しますか？
2024-07-10 15:44:29,191 [INFO] context_length: 20
2024-07-10 15:44:49,963 [INFO] 

********************************************************************************
<related>true</related>

<answer>
バーンダウンチャートは、プロジェクトの進捗状況を視覚的に表現するグラフツールです。以下にその概要と使用方法を説明します：

1. バーンダウンチャートの定義：
   - 「期限までに全ての作業を消化できるのか？」を一目で確認できるグラフです。
   - 縦軸に「作業量」、横軸に「時間」を割り当て、残りの作業量をグラフ表示します。
   - 時間が進むにつれて作業量が減少するため、右肩下がりのグラフになります。

2. チャートの構成要素：
   - 実績線：その日時点での残りの作業量を表します。
   - 計画線：課題に設定された「期限日」と「予定時間」をもとに表示されます。
   - 理想線：全作業量を期間で平均した理想的な進捗を示します。

3. 使用方法：
   - プロジェクトの基本設定で「チャートを使用する」を有効にします。
   - マイルストーンの「開始日」と「終了日」を設定します（推奨期間は1週間〜1ヶ月半程度）。
   - 課題登録時に「マイルストーン」「期限日」「予定時間」を入力します。
   - 課題が完了すると、設定された「予定時間」分だけ実績線が下がります。

4. 活用のポイント：
   - 正確なチャート表示のために、課題ごとに「予定時間」を入力することが推奨されます。
   - 「予定時間」未入力の場合、デフォルトで1時間として計算されます。
   - プロジェクトホームのバーンダウンチャートをクリックすると、拡大表示が可能です。

バーンダウンチャートを効果的に使用することで、プロジェクトの進捗状況を可視化し、計画と実績の差異を容易に把握することができます。
</answer>
```


## ｢Backlogにデータをインポートする方法を教えてください。｣
Backlogでは､APIやインテグレーション(Google スプレッドシート)を介してデータをインポートすることができます｡ヘルプセンターには以下のページで案内があります｡

- [CSV から課題を追加することができますか？](https://support-ja.backlog.com/hc/ja/articles/360036149513)
- [複数の課題をまとめて登録することはできますか？
](https://support-ja.backlog.com/hc/ja/articles/360036149493)
- [他の管理ツールから Backlog へデータを移行できますか？](https://support-ja.backlog.com/hc/ja/articles/360035644794)
- [Subversion をインポートできますか?](https://support-ja.backlog.com/hc/ja/articles/360035645334)

クエリ拡張なしの場合は､`<related>false</related>`となり､上記の情報は利用されず回答が得られませんでした｡一方､クエリ拡張ありの場合はSubversionのインポートに関する情報を回答し､加えてAPIやインテグレーションについての案内が得られました｡この質問については､回答精度に明らかな違いを観測することができました｡

### クエリ拡張なし
```terminal
2024-07-10 15:56:30,469 [INFO] origin_query: Backlogにデータをインポートする方法を教えてください。
2024-07-10 15:56:32,015 [INFO] search_query: Backlogにデータをインポートする方法を教えてください。
2024-07-10 15:56:32,016 [INFO] context_length: 4
2024-07-10 15:56:38,416 [INFO] 

********************************************************************************
<related>false</related>

<answer>
申し訳ありませんが、提供された情報の中にBacklogへのデータインポート方法に関する具体的な説明がありません。与えられた情報は主にBacklogサーバーの移行手順、社外メンバーの招待方法、カレンダーソフトへの予定の取り込み方法に関するものです。Backlogへのデータインポート方法については、別の情報源を参照する必要があります。
</answer>
```

### クエリ拡張あり
```terminal
2024-07-10 15:56:56,941 [INFO] origin_query: Backlogにデータをインポートする方法を教えてください。
2024-07-10 15:57:01,448 [INFO] search_query: Backlog データインポート 方法
2024-07-10 15:57:02,066 [INFO] search_query: バックログ import データ移行 プロジェクト管理
2024-07-10 15:57:02,637 [INFO] search_query: Backlog データ取り込み CSV Excel API インポート機能
2024-07-10 15:57:03,221 [INFO] search_query: Backlogにデータをインポートする方法を教えてください。
2024-07-10 15:57:03,222 [INFO] context_length: 17
2024-07-10 15:57:17,714 [INFO] 

********************************************************************************
<related>true</related>

<answer>
Backlogにデータをインポートする方法については、以下の情報が得られました：

1. CSVからの課題の一括追加：
   残念ながら、CSVから直接課題を追加する機能はBacklogには用意されていません。代替手段として、APIやインテグレーションの利用が提案されています。

2. Subversionリポジトリのインポート：
   Subversionのリポジトリデータをインポートすることは可能ですが、これは有料オプションとして提供されています。料金は1リポジトリにつき33,000円（税込）です。インポート作業は以下の手順で行われます：
   - お客様がダンプデータを用意する（または、Backlogからの移行の場合は弊社でデータ抽出可能）
   - 弊社側でインポート作業を実施

3. その他のデータインポート：
   質問に対する直接的な回答はありませんが、他のタイプのデータ（例：Git、課題、Wiki等）のインポートについては明確な情報がありません。それぞれのデータタイプに応じて、異なる方法やオプションがある可能性があります。

インポートの詳細な方法や、他のデータタイプのインポートについては、Backlogのサポートに直接問い合わせることをお勧めします。
</answer>
```

# まとめ
クエリ拡張の有無により、回答内容は以下のように分類できました。

- case 1: クエリ拡張を行わなかった場合に、質問に関する情報を検索できない
- case 2: クエリ拡張を行わなかったほうが回答内容の情報量が多く、質問者の助けになっている
- case 3: クエリ拡張の有無にかかわらず回答内容がほぼ同一
- case 4: クエリ拡張を行うことで､正しい回答が得られる

case2はクエリ拡張の結果として不正確ではないものの情報不足が観測されました。質問内容や生成された検索用クエリ、あるいは参照した記事データの情報量に課題があるのかもしれません。[AWSの検証記事](https://aws.amazon.com/jp/blogs/news/verifying-the-accuracy-contribution-of-advanced-rag-methods-on-rag-systems-built-with-amazon-kendra-and-amazon-bedrock/)でもクエリ拡張で`一部正確 (情報不足)`という結果が観測されているため、想定通りと言えるかもしれません。また､case 4のようにクエリ拡張を行うことで正しい回答を得られることもあり得るため､全体的にクエリ拡張は有効に機能していると言えそうです｡