

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Implementierung von Belohnungsfunktionen
<a name="nova-implementing-reward-functions"></a>

## -Übersicht
<a name="nova-reward-overview"></a>

Die Belohnungsfunktion (auch Scorer oder Grader genannt) ist die Kernkomponente, die Modellantworten auswertet und Feedbacksignale für das Training liefert. Sie muss als Lambda-Funktion implementiert werden, die Modellantworten akzeptiert und Belohnungspunkte zurückgibt.

## Format der Schnittstelle
<a name="nova-reward-interface"></a>

Ihre Prämienfunktion muss Daten im folgenden Format akzeptieren und zurückgeben:

**Beispiel für ein Eingabebeispiel für das Training**

```
{  
    "messages": [  
        {  
            "role": "user",  
            "content": "Do you have a dedicated security team?"  
        }  
    ],              
   "reference_answer": {  
       "compliant": "No",  
       "explanation": "As an AI developed by Company, I do not have a traditional security team..."  
    }  
}
```

**Beispielnutzlast für das Belohnungs-Lambda**

Der Container transformiert Ihre Daten automatisch, bevor er sie an Ihre Lambda-Funktion sendet, indem er:

1. Generieren einer Modellantwort für jede Aufforderung

1. Der Turn des Assistenten (generierte Antwort) wird an das Nachrichten-Array angehängt

1. Ein eindeutiges `id` Feld für die Nachverfolgung hinzufügen

Ihre Lambda-Funktion empfängt Daten in diesem transformierten Format:

```
{    
   "id": "123",  
    "messages": [  
        {  
            "role": "user",  
            "content": "Do you have a dedicated security team?"  
        },  
        {  
            "role": "assistant",  
            "content": "As an AI developed by Amazon, I don not have a dedicated security team..."  
        }  
    ],              
    # Following section will be same as your training dataset sample  
    "reference_answer": {  
        "compliant": "No",  
        "explanation": "As an AI developed by Company, I do not have a traditional security team..."  
    }  
}
```

**Lambda-Vertrag belohnen**

```
def lambda_handler(event, context):  
   return lambda_grader(event)  
  
def lambda_grader(samples: list[dict]) -> list[dict]:  
    """  
    Args:  
        samples: List of dictionaries in OpenAI format  
          
        Example input:  
        {     
            "id": "123",  
            "messages": [  
                {  
                    "role": "user",  
                    "content": "Do you have a dedicated security team?"  
                },  
                {  
                    "role": "assistant",  
                    "content": "As an AI developed by Company, I don nott have a dedicated security team..."  
                }  
            ],              
            # This section will be same as your training dataset  
            "reference_answer": {  
                "compliant": "No",  
                "explanation": "As an AI developed by Company, I do not have a traditional security team..."  
            }  
        }  
      
    Returns:  
        List of dictionaries with reward scores:  
        {  
            "id": str,                              # Same id as input sample  
            "aggregate_reward_score": float,        # Overall score for the sample  
            "metrics_list": [                       # OPTIONAL: Component scores  
                {  
                    "name": str,                    # Name of the component score  
                    "value": float,                 # Value of the component score  
                    "type": str                     # "Reward" or "Metric"  
                }  
            ]  
        }  
    """
```

## Eingabe- und Ausgabefelder
<a name="nova-reward-fields"></a>

### Eingabefelder
<a name="nova-reward-input-fields"></a>


| Feld | Description | Weitere Hinweise | 
| --- | --- | --- | 
| id | Eindeutiger Bezeichner für die Probe | In der Ausgabe wiedergegeben. Zeichenkettenformat | 
| messages | Chatverlauf im OpenAI-Format bestellt | Reihe von Nachrichtenobjekten | 
| nachrichten [] .role | Sprecher der Nachricht | Allgemeine Werte: „Benutzer“, „Assistent“, „System“ | 
| nachrichten [] .content | Textinhalt der Nachricht | Einfache Zeichenfolge | 
| \*\*Metadaten | Informationen in freier Form zur Unterstützung der Benotung | Objekt; optionale Felder, die aus Trainingsdaten übernommen wurden | 

### Ausgabefelder
<a name="nova-reward-output-fields"></a>


| Feld | Description | Weitere Hinweise | 
| --- | --- | --- | 
| id | Derselbe Bezeichner wie beim Eingabebeispiel | Muss mit der Eingabe übereinstimmen | 
| aggregate\_reward\_score | Gesamtpunktzahl für die Stichprobe | Float (z. B. 0,0—1,0 oder aufgabendefinierter Bereich) | 
| metrics\_list | Die Werte der Komponenten, aus denen sich das Aggregat zusammensetzt | Anordnung metrischer Objekte | 

## Technische Einschränkungen
<a name="nova-reward-constraints"></a>
+ **Timeout-Limit** — maximale Ausführungszeit von 15 Minuten pro Lambda-Aufruf
+ **Parallelität — Muss gleichzeitige** Anfragen bearbeiten `rollout_worker_replicas * 64`
+ **Zuverlässigkeit** — Muss eine angemessene Fehlerbehandlung implementieren und konsistent gültige Ergebnisse zurückgeben
+ **Leistung** — Optimiere für eine schnelle Ausführung (Sekunden, nicht Minuten), um effizientes Training zu ermöglichen

**Best Practices**
+ Minimiere externe API-Aufrufe
+ Verwenden Sie effiziente Algorithmen und Datenstrukturen
+ Implementieren Sie eine Wiederholungslogik für vorübergehende Fehler
+ Wiederverwendbare Berechnungen zwischenspeichern
+ Testen Sie vor dem Training gründlich, um eine fehlerfreie Ausführung sicherzustellen

## Verwenden von benutzerdefinierten Belohnungsfunktionen
<a name="nova-reward-using-custom"></a>

Implementieren Sie benutzerdefinierte Belohnungsfunktionen, wenn Sie aufgabenspezifische Bewertungskriterien haben:
+ **Definieren Sie Bewertungskriterien** — Ermitteln Sie, was eine gute Antwort auf Ihre Aufgabe ausmacht
+ **Lambda-Funktion implementieren** — Erstellen Sie eine Lambda-Funktion im Schnittstellenformat
+ **Lokal testen** — Stellen Sie sicher, dass Ihre Funktion korrekte Werte für Beispieleingaben zurückgibt
+ **Bereitstellen auf AWS** — Stellen Sie Ihr Lambda bereit und notieren Sie sich den ARN
+ **Rezept konfigurieren** — Fügen Sie den Lambda-ARN zum Feld Ihres Rezepts `reward_lambda_arn` hinzu
+ **Test mit kleinem Datensatz** — Führen Sie RFT mit minimalen Daten aus, um die Integration zu überprüfen

## IAM-Berechtigungen
<a name="nova-reward-iam"></a>

### Erforderliche Berechtigungen
<a name="nova-reward-required-permissions"></a>

Ihre SageMaker Ausführungsrolle muss über Berechtigungen zum Aufrufen Ihrer Lambda-Funktion verfügen. Fügen Sie diese Richtlinie zu Ihrer SageMaker Ausführungsrolle hinzu:

```
{  
  "Version": "2012-10-17",		 	 	   
  "Statement": [  
    {  
      "Effect": "Allow",  
      "Action": [  
        "lambda:InvokeFunction"  
      ],  
      "Resource": "arn:aws:lambda:region:account-id:function:function-name"  
    }  
  ]  
}
```

### Lambda-Ausführungsrolle
<a name="nova-reward-lambda-role"></a>

Die Ausführungsrolle Ihrer Lambda-Funktion benötigt grundlegende Lambda-Ausführungsberechtigungen:

```
{  
  "Version": "2012-10-17",		 	 	   
  "Statement": [  
    {  
      "Effect": "Allow",  
      "Action": [  
        "logs:CreateLogGroup",  
        "logs:CreateLogStream",  
        "logs:PutLogEvents"  
      ],  
      "Resource": "arn:aws:logs:*:*:*"  
    }  
  ]  
}
```

Zusätzliche Berechtigungen: Wenn Ihre Lambda-Funktion auf andere AWS Dienste zugreift (z. B. S3 für Referenzdaten, DynamoDB für die Protokollierung), fügen Sie diese Berechtigungen der Lambda-Ausführungsrolle hinzu.

## Beispiel: LLM als Prämienfunktion für Richter
<a name="nova-reward-llm-judge-example"></a>

Dieses Beispiel zeigt, wie Amazon Bedrock-Modelle als Richter verwendet werden, um Modellantworten zu bewerten, indem sie mit Referenzantworten verglichen werden. Diese Lambda-Vorlage bietet Kunden ein Framework, mit dem sie Aufrufe an Amazon Bedrock für Inferenzanfragen zur Verarbeitung von Richterbeurteilungen implementieren können. Die Lambda-Funktion behält den gleichen input/output Vertrag wie andere Belohnungsfunktionen bei.

### Implementierung
<a name="nova-reward-llm-judge-implementation"></a>

Diese Lambda-Funktion implementiert einen zweistufigen Bewertungsprozess: Sie `lambda_handler` extrahiert Modellantworten und Referenzantworten aus eingehenden Stichproben. Anschließend ruft die `lambda_graded` Funktion Amazon Bedrock auf, um die semantische Ähnlichkeit zwischen ihnen zu bewerten. Die Implementierung umfasst eine robuste Fehlerbehandlung mit automatischen Wiederholungsversuchen bei vorübergehenden Fehlern und unterstützt flexible Referenzantwortformate (sowohl Zeichenketten- als auch strukturierte Wörterbuchformate).

**Einzelheiten der Implementierung:**
+ **Retry Logic**: Implementiert exponentielles Backoff (1s, 2s, 4s) zur Drosselung von Ausnahmen, um Bedrock-API-Ratenbegrenzungen zu umgehen
+ **Fehlerbehandlung: Gibt für fehlgeschlagene** Auswertungen einen Wert von 0,0 zurück, anstatt Ausnahmen auszulösen
+ **Deterministische Bewertung**: Verwendet Temperatur=0,0, um konsistente Ergebnisse bei allen Bewertungen sicherzustellen
+ **Flexibles Referenzformat**: Verarbeitet automatisch Antworten auf Zeichenketten und Wörterbuchreferenzen
+ **Punktebegrenzung**: Stellt sicher, dass alle Ergebnisse innerhalb des gültigen Bereichs [0,0, 1,0] liegen
+ **Modellunabhängig**: Ändern Sie JUDGE\_MODEL\_ID, um ein beliebiges Amazon Bedrock-Modell (Nova, Llama, Mistral usw.) zu verwenden

```
"""  
LLM Judge Lambda POC - Working implementation using Amazon Bedrock  
"""  
  
import json  
import time  
import boto3  
  
bedrock_runtime = boto3.client('bedrock-runtime', region_name='us-east-1')  
JUDGE_MODEL_ID = "anthropic.claude-3-5-sonnet-20240620-v1:0"  
SYSTEM_PROMPT = "You must output ONLY a number between 0.0 and 1.0. No explanations, no text, just the number."  
  
JUDGE_PROMPT_TEMPLATE = """Compare the following two responses and rate how similar they are on a scale of 0.0 to 1.0, where:  
- 1.0 means the responses are semantically equivalent (same meaning, even if worded differently)  
- 0.5 means the responses are partially similar  
- 0.0 means the responses are completely different or contradictory  
  
Response A: {response_a}  
  
Response B: {response_b}  
  
Output ONLY a number between 0.0 and 1.0. No explanations."""  
  
  
def lambda_graded(response_a: str, response_b: str, max_retries: int = 3) -> float:  
    """Call Bedrock to compare responses and return similarity score."""  
    prompt = JUDGE_PROMPT_TEMPLATE.format(response_a=response_a, response_b=response_b)  
      
    for attempt in range(max_retries):  
        try:  
            response = bedrock_runtime.converse(  
                modelId=JUDGE_MODEL_ID,  
                messages=[{"role": "user", "content": [{"text": prompt}]}],  
                system=[{"text": SYSTEM_PROMPT}],  
                inferenceConfig={"temperature": 0.0, "maxTokens": 10}  
            )  
            print(f"Bedrock call successful: {response}")  
            output = response['output']['message']['content'][0]['text'].strip()  
            score = float(output)  
            print(f"Score parsed: {score}")  
            return max(0.0, min(1.0, score))  
                  
        except Exception as e:  
            if "ThrottlingException" in str(e) and attempt < max_retries - 1:  
                time.sleep(2 ** attempt)  
            else:  
                print(f"Bedrock call failed: {e}")  
                return None  
    return None  
  
  
def lambda_handler(event, context):  
    """AWS Lambda handler - processes samples from RFTEvalInvoker."""  
    try:  
        samples = event if isinstance(event, list) else [event]  
        results = []  
          
        for sample in samples:  
            sample_id = sample.get("id", "unknown")  
            messages = sample.get("messages", [])  
              
            # Extract assistant response (response A)  
            response_a = ""  
            for msg in messages:  
                if msg.get("role") in ["assistant", "nova_assistant"]:  
                    response_a = msg.get("content", "")  
                    break  
              
            # Extract reference answer from root level (no longer in metadata)  
            reference_answer = sample.get("reference_answer", "")  
              
            # Handle both string and dict reference_answer formats  
            if isinstance(reference_answer, dict):  
                # If reference_answer is a dict, extract the explanation or compliant field  
                response_b = reference_answer.get("explanation", reference_answer.get("compliant", ""))  
            else:  
                response_b = reference_answer  
              
            if not response_a or not response_b:  
                results.append({  
                    "id": sample_id,  
                    "aggregate_reward_score": 0.0,  
                    "metrics_list": [{"name": "similarity_score", "value": 0.0, "type": "Metric"}]  
                })  
                continue  
              
            # Get similarity score  
            score = lambda_graded(response_a, response_b)  
              
            results.append({  
                "id": sample_id,  
                "aggregate_reward_score": score,  
                "metrics_list": [  
                    {  
                        "name": "similarity_score",  
                        "value": score,  
                        "type": "Metric"  
                    }  
                ]  
            })  
          
        return {"statusCode": 200, "body": json.dumps(results)}  
          
    except Exception as e:  
        print(f"Error: {e}")  
        return {"statusCode": 500, "body": json.dumps({"error": str(e)})}
```

### Eingabeformat
<a name="nova-reward-llm-judge-input"></a>

Das Lambda erhält dasselbe Eingabeformat wie andere Belohnungsfunktionen:

```
{  
    "id": "sample-001",  
    "messages": [  
        {  
            "role": "user",  
            "content": "Do you have a dedicated security team?"  
        },  
        {  
            "role": "assistant",  
            "content": "As an AI developed by Amazon, I don't have a dedicated security team..."  
        }  
    ],  
    "reference_answer": {  
        "compliant": "No",  
        "explanation": "As an AI developed by Company, I do not have a traditional security team..."  
    },  
    "my_custom_field": "custom_value"  
}
```

### Ausgabeformat
<a name="nova-reward-llm-judge-output"></a>

```
{  
    "id": "sample-001",  
    "aggregate_reward_score": 0.85,  
    "metrics_list": [  
        {  
            "name": "similarity_score",  
            "value": 0.85,  
            "type": "Metric"  
        }  
    ]  
}
```

### Überlegungen zur Bereitstellung
<a name="nova-reward-llm-judge-deployment"></a>

Möglicherweise müssen Sie auch die Eingabeaufforderungsvorlage und die Inferenzparameter an die Funktionen und das API-Format Ihres ausgewählten Modells anpassen.
+ **IAM-Berechtigungen**: Die Lambda-Ausführungsrolle muss über `bedrock:InvokeModel` Berechtigungen für das von Ihnen gewählte Modell verfügen
+ **Timeout**: Legen Sie das Lambda-Timeout auf mindestens 60 Sekunden fest, um der Bedrock-API-Latenz und den Wiederholungsversuchen Rechnung zu tragen
+ **Region**: In einer Region einsetzen, in der das von Ihnen gewählte Bedrock-Modell verfügbar ist
+ **Kosten**: Überwachen Sie die Bedrock-API-Nutzung, da bei jeder Evaluierung ein API-Aufruf pro Probe erfolgt
+ **Durchsatz**: Fordern Sie für umfangreiche Evaluationen erhöhte Bedrock-Kontingente an, um Drosselungen zu vermeiden

**Erhöhung des Durchsatzes im Grundgestein**

Wenn Sie während der Evaluierung eine Drosselung feststellen, erhöhen Sie die Kontingente für Ihr Bedrock-Modell:
+ Navigieren Sie zur AWS Service Quotas Quotas-Konsole.
+ Suchen Sie nach „Bedrock“ und wählen Sie Ihre Region aus
+ Finden Sie das Kontingent für das von Ihnen gewählte Modell heraus (zum Beispiel „Aufrufe pro Minute für Claude 3.5 Sonnet“)
+ Klicken Sie auf „Erhöhung des Kontingents beantragen“ und geben Sie den gewünschten Durchsatz an
+ Begründen Sie die Erhöhung (z. B. „Arbeitsaufwand bei der RFT-Evaluierung“)

Die integrierte Wiederholungslogik von Lambda verarbeitet gelegentliche Drosselungen, aber dauerhaft umfangreiche Auswertungen erfordern angemessene Quotenerhöhungen.

**Erforderliche IAM-Richtlinie:**

```
{  
    "Version": "2012-10-17",		 	 	   
    "Statement": [  
        {  
            "Effect": "Allow",  
            "Action": [  
                "bedrock:InvokeModel"  
            ],  
            "Resource": "arn:aws:bedrock:*::foundation-model/*"  
        }  
    ]  
}
```