最後の機能である Contextual Grounding
他の機能については以下をご参照ください。
Contextual Grounding の詳細はこちらですが、RAG でのハルシネーションのチェック機能で利用します。
これについては実際に見たほうが速いのでとっととやります。
Contextual Grounding のガードレールの作成
さて、いきなり問題が。
2024/8/16 時点で CDK で Contextual Grounding が対応していません。
CDK の PR を見てみるとマージ済になっているので、近いうちには出てくると思いますが…。
ということで、しかたなく boto3 から実行します。
boto3 で以下 API を叩きます。
import boto3
from pprint import pprint
br = boto3.client('bedrock')
response = br.create_guardrail(
name='contextual-grounding',
contextualGroundingPolicyConfig={
'filtersConfig': [
{
'type': 'GROUNDING',
'threshold': 0.5
},
{
'type': 'RELEVANCE',
'threshold': 0.5
},
]
},
blockedInputMessaging='そんなの入れちゃダメぇぇぇ!!',
blockedOutputsMessaging='変なの出ちゃぅぅ!!',
)
guardrail_id = response['guardrailId']
response = br.create_guardrail_version(
guardrailIdentifier=guardrail_id,
)
version = response['version']
これでガードレール及びバージョンの作成が完了です。
試してみる
データを4パターン用意してみました。
contents = [
# 合っている場合
[
{
'text': {
'text': 'イギリスの首都はロンドンです。日本の首都は東京です。',
'qualifiers': ['grounding_source'] # 検索結果(とする)
}
},
{
'text': {
'text': '日本の首都はどこですか?',
'qualifiers': ['query'] # ユーザーの質問
}
},
{
'text': {
'text': '東京です。' # 生成結果
}
},
],
# 検索結果がおかしかった場合
[
{
'text': {
'text': 'イギリスの首都はロンドンです。フランスの首都はパリです。',
'qualifiers': ['grounding_source']
}
},
{
'text': {
'text': '日本の首都はどこですか?',
'qualifiers': ['query']
}
},
{
'text': {
'text': '東京です。'
}
},
],
# 生成結果がおかしかった場合
[
{
'text': {
'text': 'イギリスの首都はロンドンです。日本の首都は東京です。',
'qualifiers': ['grounding_source']
}
},
{
'text': {
'text': '日本の首都はどこですか?',
'qualifiers': ['query']
}
},
{
'text': {
'text': '江戸です。'
}
},
],
# 何もかもがおかしかった場合
[
{
'text': {
'text': 'イギリスの首都はロンドンです。フランスの首都はパリです。',
'qualifiers': ['grounding_source']
}
},
{
'text': {
'text': '日本の首都はどこですか?',
'qualifiers': ['query']
}
},
{
'text': {
'text': '江戸です。'
}
},
],
]
最初の QA 以外はすべて誤りです。
実行してみましょう。
for content in contents:
response = brt.apply_guardrail(
guardrailIdentifier=guardrail_id,
guardrailVersion=version,
source='OUTPUT',
content=content
)
pprint(response['assessments'][0])
{'contextualGroundingPolicy': {'filters': [{'action': 'NONE',
'score': 0.76,
'threshold': 0.5,
'type': 'GROUNDING'},
{'action': 'NONE',
'score': 0.61,
'threshold': 0.5,
'type': 'RELEVANCE'}]}}
{'contextualGroundingPolicy': {'filters': [{'action': 'NONE',
'score': 0.76,
'threshold': 0.5,
'type': 'GROUNDING'},
{'action': 'NONE',
'score': 0.61,
'threshold': 0.5,
'type': 'RELEVANCE'}]}}
{'contextualGroundingPolicy': {'filters': [{'action': 'NONE',
'score': 0.76,
'threshold': 0.5,
'type': 'GROUNDING'},
{'action': 'NONE',
'score': 0.61,
'threshold': 0.5,
'type': 'RELEVANCE'}]}}
{'contextualGroundingPolicy': {'filters': [{'action': 'NONE',
'score': 0.76,
'threshold': 0.5,
'type': 'GROUNDING'},
{'action': 'NONE',
'score': 0.61,
'threshold': 0.5,
'type': 'RELEVANCE'}]}}
うーん、全部同じスコアが出てしまいましたね…。
英語で試してみましょう。
contents = [
# 合っている場合
[
{
'text': {
'text': 'The capital of the United Kingdom is London. The capital of Japan is Tokyo.',
'qualifiers': ['grounding_source'] # 検索結果(とする)
}
},
{
'text': {
'text': 'What is the capital of Japan?',
'qualifiers': ['query'] # ユーザーの質問
}
},
{
'text': {
'text': 'Tokyo' # 生成結果
}
},
],
# 検索結果がおかしかった場合
[
{
'text': {
'text': 'The capital of the United Kingdom is London. The capital of France is Paris.',
'qualifiers': ['grounding_source']
}
},
{
'text': {
'text': 'What is the capital of Japan?',
'qualifiers': ['query']
}
},
{
'text': {
'text': 'Tokyo'
}
},
],
# 生成結果がおかしかった場合
[
{
'text': {
'text': 'The capital of the United Kingdom is London. The capital of Japan is Tokyo.',
'qualifiers': ['grounding_source']
}
},
{
'text': {
'text': 'What is the capital of Japan?',
'qualifiers': ['query']
}
},
{
'text': {
'text': 'Edo'
}
},
],
# 何もかもがおかしかった場合
[
{
'text': {
'text': 'The capital of the United Kingdom is London. The capital of France is Paris',
'qualifiers': ['grounding_source']
}
},
{
'text': {
'text': 'What is the capital of Japan?',
'qualifiers': ['query']
}
},
{
'text': {
'text': 'Edo'
}
},
],
]
for content in contents:
response = brt.apply_guardrail(
guardrailIdentifier=guardrail_id,
guardrailVersion=version,
source='OUTPUT',
content=content
)
pprint(response['assessments'][0])
{'contextualGroundingPolicy': {'filters': [{'action': 'NONE',
'score': 1.0,
'threshold': 0.5,
'type': 'GROUNDING'},
{'action': 'NONE',
'score': 1.0,
'threshold': 0.5,
'type': 'RELEVANCE'}]}}
{'contextualGroundingPolicy': {'filters': [{'action': 'BLOCKED',
'score': 0.14,
'threshold': 0.5,
'type': 'GROUNDING'},
{'action': 'NONE',
'score': 1.0,
'threshold': 0.5,
'type': 'RELEVANCE'}]}}
{'contextualGroundingPolicy': {'filters': [{'action': 'BLOCKED',
'score': 0.0,
'threshold': 0.5,
'type': 'GROUNDING'},
{'action': 'NONE',
'score': 0.94,
'threshold': 0.5,
'type': 'RELEVANCE'}]}}
{'contextualGroundingPolicy': {'filters': [{'action': 'BLOCKED',
'score': 0.0,
'threshold': 0.5,
'type': 'GROUNDING'},
{'action': 'NONE',
'score': 0.99,
'threshold': 0.5,
'type': 'RELEVANCE'}]}}
さて、最初のパターンから見ていきましょう。
日本の首都はどこですか?に対して、日本の首都は東京であるという検索結果から、東京、という回答を生成したので、GROUNDING, RELEVANCE 共に 1.0 というスコアで通りました。
2 番目のパターンです。
日本の首都はどこですか?に対して、イギリスとフランスの首都しか検索結果に含まれないにもかかわらず、東京、という回答を生成しました。
GROUNDING(検索結果)を使った回答をしていないため、GROUNDING が0.14 という低スコアでブロックされました(しきい値はガードレールを作成した時に設定した0.5にしてあります)。
3 番目のパターンです。
日本の首都はどこですか?に対して、日本の首都は東京であるという検索結果があるにもかかわらず、江戸と回答を生成しました。
やはりこれもGROUNDING(検索結果)を使った回答をしていないため、GROUNDING が0 というスコアでブロックされました。
4 番目も同様です。
しかし、ここまで GROUNDING のチェックしかできなかったので RELEVANCE を試してみましょう。
contents = [
# 合っている場合
[
{
'text': {
'text': 'The capital of the United Kingdom is London. The capital of Japan is Tokyo.',
'qualifiers': ['grounding_source'] # 検索結果(とする)
}
},
{
'text': {
'text': 'What did you eat last lunch?',
'qualifiers': ['query'] # ユーザーの質問
}
},
{
'text': {
'text': 'Tokyo' # 生成結果
}
},
],
]
for content in contents:
response = brt.apply_guardrail(
guardrailIdentifier=guardrail_id,
guardrailVersion=version,
source='OUTPUT',
content=content
)
pprint(response['assessments'][0])
{'contextualGroundingPolicy': {'filters': [{'action': 'NONE',
'score': 0.53,
'threshold': 0.5,
'type': 'GROUNDING'},
{'action': 'BLOCKED',
'score': 0.25,
'threshold': 0.5,
'type': 'RELEVANCE'}]}}
昼何食べた?という質問に対して首都の検索結果という若干頭がバグる検索結果を出し、その検索結果から東京という回答を生成した場合、質問に対して検索結果が関係ないため、RELEVANCE が 0.25 でブロックされました。
しかし、首都は外国の首都でも首都の検索結果を出しているので、スコアが高めに出されていたようですね。
あとはしきい値の調整でがんばる領域ではありますがとりあえず機能することがわかりました。
まとめ
- Contextual Grounding は2024/8/16 現在 CDK に対応していない
- Contextual Grounding は2024/8/16 現在日本語に対応していない
- Contextual Grounding は英語だとそれなりに機能する
ちゃんちゃん。