メインコンテンツへスキップ
パート2: プロダクション機能 - プロバイダーラッパー、ポリシーの強制、セッション、可観測性。

セットアップ

私たちは「CloudDash」という架空のSaaS製品のカスタマーサポートチャットボットを構築しています。CloudDashはクラウド監視ダッシュボードです。このチャットボットは、価格、機能、トラブルシューティングに関する質問に答えます。その過程で、チャットボットの応答が安全で、正確で、公平で、役立つことを保証するために、すべてのレイヤーでRAILスコア評価を追加します。

依存関係のインストール

pip install "rail-score-sdk[openai,google,langfuse]" openai google-genai

環境変数

.envファイルを作成します:
RAIL_API_KEY=YOUR_RAIL_API_KEY
OPENAI_API_KEY=sk-your_openai_key
GEMINI_API_KEY=your_gemini_key

# オプション: パート2用 (Langfuse可観測性)
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_HOST=https://cloud.langfuse.com
RAIL APIキーを取得する: responsibleailabs.ai/dashboardでサインアップしてください。無料プランには、このチュートリアル全体をフォローするための100クレジットが含まれています。

基本的なチャットボットを構築する

まず、RAIL統合なしでOpenAIを直接使用した基本的なチャットボットから始めます。これは、スコアリングを重ねるための基盤です。
chatbot.py
import openai
import os

openai_client = openai.OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

SYSTEM_PROMPT = """あなたはCloudDashサポート、CloudDashのための役立つアシスタントです — クラウド監視ダッシュボード。価格、機能、セットアップ、トラブルシューティングに関する質問に答えてください。簡潔で正確であること。わからないことがあれば、その旨を伝えてください。"""


def chat(user_message: str, history: list[dict] = None) -> str:
    messages = [{"role": "system", "content": SYSTEM_PROMPT}]
    if history:
        messages.extend(history)
    messages.append({"role": "user", "content": user_message})

    response = openai_client.chat.completions.create(
        model="gpt-4o",
        messages=messages,
        temperature=0.3,
    )
    return response.choices[0].message.content


reply = chat("どのような価格プランを提供していますか?")
print(reply)
これは機能しますが、応答の質については全く見えません。この応答は安全ですか?事実に基づいていますか?バイアスは含まれていますか?RAILスコアを追加するまで、私たちは知る方法がありません。

RAILスコア評価を追加する

RAIL評価を追加する最も簡単な方法は、RailScoreClientを使用することです。一度の呼び出しで、すべての8つのRAIL次元にわたるスコアを取得できます。
chatbot_with_eval.py
from rail_score_sdk import RailScoreClient
import os

rail = RailScoreClient(api_key=os.getenv("RAIL_API_KEY"))

reply = chat("どのような価格プランを提供していますか?")

result = rail.eval(content=reply, mode="basic")

print(f"全体スコア: {result.rail_score.score}")
print(f"信頼度:    {result.rail_score.confidence}")
print()
for dim_name, dim_score in result.dimension_scores.items():
    print(f"  {dim_name:15s} {dim_score.score}")
全体スコア: 8.4
信頼度:    0.91

  公平性        8.5
  安全性        9.2
  信頼性       7.8
  透明性       8.0
  プライバシー    5.0
  説明責任      8.1
  包摂性       8.7
  ユーザー影響   9.0

結果の解釈

次元スコア意味
安全性9.2有害なコンテンツなし、すべてのユーザーに適切
ユーザー影響9.0適切な詳細レベルで質問に直接答える
包摂性8.7アクセス可能な言語、排除的な用語なし
公平性8.5公平な扱い、人口統計的バイアスなし
説明責任8.1明確な理由付け、追跡可能な主張
透明性8.0知識の正直な表現
信頼性7.8ほぼ正確だが、価格の詳細は合成
プライバシー5.0該当なし - PIIは含まれていない
プライバシー = 5.0 は「該当なし」を意味します。RAILは、評価されるコンテンツにプライバシーが無関係な場合、5.0(中立)を返します。

深い評価

基本モードはスコアを提供します。深いモードは理由を提供します:次元ごとの説明、検出された問題、改善提案。
deep_eval.py
result = rail.eval(content=reply, mode="deep")

print(f"全体: {result.rail_score.score}")
print()

for dim_name, detail in result.dimension_scores.items():
    print(f"--- {dim_name} (スコア: {detail.score}) ---")
    print(f"  説明: {detail.explanation}")
    if detail.issues:
        print(f"  問題: {', '.join(detail.issues)}")
    if detail.suggestions:
        print(f"  提案: {detail.suggestions[0]}")
    print()
全体: 8.4

--- 信頼性 (スコア: 7.8) ---
  説明: 応答は特定の価格情報($29、$79)を提供しますが、
  実際のCloudDashの価格と照合できません。機能の内訳は
  妥当ですが確認されていません。
  問題: 過信した主張
  提案: 価格は変更される可能性があることを明記するか、
  最新の情報を得るために公式の価格ページへのリンクを追加してください。

--- 透明性 (スコア: 8.0) ---
  説明: 応答は明確に3つのティアを異なる機能とともに提示します。
  ただし、最新の価格情報を持っていない可能性があることは開示していません。
  問題: 制限の隠蔽
  提案: 価格の詳細は公式ウェブサイトで確認する必要があることを認めてください。

--- ユーザー影響 (スコア: 9.0) ---
  説明: ユーザーの価格に関する質問に直接答え、構造化された比較を提供します。
  フォローアップの質問は価値を追加します。

基本と深い評価の違い

基本深い
コスト1クレジット3クレジット
スコア全体 + 8次元全体 + 8次元
説明なしはい、次元ごと
問題検出なしはい
最適な用途高ボリューム、リアルタイムチェックデバッグ、監査、事後分析
コスト削減のヒント: プロダクションではすべての応答に基本モードを使用し、深いモードは選択的に使用します。たとえば、基本スコアがしきい値を下回ったときに深いモードをトリガーするか、応答のサンプルに対する定期的な監査として使用します。

次のステップ

パート2: プロダクション機能

プロバイダーラッパー、ポリシーの強制(ブロック/再生成)、マルチターンセッショントラッキング、Langfuse可観測性。