Guardrails for Amazon Bedrock の禁止トピックを試す

こちらの続編で、今度は禁止トピックを試します。

https://qiita.com/kazuneet/items/89aeca6d8884c543daec

## 一応振り返り
Guardrails for Amazon Bedrock はモデルに対する入力と出力結果に対してチェックをかける機能を提供します。

チェックは以下の機能を有します。

* [コンテンツフィルター(前回の記事)](https://qiita.com/kazuneet/items/89aeca6d8884c543daec)
* 禁止トピック
* 機密情報フィルター
* 単語フィルター
* 文脈的根拠チェック

この記事では禁止トピックを扱います。

## 禁止トピック

[詳しくはここ](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-denied-topics.html)を見てください、ですがざっくり説明します。

AI との会話で話してほしくない会話の内容があります。
例えば製造業で AI を使っているのに、従業員にギャンブルの話を AI とさせたい、という経営者やマネージャーはなかなかいないでしょう。

そんなときに AI の入出力を Guardrails for Amazon Bedrock で封じてやろう、という使い方です。

## 使ってみる

せっかくなので文脈的にギャンブルの話を封じるような、禁止トピックを設定してみましょう。
例によって CDK で実装します。

```typescript:lib
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { aws_bedrock as bedrock } from 'aws-cdk-lib';

export class GuardrailsJapaneseTestStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    
    const cfnGuardrail = new bedrock.CfnGuardrail(this,`contentGuardrail`,{
      blockedInputMessaging: 'そんなの入れちゃダメぇぇぇ！！',
      blockedOutputsMessaging: '変なの出ちゃぅぅ！！',
      name : `denyTopicGuardrail`,
      topicPolicyConfig: {
        topicsConfig: [{
          name: 'Gambling',
          definition: '賭博とは、金銭や品物などを賭けて勝負を争う遊戯のことである。金銭や品物などの財物を賭けて、（偶然性の要素が含まれる）勝負を行い、その勝負の結果によって、負けた方は賭けた財物を失い、勝った方は（なんらかの取り決めに基づいて）財物を得る、と言う仕組みの遊戯（ゲーム）の総称である。',
          type: 'DENY',
        }],
      },
    
    })
    new bedrock.CfnGuardrailVersion(this, `contentGuardrailVersion`, {
      guardrailIdentifier:cfnGuardrail.attrGuardrailId,
      description: `initial version`,
    })
  }
}

```

今回は [wikipedia の賭博](https://ja.wikipedia.org/wiki/%E8%B3%AD%E5%8D%9A)から説明文を取ってきました。

さて、作成した禁止トピックのガードレールを試してみます。
例によって imvoke_model や converse ではなく、apply_guardrail を使用してみます。
また入力側のみを確認します。

```python:test.ipynb
import boto3
from pprint import pprint
brt = boto3.client('bedrock-runtime')
prompt_list = [
    'ギャンブル必勝法を教えて下さい',
    '賭博の必勝法を教えて下さい',
    'マーチンゲールってなんですか？',
    'What is Gambling?'
]
for prompt in prompt_list:
    print(prompt)
    response = brt.apply_guardrail(
        guardrailIdentifier='xxxxx', # 今回作成したヤツ
        guardrailVersion='DRAFT',
        source='INPUT',
        content=[
            {
                'text': {
                    'text': prompt,
                    'qualifiers': [
                        'guard_content',
                    ]
                }
            },
        ]
    )
    print(response['assessments'])
```

```text:出力
ギャンブル必勝法を教えて下さい
[{}]
賭博の必勝法を教えて下さい
[{}]
マーチンゲールってなんですか？
[{}]
What is Gambling?
[{'topicPolicy': {'topics': [{'name': 'Gambling', 'type': 'DENY', 'action': 'BLOCKED'}]}}]
```

英語しか取れてないやんけ・・・。
しかし、日本語で定義したのに、英語で取れるという面白い現象が起きてますね。
さて、禁止トピックは改善の余地があります。ガードレールを作成する際に、examples という引数で、few-shot することができます。

```typescript:guardrails-japanese-test-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { aws_bedrock as bedrock } from 'aws-cdk-lib';

export class GuardrailsJapaneseTestStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    
    const cfnGuardrail = new bedrock.CfnGuardrail(this,`contentGuardrail`,{
      blockedInputMessaging: 'そんなの入れちゃダメぇぇぇ！！',
      blockedOutputsMessaging: '変なの出ちゃぅぅ！！',
      name : `denyTopicGuardrail`,
      topicPolicyConfig: {
        topicsConfig: [{
          name: 'Gambling',
          definition: '賭博とは、金銭や品物などを賭けて勝負を争う遊戯のことである。金銭や品物などの財物を賭けて、（偶然性の要素が含まれる）勝負を行い、その勝負の結果によって、負けた方は賭けた財物を失い、勝った方は（なんらかの取り決めに基づいて）財物を得る、と言う仕組みの遊戯（ゲーム）の総称である。',
          examples: [ // 追加
            '競馬の勝ち方を教えて下さい', // 追加
            '賭博をやっていると脳汁が出るのですが、脳汁の招待ってなんですか？', // 追加
            '競艇ってなんですか？', // 追加
            'チンチロリンの四五六賽とは４・５・６しか出ないサイコロである' // 追加
          ],
          type: 'DENY',
        }],
      },
    
    })
    new bedrock.CfnGuardrailVersion(this, `contentGuardrailVersion`, {
      guardrailIdentifier:cfnGuardrail.attrGuardrailId,
      description: `initial version`,
    })
  }
}

```

さて、全く同じプロンプトで再実行してみます。
```text:出力
ギャンブル必勝法を教えて下さい
[{}]
賭博の必勝法を教えて下さい
[{}]
マーチンゲールってなんですか？
[{}]
What is Gambling?
[{'topicPolicy': {'topics': [{'name': 'Gambling', 'type': 'DENY', 'action': 'BLOCKED'}]}}]
```
やっぱり日本語ダメやんけ・・・。

few-shotで使った全く同じ文章を使っていけるかを確認しましょう。

```python:test.ipynb
prompt_list = [
    '競馬の勝ち方を教えて下さい',
]
for prompt in prompt_list:
    print(prompt)
    response = brt.apply_guardrail(
        guardrailIdentifier='msqupkqnj4tr', # 'HATE-HIGH-contentGuardrail
        guardrailVersion=guardrail['version'],
        source='INPUT',
        content=[
            {
                'text': {
                    'text': prompt,
                    'qualifiers': [
                        'guard_content',
                    ]
                }
            },
        ]
    )
    print(response['assessments'])
```
```text:出力
競馬の勝ち方を教えて下さい
[{}]
```

そうだね、パッションだね。
日本語はそもそもダメでした。

## まとめ
禁止トピックは日本語が2024/8/14時点でまだ使えないが英語は効く。