Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.
Création d'actifs pour l'apprentissage par renforcement à plusieurs tours
Format de jeu de données rapide
Votre ensemble de données d'entraînement est un ensemble d'instructions que l' SageMaker IA envoie à votre agent pendant l'entraînement. Chaque invite donne le coup d'envoi d'un déploiement : votre agent le traite, prend des mesures en un ou plusieurs tours et renvoie une récompense. La qualité et la structure de votre jeu de données influent directement sur ce que le modèle apprend.
Formats de fichier pris en charge
| Format | Extension | Remarques |
|---|---|---|
| Apache Parquet | .parquet | Recommandé pour les grands ensembles de données : stockage efficace et chargement rapide |
| JSON Lines | .json | Un objet JSON par ligne, facile à créer et lisible par l'homme |
| JSON | .json | Tableau d'objets JSON |
| CSV | .csv | Comma-separated valeurs avec une ligne d'en-tête |
schéma du jeu de données
Détection rapide des colonnes
Le service RFT détecte la colonne d'invite selon les règles suivantes, dans l'ordre :
-
Si une colonne nommée
promptexiste, elle est utilisée. -
Dans le cas contraire, c'est la première colonne de l'ensemble de données qui est utilisée.
Nommez toujours votre colonne prompt d'invite pour éviter toute ambiguïté. Vous pouvez inclure des colonnes supplémentaires à des fins de suivi, mais seule la colonne d'invite est lue par le service RFT.
Comment les invites sont utilisées
Le service RFT lit la colonne d'invite et transmet la valeur de la chaîne directement à votre agent telle quelle. Il n'analyse, ne valide ni ne transforme le contenu. Le format à utiliser dépend entièrement des attentes de votre agent : un agent simple peut utiliser du texte brut, tandis qu'un agent plus sophistiqué peut s'attendre à une chaîne JSON contenant l'historique des conversations, la configuration des outils et les spécifications des récompenses.
Protection des données
Étant donné que le service RFT transmet les instructions sans inspection, vous êtes responsable de la protection du contenu sensible. Envisagez d'encoder ou de chiffrer les données d'invite avant de les stocker, et de gérer le décodage ou le déchiffrement dans votre agent.
Approches communes :
-
Encodage Base64 : obfuscation simple pour les données non sensibles
-
Chiffrement : pour les données sensibles ou propriétaires (par exemple, AES avec des clés gérées par votre agent)
Exemple 1 : jeu de données Q & A simple (texte brut)
Pour des tâches de formation simples avec des instructions en texte brut.
Cas d'utilisation : réponse à une question de base, instructions simples à suivre
Parquet (Python)
import pyarrow as pa import pyarrow.parquet as pq data = { "prompt": [ "What is 2 + 2?", "Explain the concept of machine learning.", "Write a Python function to reverse a string.", "What is the capital of France?", "How does photosynthesis work?", ] } table = pa.table(data) pq.write_table(table, "training_data.parquet")
Lignes JSON (.jsonl)
{"prompt": "What is 2 + 2?"} {"prompt": "Explain the concept of machine learning."} {"prompt": "Write a Python function to reverse a string."}
Exemple 2 : Search/Reasoning avec l'utilisation d'outils
Pour les tâches nécessitant un accès à un outil externe (par exemple, les moteurs de recherche) lors du raisonnement du modèle.
Cas d'utilisation : Fact-based questions-réponses avec recherche sur le Web, raisonnement assisté par extraction
Structure :
prompt (column) = JSON string (recommend encoded/encrypted) containing: ├── data_source: Dataset origin identifier ├── prompt: Conversation messages [system, user] ├── ability: Task category (e.g., "fact-reasoning") ├── env_class: "search" ├── reward_spec: Ground truth answer for evaluation └── extra_info: Tool configuration and metadata
Exemple de ligne :
import pyarrow as pa import pyarrow.parquet as pq import json task_data = { "data_source": "searchR1_nq", "prompt": [ { "role": "system", "content": "You are a helpful and harmless assistant." }, { "role": "user", "content": "Answer the given question. You must conduct reasoning inside <think> and </think> first every time you get new information. After reasoning, if you find you lack some knowledge, you can call a search engine by <search> query </search> and it will return the top searched results between <information> and </information>. You can search as many times as you want. If you find no further external knowledge needed, you can directly provide the answer inside <answer> and </answer>, without detailed illustrations. For example, <answer> Beijing </answer>. Question: total number of death row inmates in the us?" } ], "ability": "fact-reasoning", "env_class": "search", "reward_spec": { "ground_truth": { "target": [ "2,718" ] }, "style": "rule" }, "extra_info": { "index": 0, "question": "total number of death row inmates in the us?", "split": "train", "need_tools_kwargs": true, "tools_kwargs": { "search": { "create_kwargs": { "question": "total number of death row inmates in the us?", "ground_truth": { "target": [ "2,718" ] }, "data_source": "searchR1_nq" } } } } } # Recommend: encode or encrypt before storing data = {"prompt": [json.dumps(task_data)]} table = pa.table(data) pq.write_table(table, "search_training_data.parquet")
Exemple 3 : génération de code SQL (Multi-Turn avec contexte complexe)
Pour les tâches de génération de code nécessitant des schémas de base de données, un raisonnement en plusieurs étapes et des commentaires sur l'exécution du code SQL.
Cas d'utilisation : Text-to-SQL génération de code avec vérification de l'exécution
Structure :
prompt (column) = JSON string (recommend encoded/encrypted) containing: ├── input_seq: Human-readable task description ├── prompt: Conversation messages [system, user] ├── env_class: "text2sql" ├── reward_spec: Ground truth SQL and evaluation config ├── instance_id: Unique task identifier ├── schema: Database schema definition ├── question: Natural language question └── extra_info: Additional metadata
Exemple de ligne :
import pyarrow as pa import pyarrow.parquet as pq import json task_data = { "input_seq": "Task Overview:\nYou are a data science expert. Below, you are provided with a database schema\nand a natural language question. Your task is to understand the schema and\ngenerate a valid SQL query to answer the question.\n\nDatabase Engine: SQLite\n\nDatabase Schema:\nCREATE TABLE countries (\n country_id INTEGER PRIMARY KEY,\n english_name TEXT,\n population INTEGER\n);\n\nCREATE TABLE country_metrics (\n metric_id INTEGER PRIMARY KEY,\n country_id INTEGER,\n metric_type TEXT,\n year INTEGER,\n value REAL\n);\n\nQuestion: List all countries with their current population and average\npopulation over the last five years.", "prompt": [ { "role": "system", "content": "Task Overview:\nYou are a data science expert. Your task is to understand the schema and generate\na valid SQL query to answer the question within limited turns.\n\nInstructions:\n- Make sure you only output the information asked in the question.\n- Think through the steps before generating the final SQL query.\n\nFormat:\n- Conduct thinking inside <think>...</think> blocks.\n- You can use SQL tool written within <sql>your sql</sql> to explore or verify.\n- SQL tool output will be shown inside <observation>...</observation>.\n- Provide the final SQL query inside <solution>...</solution>." }, { "role": "user", "content": "Database Schema:\nCREATE TABLE countries (\n country_id INTEGER PRIMARY KEY,\n english_name TEXT,\n population INTEGER\n);\n\nCREATE TABLE country_metrics (\n metric_id INTEGER PRIMARY KEY,\n country_id INTEGER,\n metric_type TEXT,\n year INTEGER,\n value REAL\n);\n\nQuestion: List all countries with their current population and average\npopulation over the last five years." } ], "env_class": "text2sql", "instance_id": "sql_task_001", "reward_spec": { "ground_truth": "SELECT c.english_name, c.population, AVG(m.value) as avg_pop\nFROM countries c\nJOIN country_metrics m ON c.country_id = m.country_id\nWHERE m.metric_type = 'Population' AND m.year > strftime('%Y', 'now') - 5\nGROUP BY c.country_id;", "style": "rule" }, "schema": "CREATE TABLE countries (...); CREATE TABLE country_metrics (...);", "question": "List all countries with their current population...", "extra_info": { "split": "train", "difficulty": "medium" } } # Recommend: encode or encrypt before storing data = {"prompt": [json.dumps(task_data)]} table = pa.table(data) pq.write_table(table, "sql_training_data.parquet")
Bonnes pratiques
Taille du jeu de données
Le nombre minimum d'exemples est au moins égal àtraining_batch_size. Il est recommandé de multiplier par 10 la taille de votre lot pour des raisons de diversité.
Qualité rapide
-
Contexte complet : incluez toutes les informations nécessaires pour que le modèle génère des réponses utiles
-
Structure cohérente : maintenez une mise en forme cohérente pour toutes les invites
-
Évitez les doublons : des instructions uniques fournissent un meilleur signal d'entraînement
-
Instructions claires : pour les tâches liées à l'utilisation d'outils, fournissez des instructions de formatage explicites
Protection des données
-
Codez ou chiffrez le contenu des messages instantanés pour protéger les données sensibles
-
Gérez les clés de déchiffrement en toute sécurité sur votre serveur de déploiement
-
Le service RFT transmet les instructions sans inspection, la protection est donc de votre responsabilité
Conception de la fonction de récompense
La conception de la fonction de récompense est essentielle pour fournir des signaux d'apprentissage efficaces dans des systèmes d'agents complexes en plusieurs étapes. Lorsque vous concevez des fonctions de récompense pour un RL à tours multiples, tenez compte des directives suivantes.
-
Commencez par des récompenses basées sur les résultats. Marquez d'abord le résultat final pour établir une base de référence claire et fiable avant d'ajouter des récompenses intermédiaires ou de façonner les récompenses.
-
Envisagez des récompenses continues plutôt que des récompenses binaires. Les récompenses continues peuvent fournir des signaux de crédit partiels plus clairs, mais elles sont faciles à jouer. Les récompenses binaires sont préférables lorsque le crédit partiel est difficile à définir ou lorsqu'une base de référence claire est nécessaire.
-
Utilisez les récompenses de façonnage avec soin. La mise en forme des récompenses peut orienter l'apprentissage, mais elles doivent être utilisées avec parcimonie, car une mise en forme trop forte ou mal alignée peut indiquer des raccourcis.
-
Prémunissez-vous contre le piratage des récompenses. Rendez les récompenses difficiles à exploiter et vérifiez que le modèle résout la vraie tâche plutôt que de contourner la règle du score.
-
Validez avant l'entraînement. Testez la fonction de récompense sur des trajectoires réelles avant de vous entraîner pour détecter les bugs, les failles ou les signaux trompeurs.
-
Surveillez les indicateurs comportementaux, et pas seulement les récompenses. Suivez des indicateurs tels que le taux d'achèvement, le nombre de tours, l'utilisation des outils et l'écart de surajustement pour vous assurer que le modèle s'améliore comme prévu.
Processus de conception des récompenses
-
Définissez à quoi ressemble le succès et déterminez s'il peut être noté automatiquement.
-
Évaluez le modèle de base pour établir un taux de réussite de référence.
-
Concevez des niveaux de récompense : récompenses positives en cas de succès, zéro récompense en cas d'échec et récompenses négatives en cas de comportement dégénéré.
-
Gérez les cas extrêmes de manière explicite, notamment les délais d'expiration, les erreurs d'environnement, les sorties mal formées et les réponses vides.
-
Vérifiez chaque élément de récompense pour détecter d'éventuels piratages de récompenses.
-
Validez sur des trajectoires réelles avant l'entraînement.
-
Surveillez parallèlement les indicateurs comportementaux pendant l'entraînement.
-
Effectuez une itération en fonction des premiers résultats.
En pratique, une fonction de récompense prend l'historique complet des messages d'un épisode comme entrée et renvoie deux sorties : une récompense scalaire (un score à virgule flottante mesurant la qualité de la trajectoire, les valeurs les plus élevées indiquant de meilleures performances) et un dictionnaire de métriques pour la journalisation, le débogage et le suivi.
Exemple : fonction de récompense d'un agent de recherche
L'exemple suivant montre une fonction de récompense pour un agent qui répond à des questions à l'aide de la recherche. Il montre l'évaluation des résultats, la mise en forme du format et la vérification de l'exactitude des réponses.
class TextAnswerReward: """Reward function to check text answer against gold answers. formula: format_coef * (correct_format - 1) + correct_answer """ gold_answers: list[str] format_coef: float = 0.1 async def __call__(self, history: list[Message]) -> tuple[float, dict[str, float]]: """Grade the completed episode by checking the final assistant message.""" final_message = None for msg in reversed(history): if msg.get("role") == "assistant": final_message = msg break if final_message is None: return 0.0, {"format": 0.0, "correct": 0.0} content = get_text_content(final_message) correct_format = float(self._extract_answer(content) is not None) correct_answer = float(self._check_answer(content)) reward = self.format_coef * (correct_format - 1) + correct_answer return reward, {"format": correct_format, "correct": correct_answer} def _extract_answer(self, text: str) -> str | None: if "Answer:" not in text: return None parts = text.split("Answer:") if len(parts) != 2: return None return parts[1].strip() def _check_answer(self, text: str) -> bool: model_answer = self._extract_answer(text) if model_answer is None or len(self.gold_answers) == 0: return False for gold in self.gold_answers: if normalize_answer(model_answer) == normalize_answer(gold): return True return False
Cette fonction de récompense inclut les principaux choix de design suivants :
-
L'exactitude domine. Une bonne réponse obtient toujours un score supérieur à une mauvaise, quel que soit le format.
-
Le format est un petit signal de mise en forme. Le coefficient de format (0,1) est de 10 % de la récompense du résultat, suffisamment faible pour que le modèle ne puisse pas tirer profit de la seule conformité au format, mais suffisamment élevé pour l'orienter vers des sorties analysables.
-
Un mauvais format avec une mauvaise réponse est légèrement pénalisé. Le score de -0,1 crée un léger gradient par rapport aux sorties totalement déstructurées, sans surcharger le signal d'apprentissage.
-
Aucune réponse n'est considérée comme incorrecte si le format est incorrect. Si le modèle ne produit jamais de message d'assistant, la fonction renvoie 0,0, ce qui le distingue de la pénalité active de -0,1 pour une réponse présente mais mal formée.