نشر في: 12 يونيو 2026 | وقت القراءة: 7 دقائق | الفئة: Salesforce


ملخص سريع (TL;DR)

يتطلب بناء وكيل خدمة Agentforce لالتقاط العملاء المحتملين التعامل مع إدارة الحالة متعددة الأدوار بشكل آمن. في حين أن التدفقات القياسية رائعة للمهام البسيطة، فإن استخدام @InvocableMethod في Apex يسمح بتتبع الحالة المستمر عبر أدوار المحادثة وعمليات DML الآمنة في وضع USER_MODE. إليك بالضبط كيفية بناء واحد.


مقدمة: عصر Agentforce

لقد غيرت Salesforce Agentforce تمامًا الطريقة التي نفكر بها في التفاعلات الآلية مع العملاء. نحن ننتقل من روبوتات الدردشة الجامدة المبنية على الأشجار إلى وكلاء مستقلين يمكنهم الاستدلال وطرح أسئلة توضيحية وتنفيذ الإجراءات.

واحدة من أكثر حالات الاستخدام المبكرة شيوعًا لـ Agentforce هي التقاط العملاء المحتملين. الهدف بسيط: يطلب وكيل الذكاء الاصطناعي من المستخدم معلوماته (مثل اسم العائلة والشركة)، ويحتفظ بهذه المعلومات عبر أدوار محادثة متعددة، وينشئ سجل عميل محتمل في Salesforce بمجرد جمع جميع البيانات المطلوبة.

في حين يمكنك محاولة القيام بذلك باستخدام تدفق شاشة أو تدفق تم تشغيله تلقائيًا، فإن إجراءات Apex القابلة للاستدعاء (invocable actions) توفر تحكمًا أكبر بكثير في إدارة الحالة والأمان.

إليك المخطط الدقيق لوكيل التقاط العملاء المحتملين جاهز للإنتاج في عام 2026.


البنية (Architecture)

يتطلب حلنا ثلاثة مكونات أساسية:

  1. موجه الوكيل (start_agent): يرحب بالمستخدم ويوجهه إلى الوكيل الفرعي الصحيح بناءً على النية.
  2. الوكيل الفرعي لالتقاط العملاء المحتملين (subagent): يوجه LLM بشأن الحقول المطلوبة بالضبط (اسم العائلة والشركة) ويشغل الإجراء.
  3. إجراء Apex القابل للاستدعاء (@InvocableMethod): "المحرك" الفعلي الذي يحلل المدخلات، ويحتفظ بالحالة، ويقوم بإدراج قاعدة البيانات.

1. لغة البرمجة النصية للوكيل (Agent Script DSL)

يستخدم Agentforce لغة برمجة نصية محددة (DSL) لتعريف سلوك الوكيل. نحدد متغيرات للاحتفاظ بمدخلات المستخدم عبر الأدوار.

variables:
    last_name: mutable string = ""
        description: "Lead last name"
    company: mutable string = ""
        description: "Lead company"
    lead_created: mutable boolean = False
        description: "Whether the lead has already been created"
    last_lead_id: mutable string = ""
        description: "The most recently created Lead ID"

يملي منطق الوكيل الفرعي الخاص بنا أنه لكل رسالة يرسلها المستخدم أثناء وجوده في موضوع التقاط العملاء المحتملين، نقوم باستدعاء إجراء Apex الخاص بنا. نمرر userMessage الحالي، بالإضافة إلى متغيرات last_name و company التي جمعناها حتى الآن.

subagent lead_capture:
    label: "Lead Capture"
    description: "Collect last name and company, then create a Salesforce Lead through Apex."
    reasoning:
        instructions: ->
            if @variables.lead_created == True:
                | A lead has already been created in this conversation. Share the Lead ID and ask if the user wants anything else.
            if @variables.lead_created == False:
                | Use Process Lead Capture Turn for every lead-capture message.
        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. إجراء Apex القابل للاستدعاء

تكمن القوة الحقيقية لهذا النمط في فئة Apex. بدلاً من جعل LLM يخمن متى يتم إنشاء العميل المحتمل، نستخدم إجراءً قابلاً للاستدعاء لإدارة منطق العمل بشكل آمن.

لماذا Apex بدلاً من Flow؟

  • الحالة متعددة الأدوار: عن طريق تمرير knownLastName و knownCompany إلى إجراء Apex، وإرجاع resolvedLastName و resolvedCompany، نحافظ على حالة المحادثة بشكل مثالي، حتى لو قدم المستخدم المعلومات بترتيب خاطئ.
  • السياق الأمني: يمكننا فرض أمان مستوى الحقل (FLS) وأذونات CRUD ديناميكيًا باستخدام AccessLevel.USER_MODE.

إليك بنية متغيرات الإدخال والإخراج:

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: Must be String, not 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. Parse the userMessage for missing fields using Regex
        // 2. Combine found fields with knownLastName and knownCompany
        // 3. If both are present, insert the Lead
        // 4. Return the Result
    }
}

مشكلة ربط leadId (Gotcha)

لاحظ أن public String leadId; معرفة كـ String وليس Id. هذا فارق دقيق حاسم في Agentforce. عند ربط مخرجات إجراء قابل للاستدعاء بمتغير نص برمجي للوكيل ( set @variables.last_lead_id = @outputs.leadId )، يفضل Agentforce بشدة أنواع السلاسل الأولية على أنواع Id الصارمة في Salesforce. قد يتسبب استخدام Id في فشل ربط صامت أثناء التنفيذ.


3. فرض الأمان باستخدام USER_MODE

عندما يقوم Agentforce بتنفيذ إجراء قابل للاستدعاء، فإنه يعمل تحت سياق مستخدم Einstein Service Agent (أو مستخدم الوكيل الافتراضي الذي قمت بتكوينه).

إذا حاولت إدراج عميل محتمل باستخدام DML قياسي (insert newLead;)، فقد يتجاوز سياق النظام فحوصات الأمان الضرورية، أو يفشل بشكل غير متوقع اعتمادًا على إعدادات مشاركة المؤسسة.

النهج الصحيح في عام 2026 هو دائمًا فرض DML في وضع المستخدم:

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

مجموعة الأذونات المفقودة

لكي يعمل الإدراج في وضع USER_MODE، يجب أن يكون لدى مستخدم Einstein Service Agent إذن لإنشاء سجلات العملاء المحتملين.

يجب عليك إنشاء مجموعة أذونات (مثل LeadCaptureAgent_Apex_Access) تمنح:

  1. الوصول إلى فئة Apex: لفئة LeadCaptureTurnAction الخاصة بك.
  2. الوصول إلى الكائن: أذونات القراءة والإنشاء على كائن Lead.
  3. أذونات الحقول: إذن التعديل لحقول LastName و Company.

قم بتعيين مجموعة الأذونات هذه لمستخدم Einstein Service Agent. بدونها، سيعمل الوكيل في حلقة لا نهائية، ويطلب الحقول التي جمعها بالفعل لأن فشل DML الصامت في وضع USER_MODE يمنع isSuccess من الإرجاع true أبدًا.


4. اختبار الوكيل محليًا

قبل النشر، يجب عليك التحقق من صحة المنطق متعدد الأدوار باستخدام Salesforce CLI. يسمح لك الأمر sf agent preview بمحاكاة المحادثة مباشرة من الطرفية الخاصة بك.

# Start the session
sf agent preview start --json --authoring-bundle LeadCaptureAgent --use-live-actions --target-org my-org

# Send the first utterance (Company only)
sf agent preview send --json --session-id <SESSION_ID> --utterance "My company is Acme Corp" --authoring-bundle LeadCaptureAgent --target-org my-org

# Send the second utterance (Last Name)
sf agent preview send --json --session-id <SESSION_ID> --utterance "My last name is Smith" --authoring-bundle LeadCaptureAgent --target-org my-org

# Verify the Lead creation
sf data query --query "SELECT Id, LastName, Company FROM Lead ORDER BY CreatedDate DESC LIMIT 1" --target-org my-org

الخلاصة

يسمح لنا Agentforce ببناء تجارب محادثة ديناميكية بشكل لا يصدق، ولكنه يتطلب تحولًا في كيفية تعاملنا مع الحالة والأمان. عن طريق توجيه التقاط العملاء المحتملين من خلال وكيل فرعي مخصص والاعتماد على إجراءات Apex القابلة للاستدعاء لإدارة الحالة الحتمية، فإنك تضمن تجربة آمنة ومرنة وسهلة الاستخدام.

تذكر دائمًا استخدام String لمخرجات المعرف، وفرض DML في وضع USER_MODE، وتعيين مجموعات الأذونات الصحيحة لمستخدم الوكيل.


حول المؤلف: تم كتابة هذا الدليل بواسطة فريق التحرير الفني في Resumity، ويستكشف تقاطع منصات الذكاء الاصطناعي الحديثة وهندسة CRM للمؤسسات.