Example agent — Revenue Assistant, an Agent Script employee agent grounded on Data 360 golden records (account brief through a Data 360 flow, lookalike search through a custom-retriever Data Library, next best offer through a prompt template)

A complete Agent Script file for a seller-facing revenue agent that passes Salesforce's open-source linter and compiler. A router sends sellers to an account brief, where a flow reads the golden record's revenue rollup and a prompt template proposes a next best offer, or to account search, where AnswerQuestionsWithKnowledge queries the golden-record search index through an Agentforce Data Library. Replace the library ID and the action targets with yours.

markdownexamplev1RM00-WYPVstage: buildtrust: officialservice: agentforceinterface: agent-scriptRevenue Assistant agentgolden record agent exampleAgentforceEmployeeAgent knowledge blockAnswerQuestionsWithKnowledge custom retrieverflow://Get_Account_Revenue_Contextprompt://Next_Best_OfferInput:Account_Contextnext best offer agentaccount brief agentlookalike accounts agent

Created 23 Oct 2026 · Modified 23 Oct 2026 · 1 version

Example: Revenue Assistant

force-app/main/default/aiAuthoringBundles/Revenue_Assistant/Revenue_Assistant.agent. How to build what it calls, and how to deploy and test it: guides/data360/ground-a-revenue-agent.md.

config:
    developer_name: "Revenue_Assistant"
    agent_label: "Revenue Assistant"
    description: "Helps sellers grow revenue from golden-record account context: briefs, lookalike accounts and next best offers"
    agent_type: "AgentforceEmployeeAgent"

variables:
    account_name: mutable string = ""
        description: "Name of the account the seller is working on"
    account_context: mutable string = ""
        description: "Revenue summary returned for the current account"

system:
    messages:
        welcome: "Hi, I can brief you on an account, find similar accounts, and suggest a next best offer."
        error: "Sorry, something went wrong. Please try again."
    instructions: "You help sellers grow revenue. Use only figures returned by your actions. Never invent orders, amounts or dates."

knowledge:
    rag_feature_config_id: "ARFPC_1JDXX0000000001AAA"
    citations_enabled: True
    citations_url: ""

start_agent agent_router:
    description: "Route the seller to the right revenue task"
    reasoning:
        instructions: |
            Pick the tool that matches the request. If no account is named for a brief or offer, ask for it.
        actions:
            go_brief: @utils.transition to @subagent.account_brief
                description: "Brief on one named account, or suggest an offer for it"
            go_find: @utils.transition to @subagent.find_accounts
                description: "Find accounts that match a description, or accounts similar to one"

subagent account_brief:
    description: "Summarize one account's golden-record revenue and suggest a next best offer"

    actions:
        get_account_context:
            description: "Get the unified revenue context for an account: lifetime revenue, order count, last order, top products"
            inputs:
                accountName: string
                    description: "Account name as the seller says it"
                    is_required: True
            outputs:
                revenueSummary: string
                    description: "Plain-text revenue summary from Data 360"
                    is_displayable: True
                lifetimeRevenue: number
                    description: "Lifetime revenue across all unified source records"
            target: "flow://Get_Account_Revenue_Context"
            include_in_progress_indicator: True
            progress_indicator_message: "Reading the golden record..."
        next_best_offer:
            description: "Suggest the next best offer from the account's revenue context"
            inputs:
                "Input:Account_Context": string
                    description: "The revenue summary for the account"
                    is_required: True
            outputs:
                promptResponse: string
                    description: "The suggested offer with its reasoning"
                    is_displayable: True
            target: "prompt://Next_Best_Offer"

    reasoning:
        instructions: ->
            | Get the account's revenue context with {!@actions.get_account_context} before answering.
            if @variables.account_context != "":
                | Summarize it in three bullets, then offer a next best offer with {!@actions.next_best_offer}.
            else:
                | Ask which account the seller means.
        actions:
            capture_account: @utils.setVariables
                description: "Record the account the seller names"
                with account_name = ...
            brief: @actions.get_account_context
                available when @variables.account_name != ""
                with accountName = @variables.account_name
                set @variables.account_context = @outputs.revenueSummary
            offer: @actions.next_best_offer
                available when @variables.account_context != ""
                with "Input:Account_Context" = @variables.account_context

subagent find_accounts:
    description: "Find accounts by description or similarity using the golden-record search index"

    actions:
        AnswerQuestionsWithKnowledge:
            description: "Searches unified account narratives (revenue, orders, products) to find matching or similar accounts"
            inputs:
                query: string
                    description: "Required. A search query created from the seller's request."
                    label: "Query"
                    is_required: True
                    is_user_input: True
                citationsUrl: string = @knowledge.citations_url
                    description: "The URL to use for citations for custom Agents."
                    label: "Citations Url"
                    is_required: False
                    is_user_input: True
                ragFeatureConfigId: string = @knowledge.rag_feature_config_id
                    description: "The RAG Feature ID to use for grounding this copilot action invocation."
                    label: "RAG Feature Configuration Id"
                    is_required: False
                    is_user_input: True
                citationsEnabled: boolean = @knowledge.citations_enabled
                    description: "Whether or not citations are enabled."
                    label: "Citations Enabled"
                    is_required: False
                    is_user_input: True
            outputs:
                knowledgeSummary: object
                    description: "Rich-text summary of the matching account narratives, with citations."
                    label: "Knowledge Summary"
                    complex_data_type_name: "lightning__richTextType"
                    filter_from_agent: False
                    is_displayable: True
                citationSources: object
                    description: "Source links for the retrieved chunks."
                    label: "Citation Sources"
                    complex_data_type_name: "@apexClassType/AiCopilot__GenAiCitationInput"
                    filter_from_agent: False
                    is_displayable: False
            target: "standardInvocableAction://streamKnowledgeSearch"
            label: "Answer Questions with Knowledge"
            require_user_confirmation: False
            include_in_progress_indicator: True
            progress_indicator_message: "Searching golden records"
            source: "EmployeeCopilot__AnswerQuestionsWithKnowledge"

    reasoning:
        instructions: ->
            | For every search, call {!@actions.AnswerQuestionsWithKnowledge} before answering.
            | Answer only from the returned summary and cite its sources. If it is empty, say no matching accounts were found.
        actions:
            search_accounts: @actions.AnswerQuestionsWithKnowledge
                with query = ...
                with citationsUrl = ...
                with ragFeatureConfigId = ...
                with citationsEnabled = ...
  • Employee agent: it runs as the signed-in seller, so there is no access block, and the seller needs Data 360 access.
  • Tool names for tests: brief, offer, search_accounts. Agent tests expect these, not the action declaration names (reference/agentforce/agent-testing.md).
  • Grounding rule: "Use only figures returned by your actions" lives in system.instructions, so every subagent inherits it.

Read this document as markdown — the same bytes an agent receives.