Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.
Creación de activos para el aprendizaje por refuerzo en varios turnos
Formato de conjunto de datos rápido
Tu conjunto de datos de entrenamiento es un conjunto de indicaciones que la SageMaker IA envía a tu agente durante el entrenamiento. Cada mensaje da inicio a un lanzamiento: tu agente lo procesa, realiza acciones en uno o más turnos y devuelve una recompensa. La calidad y la estructura del conjunto de datos afectan directamente a lo que aprende el modelo.
Formatos de archivo compatibles
| Formato | Extensión | Notas |
|---|---|---|
| Apache Parquet | .parquet | Recomendado para conjuntos de datos grandes: almacenamiento eficiente y carga rápida |
| Líneas de JSON | .jsonl | Un objeto JSON por línea: fácil de crear y legible por humanos |
| JSON | .json | Matriz de objetos JSON |
| CSV | .csv | Comma-separated valores con una fila de encabezado |
esquema de conjunto de datos
Detección rápida de columnas
El servicio RFT detecta la columna de mensajes siguiendo las siguientes reglas, en orden:
-
Si
promptexiste una columna con el nombre, se utiliza esa columna. -
De lo contrario, se utiliza la primera columna del conjunto de datos.
Siempre asigne un nombre a la columna de prompt preguntas para evitar ambigüedades. Puedes incluir columnas adicionales para tus propios fines de seguimiento, pero el servicio de RFT solo lee la columna de mensajes.
Cómo se utilizan las indicaciones
El servicio RFT lee la columna de mensajes y pasa el valor de la cadena directamente al agente tal como está. No analiza, valida ni transforma el contenido. El formato que se utilice depende totalmente de lo que espere su agente: un agente simple podría usar texto sin formato, mientras que uno más sofisticado podría esperar una cadena JSON que contenga el historial de conversaciones, la configuración de las herramientas y las especificaciones de recompensas.
Protección de los datos
Como el servicio de RFT envía las instrucciones sin necesidad de inspeccionarlas, usted es responsable de proteger el contenido confidencial. Considere la posibilidad de codificar o cifrar los datos de las solicitudes antes de almacenarlos y de gestionar la decodificación o el descifrado en su agente.
Enfoques comunes:
-
Codificación Base64: ofuscación simple para datos no confidenciales
-
Cifrado: para datos confidenciales o privados (por ejemplo, AES con claves administradas por su agente)
Ejemplo 1: conjunto de datos de & preguntas y respuestas simple (texto sin formato)
Para tareas de entrenamiento sencillas con instrucciones en texto plano.
Caso de uso: respuesta básica a preguntas, seguimiento de instrucciones sencillas
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")
Líneas JSON (.jsonl)
{"prompt": "What is 2 + 2?"} {"prompt": "Explain the concept of machine learning."} {"prompt": "Write a Python function to reverse a string."}
Ejemplo 2: Search/Reasoning con el uso de herramientas
Para tareas que requieren acceso a herramientas externas (por ejemplo, motores de búsqueda) durante el razonamiento del modelo.
Caso de uso: Fact-based preguntas y respuestas con búsqueda en la web, razonamiento con recuperación aumentada
Estructura:
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
Fila de ejemplo:
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")
Ejemplo 3: Generación de SQL (Multi-Turn con un contexto complejo)
Para tareas de generación de código que requieren esquemas de bases de datos, razonamiento en varios pasos y comentarios sobre la ejecución de SQL.
Caso de uso: generación Text-to-SQL de código con verificación de ejecución
Estructura:
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
Fila de ejemplo:
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")
Prácticas recomendadas
Tamaño del conjunto de datos
El número mínimo de ejemplos es igual atraining_batch_size. Se recomienda multiplicar por más de 10 el tamaño del lote por motivos de diversidad.
Calidad inmediata
-
Contexto completo: incluya toda la información necesaria para que el modelo genere respuestas útiles
-
Estructura coherente: mantenga un formato coherente en todas las solicitudes
-
Evita los duplicados: las indicaciones únicas proporcionan una mejor señal de entrenamiento
-
Instrucciones claras: para las tareas de uso de herramientas, proporciona instrucciones de formato explícitas
Protección de los datos
-
Codifique o cifre el contenido de los mensajes para proteger los datos confidenciales
-
Gestione las claves de descifrado de forma segura en su servidor de despliegue
-
El servicio de RFT envía las instrucciones sin necesidad de inspeccionarlas, por lo que la protección es su responsabilidad
Diseño de la función de recompensa
El diseño de la función de recompensa es fundamental para proporcionar señales de aprendizaje eficaces en sistemas de agentes complejos y de varios pasos. Al diseñar funciones de recompensa para RL de varios turnos, ten en cuenta las siguientes pautas.
-
Comience con las recompensas basadas en los resultados. Puntúa primero el resultado final para establecer una base clara y fiable antes de añadir recompensas intermedias o modelar las recompensas.
-
Considera las recompensas continuas en lugar de las recompensas binarias. Las recompensas continuas pueden proporcionar señales más claras de crédito parcial, pero son fáciles de engañar. Se prefieren las recompensas binarias cuando es difícil definir el crédito parcial o cuando se necesita una base de referencia clara.
-
Utilice el modelado de recompensas con cuidado. Dar forma a las recompensas puede servir de guía para el aprendizaje, pero debes usarlas con moderación, ya que darles una forma demasiado fuerte o desalineada puede enseñar atajos.
-
Protégete del hackeo con recompensas. Haz que las recompensas sean difíciles de aprovechar y comprueba que el modelo está resolviendo la verdadera tarea en lugar de seguir la regla de puntuación.
-
Valide antes del entrenamiento. Prueba la función de recompensa en trayectorias reales antes de entrenar para atrapar bichos, lagunas o señales engañosas.
-
Supervisa las métricas de comportamiento, no solo las recompensas. Realice un seguimiento de métricas como la tasa de finalización, el número de turnos, el uso de herramientas y la brecha de sobreajuste para garantizar que el modelo mejore de la manera prevista.
Proceso de diseño de recompensas
-
Defina qué aspecto tiene el éxito y determine si se puede puntuar automáticamente.
-
Evalúe el modelo base para establecer una tasa de éxito de referencia.
-
Diseñe niveles de recompensa: recompensas positivas por el éxito, cero recompensas por el fracaso y recompensas negativas por un comportamiento degenerado.
-
Gestione los casos extremos de forma explícita, como los tiempos de espera, los errores del entorno, los resultados con formato incorrecto y las respuestas vacías.
-
Comprueba cada componente de recompensa para ver si es posible hackear una recompensa.
-
Valide las trayectorias reales antes del entrenamiento.
-
Supervisa junto con las métricas de comportamiento durante el entrenamiento.
-
Repite en función de los resultados iniciales.
En la práctica, una función de recompensa toma como entrada el historial completo de mensajes de un episodio y devuelve dos resultados: una recompensa escalar (una puntuación de punto flotante que mide la calidad de la trayectoria, con valores más altos que indican un mejor rendimiento) y un diccionario de métricas para registrar, depurar y monitorizar.
Ejemplo: función de recompensa de un agente de búsqueda
En el siguiente ejemplo, se muestra una función de recompensa para un agente que responde a las preguntas mediante la búsqueda. Muestra la evaluación de los resultados, la configuración del formato y la comprobación de la exactitud de las respuestas.
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
Esta función de recompensa incluye las siguientes opciones de diseño clave:
-
Predomina la corrección. Una respuesta correcta siempre obtiene una puntuación más alta que una incorrecta, independientemente del formato.
-
El formato es una señal de modelado pequeña. El coeficiente de formato (0,1) es el 10% de la recompensa del resultado, lo suficientemente pequeño como para que el modelo no pueda beneficiarse únicamente del cumplimiento del formato, pero lo suficientemente grande como para orientarlo hacia resultados analizables.
-
El formato incorrecto con una respuesta incorrecta se penaliza levemente. La puntuación de -0,1 crea un pequeño gradiente lejos de las salidas completamente desestructuradas, sin sobrecargar la señal de aprendizaje.
-
Ninguna respuesta se considera incorrecta con un formato incorrecto. Si el modelo nunca genera un mensaje auxiliar, la función devuelve 0.0, distinguiéndolo de la penalización activa de -0.1 para una respuesta presente pero mal formada.