Herramientas de clases Apex
¿Qué es una herramienta de clase Apex?
Una herramienta de clase Apex es el tercer tipo de herramienta que puedes crear en el Generador de herramientas de REDA AI, junto a las de plantilla SOQL y las de mapeo de archivos. Recurre a ella cuando:
- El trabajo requiere lógica condicional, varios pasos o escrituras en más de un objeto
- Necesitas hacer una llamada externa a otro sistema como parte de la herramienta
- Quieres conciliar con registros existentes, eliminar duplicados o aplicar reglas de negocio antes de escribir
- Estás configurando una extracción a partir de un archivo cuya estructura de datos es demasiado rica para un mapeo declarativo
La plataforma se encarga del contrato con el agente: el JSON Schema, la validación de la entrada, el envoltorio de errores, la confirmación de acciones, el registro de auditoría y el formato del resultado. Tu clase Apex solo se ocupa del trabajo en sí.
La interfaz del ejecutor
Cada herramienta de clase Apex implementa una única interfaz global:
global interface REDAAI_Executable {
Object execute(String toolName, Map<String, Object> input);
}
Dos parámetros, un valor de retorno:
toolName— el nombre de desarrollador de la Definición de herramienta que originó esta llamada. Úsalo si una misma clase implementa varias herramientas y necesita ramificar según quién la invoca.input— los parámetros que proporcionó el agente, validados contra el JSON de tu Esquema de entrada, más la clave_channelque se describe más abajo.- Valor de retorno — depende de la categoría de la herramienta (consulta Contrato de retorno más abajo).
Saber en qué canal te estás ejecutando
La misma herramienta puede ser invocada por un agente con el que un compañero conversa dentro de Salesforce, por un widget público de un sitio web o por un agente de API sin supervisión que se ejecuta de madrugada, y a menudo lo correcto es comportarse de forma distinta en cada caso. Por eso REDA AI añade un conjunto de claves proporcionadas por la plataforma al mapa input antes de llamarte, empezando por el canal:
global class OrderLookupTool implements REDAAI_Executable {
global Object execute(String toolName, Map<String, Object> input) {
String channel = (String) input.get('_channel'); // 'Internal' | 'External_Widget' | 'Community' | 'API'
if (REDAAIConstants.CHANNEL_EXTERNAL_WIDGET.equals(channel)) {
return summaryForPublicVisitor(input);
}
return fullInternalDetail(input);
}
}
El valor es Internal, External_Widget, Community o API — los mismos valores que usa el campo Canal, así que compara con las constantes REDAAIConstants.CHANNEL_* en lugar de escribir el literal. Lo establece la plataforma, no el agente. Si el modelo intenta proporcionar _channel por su cuenta, REDA AI lo sobrescribe; y cuando el canal realmente no puede resolverse, la clave se elimina por completo en lugar de dejarla con un valor inventado por el modelo. Así, un _channel presente siempre es fiable, y su ausencia significa «desconocido», nunca «Internal».
_channel te dice dónde estás, no lo que puedes hacer. Es contexto para dar forma a una respuesta —cuánto detalle devolver, qué tono usar— y no es una señal de permisos. Nunca interpretes _channel == 'API' como licencia para omitir una comprobación que tu herramienta haría de otro modo. El acceso a objetos y campos lo decide la plataforma y el usuario que ejecuta, como se describe en Acceso a datos y permisos; una herramienta que se concede a sí misma poderes adicionales a partir de esta clave está escribiendo su propio modelo de seguridad, y se equivocará.
Dos claves más llegan de la misma forma, con la misma garantía de sobrescritura y eliminación — la plataforma siempre las proporciona, y cualquier valor que el modelo intente establecer se descarta:
| Clave | Qué contiene | Úsala para |
|---|---|---|
_conversation_id |
El Id de la conversación en la que se ejecuta la herramienta. | Escribir una traza de auditoría de vuelta en la conversación, o resolver configuración con ámbito de conversación (así es como el correo con marca encuentra la marca correcta). |
_agent_definition_id |
El Id del agente que llamó a la herramienta. | Comportarse de forma distinta según el agente, o registrar qué agente realizó una escritura. |
Ambas se eliminan en lugar de quedarse obsoletas cuando no hay conversación o agente en contexto — así que, igual que con _channel, un valor presente es fiable y su ausencia significa «desconocido».
Las herramientas existentes no necesitan ningún cambio. Una herramienta que nunca lee _channel simplemente ignora una entrada más del mapa y se comporta exactamente igual que antes.
Campos de la Definición de herramienta
| Campo | Obligatorio | Propósito |
|---|---|---|
| Tipo de herramienta | Sí | Establécelo en Apex_Class. |
| Clase ejecutora | Sí | Nombre completamente calificado de la clase Apex que implementa REDAAI_Executable. Se admiten clases con espacio de nombres (p. ej. MyNs.OrderCreator). |
| Categoría | Sí | Tool para recuperación de solo lectura, Action para cualquier cosa que escriba o tenga efectos secundarios. Las herramientas de clases Apex pueden ser de cualquiera de los dos tipos: elige según lo que realmente haga tu clase. |
| Descripción | Sí | La descripción en lenguaje natural que se envía al agente. Es así como el modelo decide cuándo llamar a tu herramienta. Sé explícito sobre el propósito, las entradas, los efectos secundarios y cualquier restricción. |
| Esquema de entrada | Sí | Un JSON Schema (de tipo objeto) que describe el Map de input esperado. Se usa para validar la llamada a la herramienta del agente antes de invocar tu clase. |
| Procesamiento de archivos | Opcional | Establécelo en true cuando la herramienta consuma datos extraídos de un archivo cargado. Activa el contexto de extracción de archivos que se describe más abajo. |
| Requiere confirmación | Opcional | Para herramientas de tipo Action, controla si el agente muestra una tarjeta de confirmación de acción antes de ejecutar. Está activado de forma predeterminada para las acciones. |
| Nivel de herramienta, Canales, Nombre del agente, Objetos de contexto | Opcional | Controles estándar de la Definición de herramienta: escalamiento de nivel, delimitación por canal, asignación por agente y a qué objetos es relevante la herramienta. |
Crear la clase Apex
Un ejecutor mínimo de tipo Action que crea un único registro:
global with sharing class MyToolExecutor implements redaai.REDAAI_Executable {
global Object execute(String toolName, Map<String, Object> input) {
try {
String name = (String) input.get('account_name');
Account a = new Account(Name = name);
insert as user a;
return new Map<String, Object>{
'success' => true,
'message' => 'Account created.',
'recordId' => a.Id
};
} catch (Exception e) {
return new Map<String, Object>{
'success' => false,
'message' => e.getMessage()
};
}
}
}
Algunos detalles a tener en cuenta:
- La clase es global. Public no sirve: la plataforma instancia la clase a través de la interfaz global para que los consumidores de paquetes gestionados puedan registrar implementaciones desde sus propios espacios de nombres.
- La clase se declara
with sharing. La plataforma no aplica el uso compartido por ti; el ejecutor es responsable del acceso a los datos que desee. - La cláusula
insert as userejecuta el DML en modo de usuario para que se aplique la seguridad a nivel de campo. Es el valor predeterminado recomendado, salvo que tengas una razón específica para escalar privilegios. - Los errores se capturan y se devuelven como una respuesta estructurada. Las excepciones no controladas igualmente se registran en el registro de incidentes, pero una respuesta limpia le da al agente algo útil que responderle al usuario.
Contrato de retorno
La estructura del retorno depende de la Categoría de la herramienta:
| Categoría | Tipo de retorno | Estructura esperada |
|---|---|---|
Tool (solo lectura) |
JSON String | Lo que el agente deba ver: normalmente un objeto con un arreglo records, un totalSize o un único objeto de resultado. Los errores se devuelven como { "error": "…" }. |
Action (escritura) |
Map<String, Object> |
Como mínimo, un booleano success y una cadena message. Incluye recordId cuando hayas creado o actualizado un registro para que el agente pueda enlazarlo. |
Herramientas Apex basadas en archivos
Establecer Procesamiento de archivos en true cambia lo que el agente te pasa. En lugar de parámetros de forma libre, la plataforma primero le pide al modelo que extraiga datos estructurados del archivo cargado usando el esquema que definiste, y luego le entrega esos datos extraídos a tu ejecutor como el Map de input.
Eso es lo que hace de las herramientas de clases Apex el patrón adecuado para trabajar con archivos no tabulares — PDF, imágenes, documentos mixtos — donde el modelo plano de columna a campo del mapeo de archivos no es suficiente.
Diseñar el esquema de entrada para la extracción
El esquema de entrada describe la estructura extraída, no el archivo en bruto. Para un documento de varias filas, el agente podría producir algo como:
{
"rows": [
{ "external_id": "INV-1001", "amount": 250.00, "due_date": "2026-05-01" },
{ "external_id": "INV-1002", "amount": 980.50, "due_date": "2026-05-15" }
]
}
Tu ejecutor luego itera ese arreglo rows, busca los registros coincidentes, aplica las reglas de negocio que necesites y escribe de vuelta en Salesforce.
Cuando creas la herramienta en el Generador de herramientas con Procesamiento de archivos activado, el Generador de IA puede producir una muestra de la estructura de datos extraída a partir de un archivo representativo que cargues. Úsala como el contrato contra el cual escribes tu Apex.
Nombres, empaquetado y resolución
- Visibilidad de la clase — tanto la clase como su método
executedeben declararseglobal(nopublic). - Implementación — debe implementar
redaai.REDAAI_Executable. - Longitud del nombre de la clase — hasta 255 caracteres en el campo Clase ejecutora.
- Una clase, varias herramientas — un mismo ejecutor puede respaldar varias Definiciones de herramienta y cambiar de comportamiento según
toolName.
public class y public Object execute(...) por global y volver a desplegar.Seguridad y gobernanza
- Tú eres responsable de la seguridad. La plataforma no aplica la FLS ni el uso compartido dentro de tu clase. Usa
with sharingy los patronesUSER_MODE/as user, salvo que tengas una razón explícita para escalar privilegios. - Reconocimiento de seguridad al guardar. La primera vez que guardas una herramienta personalizada (Apex, plantilla SOQL o mapeo de archivos) en el Generador de herramientas, aceptas un reconocimiento de responsabilidad compartida en el que confirmas que eres responsable de su seguridad, sus permisos (CRUD/FLS), la delimitación de datos, la validación de entradas y el cumplimiento legal, porque REDA AI puede invocarla de forma autónoma, incluso en los canales de Comunidad y externos sin un paso de confirmación humana. Tu aceptación (nombre + marca de tiempo) se registra en la herramienta y complementa el Contrato Marco de Servicios de REDA AI. Las herramientas integradas (de ISV) están exentas; aceptas una sola vez por herramienta y esa aceptación se conserva entre ediciones.
- La entrada se valida. La plataforma valida
inputcontra tu esquema antes de invocar tu clase — puedes confiar en los nombres y tipos de campo que declaraste, pero siempre convierte los valores de forma defensiva. - La confirmación de acción sigue aplicándose. Establecer la Categoría en
Actionsignifica que el agente muestra una tarjeta de confirmación antes de llamar a tu clase, a menos que el agente esté configurado para ejecución automática. - Los errores terminan en incidentes. Las excepciones no controladas se capturan como registros de incidentes de REDA AI con la conversación, el nombre de la herramienta y el contexto de la pila. Devolver una respuesta de error limpia es más amigable; el registro de incidentes es la red de seguridad.
- Ejecución sincrónica. Las herramientas de clases Apex se ejecutan de forma sincrónica como parte del turno del agente. Los trabajos de larga duración debe encolarlos tu ejecutor (Queueable, Schedulable, batch) y la respuesta inmediata debe indicarle al usuario que el trabajo ya comenzó.
Cuándo recurrir a una herramienta Apex
| Necesidad | Tipo de herramienta adecuado |
|---|---|
| Leer registros con una consulta parametrizada | Herramienta de plantilla SOQL |
| Cargar en bloque un CSV en un objeto de Salesforce con un mapeo estable | Herramienta de mapeo de archivos |
| Escrituras en varios objetos, lógica condicional, eliminación de duplicados, llamadas externas u orquestación | Herramienta de clase Apex (esta página) |
| Extraer datos estructurados de PDF, imágenes o documentos mixtos y actuar sobre ellos | Herramienta de clase Apex con Procesamiento de archivos activado |
Prácticas recomendadas
Haz que la descripción sea implacable. La decisión del agente de llamar a tu herramienta depende casi por completo de la descripción de la herramienta. Detalla qué hace la herramienta, qué no hace y cualquier condición previa.
Mantén los esquemas ajustados. Usa required, enum, maxLength y tipos explícitos. Cuanto más ajustado sea el esquema, menos sorpresas le llegarán a tu Apex.
Devuelve siempre un mensaje útil. Incluso ante un fallo, devuelve success: false y un message legible para las personas. El agente le lee el mensaje al usuario; los errores opacos generan conversaciones confusas.
Mantente sincrónico, o encola e informa. No bloquees el turno del agente con una llamada externa lenta. O termina rápido, o encola el trabajo asíncrono y devuelve una respuesta que le indique al usuario que está en curso.
Prueba con el panel de vista previa del Generador de herramientas. El panel de impacto en vivo muestra el esquema de entrada, la tarjeta de acción y el contrato de ejecución que verá el agente — detecta ahí las discrepancias antes de la primera conversación real.
Preguntas frecuentes
No. Puede residir en tu propio espacio de nombres, en un paquete gestionado que distribuyas o en el código sin gestionar de la organización de un cliente. Mientras implemente redaai.REDAAI_Executable y el campo Clase ejecutora de la Definición de herramienta pueda resolverla, la plataforma la invocará.
Sí. El primer parámetro de execute() es el nombre de desarrollador de la herramienta — úsalo en un switch para dirigir internamente hacia el método correcto. Es una forma limpia de agrupar operaciones relacionadas bajo un mismo ejecutor.
No. La plataforma aplica la FLS para sus propias herramientas integradas, pero dentro de tu Apex tú eres responsable del acceso a los datos. Declara la clase with sharing y usa as user / AccessLevel.USER_MODE en el DML y las consultas, salvo que tengas una razón específica para escalar privilegios.
La plataforma la captura, registra un incidente con el contexto de la conversación y devuelve un error genérico al agente. El usuario ve una disculpa en lugar de un seguimiento de la pila. Capturar y devolver una respuesta de error estructurada es más amigable — tú controlas el mensaje que escucha el usuario.
La llamada a execute() se ejecuta de forma sincrónica dentro del turno del agente. Para trabajos largos, tu ejecutor debe encolar un Queueable o programar un trabajo y devolver de inmediato una respuesta que le indique al usuario que el trabajo ya comenzó.
Actívalo cuando la función de la herramienta sea actuar sobre datos extraídos de un archivo cargado. La plataforma primero pasará el archivo por el modelo, lo materializará con la estructura que describe tu esquema de entrada y le entregará esa estructura a tu ejecutor — en lugar de que tengas que analizar el archivo por tu cuenta.
Hasta 10.000 caracteres. Es más que suficiente para los esquemas que necesitan la mayoría de las herramientas; si llegas al límite, probablemente la herramienta está intentando hacer demasiado — considera dividirla.
Próximos pasos
Lee Herramientas de plantillas SOQL para el patrón más ligero cuando todo lo que necesitas es una consulta parametrizada, o Procesamiento de documentos para tener una visión más amplia de cómo fluyen los archivos por REDA AI.