Guardrails for Amazon Bedrockのハルシネーション検出(contextual grounding check)を試してみた
こんにちは、つくぼし(tsukuboshi0755)です!
以下のアップデートにより、Guardrails for Amazon Bedrockにハルシネーションを検出できる機能が追加されました。
今回はこちらのアップデートについて、具体的に何ができるようになったか解説していきます!
今回のアップデート内容
今回のGuardrails for Amazon Bedrockにおけるアップデート内容は、以下の公式ブログでも解説があります。
特に目玉となるのが、ハルシネーションを検出できると謳われているcontextual grounding check機能です。
この機能では、フィルター基準として現状以下の2つが用意されています。
- Grounding
- Content(モデルからの応答)がGrounding source(参照ソースから提供される情報)とどの程度関連しているかを表す
- 回答の内容が根拠に基づいていない場合が該当します
- Relevance
- Content(モデルからの応答)がQuery(ユーザーからの質問)とどの程度関連しているかを表す
- 質問の意図を読み取って回答できていない場合が該当します
contextual grounding check機能を使用する場合は、上記いずれかの基準を設定したガードレールを作成します。
このガードレールをQuery、Grounding source、Content要素を渡して呼び出す事で、設定されたいずれかまたは両方の基準の信頼スコアが0~0.99の間で計算されます。
この信頼スコアが高いほど、選択したフィルター基準における2つの要素の関連性が高いと判断されます。
例えばQuery(ユーザーからの質問)とGrounding source(参照ソースから提供される情報)を以下とします。
- Query
日本で一番高い山はなんですか?
- Grounding Source
日本で一番高い山:富士山 | アメリカで一番高い山:マッキンリー山
その場合、Content(モデルからの応答)の例に対して、Grounding及びRelevanceの信頼スコアはそれぞれ以下のように計算される傾向にあります。
Contentの例 | Grounding | Relevance |
---|---|---|
日本で一番高い山は富士山です。 | 高くなりやすい | 高くなりやすい |
日本で一番高い山はマッキンリー山です。 | 低くなりやすい | 高くなりやすい |
アメリカで一番高い山はマッキンリー山です。 | 高くなりやすい | 低くなりやすい |
アメリカで一番高い山は富士山です。 | 低くなりやすい | 低くなりやすい |
そして上記で計算される信頼スコアが、ユーザーが設定した閾値を下回った場合に、2つの要素の関連性が低いためハルシネーションとして検出されたと判定される仕組みになっています。
上記の仕組みの詳細については以下のドキュメントにも記載がありますので、別途ご参照ください。
なお信頼スコアはQuery、Grounding source、Contentの内容によって大きく変わるため、ユーザー側で事前検証頂いた後に閾値を設定頂くのが良さそうです。
試してみた
構成図
今回のcontextual grounding check機能は、特にRAGにおいてハルシネーションが生じていないかを確認するべく、Groundingの信頼スコアをチェックするパターンが一般的かと想定されます。
そこで以下の構成で、contextual grounding check機能を用いてGroundingの信頼スコアをチェックし、設定した閾値に達しない場合はハルシネーションと判定するようにします。
上記構成を構築するため、SAMを使用してLambda関数を作成し、RetrieveAndGenerate API及びApplyGuardrail APIを呼び出すようにします。
サンプルコード
今回使用するサンプルコードは以下のリポジトリにて公開していますので、適宜ご参照ください。
なおガードレールのバージョンが現状CloudFormationに対応していないため、別途Lambda-backend Custom Resourceでバージョンを作成するようにしています。
Guardrails for Amazon BedrockにおけるCloudFormationの詳細については、以下をご参照ください。
処理内容解説
先に示した構成図にもある通り、以下の順番で処理を実施します。
①RetrieveAndGenerate APIにQueryを渡して実行
②RetrieveAndGenerate APIのレスポンスから、Grounding source及びContentを抽出
③ApplyGuardrail APIにQuery, Grounding source, Contentを渡して実行
まず①では、今回ナレッジベースのリソースなしで簡単にRAGを試したいため、Knowledge Bases for Amazon BedrockにおけるChat with your document機能を使用します。
Chat with your document機能を利用するため、今回はバージニアリージョンで環境構築します。
本機能の詳細は、以下の記事をご参照ください。
今回はQuery内容をquery.txt
、RAGのソースとなるPDFファイルをdocument.pdf
として指定しています。
上記ファイルは両者とも同名ファイルであれば差し替え可能ですので、必要に応じてご自身の環境に合わせて内容を変更してください。
今回は以下のような内容とします。
- Query
これはサンプルです会社の従業員数を教えてください
- PDFファイル
そして事前にfunction/src
ディレクトリに各々のファイルを配置しておき、以下のコードで読み込みます。
with open("src/query.txt", "rt") as file:
query = file.read()
with open("src/document.pdf", "rb") as file:
bs64 = file.read()
Chat with your document機能をAPIから利用するには、以下のようにRetrieveAndGenerate APIに対してexternalSourcesConfiguration
を指定し、モデルARNと先ほど読み込んだQuery及びPDFファイルを渡します。
response = bar.retrieve_and_generate(
input={"text": query},
retrieveAndGenerateConfiguration={
"type": "EXTERNAL_SOURCES",
"externalSourcesConfiguration": {
"modelArn": model_arn,
"sources": [
{
"sourceType": "BYTE_CONTENT",
"byteContent": {
"contentType": "application/pdf",
"data": bs64,
"identifier": "document.pdf",
},
}
],
},
},
)
次に②では、RetrieveAndGenerate APIのresponseから、Grounding source及びContentを抽出します。
Pythonコードの場合、responseからそれぞれ以下の内容で抽出可能です。
- Content(モデルからの応答)
output = response["output"]["text"]
- Grounding source(参照ソースから提供される情報)
reference = []
for citation in response["citations"]:
for retrievedReference in citation["retrievedReferences"]:
context = retrievedReference["content"]["text"]
reference.append(context)
このresponseからの抽出方法はRetrieveAndGenerate API共通のため、Chat with your Document機能のみならず、通常のKnowledge Basesを作成し指定した場合でも同様になります。
最後に③では同じアップデートで追加されたApplyGuardrail APIを用いて、Query、Grounding source、Content要素を別途渡します。
今回のLambda関数では、以下の通りApplyGuardrail APIに渡す各種要素群と、そのレスポンスの両方を戻り値として返しているため、どの要素を組み合わせるとどの程度の信頼スコアが計算されるか表示できるようにしています。
return gr_content, gr_response
実行結果
今回の構成を以下のSAMコマンドでデプロイした後、Groundingの信頼スコアに基づきハルシネーションを検出できるか検証してみます。
sam build
sam deploy
まずは作成したLambdaに対して、以下のようなQueryとPDFファイルを渡してみます。
するとLambdaの実行結果として、以下のようなレスポンスが返ってきます。
[
[
{
"text": {
"text": "これはサンプルです株式会社の従業員数を教えてください。\n",
"qualifiers": [
"query"
]
}
},
{
"text": {
"text": "これはサンプルです株式会社 ホーム 会社概要 サービス お問い合わせ ようこそ これはサンプルです株式会社へようこそ。持続可能な未来のための⾰新的なソリューションを提供していま す。 会社概要 設⽴: 2000年1⽉1⽇ | 資本⾦: 1億円 | 従業員数: 10名 所在地: 〒XXX-XXXX 東京都○○区○○X-X-X サンプルビル サービス エコスマートホーム AI制御による省エネ住宅システム。電気代を最⼤50%削減。 ソーラーテクノロジー 最新の太陽光発電システムでクリーンエネルギーを促進。 バイオリサイクル 有機廃棄物を100%再利⽤可能な資源に変換する⾰新的システム。 お問い合わせ 電話: 03-XXXX-XXXX | メール: info@sample-company.co.jp 受付時間: 平⽇ 9:00 - 18:00 © 2023 これはサンプルです株式会社. All rights reserved.",
"qualifiers": [
"grounding_source"
]
}
},
{
"text": {
"text": "これはサンプルです株式会社の従業員数は10名です。"
}
}
],
{
"ResponseMetadata": {
"RequestId": "e175ce87-752c-4485-a8c3-869eb66fb6ee",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"date": "Tue, 06 Aug 2024 10:25:18 GMT",
"content-type": "application/json",
"content-length": "354",
"connection": "keep-alive",
"x-amzn-requestid": "e175ce87-752c-4485-a8c3-869eb66fb6ee"
},
"RetryAttempts": 0
},
"usage": {
"topicPolicyUnits": 0,
"contentPolicyUnits": 0,
"wordPolicyUnits": 0,
"sensitiveInformationPolicyUnits": 0,
"sensitiveInformationPolicyFreeUnits": 0,
"contextualGroundingPolicyUnits": 1
},
"action": "NONE",
"outputs": [],
"assessments": [
{
"contextualGroundingPolicy": {
"filters": [
{
"type": "GROUNDING",
"threshold": 0.85,
"score": 0.93,
"action": "NONE"
}
]
}
}
]
}
]
信頼スコアを見てみると、Groundingの信頼スコアが0.93となっています。
これは今回設定した閾値0.85を超えているため、Content「この会社の従業員数は10名です。」からはハルシネーションが検出されていないと判定されました!
次にあえてハルシネーションが起きた状況を作り出すため、意図的に嘘が紛れ込んでいるoutput.txt
を読み込んでContentとし、再度ApplyGuardrail APIを実行してみます。
今回のContentはoutput.txt
から読み込む形とし、以下のような内容とします。
- Content (with hallucination)
この会社の従業員数は20名です。
正しくは10名ですが、今回意図的に20名に変更しているため、Groundingの信頼スコアが下がると予想されます。
Contentをoutput.txt
から読み込む形で固定するには、samconfig.toml
で設定されているparameter_overridesの内、OutputControlをTrueに修正します。
parameter_overrides = [
"ModelRegion=us-east-1",
"ModelId=anthropic.claude-3-sonnet-20240229-v1:0",
"OutputControl=True",
"GuardrailVersion=1"
]
変更後、再デプロイを忘れず実施してください。
sam build
sam deploy
再デプロイ完了後にLambdaを実行すると、以下のようなレスポンスが返ってきます。
[
[
{
"text": {
"text": "これはサンプルです株式会社の従業員数を教えてください。\n",
"qualifiers": [
"query"
]
}
},
{
"text": {
"text": "これはサンプルです株式会社 ホーム 会社概要 サービス お問い合わせ ようこそ これはサンプルです株式会社へようこそ。持続可能な未来のための⾰新的なソリューションを提供していま す。 会社概要 設⽴: 2000年1⽉1⽇ | 資本⾦: 1億円 | 従業員数: 10名 所在地: 〒XXX-XXXX 東京都○○区○○X-X-X サンプルビル サービス エコスマートホーム AI制御による省エネ住宅システム。電気代を最⼤50%削減。 ソーラーテクノロジー 最新の太陽光発電システムでクリーンエネルギーを促進。 バイオリサイクル 有機廃棄物を100%再利⽤可能な資源に変換する⾰新的システム。 お問い合わせ 電話: 03-XXXX-XXXX | メール: info@sample-company.co.jp 受付時間: 平⽇ 9:00 - 18:00 © 2023 これはサンプルです株式会社. All rights reserved.",
"qualifiers": [
"grounding_source"
]
}
},
{
"text": {
"text": "これはサンプルです株式会社の従業員数は20名です。\n"
}
}
],
{
"ResponseMetadata": {
"RequestId": "97d20eb2-30a7-4e1e-9c24-a2b641de7593",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"date": "Tue, 06 Aug 2024 10:31:50 GMT",
"content-type": "application/json",
"content-length": "464",
"connection": "keep-alive",
"x-amzn-requestid": "97d20eb2-30a7-4e1e-9c24-a2b641de7593"
},
"RetryAttempts": 0
},
"usage": {
"topicPolicyUnits": 0,
"contentPolicyUnits": 0,
"wordPolicyUnits": 0,
"sensitiveInformationPolicyUnits": 0,
"sensitiveInformationPolicyFreeUnits": 0,
"contextualGroundingPolicyUnits": 1
},
"action": "GUARDRAIL_INTERVENED",
"outputs": [
{
"text": "response blocked"
}
],
"assessments": [
{
"contextualGroundingPolicy": {
"filters": [
{
"type": "GROUNDING",
"threshold": 0.85,
"score": 0.56,
"action": "BLOCKED"
}
]
}
}
]
}
]
再度信頼スコアを見てみると、今度はGroundingの信頼スコアが0.56となっています。
これは今回設定した閾値0.85を下回っているため、Content「この会社の従業員数は20名です。」からはハルシネーションが検出されたと判定され、ApplyGuardrail APIよりブロックメッセージresponse blocked
が返却されました!
このように、contextual grounding check機能を用いる事で、ユーザーが指定した信頼スコア閾値を基準にハルシネーションが検出されているか判定し、検出された場合のみブロックメッセージを出力させる事が可能となります。
最後に
今回はGuardrails for Amazon Bedrockのハルシネーション検出(contextual grounding check)機能について解説しました。
ハルシネーションはRAG活用において重要な課題の一つであるため、今回のアップデートによりハルシネーションを検出するための新たな手法がAWSから提供されたのは嬉しいですね。
今後もGuardrails for Amazon Bedrockのアップデートに注目していきたいと思います!
以上、つくぼし(tsukuboshi0755)でした!