Publicado: 12 de junio de 2026 | Tiempo de Lectura: 7 minutos | Categoría: Salesforce


Resumen

Construir un Agente de Servicio de Agentforce para capturar leads requiere manejar la gestión de estado de múltiples turnos de forma segura. Si bien los Flujos estándar son excelentes para tareas simples, usar un @InvocableMethod de Apex permite un seguimiento persistente del estado a través de los turnos de conversación y operaciones DML seguras en USER_MODE. Aquí se explica exactamente cómo construir uno.


Introducción: La Era de Agentforce

Agentforce de Salesforce ha cambiado por completo la forma en que pensamos sobre las interacciones automatizadas con los clientes. Estamos pasando de chatbots rígidos basados en árboles a agentes autónomos que pueden razonar, hacer preguntas aclaratorias y ejecutar acciones.

Uno de los casos de uso tempranos más comunes para Agentforce es la Captura de Leads. El objetivo es simple: un agente de IA solicita al usuario su información (por ejemplo, Apellido y Empresa), retiene esa información a través de múltiples turnos de conversación y crea un registro de Lead de Salesforce una vez que se recopilan todos los datos requeridos.

Si bien podrías intentar esto con un flujo de pantalla o un flujo autolanzado, las acciones invocables de Apex proporcionan un control significativamente mayor sobre la gestión del estado y el contexto de seguridad.

Aquí está el plano exacto para un Agente de Captura de Leads listo para producción en 2026.


La Arquitectura

Nuestra solución requiere tres componentes principales:

  1. El Enrutador de Agentes (start_agent): Da la bienvenida al usuario y lo dirige al subagente correcto según la intención.
  2. El Subagente de Captura de Leads (subagent): Instruye al LLM sobre los campos exactos requeridos (Apellido y Empresa) y activa la acción.
  3. La Acción Invocable de Apex (@InvocableMethod): El "motor" real que analiza la entrada, mantiene el estado y realiza la inserción en la base de datos.

1. El DSL del Script del Agente

Agentforce utiliza un Lenguaje de Dominio Específico (DSL) específico para definir el comportamiento del agente. Definimos variables para mantener la entrada del usuario a través de los turnos.

variables:
    last_name: mutable string = ""
        description: "Apellido del Lead"
    company: mutable string = ""
        description: "Empresa del Lead"
    lead_created: mutable boolean = False
        description: "Si el lead ya ha sido creado"
    last_lead_id: mutable string = ""
        description: "El ID del Lead creado más recientemente"

La lógica de nuestro subagente dicta que para cada mensaje que el usuario envía mientras está en el tema de captura de leads, llamamos a nuestra acción de Apex. Pasamos el userMessage actual, junto con las variables last_name y company que hemos recopilado hasta ahora.

subagent lead_capture:
    label: "Captura de Leads"
    description: "Recopilar apellido y empresa, luego crear un Lead de Salesforce a través de Apex."
    reasoning:
        instructions: ->
            if @variables.lead_created == True:
                | Se ha creado un lead en esta conversación. Comparte el ID del Lead y pregunta si el usuario necesita algo más.
            if @variables.lead_created == False:
                | Usa Process Lead Capture Turn para cada mensaje de captura de leads.
        actions:
            process_lead_turn: @actions.process_lead_turn
                    with userMessage = ...
                    with knownLastName = @variables.last_name
                    with knownCompany = @variables.company
                    set @variables.last_name = @outputs.resolvedLastName
                    set @variables.company = @outputs.resolvedCompany
                    set @variables.lead_created = @outputs.isSuccess
                    set @variables.last_lead_id = @outputs.leadId

2. La Acción Invocable de Apex

El verdadero poder de este patrón reside en la clase Apex. En lugar de que el LLM adivine cuándo crear el lead, usamos una acción invocable para gestionar la lógica de negocio de forma segura.

¿Por qué Apex en lugar de Flow?

  • Estado de Múltiples Turnos: Al pasar knownLastName y knownCompany a la acción de Apex y devolver resolvedLastName y resolvedCompany, mantenemos el estado de la conversación perfectamente, incluso si el usuario proporciona la información en orden desordenado.
  • Contexto de Seguridad: Podemos aplicar el Nivel de Acceso a Campos (FLS) y los permisos CRUD dinámicamente usando AccessLevel.USER_MODE.

Aquí está la estructura de las variables de entrada y salida:

public class LeadCaptureTurnAction {
    
    public class Request {
        @InvocableVariable(required=true label='Mensaje del Usuario')
        public String userMessage;
        
        @InvocableVariable(label='Apellido Conocido')
        public String knownLastName;
        
        @InvocableVariable(label='Empresa Conocida')
        public String knownCompany;
    }
    
    public class Result {
        @InvocableVariable(label='¿Es Éxito?')
        public Boolean isSuccess;
        
        @InvocableVariable(label='ID del Lead')
        public String leadId; // GOTCHA: Debe ser String, no Id
        
        @InvocableVariable(label='Apellido Resuelto')
        public String resolvedLastName;
        
        @InvocableVariable(label='Empresa Resuelta')
        public String resolvedCompany;
        
        @InvocableVariable(label='Mensaje')
        public String message;
    }
    
    @InvocableMethod(label='Procesar Turno de Captura de Leads')
    public static List<Result> processTurn(List<Request> requests) {
        // 1. Analizar el userMessage en busca de campos faltantes usando Regex
        // 2. Combinar los campos encontrados con knownLastName y knownCompany
        // 3. Si ambos están presentes, insertar el Lead
        // 4. Devolver el Resultado
    }
}

El "Gotcha" de Vinculación de leadId

Observe que public String leadId; se define como un String y no como un Id. Este es un matiz crítico en Agentforce. Al vincular la salida de una acción invocable a una variable de script de Agente (set @variables.last_lead_id = @outputs.leadId), Agentforce prefiere fuertemente los tipos de cadena primitivos sobre los tipos Id estrictos de Salesforce. Usar Id puede causar fallos de vinculación silenciosos durante la ejecución.


3. Aplicar Seguridad con USER_MODE

Cuando Agentforce ejecuta una acción invocable, se ejecuta bajo el contexto del usuario Agente de Servicio de Einstein (o su usuario agente predeterminado configurado).

Si intentas insertar un lead usando DML estándar (insert newLead;), el contexto del sistema podría omitir las verificaciones de seguridad necesarias o fallar de forma impredecible dependiendo de la configuración de uso compartido de la organización.

El enfoque correcto en 2026 es aplicar siempre DML en modo de usuario:

Database.SaveResult sr = Database.insert(newLead, false, AccessLevel.USER_MODE);

El Permiso Faltante

Para que la inserción en USER_MODE funcione, el usuario Agente de Servicio de Einstein debe tener permiso para crear registros de Lead.

Debes crear un Conjunto de Permisos (por ejemplo, LeadCaptureAgent_Apex_Access) que otorgue:

  1. Acceso a Clase Apex: A tu clase LeadCaptureTurnAction.
  2. Acceso a Objetos: Permisos de Lectura y Creación en el objeto Lead.
  3. Permisos de Campos: Acceso de edición a LastName y Company.

Asigna este Conjunto de Permisos al usuario Agente de Servicio de Einstein. Sin él, el agente entrará en un bucle infinito, solicitando campos que ya ha recopilado porque el fallo silencioso de DML en USER_MODE impide que isSuccess devuelva true.


4. Probar el Agente Localmente

Antes de publicar, debes validar la lógica de múltiples turnos utilizando la CLI de Salesforce. El comando sf agent preview te permite simular la conversación directamente desde tu terminal.

# Iniciar la sesión
sf agent preview start --json --authoring-bundle LeadCaptureAgent --use-live-actions --target-org my-org

# Enviar la primera intervención (solo Empresa)
sf agent preview send --json --session-id <SESSION_ID> --utterance "Mi empresa es Acme Corp" --authoring-bundle LeadCaptureAgent --target-org my-org

# Enviar la segunda intervención (Apellido)
sf agent preview send --json --session-id <SESSION_ID> --utterance "Mi apellido es Smith" --authoring-bundle LeadCaptureAgent --target-org my-org

# Verificar la creación del Lead
sf data query --query "SELECT Id, LastName, Company FROM Lead ORDER BY CreatedDate DESC LIMIT 1" --target-org my-org

En Resumen

Agentforce nos permite crear experiencias conversacionales increíblemente dinámicas, pero requiere un cambio en la forma en que manejamos el estado y la seguridad. Al dirigir la captura de leads a través de un subagente dedicado y confiar en las acciones invocables de Apex para la gestión determinista del estado, garantizas una experiencia segura, resiliente y fácil de usar.

Recuerda siempre usar String para las salidas de ID, aplicar DML en USER_MODE y asignar los conjuntos de permisos correctos a tu usuario agente.


Sobre el Autor: Esta guía está escrita por el equipo editorial técnico de Resumity, explorando la intersección de las plataformas de IA modernas y la arquitectura CRM empresarial.