a few more topic -> subagent replacements

This commit is contained in:
Steve Hetzel 2026-04-24 17:37:23 -06:00
parent 18dc7cf05a
commit 55fc68ba54
No known key found for this signature in database
GPG Key ID: 4577056100BDA892
24 changed files with 83 additions and 83 deletions

View File

@ -1,6 +1,6 @@
---
name: developing-agentforce
description: "Build, modify, debug, and deploy agents with Agentforce Agent Script. TRIGGER when: user creates, modifies, or asks about .agent files or aiAuthoringBundle metadata; changes agent behavior, responses, or conversation logic; designs agent topics, actions, tools, sub-agents, or flow control; writes or reviews an Agent Spec; previews, debugs, deploys, publishes, or tests agents; uses Agent Script CLI commands (sf agent generate/preview/publish/test). DO NOT TRIGGER when: Apex development, Flow building, Prompt Template authoring, Experience Cloud configuration, or general Salesforce CLI tasks unrelated to Agent Script."
description: "Build, modify, debug, and deploy agents with Agentforce Agent Script. TRIGGER when: user creates, modifies, or asks about .agent files or aiAuthoringBundle metadata; changes agent behavior, responses, or conversation logic; designs agent actions, tools, subagents, or flow control; writes or reviews an Agent Spec; previews, debugs, deploys, publishes, or tests agents; uses Agent Script CLI commands (sf agent generate/preview/publish/test). DO NOT TRIGGER when: Apex development, Flow building, Prompt Template authoring, Experience Cloud configuration, or general Salesforce CLI tasks unrelated to Agent Script."
license: Apache-2.0
compatibility: "Requires Agentforce license, API v66.0+, Einstein Agent User"
metadata:
@ -18,7 +18,7 @@ Agent Script is Salesforce's scripting language for authoring next-generation AI
language. Do NOT confuse Agent Script syntax or semantics with any other
language you have been trained on.
Agent Script agents are defined by `AiAuthoringBundle` metadata — a directory with a `.agent` file containing Agent Script source that describes topics, actions, instructions, flow control, and configuration; and a `bundle-meta.xml` file containing bundle metadata. Agents process utterances by routing through topics, each with instructions and actions backed by Apex, Flows, Prompt Templates, and other types of backing logic.
Agent Script agents are defined by `AiAuthoringBundle` metadata — a directory with a `.agent` file containing Agent Script source that describes actions, instructions, subagents, flow control, and configuration; and a `bundle-meta.xml` file containing bundle metadata. Agents process utterances by routing through subagents, each with instructions and actions backed by Apex, Flows, Prompt Templates, and other types of backing logic.
This skill covers the full Agent Script lifecycle: designing agents,
writing Agent Script code, validating and debugging, deploying and
@ -53,7 +53,7 @@ Every task domain below has **Required Steps**. Follow verbatim, in order. Do no
### Create an Agent
User wants to build new agent from scratch. ALWAYS use Agent Script. Work with User to understand the agent's purpose, topics, and actions using plain language without Salesforce-specific terminology.
User wants to build new agent from scratch. ALWAYS use Agent Script. Work with User to understand the agent's purpose, subagents, and actions using plain language without Salesforce-specific terminology.
#### Required Steps

View File

@ -24,7 +24,7 @@ What do you need?
├─► "Just starting"
│ └─► agents/hello-world.agent
├─► "Complete agent with topics"
├─► "Complete agent with subagents"
│ └─► agents/multi-subagent.agent
├─► "Add actions to my agent"
@ -57,7 +57,7 @@ What do you need?
|----------|---------|
| `flow-action.agent` | Flow action integration |
| `apex-action.agent` | Apex action integration |
| `subagent-with-actions.agent` | Topic with actions |
| `subagent-with-actions.agent` | Subagent with actions |
| `error-handling.agent` | Input validation |
| `escalation-setup.agent` | Human handoff |
@ -67,8 +67,8 @@ What do you need?
|----------|---------|------------|
| `lifecycle-events.agent` | before/after reasoning | GenAiPlannerBundle |
| `action-callbacks.agent` | Deterministic chains | GenAiPlannerBundle |
| `bidirectional-routing.agent` | Topic routing with return | Both |
| `system-instruction-overrides.agent` | Topic-level personas | Both |
| `bidirectional-routing.agent` | Subagent routing with return | Both |
| `system-instruction-overrides.agent` | Subagent-level personas | Both |
| *(6 more patterns)* | | |
### metadata/ - XML Templates

View File

@ -1,10 +1,10 @@
# Multi-Topic Agent Template
# An agent with multiple conversation topics (hub-and-spoke pattern)
# Users are routed to specialized topics based on their needs
# Multi-Subagent Agent Template
# An agent with multiple conversation subagents (hub-and-spoke pattern)
# Users are routed to specialized subagents based on their needs
#
# Usage: Replace {{placeholders}} with your values
# Required: agent_name, default_agent_user, agent_label, description
# Required: At least 2 topics with label and description
# Required: At least 2 subagents with label and description
system:
instructions: "{{SystemInstructions}}"
@ -46,39 +46,39 @@ start_agent agent_router:
| Route them to the most appropriate subagent.
| If unclear, ask clarifying questions.
actions:
go_to_topic_one: @utils.transition to @subagent.{{topic_one_name}}
go_to_topic_two: @utils.transition to @subagent.{{topic_two_name}}
go_to_topic_three: @utils.transition to @subagent.{{topic_three_name}}
go_to_subagent_one: @utils.transition to @subagent.{{subagent_one_name}}
go_to_subagent_two: @utils.transition to @subagent.{{subagent_two_name}}
go_to_subagent_three: @utils.transition to @subagent.{{subagent_three_name}}
go_to_farewell: @utils.transition to @subagent.farewell
go_to_escalation: @utils.transition to @subagent.escalation
subagent {{topic_one_name}}:
label: "{{TopicOneLabel}}"
description: "{{TopicOneDescription}}"
subagent {{subagent_one_name}}:
label: "{{SubagentOneLabel}}"
description: "{{SubagentOneDescription}}"
reasoning:
instructions: ->
| {{TopicOneInstructions}}
| {{SubagentOneInstructions}}
actions:
back_to_menu: @utils.transition to @subagent.agent_router
subagent {{topic_two_name}}:
label: "{{TopicTwoLabel}}"
description: "{{TopicTwoDescription}}"
subagent {{subagent_two_name}}:
label: "{{SubagentTwoLabel}}"
description: "{{SubagentTwoDescription}}"
reasoning:
instructions: ->
| {{TopicTwoInstructions}}
| {{SubagentTwoInstructions}}
actions:
back_to_menu: @utils.transition to @subagent.agent_router
subagent {{topic_three_name}}:
label: "{{TopicThreeLabel}}"
description: "{{TopicThreeDescription}}"
subagent {{subagent_three_name}}:
label: "{{SubagentThreeLabel}}"
description: "{{SubagentThreeDescription}}"
reasoning:
instructions: ->
| {{TopicThreeInstructions}}
| {{SubagentThreeInstructions}}
actions:
back_to_menu: @utils.transition to @subagent.agent_router

View File

@ -3,7 +3,7 @@
#
# A complex real-world agent for e-commerce customer service featuring:
# - Verification gate before order access
# - Multiple specialized topics (order status, tracking, returns)
# - Multiple specialized subagents (order status, tracking, returns)
# - Two-level action system with Flow targets
# - after_reasoning for post-action routing
# - available when guards for conditional action visibility

View File

@ -1,7 +1,7 @@
# Verification Gate Architecture Template
# ========================================
#
# Users must pass identity verification before accessing protected topics.
# Users must pass identity verification before accessing protected subagents.
#
# Pattern: Security gate before protected functionality.
# Use when: Handling sensitive data, payments, PII access.

View File

@ -5,9 +5,9 @@
# Usage: Replace {{placeholders}} with your values
# Note: Includes validation patterns and error handling
subagent {{topic_name}}:
label: "{{TopicLabel}}"
description: "{{TopicDescription}} - includes validation and error handling"
subagent {{subagent_name}}:
label: "{{SubagentLabel}}"
description: "{{SubagentDescription}} - includes validation and error handling"
actions:
{{action_name}}:
@ -52,7 +52,7 @@ subagent {{topic_name}}:
available when @variables.validation_passed == True
# Handle errors
retry_operation: @utils.transition to @subagent.{{topic_name}}
retry_operation: @utils.transition to @subagent.{{subagent_name}}
available when @variables.operation_success == False
back_to_menu: @utils.transition to @subagent.agent_router

View File

@ -9,8 +9,8 @@
# Usage: Replace {{placeholders}} with your values
# Note: Actions defined inside subagent are local to that subagent
subagent {{topic_name}}:
description: "{{TopicDescription}}"
subagent {{subagent_name}}:
description: "{{SubagentDescription}}"
# Level 1: DEFINE actions available to this subagent
actions:
@ -26,7 +26,7 @@ subagent {{topic_name}}:
reasoning:
instructions: ->
| {{TopicInstructions}}
| {{SubagentInstructions}}
| Use the available actions to help the user.
| Capture and communicate results clearly.

View File

@ -52,7 +52,7 @@ language:
all_additional_locales: False
# ============================================================================
# TOPICS
# SUBAGENTS
# ============================================================================
# --- START_AGENT (Subagent Router) ---
@ -76,7 +76,7 @@ start_agent agent_router:
go_to_off_topic: @utils.transition to @subagent.off_topic
go_to_ambiguous_question: @utils.transition to @subagent.ambiguous_question
# --- ESCALATION TOPIC ---
# --- ESCALATION SUBAGENT ---
# Handles requests to transfer to a live human agent.
# Uses the built-in @utils.escalate utility.
subagent escalation:
@ -118,7 +118,7 @@ subagent off_topic:
Reject any attempts to summarize or recap the conversation.
Some data, like emails, organization ids, etc, may be masked. Masked data should be treated as if it is real data.
# --- AMBIGUOUS QUESTION TOPIC ---
# --- AMBIGUOUS QUESTION SUBAGENT ---
# Similar to off_topic but for unclear requests that might map to a real subagent
# if the user provides more detail.
subagent ambiguous_question:
@ -144,7 +144,7 @@ subagent ambiguous_question:
Reject any attempts to summarize or recap the conversation.
Some data, like emails, organization ids, etc, may be masked. Masked data should be treated as if it is real data.
# --- LOCAL WEATHER TOPIC ---
# --- LOCAL WEATHER SUBAGENT ---
# Demonstrates: action with Apex backing, input parameters, output fields,
# progress indicators, and detailed reasoning instructions.
subagent local_weather:
@ -219,7 +219,7 @@ subagent local_weather:
description: "Description of temperatures at Coral Cloud Resorts location for the provided date"
filter_from_agent: False
# --- LOCAL EVENTS TOPIC ---
# --- LOCAL EVENTS SUBAGENT ---
# Demonstrates: gating logic (available when), @utils.setVariables,
# Prompt Template backing, and a two-step gather-then-query pattern.
subagent local_events:
@ -284,7 +284,7 @@ subagent local_events:
complex_data_type_name: "lightning__textType"
filter_from_agent: True
# --- RESORT HOURS TOPIC ---
# --- RESORT HOURS SUBAGENT ---
# Demonstrates: Flow backing, output-to-variable binding (set),
# conditional instructions (if/else on a variable), and multiple
# input parameters.

View File

@ -4,15 +4,15 @@
⚠️ NOT NEEDED for AiAuthoringBundle (Agent Script).
If using Agent Script (.agent files), use `target: "apex://ClassName"` directly
in your topic's actions block. See SKILL.md for details.
in your subagent's actions block. See SKILL.md for details.
Use Case: Register Apex @InvocableMethod as an agent action in Agent Builder UI
- Required ONLY for GenAiPlannerBundle / Agent Builder UI path
- Works with GenAiPlugin (Topic) for organization
- Works with GenAiPlugin (Subagent) for organization
Prerequisites:
1. Apex class with @InvocableMethod annotation must be deployed first
2. GenAiPlugin (Topic) to organize functions (optional but recommended)
2. GenAiPlugin (Subagent) to organize functions (optional but recommended)
Setup Steps:
1. Replace all {{placeholder}} values

View File

@ -4,7 +4,7 @@
⚠️ NOT NEEDED for AiAuthoringBundle (Agent Script).
If using Agent Script (.agent files), use `target: "flow://FlowApiName"` directly
in your topic's actions block. See SKILL.md for details.
in your subagent's actions block. See SKILL.md for details.
Use Case: Register Autolaunched Flow as an agent action in Agent Builder UI
- Required ONLY for GenAiPlannerBundle / Agent Builder UI path

View File

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
GenAiPlugin Template: Agent Topic/Plugin Container
GenAiPlugin Template: Agent Subagent/Plugin Container
Use Case: Organize GenAiFunctions into logical groups (Topics)
Use Case: Organize GenAiFunctions into logical groups (Subagents)
- Groups related functions together
- Provides topic-level instructions
- Maps to Agent Script topic concepts
- Provides subagent-level instructions
- Maps to Agent Script subagent concepts
Note: GenAiPlugin is the metadata equivalent of a "topic" in Agent Script.
Note: GenAiPlugin is the metadata equivalent of a "subagent" in Agent Script.
Use this when you want to organize functions deployed via metadata
rather than Agent Script.
@ -19,7 +19,7 @@
File Location: force-app/main/default/genAiPlugins/{{PluginName}}.genAiPlugin-meta.xml
-->
<GenAiPlugin xmlns="http://soap.sforce.com/2006/04/metadata">
<!-- Display name for the topic/plugin -->
<!-- Display name for the subagent/plugin -->
<masterLabel>{{PluginLabel}}</masterLabel>
<!-- Description shown in Agent Builder -->
@ -62,8 +62,8 @@
After deploying GenAiPlugin:
1. Open Agent Builder in Setup
2. Navigate to Topics
3. Your plugin appears as a Topic
2. Navigate to Subagents
3. Your plugin appears as a Subagent
4. Associated functions are available as Actions
This provides an alternative to Agent Script for more

View File

@ -103,7 +103,7 @@ consult_pricing: @utils.transition to @subagent.pricing_specialist
# In specialist subagent
before_reasoning:
set @variables.return_topic = "main_hub"
set @variables.return_subagent = "main_hub"
# ... do specialist work ...
@ -168,7 +168,7 @@ reasoning:
system:
instructions: "You are a professional agent. Be helpful and courteous."
# Topic reasoning: Dynamic overrides
# Subagent reasoning: Dynamic overrides
reasoning:
instructions: ->
if @variables.customer_tier == "vip":
@ -239,7 +239,7 @@ open-gate-routing + lifecycle-events
| Lifecycle Events | +5 pts | Proper block placement |
| Bidirectional | +5 pts | Return transitions |
| Input Bindings | +5 pts | Proper binding patterns |
| System Overrides | +5 pts | Static system, dynamic topics |
| System Overrides | +5 pts | Static system, dynamic subagents |
| Open Gate | +5 pts | 3-variable coordination |
## Anti-Patterns to Avoid

View File

@ -148,7 +148,7 @@ subagent farewell:
# ★ Alternative: Simple one-way transitions (when you don't need to return)
#
# If the specialist doesn't need to return results to a coordinator,
# use simple transitions without the return_topic pattern:
# use simple transitions without the return_subagent pattern:
#
# go_orders: @utils.transition to @subagent.orders
# go_billing: @utils.transition to @subagent.billing

View File

@ -62,13 +62,13 @@
# See: bidirectional-routing.agent for full implementation
variables:
return_topic: mutable string = ""
return_subagent: mutable string = ""
description: "Subagent to return to after specialist"
specialist_result: mutable string = ""
description: "Result from specialist consultation"
# Before going to specialist, store return address:
# set @variables.return_topic = "main_hub"
# set @variables.return_subagent = "main_hub"
# go_specialist: @utils.transition to @subagent.specialist
# In specialist, transition back when done:

View File

@ -67,7 +67,7 @@ subagent conversation:
inputs:
turn_number: number
description: "Which turn this is"
topic_name: string
subagent_name: string
description: "Current subagent"
outputs:
logged: boolean
@ -112,7 +112,7 @@ subagent conversation:
# Log analytics for each turn
run @actions.log_turn
with turn_number=@variables.turn_count
with topic_name="conversation"
with subagent_name="conversation"
# Update last activity timestamp
run @actions.get_timestamp

View File

@ -122,7 +122,7 @@ subagent order_assistance:
available when @variables.has_order_id == True
available when @variables.order_status != "shipped"
# Topic transitions
# Subagent transitions
go_help: @utils.transition to @subagent.general_help
go_escalation: @utils.transition to @subagent.escalation
available when @variables.needs_human == True

View File

@ -15,7 +15,7 @@
#
# ★ The 3 Variables:
# open_gate — Which subagent currently holds focus ("null" = none)
# next_topic — Deferred destination after auth completes
# next_subagent — Deferred destination after auth completes
# authenticated — Whether the user has passed authentication
#
# ★ EXIT_PROTOCOL:
@ -35,7 +35,7 @@ variables:
# ... standard linked variables ...
open_gate: mutable string = "null"
description: "Which subagent currently holds focus (null = LLM decides)"
next_topic: mutable string = ""
next_subagent: mutable string = ""
description: "Deferred destination after authentication completes"
authenticated: mutable boolean = False
description: "Whether the user has passed authentication"
@ -79,7 +79,7 @@ subagent protected_workflow:
before_reasoning:
# ★ AUTH CHECK: Redirect unauthenticated users to auth gate
if @variables.authenticated == False:
set @variables.next_topic = "protected_workflow"
set @variables.next_subagent = "protected_workflow"
set @variables.open_gate = "authentication_gate"
transition to @subagent.authentication_gate
@ -115,7 +115,7 @@ subagent account_management:
before_reasoning:
# ★ AUTH CHECK: Same pattern as protected_workflow
if @variables.authenticated == False:
set @variables.next_topic = "account_management"
set @variables.next_subagent = "account_management"
set @variables.open_gate = "authentication_gate"
transition to @subagent.authentication_gate
@ -140,7 +140,7 @@ subagent account_management:
# ─────────────────────────────────────────────────────────────────────
# AUTHENTICATION GATE
# Handles auth flow, then routes back via next_topic
# Handles auth flow, then routes back via next_subagent
# ─────────────────────────────────────────────────────────────────────
subagent authentication_gate:
description: "Verifies customer identity before allowing access to protected subagents"
@ -166,10 +166,10 @@ subagent authentication_gate:
after_reasoning:
# ★ POST-AUTH ROUTING: If authenticated, route to deferred destination
if @variables.authenticated == True:
if @variables.next_topic == "protected_workflow":
if @variables.next_subagent == "protected_workflow":
set @variables.open_gate = "protected_workflow"
transition to @subagent.protected_workflow
if @variables.next_topic == "account_management":
if @variables.next_subagent == "account_management":
set @variables.open_gate = "account_management"
transition to @subagent.account_management
@ -183,7 +183,7 @@ subagent exit_protocol:
before_reasoning:
# ★ RELEASE GATE: Clear all gate state
set @variables.open_gate = "null"
set @variables.next_topic = ""
set @variables.next_subagent = ""
transition to @subagent.agent_router
reasoning:
@ -238,7 +238,7 @@ subagent general_inquiry:
# │ before_reasoning: lock gate │
# │ reasoning: verify identity │
# │ after_reasoning: │
# │ if auth → route via next_topic
# │ if auth → route via next_subagent │
# └──────────────────────────────────────┘
#
# ═════════════════════════════════════════════════════════════════════
@ -251,7 +251,7 @@ subagent general_inquiry:
# open_gate = "null" → LLM reasons → routes to protected_workflow
#
# Step 2: protected_workflow.before_reasoning
# authenticated = False → set next_topic = "protected_workflow"
# authenticated = False → set next_subagent = "protected_workflow"
# → set open_gate = "authentication_gate"
# → transition to authentication_gate
#
@ -262,7 +262,7 @@ subagent general_inquiry:
# authenticated = True
#
# Step 5: authentication_gate.after_reasoning
# authenticated = True, next_topic = "protected_workflow"
# authenticated = True, next_subagent = "protected_workflow"
# → set open_gate = "protected_workflow"
# → transition to protected_workflow
#

View File

@ -9,7 +9,7 @@
#
# ★ Key Insight:
# - System block defines BASE behavior (always applies)
# - Topic instructions can OVERRIDE or EXTEND system behavior
# - Subagent instructions can OVERRIDE or EXTEND system behavior
# - Use conditionals in reasoning to dynamically adjust tone
# - Variables can control instruction branches
#

View File

@ -10,7 +10,7 @@
# CREDIT CONSUMPTION:
# - Prompt Templates: 2-16 credits per invocation
# - Retriever actions: 20 credits per search
# - TIP: Cache retriever results in variables, reuse across topics
# - TIP: Cache retriever results in variables, reuse across subagents
system:
messages:

View File

@ -2,7 +2,7 @@
# ========================================
#
# This template demonstrates the Verification Gate pattern where users
# must pass through identity verification before accessing sensitive topics.
# must pass through identity verification before accessing sensitive subagents.
#
# Pattern: Security gate before protected functionality
# Use when: Handling sensitive data, payments, PII access

View File

@ -83,7 +83,7 @@ language:
start_agent agent_router:
...
subagent my_topic:
subagent my_subagent:
...
```
@ -612,7 +612,7 @@ Expose the transition as a reasoning action when the LLM should judge the right
```agentscript
reasoning:
actions:
go_next: @utils.transition to @subagent.next_topic
go_next: @utils.transition to @subagent.next_subagent
description: "Move to the next subagent"
available when @variables.ready == True
```
@ -919,7 +919,7 @@ The LLM extracts values from the conversation and populates the specified variab
```agentscript
reasoning:
actions:
consult_expert: @subagent.expert_topic
consult_expert: @subagent.expert_subagent
description: "Get expert guidance"
available when @variables.needs_expert_help == True
```
@ -1138,7 +1138,7 @@ reasoning:
```agentscript
# If you need to record state, set before transitioning
before_reasoning:
set @variables.last_topic = "current_topic"
set @variables.last_subagent = "current_subagent"
transition to @subagent.next
```

View File

@ -58,7 +58,7 @@ When a target is missing:
Agentforce ADLC Discovery Report
Agent: OrderManagement
Topic: order_inquiry
Subagent: order_inquiry
Action: get_order_status
Target: flow://Get_Order_Status Found
Action: track_shipment

View File

@ -454,7 +454,7 @@ set @variables.counter = @variables.counter + 1
### Deterministic Transition
```
transition to @subagent.next_topic
transition to @subagent.next_subagent
```
### Conditional Transition

View File

@ -165,7 +165,7 @@ Unresolved platform bugs, limitations, and edge cases that affect Agent Script d
- **Affects**: Agents with actions targeting secured resources
- **Symptom**: If the running user (Einstein Agent User or session user) lacks permission to execute ANY action defined in the agent — even actions in other subagents — the entire agent may fail with a permission error rather than gracefully skipping the unauthorized action.
- **Root Cause**: The planner appears to validate permissions for all registered actions at startup, not lazily per-subagent.
- **Workaround**: For **Service Agents**: Ensure the Einstein Agent User has both the `AgentforceServiceAgentUser` system PS AND a custom `{AgentName}_Access` PS with `<classAccesses>` for ALL Apex classes across all topics. Do NOT rely on the auto-generated `NextGen_{AgentName}_Permissions` — it is often incomplete (ORM1 testing: 3/4 classes, missing `ShipmentTracker`). For **Employee Agents**: Ensure each employee user has the custom PS assigned. See [agent-user-setup.md](agent-user-setup.md) for the full provisioning workflow and permission set XML template. Alternatively, split agents by permission boundary.
- **Workaround**: For **Service Agents**: Ensure the Einstein Agent User has both the `AgentforceServiceAgentUser` system PS AND a custom `{AgentName}_Access` PS with `<classAccesses>` for ALL Apex classes across all subagents. Do NOT rely on the auto-generated `NextGen_{AgentName}_Permissions` — it is often incomplete (ORM1 testing: 3/4 classes, missing `ShipmentTracker`). For **Employee Agents**: Ensure each employee user has the custom PS assigned. See [agent-user-setup.md](agent-user-setup.md) for the full provisioning workflow and permission set XML template. Alternatively, split agents by permission boundary.
- **Open Questions**: Will the planner support lazy permission checking in a future release?
---