👻

検索結果の評価プロンプト

2025/02/07に公開
import openai
from openai.resources.chat.completions import ChatCompletion
import os, json

def evaluate_relevance(question: str, search_results: list) -> str:
    """
    質問文と検索結果のリストに基づいて、各検索結果("text" フィールド)の関連性評価を実行する関数

    :param question: 質問文
    :param search_results: [{ "idx": int, "scores": 任意, "text": str }, ...] の形式の検索結果リスト
    :return: LLMから返された評価結果
    """
    # 検索結果リストをJSON形式に整形(可読性のためインデント付き)
    search_results_str = json.dumps(search_results, ensure_ascii=False, indent=2)
    
    # プロンプトの作成
    # prompt = """
    # """.format(question=question, search_results_str=search_results_str)
    prompt = """次の入力データに基づいて、知識検索結果のリストに含まれる各検索結果の "text" フィールドが、質問文に対してどの程度関連しているかを評価してください。

【質問文】
{question}

【検索結果のリスト】
{search_results_str}

【評価形式】
各検索結果に対して、以下の形式で評価してください。
- idx: 対象の検索結果の識別番号
- score: 0〜100の数値(例: "85/100")または0〜1のスケールで示してください。
- reason: 簡潔な説明(1~2文程度)で、どの点からそのスコアに至ったか説明してください。

なお、結果は有効なJSON形式のリスト(list of dict)として出力してください。

例)
[
    \{
        "idx": 1,
        "score": "85/100",
        "reason": "この検索結果は質問文の主要なキーワードに直接触れており、具体的な情報が含まれているため関連性が高いと判断されます。"
    \},
    \{
        "idx": 2,
        "score": "60/100",
        "reason": "この検索結果は質問文の一部のキーワードに触れているものの、情報が限定的なため関連性は中程度と判断されます。"
    \}
]"""

    # prompt = prompt.format(question=question, search_results_str=search_results_str)
    prompt = prompt.replace("{question}", question).replace("{search_results_str}", search_results_str)
    # print(prompt)
    # ChatCompletion API を呼び出して評価を実行
    client = openai.AzureOpenAI(
        azure_endpoint=os.environ.get("AZURE_OPENAI_ENDPOINT"),
        api_key=os.environ.get("AZURE_OPENAI_API_KEY"),
        api_version=os.environ.get("OPENAI_API_VERSION")
    )

    response: ChatCompletion = client.chat.completions.create(
        model="gpt-4o",  # 必要に応じてモデル名を変更してください
        messages=[
            {"role": "system", "content": "あなたは質問文と検索結果の関連性評価の専門家です。"},
            {"role": "user", "content": prompt}
        ],
        temperature=0.0,  # 出力の安定性を重視する場合は低めの温度に設定
    )

    # 応答から評価結果のテキスト部分を抽出して返す
    result_text = response.choices[0].message.content.strip()
    # print(result_text)
    
    # 出力が有効なJSON形式のリストになるようにパース
    try:
        evaluation_results = json.loads(result_text)
    except json.JSONDecodeError as e:
        print("JSONデコードエラー:", e)
        evaluation_results = None
    return evaluation_results

if __name__ == "__main__":
    # 使用例:質問文と検索結果リストを設定
    sample_question = "再生可能エネルギーの主な利点は何ですか?"
    sample_search_results = [
        {"idx": 1, "scores": None, "text": "再生可能エネルギーは、環境への影響が少なく、持続可能なエネルギー供給を実現するために不可欠な資源です。"},
        {"idx": 2, "scores": None, "text": "再生可能エネルギーは、初期投資が高いが運用コストが低いという特徴があります。"}
    ]
    
    # 評価を実行し、結果を list[dict] として受け取る
    evaluation = evaluate_relevance(sample_question, sample_search_results)
    print("評価結果:")
    print(evaluation)

Discussion