Publié : 12 juin 2026 | Temps de lecture : 7 minutes | Catégorie : Salesforce
TL;DR
La construction d'un agent de service Agentforce pour capturer des prospects nécessite une gestion de l'état multi-tours sécurisée. Alors que les Flows standards sont parfaits pour les tâches simples, l'utilisation d'une @InvocableMethod Apex permet un suivi persistant de l'état entre les tours de conversation et des opérations DML sécurisées en USER_MODE. Voici exactement comment en construire une.
Introduction : L'ère Agentforce
Salesforce Agentforce a complètement changé notre façon de concevoir les interactions client automatisées. Nous passons de chatbots rigides basés sur des arbres à des agents autonomes capables de raisonner, de poser des questions de clarification et d'exécuter des actions.
L'un des premiers cas d'utilisation les plus courants pour Agentforce est la capture de prospects. L'objectif est simple : un agent IA demande à l'utilisateur ses informations (par exemple, Nom de famille et Entreprise), conserve ces informations sur plusieurs tours de conversation et crée un enregistrement de prospect Salesforce une fois que toutes les données requises sont collectées.
Bien que vous puissiez tenter cela avec un flux d'écran ou un flux auto-lancé, les actions invocables Apex offrent un contrôle considérablement plus important sur la gestion de l'état et le contexte de sécurité.
Voici le plan exact pour un agent de capture de prospects prêt pour la production en 2026.
L'Architecture
Notre solution nécessite trois composants principaux :
- Le Routeur d'Agent (
start_agent) : Accueille l'utilisateur et le dirige vers le sous-agent approprié en fonction de l'intention. - Le Sous-Agent de Capture de Prospects (
subagent) : Indique au LLM exactement quels champs sont requis (Nom de famille et Entreprise) et déclenche l'action. - L'Action Invocable Apex (
@InvocableMethod) : Le véritable "moteur" qui analyse l'entrée, maintient l'état et effectue l'insertion dans la base de données.
1. Le DSL de Script d'Agent
Agentforce utilise un langage spécifique (DSL) pour définir le comportement de l'agent. Nous définissons des variables pour conserver les entrées de l'utilisateur entre les tours.
variables:
last_name: mutable string = ""
description: "Nom de famille du prospect"
company: mutable string = ""
description: "Entreprise du prospect"
lead_created: mutable boolean = False
description: "Indique si le prospect a déjà été créé"
last_lead_id: mutable string = ""
description: "L'ID du prospect le plus récemment créé"
La logique de notre sous-agent dicte que pour chaque message que l'utilisateur envoie lorsqu'il est dans le sujet de capture de prospects, nous appelons notre action Apex. Nous passons le userMessage actuel, ainsi que les variables last_name et company que nous avons collectées jusqu'à présent.
subagent lead_capture:
label: "Capture de prospects"
description: "Collecte le nom de famille et l'entreprise, puis crée un prospect Salesforce via Apex."
reasoning:
instructions: ->
if @variables.lead_created == True:
| Un prospect a déjà été créé dans cette conversation. Partagez l'ID du prospect et demandez si l'utilisateur souhaite autre chose.
if @variables.lead_created == False:
| Utilisez Process Lead Capture Turn pour chaque message de capture de prospects.
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. L'Action Invocable Apex
La véritable puissance de ce modèle réside dans la classe Apex. Au lieu de laisser le LLM deviner quand créer le prospect, nous utilisons une action invocable pour gérer la logique métier en toute sécurité.
Pourquoi Apex plutôt que Flow ?
- État multi-tours : En passant
knownLastNameetknownCompanyà l'action Apex, et en retournantresolvedLastNameetresolvedCompany, nous maintenons parfaitement l'état de la conversation, même si l'utilisateur fournit les informations dans le désordre. - Contexte de sécurité : Nous pouvons appliquer les permissions de sécurité au niveau du champ (FLS) et les permissions CRUD dynamiquement à l'aide de
AccessLevel.USER_MODE.
Voici la structure des variables d'entrée et de sortie :
public class LeadCaptureTurnAction {
public class Request {
@InvocableVariable(required=true label='User Message')
public String userMessage;
@InvocableVariable(label='Known Last Name')
public String knownLastName;
@InvocableVariable(label='Known Company')
public String knownCompany;
}
public class Result {
@InvocableVariable(label='Is Success')
public Boolean isSuccess;
@InvocableVariable(label='Lead ID')
public String leadId; // GOTCHA : Doit être String, pas Id
@InvocableVariable(label='Resolved Last Name')
public String resolvedLastName;
@InvocableVariable(label='Resolved Company')
public String resolvedCompany;
@InvocableVariable(label='Message')
public String message;
}
@InvocableMethod(label='Process Lead Capture Turn')
public static List<Result> processTurn(List<Request> requests) {
// 1. Analyser le userMessage pour les champs manquants à l'aide d'expressions régulières
// 2. Combiner les champs trouvés avec knownLastName et knownCompany
// 3. Si les deux sont présents, insérer le prospect
// 4. Retourner le résultat
}
}
Le piège de la liaison leadId
Notez que public String leadId; est défini comme un String et non comme un Id. C'est une nuance critique dans Agentforce. Lors de la liaison de la sortie d'une action invocable à une variable de script d'agent (set @variables.last_lead_id = @outputs.leadId), Agentforce préfère fortement les types de chaînes primitifs aux types Id stricts de Salesforce. L'utilisation de Id peut entraîner des échecs de liaison silencieux pendant l'exécution.
3. Application de la sécurité avec USER_MODE
Lorsque Agentforce exécute une action invocable, il s'exécute dans le contexte de l'utilisateur Einstein Service Agent (ou de votre utilisateur agent par défaut configuré).
Si vous tentez d'insérer un prospect en utilisant des DML standards (insert newLead;), le contexte système peut contourner les vérifications de sécurité nécessaires, ou échouer de manière imprévisible en fonction des paramètres de partage de l'organisation.
L'approche correcte en 2026 est d'appliquer systématiquement les DML en mode utilisateur :
Database.SaveResult sr = Database.insert(newLead, false, AccessLevel.USER_MODE);
L'ensemble d'autorisations manquant
Pour que l'insertion USER_MODE fonctionne, l'utilisateur Einstein Service Agent doit avoir l'autorisation de créer des enregistrements de prospects.
Vous devez créer un ensemble d'autorisations (par exemple, LeadCaptureAgent_Apex_Access) qui accorde :
- Accès à la classe Apex : À votre classe
LeadCaptureTurnAction. - Accès à l'objet : Permissions de lecture et de création sur l'objet
Lead. - Permissions sur les champs : Accès en modification aux champs
LastNameetCompany.
Assignez cet ensemble d'autorisations à l'utilisateur Einstein Service Agent. Sans cela, l'agent bouclera indéfiniment, demandant des champs qu'il a déjà collectés car l'échec silencieux des DML en USER_MODE empêche isSuccess de retourner true.
4. Test de l'agent localement
Avant de publier, vous devez valider la logique multi-tours à l'aide de la Salesforce CLI. La commande sf agent preview vous permet de simuler la conversation directement depuis votre terminal.
# Démarrer la session
sf agent preview start --json --authoring-bundle LeadCaptureAgent --use-live-actions --target-org my-org
# Envoyer la première énonciation (Entreprise uniquement)
sf agent preview send --json --session-id <SESSION_ID> --utterance "My company is Acme Corp" --authoring-bundle LeadCaptureAgent --target-org my-org
# Envoyer la deuxième énonciation (Nom de famille)
sf agent preview send --json --session-id <SESSION_ID> --utterance "My last name is Smith" --authoring-bundle LeadCaptureAgent --target-org my-org
# Vérifier la création du prospect
sf data query --query "SELECT Id, LastName, Company FROM Lead ORDER BY CreatedDate DESC LIMIT 1" --target-org my-org
Le résultat
Agentforce nous permet de créer des expériences conversationnelles incroyablement dynamiques, mais cela nécessite un changement dans la manière dont nous gérons l'état et la sécurité. En acheminant la capture de prospects via un sous-agent dédié et en s'appuyant sur les actions invocables Apex pour une gestion déterministe de l'état, vous garantissez une expérience sécurisée, résiliente et conviviale.
N'oubliez jamais d'utiliser String pour les sorties d'ID, d'appliquer les DML en USER_MODE et d'attribuer les bons ensembles d'autorisations à votre utilisateur agent.
À propos de l'auteur : Ce guide est rédigé par l'équipe éditoriale technique de Resumity, explorant l'intersection des plateformes d'IA modernes et de l'architecture CRM d'entreprise.