Agentforce Example: Customer Support Agent

This example builds a customer support agent that verifies a customer’s identity and helps them get information about their orders. You can build the same agent in three different ways (Headless, Script, or Canvas). Choose the path that fits how you work.

Subagent Summary 

The agent contains three subagents:

  • The agent_router subagent, which provides general instructions to the LLM and exposes two tools that the LLM can select to call. The two tools are utilities that transition to the required subagents, based on user input.
  • The Identity subagent, which verifies the user’s identity. This subagent allows the LLM to request the user’s email (if it doesn’t exist), then sends a verification code to the provided email. Then, the LLM can validate the verification code that the customer provides. This subagent contains deterministic tools and actions, while allowing the LLM freedom to use natural language to interact with the user.
  • The Order_Management subagent, which allows the user to look up order details.

Prerequisites 

Before you build the agent on any path, make sure that your org is ready:

  • Einstein and Agentforce are enabled. See Set Up Einstein and Agentforce.
  • You have an active user for the agent. Every agent runs as a specific user. These examples use agentforce@salesforce.com as a placeholder for the default_agent_user — replace it with an active Einstein Agent User in your own org. To find one, in Setup go to Users, or query SELECT Username FROM User WHERE UserType = 'EinsteinAgent' AND IsActive = true.
  • The flows the agent calls exist in your org. See Flows This Agent Calls. If they don’t exist yet, stub them so you can preview the agent end-to-end.
  • For the Headless and Script paths, the Salesforce CLI must be installed and authorized to your org. See Set Up Your DX Environment.

Flows This Agent Calls 

No matter which path you select, this agent calls four flows to do its work. The agent expects them to exist in your org. These names are the example’s defaults. If you point an action at a different flow, keep its input and output variable names the same so the action’s contract still matches.

FlowCalled to…InputsOutputs
Get_Verification_CodeSend a verification code by emailemail, member_numberverification_code, member_name
validate_Verification_CodeConfirm the code that the customer enteredverification_codeverification (boolean)
Get_Current_OrderLook up the customer’s current ordermember_emailorder_summary, order_id
Get_Past_OrderLook up a past order by IDqueryorder_summary, order_id

All four flows are specific to this example. (In a real Service Cloud org, the order lookups are often handled by standard SvcCopilotTmpl__ flows instead. That namespace is reserved for a managed package, so this example uses its own plainly named flows that any org can create.)

If a flow doesn’t exist in your org, the agent won’t publish — a flow action can’t point at a flow:// target that isn’t there. To try the agent end-to-end without wiring up real backends, replace each flow with a stub: an autolaunched flow that ignores its inputs and returns canned values.

A stub flow needs only three things:

  1. Input variables that match the action’s inputs (marked Available for input), so the agent can pass values in.
  2. Output variables that match the action’s outputs (marked Available for output), so the agent can read results back.
  3. An Assignment element that sets each output variable to a fixed value.

For example, a validate_Verification_Code stub takes a verification_code input, ignores it, and assigns true to a verification output — so any code the customer enters passes. A Get_Verification_Code stub returns a fixed verification_code (such as 123456) and a member_name. Give each stub the exact flow name and variable names from the table above, deploy it (sf project deploy start), then build the agent.

Choose Your Path 

You can build this agent three ways. Select a tab to follow that path from start to finish.

If you’re a…You’ll build with…Open the tab…
Vibe coder (instruct an AI agent)Natural-language prompts to an AI coding agent, no platform UI requiredHeadless
Developer (code)Agent Script in Script view, Agentforce DX, or the CLIScript
Admin (clicks, not code)Agentforce Builder Canvas viewCanvas

Build the agent by describing what you want in natural language and letting an AI coding agent generate the metadata for you — no platform UI required. To get reliable results, use a coding agent that has Salesforce development context loaded, so it follows platform best practices and produces valid Agent Script.

With this context in place, paste the prompt from each step below into your coding agent. The more specific your prompt — naming the agent’s behavior, the rules it must follow, and any flows or actions it needs to call — the closer the result matches.

Headless Step 1: Scaffold the Agent 

This prompt sets up the agent’s foundation — its name, instructions, welcome message, running user, and locale.

1Build an Agentforce customer support agent in Agent Script, with the developer name pronto_customer_support_assistant. Its job is to help customers get information about their orders while following professional support policies. Set the welcome message to "Hi there, I'm your Pronto Customer Support Assistant," use agentforce@salesforce.com as the default agent user, and set the locale to en_US.

Headless Step 2: Define the Variables 

When you build headlessly, you don’t hand-write variable declarations or specify Agent Script types — but do name the variables explicitly, so they match the references in the prompts for later steps.

1Define the agent's variables using these exact names. For identity: member_name, member_email, member_number, verification_code (the code the agent sends), user_verification_code (the code the customer enters), and a verified boolean that defaults to False and gates access to order lookups. For orders: order_id and an order_summary string that starts empty. You don't need to specify types — just name each variable and describe what it holds.

Headless Step 3: Build the Router 

This prompt creates the router subagent — the agent’s entry point that welcomes the customer and routes them to the right subagent based on whether they’re verified.

1Add a start_agent router subagent that welcomes the customer and decides which subagent should handle their request. Give it two transition tools, gated by the verified variable: a transition to the Identity subagent available only when verified is False, and a transition to the Order Management subagent available only when verified is True. Tell it to never escalate to a human unless the customer explicitly asks.

Headless Step 4: Build the Identity Subagent 

This prompt creates the Identity subagent, which verifies the customer by email before any order data is exposed, calling flows to send and validate a verification code.

1Add an Identity subagent that verifies the customer before they can look up orders. When member_email is known, send a verification code by calling the Get_Verification_Code flow and store its outputs in verification_code and member_name. Ask the customer for the code they received, save it in user_verification_code, and validate it by calling the validate_Verification_Code flow, setting the verified variable from the result. If they didn't get the code, confirm their email and resend it. Once verified is True, allow a transition to the Order Management subagent.

Headless Step 5: Build the Order Management Subagent 

This prompt creates the Order Management subagent, which automatically looks up the customer’s current order on entry and can also retrieve a past order by ID.

1Add an Order Management subagent. When the customer enters this subagent and the order_summary variable is empty, automatically run a lookup of their current order by email (backed by the Get_Current_Order flow) and store the result in order_summary. Address the customer by name and show their order summary. If they ask about a past order, request the Order ID and look it up with the Get_Past_Order flow.

Headless Step 6: Preview and Test 

Deploy the agent to your org with the Salesforce CLI or your coding agent’s MCP connection, then open it in Agentforce Builder and select Preview. Start a conversation, such as I need help with my order, and confirm the agent asks you to verify your identity first.

Build the agent by writing Agent Script directly in Script view, in Agentforce DX, or with the CLI. The snippets below assemble into the complete script in The Complete Script at the end of this tab.

Script Step 1: Scaffold the Agent 

Set up the agent’s foundation. This Agent Script snippet defines the system block (the agent’s instructions and welcome and error messages), the config block (developer name and description), the access block (the default agent user), and the language block (locale settings).

Step 1 - Scaffold
1system:
2    instructions: "You are a helpful, professional assistant that provides customers with information about their orders."
3    messages:
4        welcome: "Hi there, I'm your Pronto Customer Support Assistant."
5        error: "Sorry, something went wrong on my end. Could you say that again in a different way?"
6
7config:
8    developer_name: "pronto_customer_support_assistant"
9    description: "Assists customers with their orders while following defined support policies."
10
11access:
12    default_agent_user: "agentforce@salesforce.com"
13
14language:
15    default_locale: "en_US"
16    additional_locales: ""
17    all_additional_locales: False

Replace agentforce@salesforce.com with an active Einstein Agent User in your org. The agent won’t publish with a default_agent_user that doesn’t exist. See Prerequisites.

Note

Script Step 2: Define the Variables 

Declare the variables that the agent uses to remember information across the conversation. This Agent Script snippet declares them in a variables block, grouped into identity variables (such as member_email and the verified boolean) and order variables (such as order_summary). Each variable is mutable, so the agent can update it during the conversation, and some have default values.

Step 2 - Variables
1variables:
2    # Identity
3    member_name: mutable string
4        description: "This is the name of the member."
5    member_email: mutable string = ""
6        description: "This is the email address of the member."
7    member_number: mutable string
8        description: "This is the member number for identification."
9    verification_code: mutable string
10        description: "This is the verification code to validate against the user's."
11    user_verification_code: mutable string
12        description: "This is the verification code entered by the user."
13    verified: mutable boolean = False
14        description: "Shows whether or not the user's identity has been verified."
15
16    # Orders
17    order_id: mutable string
18        description: "This is the Order ID of the order they placed."
19    order_summary: mutable string = ""
20        description: "This is the summary of the order."

Script Step 3: Build the Router 

Add the agent_router subagent as the agent’s entry point. This Agent Script snippet defines the start_agent subagent with a reasoning block. The reasoning instructions tell the LLM how to greet and route the customer, and the actions section exposes two @utils.transition tools, each gated by an available when condition on the verified variable, so customers must verify before they can look up orders.

Step 3 - Router
1# The entry point for the agent, on every customer utterance.
2start_agent agent_router:
3    description: "Welcome the user and determine the appropriate subagent based on user input"
4    reasoning:
5        instructions: ->
6            | You are an agent router for a Customer Service Bot assistant.
7              Welcome the guest and analyze their input to determine the most appropriate subagent to handle their request.
8              NEVER escalate to a human unless explicitly requested. A bad experience shouldn't automatically escalate.
9        # This section lists the tools that the LLM
10        # can choose to use. In this example, the LLM has two tools:
11        # transitioning to the Identity subagent or transitioning to the
12        # Order_Management subagent
13        actions:
14            # Transitions deterministically route execution to the specified subagent.
15            # Once the LLM chooses to use this tool, the execution is guaranteed
16            # to transition.
17            go_to_identity: @utils.transition to @subagent.Identity
18                description: "verifies user identity"
19                available when @variables.verified == False
20            go_to_order: @utils.transition to @subagent.Order_Management
21                description: "Handles order lookup, refunds, order updates, and summarizes status, order date, current location, delivery address, items, and driver name."
22                available when @variables.verified == True

Script Step 4: Build the Identity Subagent 

Add the Identity subagent, which verifies the customer before any order data is exposed. This Agent Script snippet defines the subagent: the reasoning block runs send_verification_code deterministically when an email exists, then guides the LLM to validate the code, while the reasoning.actions section exposes the two verification actions and a transition tool. The subagent’s own actions section defines send_verification_code and validate_verification_code, each targeting a flow.

Step 4 - Identity Subagent
1subagent Identity:
2    description: "Handles verification of the user's identity before providing access to all other topics."
3    reasoning:
4        instructions: ->
5            if @variables.member_email != "":
6                run @actions.send_verification_code
7                    with email=@variables.member_email
8                    with member_number = @variables.member_number
9                    set @variables.verification_code=@outputs.verification_code
10                    set @variables.member_name=@outputs.member_name
11
12            | Greet the user and inform them that to help them get started you've sent them a verification code via email.
13              # This prompt contains two actions that the LLM can choose to run -
14              # a tool to send the verification code, and a tool to validate the
15              # verification code. Once the LLM chooses to run these actions,
16              # the actions are run deterministically
17              Ask the user for the verification code they received and verify it using {!@actions.validate_verification_code}.
18              If the user says they did not receive the code, ask them to confirm their email and resend the verification code using {!@actions.send_verification_code}
19
20        # The reasoning.actions section declares the tools that the LLM can choose
21        # to run. This section has three tools - two actions and
22        # one transition.
23        actions:
24            send_verification_code: @actions.send_verification_code
25                with email=@variables.member_email
26                with member_number=@variables.member_number
27                set @variables.verification_code=@outputs.verification_code
28
29            validate_verification_code: @actions.validate_verification_code
30                available when @variables.verification_code != None
31                with verification_code=@variables.user_verification_code
32                set @variables.verified=@outputs.verification
33
34            go_to_order_management: @utils.transition to @subagent.Order_Management
35                available when @variables.verified == True
36
37
38    # This section defines the actions available to this subagent. Actions are
39    # only valid within the subagent in which they are defined.
40    actions:
41        send_verification_code:
42            description: "Send a verification code to the member and verify confirmation."
43            inputs:
44                email: string
45                member_number: string
46            outputs:
47                verification_code: string
48                member_name: string
49            target: "flow://Get_Verification_Code"
50
51
52        validate_verification_code:
53            description: "validate the verification code"
54            inputs:
55                verification_code: string
56            outputs:
57                verification: boolean
58                    description: "always validate and return True"
59            target: "flow://validate_Verification_Code"

Script Step 5: Build the Order Management Subagent 

Add the Order_Management subagent, which looks up order details. This Agent Script snippet defines the subagent: the reasoning block runs lookup_current_order when order_summary is empty and stores the result in variables, and the reasoning.actions section exposes both lookup actions. The subagent’s actions section defines lookup_order and lookup_current_order, each targeting a flow.

Step 5 - Order Management Subagent
1subagent Order_Management:
2    description: "Handles order lookup, order updates, and summaries including status, date, location, items, and driver."
3
4    reasoning:
5        instructions: ->
6            if @variables.order_summary == "":
7                run @actions.lookup_current_order
8                    with member_email=@variables.member_email
9                    set @variables.order_summary=@outputs.order_summary
10
11                | Refer to the user by name {!@variables.member_name}.
12                  Show their current order summary: {!@variables.order_summary} when conversation starts or if requested.
13                  If they want past order info, ask for Order ID and use {!@actions.lookup_order}.
14
15        actions:
16            # The ... indicates that the LLM can use reasoning to select the
17            # information from the customer's conversation, then input
18            # the information into the correct input variables
19            lookup_order: @actions.lookup_order
20                with query = ...
21                # Store the action's output into variables
22                set @variables.order_summary=@outputs.order_summary
23                set @variables.order_id=@outputs.order_id
24
25
26            lookup_current_order: @actions.lookup_current_order
27                with member_email=@variables.member_email
28                set @variables.order_summary=@outputs.order_summary
29                set @variables.order_id=@outputs.order_id
30
31    actions:
32        lookup_order:
33            description: "Retrieve order details."
34            inputs:
35                query: string
36            outputs:
37                order_summary: string
38                order_id: string
39            target: "flow://Get_Past_Order"
40
41        lookup_current_order:
42            description: "Retrieve current order details."
43            inputs:
44                member_email: string
45            outputs:
46                order_summary: string
47                order_id: string
48            target: "flow://Get_Current_Order"

Script Step 6: Preview and Test 

In Script view, select Preview and start a conversation, such as I need help with my order. Confirm that the agent asks you to verify your identity first, and that order details return correctly after verification.

  • Each agent needs a unique developer_name. If you make multiple agents from one example script, change the developer name each time.
  • If you encounter an unexpected error in Agentforce Builder with the last line of your script, add a blank line or a comment to the end.

Tip

The Complete Script 

The snippets from Steps 1–5 combine into this complete script. Copy and paste it to create the agent in one shot.

Example - Customer Support Agent
1system:
2    instructions: "You are a helpful, professional assistant that provides customers with information about their orders."
3    messages:
4        welcome: "Hi there, I'm your Pronto Customer Support Assistant."
5        error: "Sorry, something went wrong on my end. Could you say that again in a different way?"
6
7config:
8    developer_name: "pronto_customer_support_assistant"
9    description: "Assists customers with their orders while following defined support policies."
10
11access:
12    default_agent_user: "agentforce@salesforce.com"
13
14variables:
15    # Identity
16    member_name: mutable string
17        description: "This is the name of the member."
18    member_email: mutable string = ""
19        description: "This is the email address of the member."
20    member_number: mutable string
21        description: "This is the member number for identification."
22    verification_code: mutable string
23        description: "This is the verification code to validate against the user's."
24    user_verification_code: mutable string
25        description: "This is the verification code entered by the user."
26    verified: mutable boolean = False
27        description: "Shows whether or not the user's identity has been verified."
28
29    # Orders
30    order_id: mutable string
31        description: "This is the Order ID of the order they placed."
32    order_summary: mutable string = ""
33        description: "This is the summary of the order."
34
35
36language:
37    default_locale: "en_US"
38    additional_locales: ""
39    all_additional_locales: False
40
41# The entry point for the agent, on every customer utterance.
42start_agent agent_router:
43    description: "Welcome the user and determine the appropriate subagent based on user input"
44    reasoning:
45        instructions: ->
46            | You are an agent router for a Customer Service Bot assistant.
47              Welcome the guest and analyze their input to determine the most appropriate subagent to handle their request.
48              NEVER escalate to a human unless explicitly requested. A bad experience shouldn't automatically escalate.
49        # This section lists the tools that the LLM
50        # can choose to use. In this example, the LLM has two tools:
51        # transitioning to the Identity subagent or transitioning to the
52        # Order_Management subagent
53        actions:
54            # Transitions deterministically route execution to the specified subagent.
55            # Once the LLM chooses to use this tool, the execution is guaranteed
56            # to transition.
57            go_to_identity: @utils.transition to @subagent.Identity
58                description: "verifies user identity"
59                available when @variables.verified == False
60            go_to_order: @utils.transition to @subagent.Order_Management
61                description: "Handles order lookup, refunds, order updates, and summarizes status, order date, current location, delivery address, items, and driver name."
62                available when @variables.verified == True
63
64subagent Identity:
65    description: "Handles verification of the user's identity before providing access to all other topics."
66    reasoning:
67        instructions: ->
68            if @variables.member_email != "":
69                run @actions.send_verification_code
70                    with email=@variables.member_email
71                    with member_number = @variables.member_number
72                    set @variables.verification_code=@outputs.verification_code
73                    set @variables.member_name=@outputs.member_name
74
75            | Greet the user and inform them that to help them get started you've sent them a verification code via email.
76              # This prompt contains two actions that the LLM can choose to run -
77              # a tool to send the verification code, and a tool to validate the
78              # verification code. Once the LLM chooses to run these actions,
79              # the actions are run deterministically
80              Ask the user for the verification code they received and verify it using {!@actions.validate_verification_code}.
81              If the user says they did not receive the code, ask them to confirm their email and resend the verification code using {!@actions.send_verification_code}
82
83        # The reasoning.actions section declares the tools that the LLM can choose
84        # to run. This section has three tools - two actions and
85        # one transition.
86        actions:
87            send_verification_code: @actions.send_verification_code
88                with email=@variables.member_email
89                with member_number=@variables.member_number
90                set @variables.verification_code=@outputs.verification_code
91
92            validate_verification_code: @actions.validate_verification_code
93                available when @variables.verification_code != None
94                with verification_code=@variables.user_verification_code
95                set @variables.verified=@outputs.verification
96
97            go_to_order_management: @utils.transition to @subagent.Order_Management
98                available when @variables.verified == True
99
100
101    # This section defines the actions available to this subagent. Actions are
102    # only valid within the subagent in which they are defined.
103    actions:
104        send_verification_code:
105            description: "Send a verification code to the member and verify confirmation."
106            inputs:
107                email: string
108                member_number: string
109            outputs:
110                verification_code: string
111                member_name: string
112            target: "flow://Get_Verification_Code"
113
114
115        validate_verification_code:
116            description: "validate the verification code"
117            inputs:
118                verification_code: string
119            outputs:
120                verification: boolean
121                    description: "always validate and return True"
122            target: "flow://validate_Verification_Code"
123
124
125subagent Order_Management:
126    description: "Handles order lookup, order updates, and summaries including status, date, location, items, and driver."
127
128    reasoning:
129        instructions: ->
130            if @variables.order_summary == "":
131                run @actions.lookup_current_order
132                    with member_email=@variables.member_email
133                    set @variables.order_summary=@outputs.order_summary
134
135                | Refer to the user by name {!@variables.member_name}.
136                  Show their current order summary: {!@variables.order_summary} when conversation starts or if requested.
137                  If they want past order info, ask for Order ID and use {!@actions.lookup_order}.
138
139        actions:
140            # The ... indicates that the LLM can use reasoning to select the
141            # information from the customer's conversation, then input
142            # the information into the correct input variables
143            lookup_order: @actions.lookup_order
144                with query = ...
145                # Store the action's output into variables
146                set @variables.order_summary=@outputs.order_summary
147                set @variables.order_id=@outputs.order_id
148
149
150            lookup_current_order: @actions.lookup_current_order
151                with member_email=@variables.member_email
152                set @variables.order_summary=@outputs.order_summary
153                set @variables.order_id=@outputs.order_id
154
155    actions:
156        lookup_order:
157            description: "Retrieve order details."
158            inputs:
159                query: string
160            outputs:
161                order_summary: string
162                order_id: string
163            target: "flow://Get_Past_Order"
164
165        lookup_current_order:
166            description: "Retrieve current order details."
167            inputs:
168                member_email: string
169            outputs:
170                order_summary: string
171                order_id: string
172            target: "flow://Get_Current_Order"
173# End of customer support script

Build the agent with clicks in Agentforce Builder’s Canvas view, which summarizes Agent Script into easily understandable blocks. For full details on the features used here, see Building Agents in Canvas View.

Canvas Step 1: Scaffold the Agent 

Create an agent in Agentforce Builder. In the setup flow, set the agent’s name, running user, description, and tone — the foundation that the agent’s instructions and welcome message build on. When you finish, Agentforce Builder opens your new agent in Canvas view.

Canvas Step 2: Define the Variables 

Open the Variables panel and create the variables that the agent uses to remember information across the conversation. For each one, set a name, a data type, and an optional default value:

  • Identity: member_name, member_email, member_number, verification_code, user_verification_code, and a verified boolean (default False).
  • Orders: order_id and an order_summary string (default empty).

The verified boolean and order_summary string are the variables that later gate which subagents and actions the agent can use. See Manage Variables.

Canvas Step 3: Build the Router 

The router is your start subagent — the agent’s entry point on every customer message. In actions available for reasoning, add two transition utilities: one to the Identity subagent, one to Order Management. Use a filter (Make this action available when:) so the transition to Identity is available only when verified equals False, and the transition to Order Management only when verified equals True. This ensures customers verify their identity before they can look up orders.

A transition utility in a subagent's actions available for reasoning in Canvas view

Canvas Step 4: Build the Identity Subagent 

Add a subagent named Identity to verify the customer before any order data is exposed. Add the send_verification_code and validate_verification_code actions (both backed by flows) to actions available for reasoning. In the reasoning instructions, use the inline action shortcuts (/) to run the send action and store its outputs in variables, and reference the actions as resources (@) so the agent validates the code the customer enters. Add a transition to Order Management, available only when verified equals True.

The inline actions shortcut menu, opened with the slash key in Canvas view reasoning instructions

Canvas Step 5: Build the Order Management Subagent 

Add a subagent named Order Management to look up order details. Add the lookup_current_order and lookup_order actions. In the reasoning instructions, use a conditional (/) so that when order_summary is empty, the agent runs lookup_current_order and stores the result in the order_summary variable. Reference member_name and order_summary as resources (@) to personalize the response. Customers can also look up a past order by providing an Order ID.

Running the lookup_current_order action inside a conditional instruction in Canvas view

Canvas Step 6: Preview and Test 

In Canvas view, select Preview and start a conversation, such as I need help with my order. Confirm that the agent asks you to verify your identity first, and that order details return correctly after verification.