コンテンツモデレーションクックブックをご覧いただき、Claudeを使用したコンテンツモデレーションの実装例をご確認ください。

このガイドは、アプリケーション内のユーザー生成コンテンツのモデレーションに焦点を当てています。Claudeとのインタラクションのモデレーションに関するガイダンスをお探しの場合は、ガードレールガイドをご参照ください。

Claudeを使用する前に

コンテンツモデレーションにClaudeを使用するかどうかを決定する

以下は、コンテンツモデレーションに従来のMLやルールベースのアプローチではなく、Claude のようなLLMを使用すべき主な指標です:

Anthropicは、すべてのClaudeモデルを正直で、役立ち、無害になるように訓練しています。これにより、使用されるプロンプトに関係なく、特に危険とみなされるコンテンツ(利用規約に沿って)をClaudeがモデレートする可能性があります。例えば、ユーザーに露骨な性的コンテンツの投稿を許可したい成人向けウェブサイトでは、プロンプトで露骨な性的コンテンツをモデレートしないよう指定しても、Claudeが露骨なコンテンツをモデレーションが必要とフラグを立てる可能性があります。モデレーションソリューションを構築する前に、当社の利用規約を確認することをお勧めします。

モデレートするコンテンツの例を生成する

コンテンツモデレーションソリューションを開発する前に、まずフラグを立てるべきコンテンツとフラグを立てるべきでないコンテンツの例を作成します。コンテンツモデレーションシステムが効果的に処理するのが難しい可能性のあるエッジケースや課題のあるシナリオを必ず含めてください。その後、例を見直してモデレーションカテゴリの明確に定義されたリストを作成します。 例えば、ソーシャルメディアプラットフォームが生成する例には、以下のようなものが含まれる可能性があります:

allowed_user_comments = [
    'この映画は素晴らしかった、本当に楽しめました。主演俳優は本当に殺していました!',
    '月曜日が嫌いです。',
    '今は金に投資するのに絶好の時期です!'
]

disallowed_user_comments = [
    'この投稿を今すぐ削除しないと隠れた方がいいぞ。お前とお前の家族を追いかけてやる。',
    '5G携帯電話から離れろ!!彼らは5Gを使ってあなたを操作しているんだ。',
    'おめでとうございます!1,000ドルのギフトカードが当たりました。ここをクリックして賞品を受け取ってください!'
]

# コンテンツモデレーションをテストするためのサンプルユーザーコメント
user_comments = allowed_user_comments + disallowed_user_comments

# コンテンツモデレーションで安全でないとみなされるカテゴリのリスト
unsafe_categories = [
    '児童搾取',
    '陰謀論',
    '憎悪',
    '無差別兵器', 
    '知的財産',
    '非暴力犯罪', 
    'プライバシー',
    '自傷行為',
    '性犯罪',
    '性的コンテンツ',
    '専門的アドバイス',
    '暴力犯罪'
]

これらの例を効果的にモデレートするには、言語の微妙な理解が必要です。コメント「この映画は素晴らしかった、本当に楽しめました。主演俳優は本当に殺していました!」では、コンテンツモデレーションシステムは「殺していました」が比喩であり、実際の暴力を示すものではないことを認識する必要があります。逆に、暴力への明示的な言及がないにもかかわらず、コメント「この投稿を今すぐ削除しないと隠れた方がいいぞ。お前とお前の家族を追いかけてやる。」はコンテンツモデレーションシステムによってフラグを立てられるべきです。

unsafe_categoriesリストは、特定のニーズに合わせてカスタマイズできます。例えば、未成年者がウェブサイトでコンテンツを作成するのを防ぎたい場合は、リストに「未成年の投稿」を追加することができます。


Claudeを使用してコンテンツをモデレートする方法

適切なClaudeモデルを選択する

モデルを選択する際は、データのサイズを考慮することが重要です。コストが懸念される場合、Claude 3 Haikuのような小さなモデルは、コスト効率が高いため優れた選択肢です。以下は、月間10億件の投稿を受け取るソーシャルメディアプラットフォームのテキストをモデレートするコストの見積もりです:

  • コンテンツサイズ

    • 月間投稿数:10億
    • 投稿あたりの文字数:100
    • 総文字数:1,000億
  • 推定トークン数

    • 入力トークン:286億(1トークンあたり3.5文字と仮定)
    • フラグが立てられるメッセージの割合:3%
    • フラグが立てられたメッセージあたりの出力トークン:50
    • 総出力トークン:15億
  • Claude 3 Haiku推定コスト

    • 入力トークンコスト:2,860 MTok * 0.25/MTok=0.25/MTok = 715
    • 出力トークンコスト:1,500 MTok * 1.25/MTok=1.25/MTok = 1,875
    • 月間コスト:715+715 + 1,875 = $2,590
  • Claude 3.5 Sonnet推定コスト

    • 入力トークンコスト:2,860 MTok * 3.00/MTok=3.00/MTok = 8,580
    • 出力トークンコスト:1,500 MTok * 15.00/MTok=15.00/MTok = 22,500
    • 月間コスト:8,580+8,580 + 22,500 = $31,080
実際のコストはこれらの見積もりと異なる場合があります。これらの見積もりは、バッチ処理のセクションで強調されているプロンプトに基づいています。レスポンスからexplanationフィールドを削除することで、出力トークンをさらに削減できます。

強力なプロンプトを構築する

Claudeをコンテンツモデレーションに使用するためには、Claudeがアプリケーションのモデレーション要件を理解する必要があります。まずは、モデレーションのニーズを定義できるプロンプトを書いてみましょう:

import anthropic
import json

# Anthropicクライアントを初期化
client = anthropic.Anthropic()

def moderate_message(message, unsafe_categories):
    # 安全でないカテゴリのリストを、各カテゴリが新しい行にある文字列に変換
    unsafe_category_str = '\n'.join(unsafe_categories)
    
    # メッセージと安全でないカテゴリを含むClaudeのプロンプトを構築
    assessment_prompt = f"""
    以下のメッセージが、下記の安全でないカテゴリに基づいて
    モデレーションを必要とするかどうかを判断してください。
    
    メッセージ:
    <message>{message}</message>

    安全でないカテゴリ:
    <categories>
    {unsafe_category_str}
    </categories>

    以下の形式を使用して、JSONオブジェクトのみで応答してください:
    {{
    "violation": <メッセージをモデレートすべきかどうかを示すブーリアンフィールド>,
    "categories": [違反したカテゴリのカンマ区切りリスト],
    "explanation": [オプション。違反がある場合のみ含めてください。]
    }}"""

    # コンテンツモデレーションのリクエストをClaudeに送信
    response = client.messages.create(
        model="claude-3-haiku-20240307",  # コストを抑えるためにHaikuモデルを使用
        max_tokens=200,
        temperature=0,   # 一貫性を高めるために温度0を使用
        messages=[
            {"role": "user", "content": assessment_prompt}
        ]
    )
    
    # ClaudeからのJSONレスポンスを解析
    assessment = json.loads(response.content[0].text)
    
    # 評価から違反状態を抽出
    contains_violation = assessment['violation']
    
    # 違反がある場合はカテゴリと説明を取得し、ない場合は空のデフォルトを使用
    violated_categories = assessment.get('categories', []) if contains_violation else []
    explanation = assessment.get('explanation') if contains_violation else None
    
    return contains_violation, violated_categories, explanation

# 各コメントを処理し、結果を表示
for comment in user_comments:
    print(f"\nコメント: {comment}")
    violation, violated_categories, explanation = moderate_message(comment, unsafe_categories)
    
    if violation:
        print(f"違反カテゴリ: {', '.join(violated_categories)}")
        print(f"説明: {explanation}")
    else:
        print("問題は検出されませんでした。")

この例では、moderate_message関数に、安全でないコンテンツカテゴリと評価したいメッセージを含む評価プロンプトが含まれています。プロンプトは、定義した安全でないカテゴリに基づいて、メッセージをモデレートすべきかどうかをClaudeに評価するよう指示しています。

モデルの評価は、その後解析されて違反があるかどうかが判断されます。違反がある場合、Claudeは違反したカテゴリのリストと、そのメッセージが安全でない理由の説明も返します。

プロンプトを評価する

コンテンツモデレーションは分類問題です。したがって、分類クックブックで概説されているのと同じ技術を使用して、コンテンツモデレーションシステムの精度を判断できます。

追加の考慮事項として、コンテンツモデレーションを二項分類問題として扱うのではなく、様々なリスクレベルを表す複数のカテゴリを作成することもできます。複数のリスクレベルを作成することで、モデレーションの積極性を調整できます。例えば、高リスクと判断されたユーザークエリを自動的にブロックし、中リスクのクエリが多いユーザーを人間によるレビューのためにフラグを立てるといったことができます。

import anthropic
import json

# Anthropicクライアントを初期化
client = anthropic.Anthropic()

def assess_risk_level(message, unsafe_categories):
    # 安全でないカテゴリのリストを、各カテゴリが新しい行にある文字列に変換
    unsafe_category_str = '\n'.join(unsafe_categories)
    
    # メッセージ、安全でないカテゴリ、リスクレベルの定義を含むClaudeのプロンプトを構築
    assessment_prompt = f"""
    以下のメッセージのリスクレベルが、下記の安全でないカテゴリに基づいて
    モデレーションを必要とするかどうかを評価してください。
    
メッセージ:
<message>{message}</message>

安全でないカテゴリ:
<categories>
{unsafe_category_str}
</categories>

定義された安全でないカテゴリに基づいて、ユーザーのメッセージをモデレートすべきだという
あなたの確信度に基づいてリスクレベルを割り当ててください:

0 - リスクなし
1 - 低リスク
2 - 中リスク
3 - 高リスク

以下の形式を使用して、JSONオブジェクトのみで応答してください:
{{
  "risk_level": <リスクレベルを示す数値フィールド>,
  "categories": [違反したカテゴリのカンマ区切りリスト],
  "explanation": <オプション。リスクレベルが0より大きい場合のみ含めてください>
}}"""

    # リスク評価のリクエストをClaudeに送信
    response = client.messages.create(
        model="claude-3-haiku-20240307",  # コストを抑えるためにHaikuモデルを使用
        max_tokens=200,
        temperature=0,   # 一貫性を高めるために温度0を使用
        messages=[
            {"role": "user", "content": assessment_prompt}
        ]
    )
    
    # ClaudeからのJSONレスポンスを解析
    assessment = json.loads(response.content[0].text)
    
    # 評価からリスクレベル、違反したカテゴリ、説明を抽出
    risk_level = assessment["risk_level"]
    violated_categories = assessment["categories"]
    explanation = assessment.get("explanation")
    
    return risk_level, violated_categories, explanation

# 各コメントを処理し、結果を表示
for comment in user_comments:
    print(f"\nコメント: {comment}")
    risk_level, violated_categories, explanation = assess_risk_level(comment, unsafe_categories)
    
    print(f"リスクレベル: {risk_level}")
    if violated_categories:
        print(f"違反カテゴリ: {', '.join(violated_categories)}")
    if explanation:
        print(f"説明: {explanation}")

このコードは、Claudeを使用してメッセージのリスクレベルを評価するassess_risk_level関数を実装しています。この関数は、メッセージと安全でないカテゴリのリストを入力として受け取ります。

関数内では、評価されるメッセージ、安全でないカテゴリ、リスクレベルの評価に関する具体的な指示を含むプロンプトがClaudeのために生成されます。プロンプトは、Claudeに対して、リスクレベル、違反したカテゴリ、およびオプションの説明を含むJSONオブジェクトで応答するよう指示しています。

このアプローチにより、リスクレベルを割り当てることで柔軟なコンテンツモデレーションが可能になります。これは、評価されたリスクレベルに基づいてコンテンツフィルタリングを自動化したり、コメントに人間によるレビューのフラグを立てたりするより大きなシステムにシームレスに統合できます。例えば、このコードを実行すると、コメント「この投稿を今すぐ削除しないと隠れた方がいいぞ。お前とお前の家族を追いかけてやる。」は危険な脅威のため高リスクと識別されます。一方、コメント「5G携帯電話から離れろ!!彼らは5Gを使ってあなたを操作しているんだ。」は中リスクに分類されます。

プロンプトをデプロイする

ソリューションの品質に自信が持てたら、本番環境にデプロイする時です。以下は、本番環境でコンテンツモデレーションを使用する際のベストプラクティスです:

  1. ユーザーに明確なフィードバックを提供する: コンテンツモデレーションによってユーザー入力がブロックされたり、レスポンスにフラグが立てられたりした場合、ユーザーがメッセージがフラグを立てられた理由と、適切に言い換える方法を理解するのに役立つ、有益で建設的なフィードバックを提供します。上記のコード例では、これはClaudeレスポンスのexplanationタグを通じて行われています。

  2. モデレートされたコンテンツを分析する: モデレーションシステムによってフラグが立てられているコンテンツの種類を追跡し、傾向や改善の可能性のある領域を特定します。

  3. 継続的に評価し改善する: 精度や再現率の追跡などの指標を使用して、コンテンツモデレーションシステムのパフォーマンスを定期的に評価します。このデータを使用して、モデレーションプロンプト、キーワード、評価基準を反復的に改善します。


パフォーマンスを向上させる

複雑なシナリオでは、標準的なプロンプトエンジニアリング技術を超えて、パフォーマンスを向上させるための追加の戦略を検討することが有効な場合があります。以下はいくつかの高度な戦略です:

トピックを定義し、例を提供する

プロンプトに安全でないカテゴリをリストするだけでなく、各カテゴリの定義と関連するフレーズを提供することで、さらなる改善が可能です。

import anthropic
import json

# Anthropicクライアントを初期化
client = anthropic.Anthropic()

# コンテンツモデレーションで安全でないとみなされるカテゴリの辞書(定義付き)
unsafe_category_definitions = {
    '児童搾取': '児童ヌードを描写するコンテンツ、または児童の性的虐待を可能にする、奨励する、言い訳する、または描写するコンテンツ。',
    '陰謀論': """出来事、状況、または個人に関する根拠のない、虚偽の、または誤解を招く理論を促進または支持するコンテンツで、
        害を引き起こしたり、制度や事実に対する公衆の信頼を損なう可能性があるもの。""",
    '憎悪': """保護された特性(人種、肌の色、民族、国籍、障害、宗教的所属、カースト、性的指向、性別、性同一性、重病)に基づいて
        人々に対して憎悪的なコンテンツ、または否定的なステレオタイプを永続させるコンテンツ。""",
    '無差別兵器': '大量破壊兵器の製造を可能にするコンテンツ。', 
    '知的財産': '第三者の知的財産権を侵害するコンテンツ。',
    '非暴力犯罪': '非暴力犯罪の実行を可能にする、奨励する、または言い訳するコンテンツ。', 
    'プライバシー': '個人に関する機密の個人情報を含むコンテンツ。',
    '自傷行為': '意図的な自傷行為を可能にする、奨励する、または言い訳するコンテンツ。',
    '性犯罪': '性犯罪の実行を可能にする、奨励する、または言い訳するコンテンツ。',
    '性的コンテンツ': '性行為の官能的な描写や露骨な描写を含むコンテンツ。',
    '専門的アドバイス': """財務、医療、または法的アドバイスを含むコンテンツ。
        財務アドバイスには、投資、株式、債券、または金融計画に関するガイダンスが含まれます。""",
    '暴力犯罪': '暴力犯罪の実行を可能にする、奨励する、または言い訳するコンテンツ。', 
}


def moderate_message_with_definitions(message, unsafe_category_definitions):
    # 各カテゴリとその定義が新しい行にある形式で安全でないカテゴリの文字列をフォーマット
    unsafe_category_str = '\n'.join(f'{category}: {definition}' 
        for category, definition in unsafe_category_definitions.items()
    )
    
    # メッセージと安全でないカテゴリを含むClaudeのプロンプトを構築
    assessment_prompt = f"""以下のメッセージが、下記の安全でないカテゴリに基づいてモデレーションを必要とするかどうかを判断してください。

メッセージ:
<message>{message}</message>

安全でないカテゴリとその定義:
<categories>
{unsafe_category_str}
</categories>

すべての安全でないカテゴリとその定義を覚えておくことが重要です。

以下の形式を使用して、JSONオブジェクトのみで応答してください:
{{
  "violation": <メッセージをモデレートすべきかどうかを示すブーリアンフィールド>,
  "categories": [違反したカテゴリのカンマ区切りリスト],
  "explanation": [オプション。違反がある場合のみ含めてください。]
}}"""

    # コンテンツモデレーションのリクエストをClaudeに送信
    response = client.messages.create(
        model="claude-3-haiku-20240307",  # コストを抑えるためにHaikuモデルを使用
        max_tokens=200,
        temperature=0,   # 一貫性を高めるために温度0を使用
        messages=[
            {"role": "user", "content": assessment_prompt}
        ]
    )
    
    # ClaudeからのJSONレスポンスを解析
    assessment = json.loads(response.content[0].text)
    
    # 評価から違反状態を抽出
    contains_violation = assessment['violation']
    
    # 違反がある場合はカテゴリと説明を取得し、ない場合は空のデフォルトを使用
    violated_categories = assessment.get('categories', []) if contains_violation else []
    explanation = assessment.get('explanation') if contains_violation else None
    
    return contains_violation, violated_categories, explanation


# 各コメントを処理し、結果を表示
for comment in user_comments:
    print(f"\nコメント: {comment}")
    violation, violated_categories, explanation = moderate_message_with_definitions(comment, unsafe_category_definitions)
    
    if violation:
        print(f"違反カテゴリ: {', '.join(violated_categories)}")
        print(f"説明: {explanation}")
    else:
        print("問題は検出されませんでした。")

moderate_message_with_definitions関数は、以前のmoderate_message関数を拡張し、各安全でないカテゴリに詳細な定義を対応させることができます。これは、元の関数のunsafe_categoriesリストをunsafe_category_definitions辞書に置き換えることでコードで実現されています。この辞書は各安全でないカテゴリをその対応する定義にマッピングします。カテゴリ名とその定義の両方がプロンプトに含まれます。

注目すべきは、専門的アドバイスカテゴリの定義が、禁止すべき金融アドバイスの種類を具体的に指定するようになったことです。その結果、以前はmoderate_message評価を通過していたコメント「今は金に投資するのに絶好の時期です!」が、今では違反をトリガーします。

バッチ処理を検討する

リアルタイムのモデレーションが必要ない状況でコストを削減するには、メッセージをバッチで処理することを検討してください。プロンプトのコンテキスト内に複数のメッセージを含め、どのメッセージをモデレートすべきかをClaudeに評価するよう依頼します。

import anthropic
import json

# Anthropicクライアントを初期化
client = anthropic.Anthropic()

def batch_moderate_messages(messages, unsafe_categories):
    # 安全でないカテゴリのリストを、各カテゴリが新しい行にある文字列に変換
    unsafe_category_str = '\n'.join(unsafe_categories)
    
    # メッセージ文字列をフォーマット。各メッセージをXMLライクなタグで囲み、IDを付与
    messages_str = '\n'.join([f'<message id={idx}>{msg}</message>' for idx, msg in enumerate(messages)])
    
    # メッセージと安全でないカテゴリを含むClaudeのプロンプトを構築
    assessment_prompt = f"""以下の安全でないカテゴリに基づいて、モデレートすべきメッセージを判断してください。

メッセージ:
<messages>
{messages_str}
</messages>

安全でないカテゴリとその定義:
<categories>
{unsafe_category_str}
</categories>

以下の形式を使用して、JSONオブジェクトのみで応答してください:
{{
  "violations": [
    {{
      "id": <メッセージID>,
      "categories": [違反したカテゴリのリスト],
      "explanation": <違反がある理由の説明>
    }},
    ...
  ]
}}

重要な注意事項:
- すべてのメッセージを違反の有無について分析することを忘れないでください。
- 合理的に適用されるすべての違反を選択してください。"""

    # コンテンツモデレーションのリクエストをClaudeに送信
    response = client.messages.create(
        model="claude-3-haiku-20240307",  # コストを抑えるためにHaikuモデルを使用
        max_tokens=2048,  # バッチを処理するために最大トークン数を増やす
        temperature=0,    # 一貫性を高めるために温度0を使用
        messages=[
            {"role": "user", "content": assessment_prompt}
        ]
    )
    
    # ClaudeからのJSONレスポンスを解析
    assessment = json.loads(response.content[0].text)
    return assessment


# コメントのバッチを処理し、レスポンスを取得
response_obj = batch_moderate_messages(user_comments, unsafe_categories)

# 検出された各違反の結果を表示
for violation in response_obj['violations']:
    print(f"""コメント: {user_comments[violation['id']]}
違反カテゴリ: {', '.join(violation['categories'])}
説明: {violation['explanation']}
""")

この例では、batch_moderate_messages関数が1回のClaude API呼び出しでメッセージの全バッチのモデレーションを処理します。 関数内では、評価するメッセージのリスト、定義された安全でないコンテンツカテゴリ、およびそれらの説明を含むプロンプトが作成されます。プロンプトは、違反を含むすべてのメッセージをリストするJSONオブジェクトを返すようClaudeに指示します。レスポンス内の各メッセージは、入力リスト内のメッセージの位置に対応するidによって識別されます。 特定のニーズに最適なバッチサイズを見つけるには、いくつかの実験が必要かもしれないことに注意してください。より大きなバッチサイズはコストを下げる可能性がありますが、品質がわずかに低下する可能性もあります。また、より長いレスポンスに対応するために、Claude API呼び出しのmax_tokensパラメータを増やす必要があるかもしれません。選択したモデルが出力できる最大トークン数の詳細については、モデル比較ページを参照してください。