sf-ai-agentscript

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

SF-AI-AgentScript Skill

SF-AI-AgentScript 技能

"Prompt engineering is like writing laws in poetry - beautiful, but not enforceable."
Agent Script transforms agent development from prompt-based suggestions to code-enforced guarantees. This skill guides you through writing, debugging, testing, and deploying Agentforce agents using the Agent Script DSL.

"提示工程就像用诗歌写法律——优美,但不具备强制执行力。"
Agent Script将智能体开发从基于提示的建议转变为代码强制执行的保障。本技能将指导你使用Agent Script DSL编写、调试、测试和部署Agentforce智能体。

⚠️ CRITICAL WARNINGS

⚠️ 关键警告

API & Version Requirements

API与版本要求

RequirementValueNotes
API Version65.0+Required for Agent Script support
LicenseAgentforceRequired for agent authoring
Einstein Agent UserRequiredMust exist in org for
default_agent_user
File Extension
.agent
Single file contains entire agent definition
要求取值说明
API版本65.0+支持Agent Script的最低版本
许可证Agentforce智能体创作所需
Einstein Agent用户必填组织中必须存在该用户以配置
default_agent_user
文件扩展名
.agent
单个文件包含完整的智能体定义

MANDATORY Pre-Deployment Checks

部署前必须检查项

  1. default_agent_user
    MUST be valid
    - Query:
    SELECT Username FROM User WHERE Profile.Name = 'Einstein Agent User' AND IsActive = true
  2. No mixed tabs/spaces - Use consistent indentation (2-space, 3-space, or tabs - never mix)
  3. Booleans are capitalized - Use
    True
    /
    False
    , not
    true
    /
    false
  4. Exactly one
    start_agent
    block
    - Multiple entry points cause compilation failure
  1. default_agent_user
    必须有效
    - 查询语句:
    SELECT Username FROM User WHERE Profile.Name = 'Einstein Agent User' AND IsActive = true
  2. 禁止混合使用制表符和空格 - 使用一致的缩进方式(2空格、3空格或制表符,切勿混合)
  3. 布尔值首字母大写 - 使用
    True
    /
    False
    ,而非
    true
    /
    false
  4. 仅存在一个
    start_agent
    - 多个入口点会导致编译失败

⛔ SYNTAX CONSTRAINTS (Validated via Testing + Official Spec)

⛔ 语法约束(经测试+官方规范验证)

Constraint❌ WRONG✅ CORRECT
No nested if statements
if x:
then
if y:
(nested)
if x and y:
(compound) OR flatten to sequential ifs
No top-level
actions:
block
actions:
at root level
Actions only inside
topic.reasoning.actions:
No
inputs:
/
outputs:
in actions
inputs:
block inside action
Use
with
for inputs,
set
for outputs
One
available when
per action
Two
available when
clauses
available when A and B
Avoid reserved action names
escalate: @utils.escalate
escalate_now: @utils.escalate
...
is slot-filling only
my_var: mutable string = ...
my_var: mutable string = ""
No defaults on linked vars
id: linked string = ""
id: linked string
+
source:
Linked vars: no object/list
data: linked object
Use
linked string
or parse in Flow
Post-action only on @actions
@utils.X
with
set
/
run
Only
@actions.X
supports post-action
agent_name must match folderFolder:
MyAgent
, config:
my_agent
Both must be identical (case-sensitive)
Reserved field names
description: string
,
label: string
Use
descriptions
,
label_text
, or suffix with
_field
约束❌ 错误示例✅ 正确示例
禁止嵌套if语句
if x:
后嵌套
if y:
使用
if x and y:
(复合条件)或拆分为顺序执行的if语句
禁止顶层
actions:
在根层级定义
actions:
仅在
topic.reasoning.actions:
内定义动作
动作内禁止
inputs:
/
outputs:
在动作中定义
inputs:
使用
with
传递输入,
set
捕获输出
每个动作仅允许一个
available when
同一动作包含两个
available when
子句
合并为
available when A and B
避免使用保留动作名称
escalate: @utils.escalate
重命名为
escalate_now: @utils.escalate
...
仅用于槽位填充
my_var: mutable string = ...
使用
my_var: mutable string = ""
关联变量禁止设置默认值
id: linked string = ""
使用
id: linked string
+
source:
关联变量不支持对象/列表类型
data: linked object
使用
linked string
或在Flow中解析
@actions
支持动作后指令
@utils.X
使用
set
/
run
@actions.X
支持动作后操作
agent_name必须与文件夹名称一致文件夹名:
MyAgent
,配置:
my_agent
两者必须完全相同(区分大小写)
保留字段名称
description: string
,
label: string
使用
descriptions
,
label_text
或后缀
_field

🔴 Reserved Field Names (Breaking in Recent Releases)

🔴 保留字段名称(近期版本会导致报错)

Common field names that cause parse errors:
❌ RESERVED (cannot use as variable/field names):
description, label, is_required, is_displayable, is_used_by_planner

✅ WORKAROUNDS:
description  → descriptions, description_text, desc_field
label        → label_text, display_label, label_field
常见会导致解析错误的字段名:
❌ 保留字段(不能用作变量/字段名):
description, label, is_required, is_displayable, is_used_by_planner

✅ 替代方案:
description  → descriptions, description_text, desc_field
label        → label_text, display_label, label_field

🔴 Features NOT Valid in Current Release (TDD Validated 2026-01-20)

🔴 当前版本不支持的功能(2026-01-20经TDD验证)

These features appear in documentation or recipes but do NOT compile in Winter '26.
FeatureWhere MentionedErrorStatus
label:
on topics
agentforce.guide
Unexpected 'label'
❌ NOT valid anywhere
label:
on actions
agentforce.guide
Unexpected 'label'
❌ NOT valid anywhere
always_expect_input:
Some docs
Unexpected 'always_expect_input'
❌ NOT implemented
require_user_confirmation:
on transitions
Recipes
Unexpected 'require_user_confirmation'
❌ NOT valid on
@utils.transition
include_in_progress_indicator:
on transitions
Recipes
Unexpected 'include_in_progress_indicator'
❌ NOT valid on
@utils.transition
output_instructions:
on transitions
Recipes
Unexpected 'output_instructions'
❌ NOT valid on
@utils.transition
progress_indicator_message:
on transitions
Recipes
Unexpected 'progress_indicator_message'
❌ May only work on
flow://
targets
What DOES work on
@utils.transition
actions:
yaml
actions:
   go_next: @utils.transition to @topic.next
      description: "Navigate to next topic"   # ✅ ONLY this works
Note: Some of these may work on
flow://
action targets (not validated). The
@utils.transition
utility action has limited property support.
这些功能出现在文档或示例中,但在Winter '26版本中无法编译
功能提及来源错误信息状态
主题上的
label:
agentforce.guide
Unexpected 'label'
❌ 任何场景均不支持
动作上的
label:
agentforce.guide
Unexpected 'label'
❌ 任何场景均不支持
always_expect_input:
部分文档
Unexpected 'always_expect_input'
❌ 未实现
转换动作上的
require_user_confirmation:
示例代码
Unexpected 'require_user_confirmation'
❌ 不支持
@utils.transition
转换动作上的
include_in_progress_indicator:
示例代码
Unexpected 'include_in_progress_indicator'
❌ 不支持
@utils.transition
转换动作上的
output_instructions:
示例代码
Unexpected 'output_instructions'
❌ 不支持
@utils.transition
转换动作上的
progress_indicator_message:
示例代码
Unexpected 'progress_indicator_message'
❌ 仅可能在
flow://
目标上生效
@utils.transition
动作支持的属性:
yaml
actions:
   go_next: @utils.transition to @topic.next
      description: "跳转到下一个主题"   # ✅ 仅该属性生效
注意:部分属性可能在
flow://
动作目标上生效(未验证)。
@utils.transition
工具动作仅支持有限的属性。

🔴
complex_data_type_name
Mapping Table (Critical for Actions)

🔴
complex_data_type_name
映射表(动作配置关键)

"#1 source of compile errors" - Use this table when defining action inputs/outputs in Agentforce Assets.
Data Type
complex_data_type_name
Value
Notes
string
(none needed)Primitive type
number
(none needed)Primitive type
boolean
(none needed)Primitive type
object
(SObject)
lightning__recordInfoType
Use for Account, Contact, etc.
list[string]
lightning__textType
Collection of text values
list[object]
lightning__textType
Serialized as JSON text
Apex Inner Class
@apexClassType/NamespacedClass__InnerClass
Namespace required
Custom LWC Type
lightning__c__CustomTypeName
Custom component types
Currency field
lightning__currencyType
For monetary values
Pro Tip: Don't manually edit
complex_data_type_name
- use the UI dropdown in Agentforce Assets > Action Definition, then export/import the action definition.
"编译错误的头号来源" - 在Agentforce资产中定义动作输入/输出时使用此表。
数据类型
complex_data_type_name
取值
说明
string
(无需设置)原始类型
number
(无需设置)原始类型
boolean
(无需设置)原始类型
object
(SObject)
lightning__recordInfoType
用于Account、Contact等对象
list[string]
lightning__textType
文本值集合
list[object]
lightning__textType
序列化为JSON文本
Apex内部类
@apexClassType/NamespacedClass__InnerClass
必须指定命名空间
自定义LWC类型
lightning__c__CustomTypeName
自定义组件类型
货币字段
lightning__currencyType
用于货币值
实用技巧:不要手动编辑
complex_data_type_name
- 在Agentforce资产 > 动作定义中使用UI下拉选择,然后导出/导入动作定义。

⚠️ Canvas View Corruption Bugs

⚠️ Canvas视图损坏问题

CRITICAL: Canvas view can silently corrupt Agent Script syntax. Make complex edits in Script view.
Original SyntaxCanvas Corrupts ToImpact
==
{! OPERATOR.EQUAL }
Breaks conditionals
if condition:
if condition
(missing colon)
Parse error
with email =
with @inputs.email =
Invalid syntax
4-space indentDe-indented (breaks nesting)Structure lost
@topic.X
(supervision)
@utils.transition to @topic.X
(handoff)
Changes return behavior
A and B
A {! and } B
Breaks compound conditions
Safe Workflow:
  1. Use Script view for all structural edits (conditionals, actions, transitions)
  2. Use Canvas only for visual validation and simple text changes
  3. Always review in Script view after any Canvas edit
关键提示:Canvas视图可能会静默破坏Agent Script语法。复杂编辑请使用脚本视图
原始语法Canvas视图损坏后的结果影响
==
{! OPERATOR.EQUAL }
破坏条件判断
if condition:
if condition
(缺少冒号)
解析错误
with email =
with @inputs.email =
无效语法
4空格缩进缩进被移除(破坏嵌套结构)丢失代码结构
@topic.X
(监督模式)
@utils.transition to @topic.X
(移交模式)
改变返回行为
A and B
A {! and } B
破坏复合条件
安全工作流:
  1. 所有结构性编辑(条件判断、动作、转换)使用脚本视图
  2. 仅使用Canvas视图进行可视化验证和简单文本修改
  3. 任何Canvas视图编辑后,务必在脚本视图中检查

⚠️ Preview Mode Critical Bugs

⚠️ 预览模式关键问题

CRITICAL REFRESH BUG: Browser refresh required after every Agent Script save before preview works properly.
IssueError MessageWorkaround
Linked vars in context, not state
"Cannot access 'X': Not a declared field in dict"
Convert to mutable + hardcode for testing
Output property access failsSilent failure, no errorAssign to variable first, then use in conditional
Simulate vs Live behavior differsWorks in Simulate, fails in LiveTest in BOTH modes before committing
Pattern for Testing Linked Variables:
yaml
undefined
关键刷新问题:每次保存Agent Script后,必须刷新浏览器才能正常使用预览功能。
问题错误信息解决方法
上下文中的关联变量而非状态变量
"Cannot access 'X': Not a declared field in dict"
转换为可变变量并在测试中硬编码值
输出属性访问失败无提示失败先赋值给变量,再在条件判断中使用
模拟与线上行为不一致模拟模式正常,线上模式失败部署前在两种模式中均进行测试
关联变量测试模式:
yaml
undefined

❌ DOESN'T WORK IN PREVIEW (linked var from session):

❌ 预览模式不生效(来自会话的关联变量):

RoutableId: linked string source: @MessagingSession.Id
RoutableId: linked string source: @MessagingSession.Id

✅ WORKAROUND FOR TESTING (hardcode value):

✅ 测试用解决方法(硬编码值):

RoutableId: mutable string = "test-session-123" description: "MessagingSession Id (hardcoded for testing)"
RoutableId: mutable string = "test-session-123" description: "MessagingSession ID(测试用硬编码值)"

After testing, switch back to linked for production

测试完成后,切换回关联变量用于生产环境


**Output Property Access Pattern:**
```yaml

**输出属性访问模式**:
```yaml

❌ DOESN'T WORK IN PREVIEW (direct output access):

❌ 预览模式不生效(直接访问输出):

if @actions.check_status.result == "approved": | Approved!
if @actions.check_status.result == "approved": | 已批准!

✅ CORRECT (assign to variable first):

✅ 正确方式(先赋值给变量):

set @variables.status = @outputs.result if @variables.status == "approved": | Approved!
undefined
set @variables.status = @outputs.result if @variables.status == "approved": | 已批准!
undefined

No Nested
if
- Two Valid Approaches

禁止嵌套if - 两种有效写法

yaml
undefined
yaml
undefined

❌ WRONG - Nested if (causes SyntaxError)

❌ 错误写法 - 嵌套if(导致SyntaxError)

if @variables.software_cost > 0: if @variables.software_cost <= 500: | Auto-approve this software request.
if @variables.software_cost > 0: if @variables.software_cost <= 500: | 自动批准该软件申请。

✅ CORRECT Approach 1 - Compound condition (when logic allows)

✅ 正确写法1 - 复合条件(逻辑允许时使用)

if @variables.software_cost > 0 and @variables.software_cost <= 500: | Auto-approve this software request.
if @variables.software_cost > 0 and @variables.software_cost <= 500: | 自动批准该软件申请。

✅ CORRECT Approach 2 - Flatten to sequential ifs (for separate messages)

✅ 正确写法2 - 拆分为顺序if(需要单独输出消息时使用)

if @variables.order_verified == False or @variables.payment_confirmed == False: | ❌ PROCESSING BLOCKED | Missing requirements:
if @variables.order_verified == False: | - Order verification pending
if @variables.payment_confirmed == False: | - Payment confirmation pending
> **When to use each**: Use compound conditions when logic permits (single condition block). Use flattening when you need separate conditional outputs that can't be combined.
if @variables.order_verified == False or @variables.payment_confirmed == False: | ❌ 处理被阻止 | 缺少必要条件:
if @variables.order_verified == False: | - 订单验证待处理
if @variables.payment_confirmed == False: | - 付款确认待处理
> **适用场景**:逻辑允许时使用复合条件(单个条件块);需要单独输出不同条件结果时使用拆分写法。

...
is Slot-Filling Syntax (LLM Extracts from Conversation)

...
是槽位填充语法(LLM从对话中提取信息)

yaml
undefined
yaml
undefined

❌ WRONG - Using ... as default value

❌ 错误用法 - 将...用作默认值

order_id: mutable string = ...
order_id: mutable string = ...

✅ CORRECT - Use ... only in action parameter binding

✅ 正确用法 - 仅在动作参数绑定中使用...

reasoning: actions: search: @actions.search_products with query=... # LLM extracts from user message with category=... # LLM decides based on context with limit=10 # Fixed value
undefined
reasoning: actions: search: @actions.search_products with query=... # LLM从用户消息中提取 with category=... # LLM根据上下文判断 with limit=10 # 固定值
undefined

Post-Action Directives: Only on
@actions.*

动作后指令:仅适用于
@actions.*

yaml
undefined
yaml
undefined

❌ WRONG - @utils does NOT support set/run/if

❌ 错误写法 - @utils不支持set/run/if

go_next: @utils.transition to @topic.main set @variables.visited = True # ERROR!
go_next: @utils.transition to @topic.main set @variables.visited = True # 错误!

✅ CORRECT - Only @actions.* supports post-action

✅ 正确写法 - 仅@actions.*支持动作后操作

process: @actions.process_order with order_id=@variables.order_id set @variables.status = @outputs.status # ✅ Works run @actions.send_notification # ✅ Works if @outputs.needs_review: # ✅ Works transition to @topic.review
undefined
process: @actions.process_order with order_id=@variables.order_id set @variables.status = @outputs.status # ✅ 生效 run @actions.send_notification # ✅ 生效 if @outputs.needs_review: # ✅ 生效 transition to @topic.review
undefined

Helper Topic Pattern (For Demo Agents Without Flows/Apex)

辅助主题模式(无Flow/Apex的演示智能体)

When you need to set variables without backend actions, use dedicated "helper topics":
yaml
undefined
当你需要在无后端动作的情况下设置变量时,使用专用的“辅助主题”:
yaml
undefined

Main topic offers LLM-selectable action

主主题提供LLM可选动作

topic verify_employee: reasoning: actions: complete_verification: @utils.transition to @topic.verification_success description: "Mark employee as verified" available when @variables.employee_verified == False
topic verify_employee: reasoning: actions: complete_verification: @utils.transition to @topic.verification_success description: "标记员工为已验证" available when @variables.employee_verified == False

Helper topic sets variables in instructions, then returns

辅助主题在指令中设置变量,然后返回

topic verification_success: description: "Set verified state and return" reasoning: instructions: -> set @variables.employee_verified = True set @variables.employee_name = "Demo Employee" | ✓ Identity verified! transition to @topic.verify_employee # Return to parent
> **Why this works**: `set` statements ARE valid inside `instructions: ->` blocks. The topic loop pattern lets you change state without Flows/Apex.

---
topic verification_success: description: "设置验证状态并返回" reasoning: instructions: -> set @variables.employee_verified = True set @variables.employee_name = "演示员工" | ✓ 身份验证通过! transition to @topic.verify_employee # 返回父主题
> **原理**:`set`语句在`instructions: ->`块中是有效的。主题循环模式允许你无需Flow/Apex即可更改状态。

---

💰 PRODUCTION GOTCHAS: Billing, Determinism & Performance

💰 生产环境注意事项:计费、确定性与性能

Credit Consumption Table

积分消耗表

Key insight: Framework operations are FREE. Only actions that invoke external services consume credits.
OperationCreditsNotes
@utils.transition
FREEFramework navigation
@utils.setVariables
FREEFramework state management
@utils.escalate
FREEFramework escalation
if
/
else
control flow
FREEDeterministic resolution
before_reasoning
FREEDeterministic pre-processing (see note below)
after_reasoning
FREEDeterministic post-processing (see note below)
reasoning
(LLM turn)
FREELLM reasoning itself is not billed
Prompt Templates2-16Per invocation (varies by complexity)
Flow actions20Per action execution
Apex actions20Per action execution
Any other action20Per action execution
✅ Lifecycle Hooks Validated (v1.3.0): The
before_reasoning:
and
after_reasoning:
lifecycle hooks are now TDD-validated. Content goes directly under the block (no
instructions:
wrapper). See "Lifecycle Hooks" section below for correct syntax.
Cost Optimization Pattern: Fetch data once in
before_reasoning:
, cache in variables, reuse across topics.
核心要点:框架操作免费。仅调用外部服务的动作会消耗积分。
操作积分消耗说明
@utils.transition
免费框架导航
@utils.setVariables
免费框架状态管理
@utils.escalate
免费框架升级
if
/
else
控制流
免费确定性解析
before_reasoning
免费确定性预处理(见下文说明)
after_reasoning
免费确定性后处理(见下文说明)
reasoning
(LLM轮次)
免费LLM推理本身不收费
提示模板2-16每次调用(根据复杂度变化)
Flow动作20每次动作执行
Apex动作20每次动作执行
其他任何动作20每次动作执行
✅ 生命周期钩子已验证(v1.3.0)
before_reasoning:
after_reasoning:
生命周期钩子现已通过TDD验证。内容需直接放置在块下(无需
instructions:
包装器)。请查看下文“生命周期钩子”部分的正确语法。
成本优化模式:在
before_reasoning:
中一次性获取数据,缓存到变量中,在多个主题中复用。

Lifecycle Hooks:
before_reasoning:
and
after_reasoning:

生命周期钩子:
before_reasoning:
after_reasoning:

TDD Validated (2026-01-20): These hooks enable deterministic pre/post-processing around LLM reasoning.
yaml
topic main:
   description: "Topic with lifecycle hooks"

   # BEFORE: Runs deterministically BEFORE LLM sees instructions
   before_reasoning:
      # Content goes DIRECTLY here (NO instructions: wrapper!)
      set @variables.pre_processed = True
      set @variables.customer_tier = "gold"

   # LLM reasoning phase
   reasoning:
      instructions: ->
         | Customer tier: {!@variables.customer_tier}
         | How can I help you today?

   # AFTER: Runs deterministically AFTER LLM finishes reasoning
   after_reasoning:
      # Content goes DIRECTLY here (NO instructions: wrapper!)
      set @variables.interaction_logged = True
      if @variables.needs_audit == True:
         set @variables.audit_flag = True
Key Points:
  • Content goes directly under
    before_reasoning:
    /
    after_reasoning:
    (NO
    instructions:
    wrapper)
  • Supports
    set
    ,
    if
    ,
    run
    statements (same as procedural
    instructions: ->
    )
  • before_reasoning:
    is FREE (no credit cost) - use for data prep
  • after_reasoning:
    is FREE (no credit cost) - use for logging, cleanup
❌ WRONG Syntax (causes compile error):
yaml
before_reasoning:
   instructions: ->      # ❌ NO! Don't wrap with instructions:
      set @variables.x = True
✅ CORRECT Syntax:
yaml
before_reasoning:
   set @variables.x = True   # ✅ Direct content under the block
经TDD验证(2026-01-20):这些钩子支持围绕LLM推理的确定性预处理/后处理。
yaml
topic main:
   description: "带生命周期钩子的主题"

   # BEFORE: 在LLM处理指令前确定性执行
   before_reasoning:
      # 内容直接放置在此处(无需instructions:包装器!)
      set @variables.pre_processed = True
      set @variables.customer_tier = "gold"

   # LLM推理阶段
   reasoning:
      instructions: ->
         | 客户等级:{!@variables.customer_tier}
         | 今天我能为你提供什么帮助?

   # AFTER: 在LLM完成推理后确定性执行
   after_reasoning:
      # 内容直接放置在此处(无需instructions:包装器!)
      set @variables.interaction_logged = True
      if @variables.needs_audit == True:
         set @variables.audit_flag = True
核心要点:
  • 内容需直接放置在
    before_reasoning:
    /
    after_reasoning:
    块下
    (无需
    instructions:
    包装器)
  • 支持
    set
    if
    run
    语句(与过程式
    instructions: ->
    相同)
  • before_reasoning:
    免费(无积分消耗)- 用于数据准备
  • after_reasoning:
    免费(无积分消耗)- 用于日志记录、清理
❌ 错误语法(导致编译错误):
yaml
before_reasoning:
   instructions: ->      # ❌ 错误!不要用instructions:包装
      set @variables.x = True
✅ 正确语法:
yaml
before_reasoning:
   set @variables.x = True   # ✅ 内容直接放置在块下

Supervision vs Handoff (Clarified Terminology)

监督模式 vs 移交模式(术语澄清)

TermSyntaxBehaviorUse When
Handoff
@utils.transition to @topic.X
Control transfers completely, child generates final responseCheckout, escalation, terminal states
Supervision
@topic.X
(as action reference)
Parent orchestrates, child returns, parent synthesizesExpert consultation, sub-tasks
yaml
undefined
术语语法行为适用场景
移交模式
@utils.transition to @topic.X
控制权完全转移,子主题生成最终响应结账、升级、终端状态
监督模式
@topic.X
(作为动作引用)
父主题编排,子主题返回结果,父主题合成响应专家咨询、子任务
yaml
undefined

HANDOFF - child topic takes over completely:

移交模式 - 子主题完全接管:

checkout: @utils.transition to @topic.order_checkout description: "Proceed to checkout"
checkout: @utils.transition to @topic.order_checkout description: "进入结账流程"

→ @topic.order_checkout generates the user-facing response

→ @topic.order_checkout生成面向用户的响应

SUPERVISION - parent remains in control:

监督模式 - 父主题保持控制权:

get_advice: @topic.product_expert description: "Consult product expert"
get_advice: @topic.product_expert description: "咨询产品专家"

→ @topic.product_expert returns, parent topic synthesizes final response

→ @topic.product_expert返回结果,父主题合成最终响应


**KNOWN BUG**: Adding ANY new action in Canvas view may inadvertently change Supervision references to Handoff transitions.

**已知问题**:在Canvas视图中添加任何新动作,可能会无意中将监督模式引用改为移交模式转换。

Action Output Flags for Zero-Hallucination Routing

零幻觉路由的动作输出标志

Key Pattern for Determinism: Control what the LLM can see and say.
When defining actions in Agentforce Assets, use these output flags:
FlagEffectUse When
is_displayable: False
LLM cannot show this value to userPreventing hallucinated responses
is_used_by_planner: True
LLM can reason about this valueDecision-making, routing
Zero-Hallucination Intent Classification Pattern:
yaml
undefined
确定性核心模式:控制LLM可见和可输出的内容。
在Agentforce资产中定义动作时,使用以下输出标志:
标志效果适用场景
is_displayable: False
LLM无法向用户展示此值防止幻觉响应
is_used_by_planner: True
LLM可以基于此值进行推理决策、路由
零幻觉意图分类模式:
yaml
undefined

In Agentforce Assets - Action Definition outputs:

在Agentforce资产 - 动作定义输出中:

outputs: intent_classification: string is_displayable: False # LLM cannot show this to user is_used_by_planner: True # LLM can use for routing decisions
outputs: intent_classification: string is_displayable: False # LLM无法向用户展示 is_used_by_planner: True # LLM可用于路由决策

In Agent Script - LLM routes but cannot hallucinate:

在Agent Script中 - LLM负责路由但无法产生幻觉:

topic intent_router: reasoning: instructions: -> run @actions.classify_intent set @variables.intent = @outputs.intent_classification
     if @variables.intent == "refund":
        transition to @topic.refunds
     if @variables.intent == "order_status":
        transition to @topic.orders
undefined
topic intent_router: reasoning: instructions: -> run @actions.classify_intent set @variables.intent = @outputs.intent_classification
     if @variables.intent == "refund":
        transition to @topic.refunds
     if @variables.intent == "order_status":
        transition to @topic.orders
undefined

Action Chaining with
run
Keyword

使用
run
关键字的动作链

Known quirk: Parent action may complain about inputs needed by chained action - this is expected.
yaml
undefined
已知特性:父动作可能会抱怨链式动作所需的输入 - 这是预期行为。
yaml
undefined

Chained action execution:

链式动作执行:

process_order: @actions.create_order with customer_id = @variables.customer_id run @actions.send_confirmation # Chains after create_order completes set @variables.order_id = @outputs.id

**KNOWN BUG**: Chained actions with Prompt Templates don't properly map inputs using `Input:Query` format:
```yaml
process_order: @actions.create_order with customer_id = @variables.customer_id run @actions.send_confirmation # 在create_order完成后执行 set @variables.order_id = @outputs.id

**已知问题**:带提示模板的链式动作无法正确使用`Input:Query`格式映射输入:
```yaml

❌ MAY NOT WORK with Prompt Templates:

❌ 提示模板可能不生效:

run @actions.transform_recommendation with "Input:Reco_Input" = @variables.ProductReco
run @actions.transform_recommendation with "Input:Reco_Input" = @variables.ProductReco

⚠️ TRY THIS (may still have issues):

⚠️ 尝试此写法(仍可能存在问题):

run @actions.transform_recommendation with Reco_Input = @variables.ProductReco

> **📖 For prompt template action definitions, input binding syntax, and grounded data patterns**, see [resources/action-prompt-templates.md](resources/action-prompt-templates.md). For context-aware descriptions, instruction references (`{!@actions.X}`), and advanced binding strategies, see [resources/action-patterns.md](resources/action-patterns.md).
run @actions.transform_recommendation with Reco_Input = @variables.ProductReco

> **📖 关于提示模板动作定义、输入绑定语法和基于事实的数据模式**,请查看[resources/action-prompt-templates.md](resources/action-prompt-templates.md)。关于上下文感知描述、指令引用(`{!@actions.X}`)和高级绑定策略,请查看[resources/action-patterns.md](resources/action-patterns.md)。

Latch Variable Pattern for Topic Re-entry

主题重入的锁存变量模式

Problem: Topic selector doesn't properly re-evaluate after user provides missing input.
Solution: Use a "latch" variable to force re-entry:
yaml
variables:
   verification_in_progress: mutable boolean = False

start_agent topic_selector:
   reasoning:
      instructions: ->
         # LATCH CHECK - force re-entry if verification was started
         if @variables.verification_in_progress == True:
            transition to @topic.verification

         | How can I help you today?
      actions:
         start_verify: @topic.verification
            description: "Start identity verification"
            # Set latch when user chooses this action
            set @variables.verification_in_progress = True

topic verification:
   reasoning:
      instructions: ->
         | Please provide your email to verify your identity.
      actions:
         verify: @actions.verify_identity
            with email = ...
            set @variables.verified = @outputs.success
            # Clear latch when verification completes
            set @variables.verification_in_progress = False
问题:用户提供缺失输入后,主题选择器无法正确重新评估。
解决方法:使用“锁存”变量强制重入:
yaml
variables:
   verification_in_progress: mutable boolean = False

start_agent topic_selector:
   reasoning:
      instructions: ->
         # 锁存检查 - 如果验证已启动则强制重入
         if @variables.verification_in_progress == True:
            transition to @topic.verification

         | 今天我能为你提供什么帮助?
      actions:
         start_verify: @topic.verification
            description: "开始身份验证"
            # 用户选择此动作时设置锁存
            set @variables.verification_in_progress = True

topic verification:
   reasoning:
      instructions: ->
         | 请提供你的邮箱以验证身份。
      actions:
         verify: @actions.verify_identity
            with email = ...
            set @variables.verified = @outputs.success
            # 验证完成后清除锁存
            set @variables.verification_in_progress = False

Loop Protection Guardrail

循环保护机制

Agent Scripts have a built-in guardrail that limits iterations to approximately 3-4 loops before breaking out and returning to the Topic Selector.
Best Practice: Map out your execution paths - particularly topic transitions. Ensure testing covers all paths and specifically check for unintended circular references between topics.
Agent Script内置保护机制,将迭代次数限制在约3-4次循环,之后会中断并返回主题选择器。
最佳实践:规划你的执行路径 - 尤其是主题转换。确保测试覆盖所有路径,并专门检查主题之间意外的循环引用。

Token & Size Limits

令牌与大小限制

Limit TypeValueNotes
Max response size1,048,576 bytes (1MB)Per agent response
Plan trace limit (Frontend)1M charactersFor debugging UI
Transformed plan trace (Backend)32k tokensInternal processing
Active/Committed Agents per org100 maxOrg limit
限制类型取值说明
最大响应大小1,048,576字节(1MB)每个智能体响应
前端计划跟踪限制100万字符用于调试UI
后端转换后计划跟踪32k令牌内部处理
组织中激活/提交的智能体数量上限100个组织限制

Progress Indicators

进度指示器

Add user feedback during long-running actions:
yaml
actions:
   fetch_data: @actions.get_customer_data
      description: "Fetch customer information"
      include_in_progress_indicator: True
      progress_indicator_message: "Fetching your account details..."
在长时间运行的动作中添加用户反馈:
yaml
actions:
   fetch_data: @actions.get_customer_data
      description: "获取客户信息"
      include_in_progress_indicator: True
      progress_indicator_message: "正在获取你的账户详情..."

VS Code Pull/Push NOT Supported

VS Code拉取/推送不支持

bash
undefined
bash
undefined

❌ ERROR when using source tracking:

❌ 使用源跟踪时出错:

Failed to retrieve components using source tracking: [SfError [UnsupportedBundleTypeError]: Unsupported Bundle Type: AiAuthoringBundle
Failed to retrieve components using source tracking: [SfError [UnsupportedBundleTypeError]: Unsupported Bundle Type: AiAuthoringBundle

✅ WORKAROUND - Use CLI directly:

✅ 解决方法 - 直接使用CLI:

sf project retrieve start -m AiAuthoringBundle:MyAgent sf agent publish authoring-bundle --api-name MyAgent -o TARGET_ORG
undefined
sf project retrieve start -m AiAuthoringBundle:MyAgent sf agent publish authoring-bundle --api-name MyAgent -o TARGET_ORG
undefined

Language Block Quirks

语言块特性

  • Hebrew and Indonesian appear twice in the language dropdown
  • Selecting from the second set causes save errors
  • Use
    adaptive_response_allowed: True
    for automatic language adaptation
yaml
language:
   locale: en_US
   adaptive_response_allowed: True  # Allow language adaptation

  • 希伯来语和印度尼西亚语在语言下拉菜单中显示两次
  • 选择第二组会导致保存错误
  • 使用
    adaptive_response_allowed: True
    实现自动语言适配
yaml
language:
   locale: en_US
   adaptive_response_allowed: True  # 允许语言适配

Cross-Skill Orchestration

跨技能编排

DirectionPatternPriority
Before Agent Script
/sf-flow
- Create Flows for
flow://
action targets
⚠️ REQUIRED
After Agent Script
/sf-ai-agentforce-testing
- Test topic routing and actions
✅ RECOMMENDED
For Deployment
/sf-deploy
- Publish agent with
sf agent publish authoring-bundle
⚠️ REQUIRED
Tip: Open Agentforce Studio list view with
sf org open authoring-bundle -o TARGET_ORG
(v2.121.7+). Open a specific agent with
sf org open agent --api-name MyAgent -o TARGET_ORG
.

方向模式优先级
Agent Script之前
/sf-flow
- 为
flow://
动作目标创建Flow
⚠️ 必填
Agent Script之后
/sf-ai-agentforce-testing
- 测试主题路由和动作
✅ 推荐
部署时
/sf-deploy
- 使用
sf agent publish authoring-bundle
发布智能体
⚠️ 必填
提示:使用
sf org open authoring-bundle -o TARGET_ORG
打开Agentforce Studio列表视图(v2.121.7+)。使用
sf org open agent --api-name MyAgent -o TARGET_ORG
打开特定智能体。

📋 QUICK REFERENCE: Agent Script Syntax

📋 快速参考:Agent Script语法

Block Structure (CORRECTED Order per Official Spec)

块结构(经官方规范修正的顺序)

yaml
config:        # 1. Required: Agent metadata (developer_name, agent_type, default_agent_user)
variables:     # 2. Optional: State management (mutable/linked)
system:        # 3. Required: Global messages and instructions
connections:   # 4. Optional: Escalation routing (Service Agents ONLY)
knowledge:     # 5. Optional: Knowledge base config
language:      # 6. Optional: Locale settings
start_agent:   # 7. Required: Entry point (exactly one)
topic:         # 8. Required: Conversation topics (one or more)
yaml
config:        # 1. 必填:智能体元数据(developer_name、agent_type、default_agent_user)
variables:     # 2. 可选:状态管理(mutable/linked)
system:        # 3. 必填:全局消息和指令
connections:   # 4. 可选:升级路由(仅适用于服务智能体)
knowledge:     # 5. 可选:知识库配置
language:      # 6. 可选:区域设置
start_agent:   # 7. 必填:入口点(仅一个)
topic:         # 8. 必填:对话主题(至少一个)

Config Block Field Names (CRITICAL)

Config块字段名称(关键)

⚠️ Common Error: Using incorrect field names from outdated documentation.
Documented Field (Wrong)Actual Field (Correct)Notes
agent_name
developer_name
Must match folder name (case-sensitive)
description
agent_description
Agent's purpose description
agent_label
(not used)Remove from examples
default_agent_user
default_agent_user
✓ Correct
(missing)
agent_type
Required:
AgentforceServiceAgent
or
AgentforceEmployeeAgent
yaml
undefined
⚠️ 常见错误:使用过时文档中的错误字段名。
文档中错误字段实际正确字段说明
agent_name
developer_name
必须与文件夹名称一致(区分大小写)
description
agent_description
智能体用途描述
agent_label
(未使用)从示例中移除
default_agent_user
default_agent_user
✓ 正确
(缺失)
agent_type
必填
AgentforceServiceAgent
AgentforceEmployeeAgent
yaml
undefined

✅ CORRECT config block:

✅ 正确的config块:

config: developer_name: "my_agent" agent_description: "Handles customer support inquiries" agent_type: "AgentforceServiceAgent" default_agent_user: "agent_user@00dxx000001234.ext"
undefined
config: developer_name: "my_agent" agent_description: "处理客户支持咨询" agent_type: "AgentforceServiceAgent" default_agent_user: "agent_user@00dxx000001234.ext"
undefined

Naming Rules (All Identifiers)

命名规则(所有标识符)

  • Only letters, numbers, underscores
  • Must begin with a letter
  • No spaces, no consecutive underscores, cannot end with underscore
  • Maximum 80 characters
  • 仅允许字母、数字、下划线
  • 必须以字母开头
  • 无空格、无连续下划线、不能以下划线结尾
  • 最大80个字符

Instruction Syntax Patterns

语法模式示例

PatternPurposeExample
instructions: |
Literal multi-line (no expressions)
instructions: | Help the user.
instructions: ->
Procedural (enables expressions)
instructions: -> if @variables.x:
| text
Literal text for LLM prompt
| Hello
+ variable injection
if @variables.x:
Conditional (resolves before LLM)
if @variables.verified == True:
run @actions.x
Execute action during resolution
run @actions.load_customer
set @var = @outputs.y
Capture action output
set @variables.risk = @outputs.score
set @var = value
Set variable in instructions
set @variables.count = 0
{!@variables.x}
Variable injection in text
Risk score: {!@variables.risk}
{!expr if cond else alt}
Conditional interpolation
{!@variables.status if @variables.status else "pending"}
available when
Control action visibility to LLM
available when @variables.verified == True
with param=...
LLM slot-filling (extracts from conversation)
with query=...
with param=value
Fixed parameter value
with limit=10
模式用途示例
`instructions: \`多行文本(无表达式)
instructions: ->
过程式(支持表达式)
instructions: -> if @variables.x:
`\text`LLM提示文本
if @variables.x:
条件判断(LLM处理前解析)
if @variables.verified == True:
run @actions.x
解析时执行动作
run @actions.load_customer
set @var = @outputs.y
捕获动作输出
set @variables.risk = @outputs.score
set @var = value
在指令中设置变量
set @variables.count = 0
{!@variables.x}
文本中的变量注入
风险评分:{!@variables.risk}
{!expr if cond else alt}
条件插值
{!@variables.status if @variables.status else "待处理"}
available when
控制动作对LLM的可见性
available when @variables.verified == True
with param=...
LLM槽位填充(从对话中提取)
with query=...
with param=value
固定参数值
with limit=10

Transition vs Delegation (CRITICAL DISTINCTION)

转换 vs 委托(关键区别)

SyntaxBehaviorReturns?Use When
@utils.transition to @topic.X
Permanent handoff❌ NoCheckout, escalation, final states
@topic.X
(in reasoning.actions)
Delegation✅ YesGet expert advice, sub-tasks
transition to @topic.X
(inline)
Deterministic jump❌ NoPost-action routing, gates
yaml
undefined
语法行为是否返回结果适用场景
@utils.transition to @topic.X
永久移交❌ 否结账、升级、最终状态
@topic.X
(在reasoning.actions中)
委托✅ 是获取专家建议、子任务
transition to @topic.X
(内联)
确定性跳转❌ 否动作后路由、网关
yaml
undefined

Delegation - returns to current topic after specialist finishes

委托 - 专家完成后返回当前主题

consulting: @topic.expert_topic description: "Get expert advice"
consulting: @topic.expert_topic description: "获取专家建议"

Transition - permanent handoff, no return

转换 - 永久移交,不返回

checkout: @utils.transition to @topic.checkout description: "Proceed to purchase"
undefined
checkout: @utils.transition to @topic.checkout description: "进入购买流程"
undefined

Expression Operators (Safe Subset)

表达式运算符(安全子集)

CategoryOperatorsNOT Supported
Comparison
==
,
<>
(not-equal),
<
,
<=
,
>
,
>=
,
is
,
is not
Logical
and
,
or
,
not
Arithmetic
+
,
-
*
,
/
,
%
Access
.
(property),
[]
(index)
Conditional
x if condition else y
类别支持运算符不支持
比较
==
,
<>
(不等于),
<
,
<=
,
>
,
>=
,
is
,
is not
逻辑
and
,
or
,
not
算术
+
,
-
*
,
/
,
%
访问
.
(属性),
[]
(索引)
条件
x if condition else y

Variable Types

变量类型

ModifierBehaviorSupported TypesDefault Required?
mutable
Read/write state
string
,
number
,
boolean
,
object
,
date
,
timestamp
,
currency
,
id
,
list[T]
✅ Yes
linked
Read-only from source
string
,
number
,
boolean
,
date
,
timestamp
,
currency
,
id
❌ No (has
source:
)
⚠️ Linked variables CANNOT use
object
or
list
types
修饰符行为支持类型是否需要默认值
mutable
可读写状态
string
,
number
,
boolean
,
object
,
date
,
timestamp
,
currency
,
id
,
list[T]
✅ 是
linked
从源只读
string
,
number
,
boolean
,
date
,
timestamp
,
currency
,
id
❌ 否(需
source:
⚠️ 关联变量不支持
object
list
类型

Linked Variable Sources by Agent Type

按智能体类型划分的关联变量源

⚠️ CRITICAL: Not all source bindings work for all agent types.
Source PatternService AgentEmployee Agent
@MessagingSession.Id
✅ Works❌ Not available
@MessagingSession.RoutableId
✅ Works❌ Not available
@Record.Id
❓ Untested❌ Does not work
@context.recordId
❓ Untested❌ Does not work
Workaround for Employee Agents: Employee Agents in the Copilot panel don't automatically receive record context. Use a mutable variable and have the Flow action look up the current record.
yaml
undefined
⚠️ 关键提示:并非所有源绑定对所有智能体类型都生效。
源模式服务智能体员工智能体
@MessagingSession.Id
✅ 生效❌ 不可用
@MessagingSession.RoutableId
✅ 生效❌ 不可用
@Record.Id
❓ 未测试❌ 不生效
@context.recordId
❓ 未测试❌ 不生效
员工智能体解决方法: Copilot面板中的员工智能体不会自动接收记录上下文。使用可变变量,让Flow动作查找当前记录。
yaml
undefined

❌ DOESN'T WORK for Employee Agents:

❌ 员工智能体不生效:

case_id: linked string source: @Record.Id
case_id: linked string source: @Record.Id

✅ WORKAROUND - use mutable variable:

✅ 解决方法 - 使用可变变量:

case_id: mutable string = "" description: "Case ID - enter or will be looked up by Flow"
undefined
case_id: mutable string = "" description: "案例ID - 手动输入或由Flow查找"
undefined

Variable vs Action I/O Type Matrix

变量与动作I/O类型矩阵

Critical distinction: Some types are valid ONLY for action inputs/outputs, NOT for Agent Script variables.
TypeVariablesAction I/ONotes
string
Universal
number
Universal
boolean
Universal
date
Universal
currency
Universal
id
Salesforce IDs
list
✅ (mutable only)Collections
object
✅ (mutable only)⚠️ Not for linked vars
datetime
Actions only
time
Actions only
integer
Actions only
long
Actions only
Source: AGENT_SCRIPT.md rules document from trailheadapps/agent-script-recipes
关键区别:部分类型仅对动作输入/输出有效,对Agent Script变量无效。
类型变量动作I/O说明
string
通用类型
number
通用类型
boolean
通用类型
date
通用类型
currency
通用类型
id
Salesforce ID
list
✅(仅mutable)集合
object
✅(仅mutable)⚠️ 不支持关联变量
datetime
仅动作支持
time
仅动作支持
integer
仅动作支持
long
仅动作支持
来源:trailheadapps/agent-script-recipes中的AGENT_SCRIPT.md规则文档

Action Target Protocols

动作目标协议

ShortLong FormUse WhenValidated?
flow
flow://
Data operations, business logic✅ TDD
apex
apex://
Custom calculations, validation✅ TDD
prompt
generatePromptResponse://
Grounded LLM responses✅ TDD
api
api://
REST API calls✅ TDD
retriever
retriever://
RAG knowledge search✅ TDD
externalService
externalService://
Third-party APIs via Named Credentials✅ TDD
standardInvocableAction
standardInvocableAction://
Built-in SF actions (email, tasks)✅ TDD
datacloudDataGraphAction
datacloudDataGraphAction://
Data Cloud graph queries📋 Spec
datacloudSegmentAction
datacloudSegmentAction://
Data Cloud segment operations📋 Spec
triggerByKnowledgeSource
triggerByKnowledgeSource://
Knowledge article triggers📋 Spec
contextGrounding
contextGrounding://
Context grounding for LLM📋 Spec
predictiveAI
predictiveAI://
Einstein prediction models📋 Spec
runAction
runAction://
Execute sub-actions📋 Spec
external
external://
External service calls📋 Spec
copilotAction
copilotAction://
Salesforce Copilot actions📋 Spec
@topic.X
(inline)Topic delegation (returns to parent)✅ TDD
Legend: ✅ TDD = Validated via deployment testing | 📋 Spec = Documented in AGENT_SCRIPT.md spec (requires specific org setup to test)
简写完整格式适用场景是否已验证
flow
flow://
数据操作、业务逻辑✅ TDD
apex
apex://
自定义计算、验证✅ TDD
prompt
generatePromptResponse://
基于事实的LLM响应✅ TDD
api
api://
REST API调用✅ TDD
retriever
retriever://
RAG知识库搜索✅ TDD
externalService
externalService://
通过命名凭证调用第三方API✅ TDD
standardInvocableAction
standardInvocableAction://
内置SF动作(邮件、任务)✅ TDD
datacloudDataGraphAction
datacloudDataGraphAction://
数据云图查询📋 规范
datacloudSegmentAction
datacloudSegmentAction://
数据云分段操作📋 规范
triggerByKnowledgeSource
triggerByKnowledgeSource://
知识库文章触发📋 规范
contextGrounding
contextGrounding://
LLM上下文关联📋 规范
predictiveAI
predictiveAI://
Einstein预测模型📋 规范
runAction
runAction://
执行子动作📋 规范
external
external://
外部服务调用📋 规范
copilotAction
copilotAction://
Salesforce Copilot动作📋 规范
@topic.X
(内联)主题委托(返回父主题)✅ TDD
图例:✅ TDD = 经部署测试验证 | 📋 规范 = 记录在AGENT_SCRIPT.md规范中(需要特定组织设置才能测试)

Using Flow and Apex Actions in Agent Script

在Agent Script中使用Flow和Apex动作

For AiAuthoringBundle (Agent Script):
flow://
and
apex://
targets work directly — no GenAiFunction registration needed. The target just needs to exist in the org (active Flow or deployed Apex class with
@InvocableMethod
).
Two-Level Action System (CRITICAL to understand):
Level 1: ACTION DEFINITION (in topic's `actions:` block)
   → Has `target:`, `inputs:`, `outputs:`, `description:`
   → Specifies WHAT to call (e.g., "apex://OrderService")

Level 2: ACTION INVOCATION (in `reasoning.actions:` block)
   → References Level 1 via `@actions.name`
   → Specifies HOW to call it (with/set clauses)
Complete Example:
yaml
topic order_status:
   description: "Look up order details"

   # Level 1: DEFINE the action with a target
   actions:
      get_case_details:
         description: "Fetch case information by ID"
         inputs:
            case_id: string
               description: "The Case record ID"
         outputs:
            subject: string
               description: "Case subject line"
         target: "flow://Get_Case_Details"   # Flow must exist and be active

   reasoning:
      instructions: |
         Help the customer check their case status.
      # Level 2: INVOKE the action defined above
      actions:
         lookup_case: @actions.get_case_details
            with case_id = @variables.case_id
            set @variables.case_subject = @outputs.subject
⚠️ Common Error:
ValidationError: Tool target 'X' is not an action definition
— This means either:
  1. The action is referenced in
    reasoning.actions:
    via
    @actions.X
    but
    X
    is not defined in the topic's
    actions:
    block, OR
  2. The
    target:
    value points to a Flow/Apex class that doesn't exist in the org
Fix: Ensure you have BOTH levels: action definition (with
target:
) AND action invocation (with
@actions.name
).
Agent Builder UI Path (GenAiPlannerBundle — different workflow): If building agents through the Agent Builder UI (not Agent Script), you DO need GenAiFunction metadata. See
resources/actions-reference.md
for details.
对于AiAuthoringBundle(Agent Script)
flow://
apex://
目标直接生效 — 无需注册GenAiFunction。目标只需在组织中存在(激活的Flow或部署的带
@InvocableMethod
的Apex类)。
两级动作系统(关键理解):
第一级:动作定义(在主题的`actions:`块中)
   → 包含`target:`、`inputs:`、`outputs:`、`description:`
   → 指定要调用的目标(例如"apex://OrderService")

第二级:动作调用(在`reasoning.actions:`块中)
   → 通过`@actions.name`引用第一级定义
   → 指定调用方式(with/set子句)
完整示例:
yaml
topic order_status:
   description: "查询订单详情"

   # 第一级:定义带目标的动作
   actions:
      get_case_details:
         description: "通过ID查询案例信息"
         inputs:
            case_id: string
               description: "案例记录ID"
         outputs:
            subject: string
               description: "案例主题"
         target: "flow://Get_Case_Details"   # Flow必须存在且已激活

   reasoning:
      instructions: |
         帮助客户查询案例状态。
      # 第二级:调用上述定义的动作
      actions:
         lookup_case: @actions.get_case_details
            with case_id = @variables.case_id
            set @variables.case_subject = @outputs.subject
⚠️ 常见错误
ValidationError: Tool target 'X' is not an action definition
— 这意味着:
  1. reasoning.actions:
    中通过
    @actions.X
    引用了动作,但
    X
    未在主题的
    actions:
    块中定义,或者
  2. target:
    值指向的Flow/Apex类在组织中不存在
修复方法:确保同时存在两级定义:动作定义(带
target:
)和动作调用(带
@actions.name
)。
Agent Builder UI路径(GenAiPlannerBundle — 不同工作流): 如果通过Agent Builder UI(而非Agent Script)构建智能体,需要GenAiFunction元数据。详情请查看
resources/actions-reference.md

Connection Block (Full Escalation Pattern)

连接块(完整升级模式)

⚠️ Service Agents Only: The
connections:
block is only valid for
agent_type: "AgentforceServiceAgent"
. Employee Agents will fail with
Unexpected 'connections' block
error. Employee Agents do not support channel-based escalation routing.
yaml
connections:
   # Messaging channel escalation
   connection messaging:
      escalation_message: "One moment, I'm transferring our conversation to get you more help."
      outbound_route_type: "OmniChannelFlow"
      outbound_route_name: "<flow://Escalate_Messaging_To_Live_Agent>"
      adaptive_response_allowed: False

   # Voice channel escalation
   connection voice:
      escalation_message: "Please hold while I transfer you to a specialist."
      outbound_route_type: "Queue"
      outbound_route_name: "Support_Queue"
      adaptive_response_allowed: True

   # Web chat escalation
   connection web:
      escalation_message: "Connecting you with a live agent now."
      outbound_route_type: "OmniChannelFlow"
      outbound_route_name: "<flow://Web_Chat_Escalation>"
Key Properties:
PropertyRequiredDescription
escalation_message
Message shown to user during handoff
outbound_route_type
OmniChannelFlow
,
Queue
, or
Skill
outbound_route_name
Flow API name or Queue name
adaptive_response_allowed
Allow LLM to adapt escalation message

⚠️ 仅服务智能体支持
connections:
块仅对
agent_type: "AgentforceServiceAgent"
有效。员工智能体使用会出现
Unexpected 'connections' block
错误。员工智能体不支持基于渠道的升级路由。
yaml
connections:
   # 消息渠道升级
   connection messaging:
      escalation_message: "请稍候,我将为你转接人工客服以获得更多帮助。"
      outbound_route_type: "OmniChannelFlow"
      outbound_route_name: "<flow://Escalate_Messaging_To_Live_Agent>"
      adaptive_response_allowed: False

   # 语音渠道升级
   connection voice:
      escalation_message: "请稍等,我将为你转接专家。"
      outbound_route_type: "Queue"
      outbound_route_name: "Support_Queue"
      adaptive_response_allowed: True

   # Web聊天升级
   connection web:
      escalation_message: "正在为你转接人工客服。"
      outbound_route_type: "OmniChannelFlow"
      outbound_route_name: "<flow://Web_Chat_Escalation>"
关键属性:
属性是否必填描述
escalation_message
移交过程中向用户显示的消息
outbound_route_type
OmniChannelFlow
Queue
Skill
outbound_route_name
Flow API名称或队列名称
adaptive_response_allowed
允许LLM调整升级消息

🔄 WORKFLOW: Agent Development Lifecycle

🔄 工作流:智能体开发生命周期

Phase 1: Requirements & Design

阶段1:需求与设计

  1. Identify deterministic vs. subjective logic
    • Deterministic: Security checks, financial thresholds, data lookups, counters
    • Subjective: Greetings, context understanding, natural language generation
  2. Design FSM architecture - Map topics as states, transitions as edges
  3. Define variables - Mutable for state tracking, linked for session context
  1. 区分确定性与主观逻辑
    • 确定性:安全检查、财务阈值、数据查询、计数器
    • 主观:问候语、上下文理解、自然语言生成
  2. 设计FSM架构 - 将主题映射为状态,转换映射为边
  3. 定义变量 - 可变变量用于状态跟踪,关联变量用于会话上下文

Phase 2: Agent Script Authoring

阶段2:Agent Script编写

  1. Create
    .agent
    file
    with required blocks
  2. Write topics with instruction resolution pattern:
    • Post-action checks at TOP (triggers on loop)
    • Pre-LLM data loading
    • Dynamic instructions for LLM
  3. Configure actions with appropriate target protocols
  4. Add
    available when
    guards
    to enforce security
  1. 创建
    .agent
    文件
    ,包含必填块
  2. 编写主题,使用指令解析模式:
    • 动作后检查放在顶部(循环时触发)
    • LLM处理前加载数据
    • 为LLM提供动态指令
  3. 配置动作,使用合适的目标协议
  4. 添加
    available when
    保护
    ,强化安全性

Phase 3: Validation (LSP + CLI)

阶段3:验证(LSP + CLI)

AUTOMATIC: LSP validation runs on every Write/Edit to
.agent
files. Errors are reported with line numbers and autofix suggestions.
自动执行:每次写入/编辑
.agent
文件时,LSP验证会自动运行。错误会附带行号和自动修复建议。

LSP Validation Loop (Find Error → Autofix)

LSP验证循环(发现错误 → 自动修复)

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│ Write/Edit  │ ──▶ │ LSP Analyze │ ──▶ │ Report      │
│ .agent file │     │ (automatic) │     │ Errors      │
└─────────────┘     └─────────────┘     └──────┬──────┘
      ┌────────────────────────────────────────┘
┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│ Claude      │ ──▶ │ Apply Fix   │ ──▶ │ Re-validate │
│ Suggests Fix│     │ (Edit tool) │     │ (loop)      │
└─────────────┘     └─────────────┘     └─────────────┘
┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│ 写入/编辑   │ ──▶ │ LSP分析     │ ──▶ │ 报告错误     │
│ .agent文件  │     │ (自动)     │     │             │
└─────────────┘     └─────────────┘     └──────┬──────┘
      ┌────────────────────────────────────────┘
┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│ Claude建议  │ ──▶ │ 应用修复     │ ──▶ │ 重新验证     │
│ 修复方案     │     │ (编辑工具) │     │ (循环)     │
└─────────────┘     └─────────────┘     └─────────────┘

LSP Checks (Automatic)

LSP自动检查项

CheckSeverityAutofix
Mixed tabs/spaces❌ ErrorConvert to consistent spacing
Lowercase booleans (
true
/
false
)
❌ ErrorCapitalize to
True
/
False
Missing required blocks❌ ErrorAdd missing block template
Missing
default_agent_user
❌ ErrorAdd placeholder with comment
Mutable + linked conflict❌ ErrorRemove conflicting modifier
Undefined topic references⚠️ WarningCreate topic stub
Post-action check position⚠️ WarningMove to top of instructions
检查项严重程度是否支持自动修复
混合制表符和空格❌ 错误转换为一致的缩进方式
小写布尔值(
true
/
false
❌ 错误转换为大写
True
/
False
缺失必填块❌ 错误添加缺失块模板
缺失
default_agent_user
❌ 错误添加带注释的占位符
mutable与linked冲突❌ 错误移除冲突修饰符
未定义的主题引用⚠️ 警告创建主题占位符
动作后检查位置错误⚠️ 警告移至指令顶部

CLI Validation (Before Deploy)

CLI验证(部署前)

bash
undefined
bash
undefined

Validate authoring bundle syntax

验证创作包语法

sf agent validate authoring-bundle --api-name MyAgent -o TARGET_ORG
undefined
sf agent validate authoring-bundle --api-name MyAgent -o TARGET_ORG
undefined

Manual Checks

手动检查项

  • default_agent_user
    exists and is active Einstein Agent User
  • All topic references resolve to existing topics
  • Action targets (
    flow://
    ,
    apex://
    , etc.) exist in org
  • default_agent_user
    是存在且激活的Einstein Agent用户
  • 所有主题引用指向已存在的主题
  • 动作目标(
    flow://
    apex://
    等)在组织中存在

Phase 4: Testing (Delegate to
/sf-ai-agentforce-testing
)

阶段4:测试(委托给
/sf-ai-agentforce-testing

  1. Batch testing - Run up to 100 test cases simultaneously
  2. Quality metrics - Completeness, Coherence, Topic/Action Assertions
  3. LLM-as-Judge - Automated scoring against golden responses
  1. 批量测试 - 同时运行多达100个测试用例
  2. 质量指标 - 完整性、连贯性、主题/动作断言
  3. LLM作为评判者 - 自动与标准响应对比评分

Phase 5: Deployment

阶段5:部署

⚠️ CRITICAL: Use
sf agent publish authoring-bundle
, NOT
sf project deploy start
  1. Create bundle directory:
    force-app/main/default/aiAuthoringBundles/AgentName/
  2. Add files:
    • AgentName.agent
      - Your Agent Script
    • AgentName.bundle-meta.xml
      - Metadata XML (NOT
      .aiAuthoringBundle-meta.xml
      )
  3. Publish:
    sf agent publish authoring-bundle --api-name AgentName -o TARGET_ORG
  4. Monitor - Use trace debugging for production issues
⚠️ 关键提示:使用
sf agent publish authoring-bundle
不要使用
sf project deploy start
  1. 创建包目录
    force-app/main/default/aiAuthoringBundles/AgentName/
  2. 添加文件:
    • AgentName.agent
      - 你的Agent Script
    • AgentName.bundle-meta.xml
      - 元数据XML(不要使用
      .aiAuthoringBundle-meta.xml
  3. 发布
    sf agent publish authoring-bundle --api-name AgentName -o TARGET_ORG
  4. 监控 - 使用跟踪调试生产环境问题

Phase 5.5: API Channel Enablement (For Agent Runtime API Testing)

阶段5.5:API渠道启用(用于Agent Runtime API测试)

⚠️ Without these steps, Agent Runtime API calls return
500 Internal Server Error
.
After publishing an Agent Script agent, the following metadata must be configured for API access:
1. GenAiPlannerBundle — Add
plannerSurfaces
block:
When deploying via the
Agent
pseudo metadata type, retrieve and verify the
GenAiPlannerBundle
XML includes:
xml
<GenAiPlannerBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <!-- ... existing elements ... -->
    <plannerSurfaces>
        <plannerSurface>
            <surfaceType>EinsteinAgentApiChannel</surfaceType>
        </plannerSurface>
    </plannerSurfaces>
</GenAiPlannerBundle>
If missing, add it and redeploy:
bash
sf project deploy start --metadata GenAiPlannerBundle:AgentName_Planner -o TARGET_ORG
2. BotVersion — Set
surfacesEnabled
to
true
:
The
BotVersion
metadata defaults
surfacesEnabled
to
false
. Update:
xml
<BotVersion xmlns="http://soap.sforce.com/2006/04/metadata">
    <!-- ... existing elements ... -->
    <surfacesEnabled>true</surfacesEnabled>
</BotVersion>
bash
sf project deploy start --metadata BotVersion:AgentName.v1 -o TARGET_ORG
3. External Client App (ECA) — Required for Client Credentials flow:
The Agent Runtime API requires OAuth with
chatbot_api
,
sfap_api
, and
api
scopes. See
/sf-connected-apps
for ECA creation.
Note: If you only need interactive testing via
sf agent preview
, skip ECA setup — preview uses standard org auth (
sf org login web
, v2.121.7+).
Validation — Confirm API access works:
bash
undefined
⚠️ 未完成此步骤,Agent Runtime API调用会返回
500 Internal Server Error
发布Agent Script智能体后,必须配置以下元数据以支持API访问:
1. GenAiPlannerBundle — 添加
plannerSurfaces
块:
当通过
Agent
伪元数据类型部署时,检索并验证
GenAiPlannerBundle
XML包含:
xml
<GenAiPlannerBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <!-- ... 现有元素 ... -->
    <plannerSurfaces>
        <plannerSurface>
            <surfaceType>EinsteinAgentApiChannel</surfaceType>
        </plannerSurface>
    </plannerSurfaces>
</GenAiPlannerBundle>
如果缺失,添加后重新部署:
bash
sf project deploy start --metadata GenAiPlannerBundle:AgentName_Planner -o TARGET_ORG
2. BotVersion — 设置
surfacesEnabled
true
:
BotVersion
元数据默认
surfacesEnabled
false
。更新为:
xml
<BotVersion xmlns="http://soap.sforce.com/2006/04/metadata">
    <!-- ... 现有元素 ... -->
    <surfacesEnabled>true</surfacesEnabled>
</BotVersion>
bash
sf project deploy start --metadata BotVersion:AgentName.v1 -o TARGET_ORG
3. 外部客户端应用(ECA) — 客户端凭证流必填:
Agent Runtime API需要带有
chatbot_api
sfap_api
api
权限的OAuth。创建ECA请查看
/sf-connected-apps
注意: 如果仅需要通过
sf agent preview
进行交互式测试,可跳过ECA设置 — 预览使用标准组织认证(
sf org login web
,v2.121.7+)。
验证 — 确认API访问正常:
bash
undefined

Acquire token

获取令牌

curl -X POST "https://YOUR_DOMAIN.my.salesforce.com/services/oauth2/token"
-d "grant_type=client_credentials&client_id=KEY&client_secret=SECRET"
curl -X POST "https://YOUR_DOMAIN.my.salesforce.com/services/oauth2/token" \ -d "grant_type=client_credentials&client_id=KEY&client_secret=SECRET"

Create agent session

创建智能体会话

curl -X POST "https://YOUR_DOMAIN.my.salesforce.com/einstein/ai-agent/v1"
-H "Authorization: Bearer TOKEN"
-H "Content-Type: application/json"
-d '{"agentDefinitionId":"0XxXXXXXXXXXXXXXXX"}'

> **Symptom**: 500 error with `"errorCode": "UNKNOWN_EXCEPTION"` → Missing `plannerSurfaces` or `surfacesEnabled=false`.
curl -X POST "https://YOUR_DOMAIN.my.salesforce.com/einstein/ai-agent/v1" \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ -d '{"agentDefinitionId":"0XxXXXXXXXXXXXXXXX"}'

> **症状**:500错误,附带`"errorCode": "UNKNOWN_EXCEPTION"` → 缺失`plannerSurfaces`或`surfacesEnabled=false`。

Phase 6: CLI Operations

阶段6:CLI操作

bash
undefined
bash
undefined

Retrieve from org

从组织拉取

sf agent retrieve --name MyAgent --target-org sandbox
sf agent retrieve --name MyAgent --target-org sandbox

Validate syntax

验证语法

sf agent validate authoring-bundle --api-name MyAgent -o TARGET_ORG
sf agent validate authoring-bundle --api-name MyAgent -o TARGET_ORG

Publish to org (NOT sf project deploy!)

发布到组织(不要用sf project deploy!)

sf agent publish authoring-bundle --api-name MyAgent -o TARGET_ORG
sf agent publish authoring-bundle --api-name MyAgent -o TARGET_ORG

Publish without retrieving metadata (CI/CD optimization, v2.122.6+)

不检索元数据发布(CI/CD优化,v2.122.6+)

sf agent publish authoring-bundle --api-name MyAgent --skip-retrieve -o TARGET_ORG
sf agent publish authoring-bundle --api-name MyAgent --skip-retrieve -o TARGET_ORG

Generate authoring bundle scaffolding

生成创作包脚手架

sf agent generate authoring-bundle --api-name MyAgent -o TARGET_ORG
sf agent generate authoring-bundle --api-name MyAgent -o TARGET_ORG

Generate without retrieving from org (useful for CI/CD)

不从组织检索生成(适用于CI/CD)

sf agent generate authoring-bundle --api-name MyAgent --skip-retrieve -o TARGET_ORG
undefined
sf agent generate authoring-bundle --api-name MyAgent --skip-retrieve -o TARGET_ORG
undefined

Bundle Structure (CRITICAL)

包结构(关键)

force-app/main/default/aiAuthoringBundles/
└── MyAgent/
    ├── MyAgent.agent              # Agent Script file
    └── MyAgent.bundle-meta.xml    # NOT .aiAuthoringBundle-meta.xml!
bundle-meta.xml content:
xml
<?xml version="1.0" encoding="UTF-8"?>
<AiAuthoringBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <bundleType>AGENT</bundleType>
</AiAuthoringBundle>

force-app/main/default/aiAuthoringBundles/
└── MyAgent/
    ├── MyAgent.agent              # Agent Script文件
    └── MyAgent.bundle-meta.xml    # 不要用.aiAuthoringBundle-meta.xml!
bundle-meta.xml内容:
xml
<?xml version="1.0" encoding="UTF-8"?>
<AiAuthoringBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <bundleType>AGENT</bundleType>
</AiAuthoringBundle>

📊 SCORING SYSTEM (100 Points)

📊 评分系统(100分)

Categories

分类

CategoryPointsKey Criteria
Structure & Syntax20Block ordering, indentation consistency, required fields present
Deterministic Logic25Security via
available when
, post-action checks, proper conditionals
Instruction Resolution20Correct use of
->
vs
|
, template injection, action execution
FSM Architecture15Clear topic separation, explicit transitions, state management
Action Configuration10Correct protocols, input/output mapping, error handling
Deployment Readiness10Valid
default_agent_user
, no compilation errors, metadata complete
分类分值关键标准
结构与语法20块顺序、缩进一致性、必填字段存在性
确定性逻辑25通过
available when
实现安全控制、动作后检查、正确条件判断
指令解析20正确使用
->
与`\
FSM架构15清晰的主题分离、明确的转换、状态管理
动作配置10正确的协议、输入/输出映射、错误处理
部署就绪性10有效的
default_agent_user
、无编译错误、元数据完整

Scoring Rubric Details

评分细则

Structure & Syntax (20 points)

结构与语法(20分)

PointsCriteria
20All required blocks present, consistent indentation, valid identifiers
15Minor issues (e.g., inconsistent spacing within tolerance)
10Missing optional blocks that would improve clarity
5Block ordering issues or mixed indentation
0Missing required blocks or compilation failures
分值标准
20所有必填块存在,缩进一致,标识符有效
15minor问题(例如,缩进不一致但在可接受范围内)
10缺失可提升清晰度的可选块
5块顺序错误或混合缩进
0缺失必填块或编译失败

Deterministic Logic (25 points)

确定性逻辑(25分)

PointsCriteria
25All security actions guarded with
available when
, post-action patterns used
20Most guards present, minor gaps in deterministic enforcement
15Some security logic relies on prompts instead of guards
10Critical actions lack
available when
guards
0Security logic entirely prompt-based (LLM can bypass)
分值标准
25所有安全动作均有
available when
保护,使用动作后检查模式
20大部分保护存在,确定性执行存在 minor 漏洞
15部分安全逻辑依赖提示而非保护
10关键动作缺失
available when
保护
0安全逻辑完全基于提示(LLM可绕过)

Instruction Resolution (20 points)

指令解析(20分)

PointsCriteria
20Arrow syntax for complex logic, proper template injection, correct action execution
15Mostly correct, minor syntax issues
10Uses pipe syntax where arrow needed, template injection errors
5Incorrect phase ordering (data loads after LLM sees instructions)
0Fundamental misunderstanding of resolution order
分值标准
20复杂逻辑使用箭头语法,模板注入正确,动作执行正确
15大部分正确,存在 minor 语法问题
10在需要箭头语法的地方使用了管道语法,模板注入错误
5阶段顺序错误(LLM处理指令后才加载数据)
0对解析顺序存在根本性误解

FSM Architecture (15 points)

FSM架构(15分)

PointsCriteria
15Clear topic boundaries, explicit transitions, appropriate escalation paths
12Good structure with minor redundancy
9Topics too broad or transitions unclear
5Monolithic topic handling multiple concerns
0No topic separation, all logic in start_agent
分值标准
15主题边界清晰,转换明确,升级路径合理
12结构良好,存在 minor 冗余
9主题过于宽泛或转换不明确
5单体主题处理多个关注点
0无主题分离,所有逻辑在start_agent中

Action Configuration (10 points)

动作配置(10分)

PointsCriteria
10Correct protocols, proper I/O mapping, descriptions present
8Minor issues (missing descriptions)
5Wrong protocol for use case
2Input/output mapping errors
0Actions don't compile
分值标准
10协议正确,输入/输出映射正确,描述存在
8minor问题(缺失描述)
5协议与使用场景不匹配
2输入/输出映射错误
0动作无法编译

Deployment Readiness (10 points)

部署就绪性(10分)

PointsCriteria
10Valid user, clean validation, metadata complete
8Minor warnings
5Validation errors that need fixing
2Missing metadata files
0Cannot deploy
分值标准
10用户有效,验证通过,元数据完整
8minor警告
5存在需要修复的验证错误
2缺失元数据文件
0无法部署

Score Thresholds

分数阈值

ScoreRatingAction
90-100⭐⭐⭐⭐⭐ ExcellentDeploy with confidence
80-89⭐⭐⭐⭐ Very GoodMinor improvements recommended
70-79⭐⭐⭐ GoodReview flagged issues before deploy
60-69⭐⭐ Needs WorkAddress issues before deploy
<60⭐ CriticalBLOCK - Fix critical issues
分数评级操作建议
90-100⭐⭐⭐⭐⭐ 优秀放心部署
80-89⭐⭐⭐⭐ 非常好建议进行 minor 改进
70-79⭐⭐⭐ 良好部署前复查标记的问题
60-69⭐⭐ 需要改进部署前解决问题
<60⭐ 关键问题阻止部署 - 修复关键问题

Score Report Format

评分报告格式

📊 AGENT SCRIPT SCORE REPORT
════════════════════════════════════════

Score: 85/100 ⭐⭐⭐⭐ Very Good
├─ Structure & Syntax:    18/20 (90%)
├─ Deterministic Logic:   22/25 (88%)
├─ Instruction Resolution: 16/20 (80%)
├─ FSM Architecture:      12/15 (80%)
├─ Action Configuration:   9/10 (90%)
└─ Deployment Readiness:   8/10 (80%)

Issues:
⚠️ [Deterministic] Missing `available when` on process_refund action
⚠️ [Resolution] Post-action check should be at TOP of instructions
✓ All Structure & Syntax checks passed
✓ All Action Configuration checks passed

📊 AGENT SCRIPT评分报告
════════════════════════════════════════

分数: 85/100 ⭐⭐⭐⭐ 非常好
├─ 结构与语法:    18/20 (90%)
├─ 确定性逻辑:   22/25 (88%)
├─ 指令解析: 16/20 (80%)
├─ FSM架构:      12/15 (80%)
├─ 动作配置:   9/10 (90%)
└─ 部署就绪性:   8/10 (80%)

问题:
⚠️ [确定性逻辑] process_refund动作缺失`available when`保护
⚠️ [解析] 动作后检查应放在指令顶部
✓ 所有结构与语法检查通过
✓ 所有动作配置检查通过

🔧 THE 6 DETERMINISTIC BUILDING BLOCKS

🔧 6个确定性构建块

These execute as code, not suggestions. The LLM cannot override them.
#BlockDescriptionExample
1Conditionalsif/else resolves before LLM
if @variables.attempts >= 3:
2Topic FiltersControl action visibility
available when @variables.verified == True
3Variable ChecksNumeric/boolean comparisons
if @variables.churn_risk >= 80:
4Inline ActionsImmediate execution
run @actions.load_customer
5Utility ActionsBuilt-in helpers
@utils.transition
,
@utils.escalate
6Variable InjectionTemplate values
{!@variables.customer_name}

这些以代码形式执行,而非建议。LLM无法覆盖它们。
序号描述示例
1条件判断if/else在LLM处理前解析
if @variables.attempts >= 3:
2主题过滤器控制动作可见性
available when @variables.verified == True
3变量检查数值/布尔值比较
if @variables.churn_risk >= 80:
4内联动作立即执行
run @actions.load_customer
5工具动作内置助手
@utils.transition
,
@utils.escalate
6变量注入模板值
{!@variables.customer_name}

📐 ARCHITECTURE PATTERNS

📐 架构模式

Pattern 1: Hub and Spoke

模式1:中心辐射式

Central router (hub) to specialized topics (spokes). Use for multi-purpose agents.
       ┌─────────────┐
       │ topic_sel   │
       │   (hub)     │
       └──────┬──────┘
    ┌─────────┼─────────┐
    ▼         ▼         ▼
┌────────┐ ┌────────┐ ┌────────┐
│refunds │ │ orders │ │support │
└────────┘ └────────┘ └────────┘
中心路由器(中心)连接到专用主题(辐射)。适用于多用途智能体。
       ┌─────────────┐
       │ topic_sel   │
       │   (中心)     │
       └──────┬──────┘
    ┌─────────┼─────────┐
    ▼         ▼         ▼
┌────────┐ ┌────────┐ ┌────────┐
│退款   │ │订单   │ │支持   │
└────────┘ └────────┘ └────────┘

Pattern 2: Verification Gate

模式2:验证网关

Security gate before protected topics. Mandatory for sensitive data.
┌─────────┐     ┌──────────┐     ┌───────────┐
│  entry  │ ──▶ │ VERIFY   │ ──▶ │ protected │
└─────────┘     │  (GATE)  │     │  topics   │
                └────┬─────┘     └───────────┘
                     │ 3 fails
                ┌──────────┐
                │ lockout  │
                └──────────┘
受保护主题前的安全网关。敏感数据场景必填。
┌─────────┐     ┌──────────┐     ┌───────────┐
│ 入口   │ ──▶ │ 验证     │ ──▶ │ 受保护主题 │
└─────────┘     │ (网关) │     │           │
                └────┬─────┘     └───────────┘
                     │ 3次失败
                ┌──────────┐
                │ 锁定     │
                └──────────┘

Pattern 3: Post-Action Loop

模式3:动作后循环

Topic re-resolves after action completes - put checks at TOP.
yaml
topic refund:
  reasoning:
    instructions: ->
      # POST-ACTION CHECK (at TOP - triggers on next loop)
      if @variables.refund_status == "Approved":
        run @actions.create_crm_case
        transition to @topic.success

      # PRE-LLM DATA LOADING
      run @actions.check_churn_risk
      set @variables.risk = @outputs.score

      # DYNAMIC INSTRUCTIONS FOR LLM
      if @variables.risk >= 80:
        | Offer full refund to retain customer.
      else:
        | Offer $10 credit instead.

动作完成后主题重新解析 - 检查放在顶部。
yaml
topic refund:
  reasoning:
    instructions: ->
      # 动作后检查(放在顶部 - 下一次循环时触发)
      if @variables.refund_status == "Approved":
        run @actions.create_crm_case
        transition to @topic.success

      # LLM处理前加载数据
      run @actions.check_churn_risk
      set @variables.risk = @outputs.score

      # 为LLM提供动态指令
      if @variables.risk >= 80:
        | 提供全额退款以挽留客户。
      else:
        | 提供10美元信用额度替代。

🐛 DEBUGGING: Trace Analysis

🐛 调试:跟踪分析

The 6 Span Types

6种跟踪类型

SpanDescription
➡️
topic_enter
Execution enters a topic
before_reasoning
Deterministic pre-processing
🧠
reasoning
LLM processes instructions
action_call
Action invoked
transition
Topic navigation
after_reasoning
Deterministic post-processing
跟踪类型描述
➡️
topic_enter
执行进入主题
before_reasoning
确定性预处理
🧠
reasoning
LLM处理指令
action_call
动作被调用
transition
主题导航
after_reasoning
确定性后处理

Debugging Workflow

调试工作流

  1. Interaction Details - Quick understanding of what happened
  2. Trace Waterfall - Technical view with exact prompts, latencies
  3. Variable State - Entry vs Exit values reveal when state was ignored
  4. Script View - Red squiggles show syntax errors
  1. 交互详情 - 快速了解发生了什么
  2. 跟踪瀑布图 - 包含准确提示、延迟的技术视图
  3. 变量状态 - 入口与出口值揭示状态何时被忽略
  4. 脚本视图 - 红色波浪线显示语法错误

Common Debug Patterns

常见调试模式

SymptomCheckFix
Wrong policy appliedVariable Entry valuesChange
mutable
to
linked
with
source:
Action executed without auth
available when
presence
Add guard clause
LLM ignores variableInstruction resolution orderMove data load before LLM text
Infinite loopTransition conditionsAdd exit condition

症状检查项修复方法
应用了错误的策略变量入口值
mutable
改为带
source:
linked
动作未授权即执行
available when
是否存在
添加保护子句
LLM忽略变量指令解析顺序将数据加载移至LLM文本之前
无限循环转换条件添加退出条件

⚠️ COMMON ISSUES & FIXES

⚠️ 常见问题与修复

IssueSymptomFix
Internal Error, try again later
Invalid
default_agent_user
Query:
sf data query -q "SELECT Username FROM User WHERE Profile.Name = 'Einstein Agent User'" -o TARGET_ORG
Default agent user X could not be found
User doesn't exist in target orgQuery the specific target org (user formats vary: some use
user@orgid.ext
)
No .agent file found in directory
agent_name
doesn't match folder
Make
agent_name
identical to folder name (case-sensitive)
SyntaxError: cannot mix spaces and tabs
Mixed indentationUse consistent spacing throughout
SyntaxError: Unexpected 'if'
Nested if statementsUse compound condition:
if A and B:
or flatten to sequential ifs
SyntaxError: Unexpected 'actions'
Top-level actions blockMove actions inside
topic.reasoning.actions:
SyntaxError: Unexpected 'inputs'
inputs:
block in action
Use
with param=value
syntax instead
SyntaxError: Unexpected 'outputs'
outputs:
block in action
Use
set @variables.x = @outputs.y
instead
SyntaxError: Unexpected 'set'
set
after
@utils.setVariables
Use Helper Topic Pattern (set in
instructions: ->
)
Duplicate 'available when' clause
Multiple guards on actionCombine:
available when A and B
Unexpected 'escalate'
Reserved action nameRename to
escalate_now
or
escalate_to_human
Transition to undefined topic
Typo in topic referenceCheck spelling, ensure topic exists
Variables cannot be both mutable AND linked
Conflicting modifiersChoose one: mutable for state, linked for external
Required fields missing: [BundleType]
Using wrong deploy commandUse
sf agent publish authoring-bundle
, NOT
sf project deploy start
Cannot find a bundle-meta.xml file
Wrong file namingRename to
AgentName.bundle-meta.xml
, NOT
.aiAuthoringBundle-meta.xml
ValidationError: Tool target 'X' is not an action definition
Action not defined in topic
actions:
block with
target:
, OR target doesn't exist in org
Define action in topic-level
actions:
block with valid
target:
(e.g.,
apex://ClassName
), then reference via
@actions.name
in
reasoning.actions:
LLM bypasses security checkUsing prompts for securityUse
available when
guards instead
Post-action logic doesn't runCheck not at TOPMove post-action check to first lines
Wrong data retrievedMissing filterWrap retriever in Flow with filter inputs
Variables don't changeUsing
@utils.setVariables
with
set
Post-action
set
only works on
@actions.*
, use Helper Topics
Wrong target protocol
flows://
instead of
flow://
Remove trailing
s
:
flow://FlowName
Prompt template input not mappedUnquoted
Input:
parameter
Quote it:
with "Input:email"=...
Missing type on action input
email:
with no type in definition
Add type:
email: string
问题症状修复方法
Internal Error, try again later
default_agent_user
无效
查询:
sf data query -q "SELECT Username FROM User WHERE Profile.Name = 'Einstein Agent User'" -o TARGET_ORG
Default agent user X could not be found
用户在目标组织中不存在专门查询目标组织(用户格式因组织而异:部分使用
user@orgid.ext
No .agent file found in directory
agent_name
与文件夹名称不匹配
使
agent_name
与文件夹名称完全相同(区分大小写)
SyntaxError: cannot mix spaces and tabs
混合缩进全程使用一致的缩进方式
SyntaxError: Unexpected 'if'
嵌套if语句使用复合条件:
if A and B:
或拆分为顺序if语句
SyntaxError: Unexpected 'actions'
顶层actions块将actions移至
topic.reasoning.actions:
SyntaxError: Unexpected 'inputs'
动作内的
inputs:
使用
with param=value
语法替代
SyntaxError: Unexpected 'outputs'
动作内的
outputs:
使用
set @variables.x = @outputs.y
替代
SyntaxError: Unexpected 'set'
@utils.setVariables
后使用
set
使用辅助主题模式(在
instructions: ->
中设置)
Duplicate 'available when' clause
动作有多个保护合并为:
available when A and B
Unexpected 'escalate'
使用了保留动作名称重命名为
escalate_now
escalate_to_human
Transition to undefined topic
主题引用拼写错误检查拼写,确保主题存在
Variables cannot be both mutable AND linked
修饰符冲突选择其一:可变变量用于状态,关联变量用于外部数据
Required fields missing: [BundleType]
使用了错误的部署命令使用
sf agent publish authoring-bundle
,不要用
sf project deploy start
Cannot find a bundle-meta.xml file
文件命名错误重命名为
AgentName.bundle-meta.xml
,不要用
.aiAuthoringBundle-meta.xml
ValidationError: Tool target 'X' is not an action definition
动作未在主题
actions:
块中定义(带
target:
),或目标在组织中不存在
在主题级
actions:
块中定义带有效
target:
的动作,然后在
reasoning.actions:
中通过
@actions.name
引用
LLM绕过安全检查使用提示实现安全使用
available when
保护替代
动作后逻辑未执行检查未放在顶部将动作后检查移至第一行
获取了错误的数据缺失过滤器在Flow中包装检索器并添加过滤输入
变量未更改
@utils.setVariables
使用
set
动作后
set
仅对
@actions.*
生效,使用辅助主题
目标协议错误
flows://
而非
flow://
移除末尾的
s
flow://FlowName
提示模板输入未映射
Input:
参数未加引号
添加引号:
with "Input:email"=...
动作输入缺失类型
email:
在定义中无类型
添加类型:
email: string

Deployment Gotchas (Validated by Testing)

部署注意事项(经测试验证)

❌ Wrong✅ Correct
AgentName.aiAuthoringBundle-meta.xml
AgentName.bundle-meta.xml
sf project deploy start
sf agent publish authoring-bundle
sf agent validate --source-dir
sf agent validate authoring-bundle --source-dir
Query user from wrong orgQuery target org specifically with
-o
flag
❌ 错误操作✅ 正确操作
AgentName.aiAuthoringBundle-meta.xml
AgentName.bundle-meta.xml
sf project deploy start
sf agent publish authoring-bundle
sf agent validate --source-dir
sf agent validate authoring-bundle --source-dir
从错误的组织查询用户使用
-o
标志专门查询目标组织

Einstein Agent User Format (Org-Specific)

Einstein Agent用户格式(组织特定)

Einstein Agent User formats vary between orgs:
  • Production/Partner orgs: Often use
    username@orgid.ext
    format (e.g.,
    resort_manager@00dak00000gdgwu480119933.ext
    )
  • Dev orgs: May use
    username.suffix@orgfarm.salesforce.com
    format
MANDATORY: Ask user to confirm which Einstein Agent User to use when creating a new agent.
Always query the specific target org:
bash
undefined
Einstein Agent用户格式因组织而异:
  • 生产/合作伙伴组织:通常使用
    username@orgid.ext
    格式(例如
    resort_manager@00dak00000gdgwu480119933.ext
  • 开发组织:可能使用
    username.suffix@orgfarm.salesforce.com
    格式
必填操作:创建新智能体时,要求用户确认使用哪个Einstein Agent用户。
务必专门查询目标组织:
bash
undefined

Query target org specifically

专门查询目标组织

sf data query -q "SELECT Username FROM User WHERE Profile.Name = 'Einstein Agent User' AND IsActive = true" -o YOUR_TARGET_ORG

Present the results to the user and ask them to select which user to use for `default_agent_user`.

> ⚠️ A user existing in one org does NOT mean it exists in another. Always verify in the deployment target.

---
sf data query -q "SELECT Username FROM User WHERE Profile.Name = 'Einstein Agent User' AND IsActive = true" -o YOUR_TARGET_ORG

将结果展示给用户,让他们选择用于`default_agent_user`的用户。

> ⚠️ 一个组织中的用户**不代表**在另一个组织中存在。部署前务必在目标组织中验证。

---

📚 DOCUMENT MAP (Progressive Disclosure)

📚 文档地图(渐进式披露)

Tier 2: Resource Guides (Comprehensive)

第二层级:资源指南(全面)

NeedDocumentDescription
Syntax referenceresources/syntax-reference.mdComplete block & expression syntax
FSM designresources/fsm-architecture.mdState machine patterns & examples
Instruction resolutionresources/instruction-resolution.mdThree-phase execution model
Data & multi-agentresources/grounding-multiagent.mdRetriever actions & SOMA patterns
Debuggingresources/debugging-guide.mdTrace analysis & forensics
Testingresources/testing-guide.mdBatch testing & quality metrics
Prompt template actionsresources/action-prompt-templates.md
generatePromptResponse://
input binding, grounded data,
run
limitation
Advanced action patternsresources/action-patterns.mdContext-aware descriptions,
{!@actions.X}
instruction refs, binding matrix
Actions referenceresources/actions-reference.mdComplete action types, GenAiFunction metadata, escalation routing, Flow/Apex/API patterns
需求文档描述
语法参考resources/syntax-reference.md完整的块与表达式语法
FSM设计resources/fsm-architecture.md状态机模式与示例
指令解析resources/instruction-resolution.md三阶段执行模型
数据与多智能体resources/grounding-multiagent.md检索器动作与SOMA模式
调试resources/debugging-guide.md跟踪分析与取证
测试resources/testing-guide.md批量测试与质量指标
提示模板动作resources/action-prompt-templates.md
generatePromptResponse://
输入绑定、基于事实的数据、
run
限制
高级动作模式resources/action-patterns.md上下文感知描述、
{!@actions.X}
指令引用、绑定矩阵
动作参考resources/actions-reference.md完整的动作类型、GenAiFunction元数据、升级路由、Flow/Apex/API模式

Tier 3: Quick References (Docs)

第三层级:快速参考(文档)

NeedDocumentDescription
CLI commandsdocs/cli-guide.mdsf agent retrieve/validate/deploy
Patternsdocs/patterns-quick-ref.mdDecision tree for pattern selection
需求文档描述
CLI命令docs/cli-guide.mdsf agent拉取/验证/部署
模式docs/patterns-quick-ref.md模式选择决策树

Tier 4: Templates

第四层级:模板

CategoryDirectoryContents
Root templatestemplates/7 .agent templates (minimal-starter, hub-and-spoke, etc.)
Complete agentstemplates/agents/4 full agent examples (hello-world, simple-qa, multi-topic, production-faq)
Componentstemplates/components/6 component fragments (apex-action, error-handling, escalation, flow-action, n-ary-conditions, topic-with-actions)
Advanced patternstemplates/patterns/11 pattern templates (action-callbacks, bidirectional-routing, delegation, lifecycle-events, etc.)
Metadata XMLtemplates/metadata/6 XML templates (GenAiFunction, GenAiPlugin, PromptTemplate, Flow)
Apextemplates/apex/Models API queueable class

分类目录内容
根模板templates/7个.agent模板(最小启动模板、中心辐射式等)
完整智能体templates/agents/4个完整智能体示例(Hello World、简单问答、多主题、生产环境FAQ)
组件templates/components/6个组件片段(Apex动作、错误处理、升级、Flow动作、多条件、带动作的主题)
高级模式templates/patterns/11个模式模板(动作回调、双向路由、委托、生命周期事件等)
元数据XMLtemplates/metadata/6个XML模板(GenAiFunction、GenAiPlugin、PromptTemplate、Flow)
Apextemplates/apex/Models API队列类

🔗 CROSS-SKILL INTEGRATION

🔗 跨技能集成

MANDATORY Delegations

必须委托的任务

TaskDelegate ToReason
Create Flows for
flow://
targets
/sf-flow
Flows must exist before agent uses them
Test agent routing & actions
/sf-ai-agentforce-testing
Specialized testing patterns
Deploy agent to org
/sf-deploy
Proper deployment validation
任务委托给原因
flow://
目标创建Flow
/sf-flow
智能体使用前必须存在Flow
测试智能体路由与动作
/sf-ai-agentforce-testing
专用测试模式
将智能体部署到组织
/sf-deploy
正确的部署验证

Integration Patterns

集成模式

FromToPattern
/sf-ai-agentscript
/sf-flow
Create Flow, then reference in agent
/sf-ai-agentscript
/sf-apex
Create Apex class with
@InvocableMethod
, then use
apex://ClassName
target directly (NO GenAiFunction needed)
/sf-ai-agentscript
/sf-integration
Set up Named Credentials for
externalService://

来源目标模式
/sf-ai-agentscript
/sf-flow
创建Flow,然后在智能体中引用
/sf-ai-agentscript
/sf-apex
创建带
@InvocableMethod
的Apex类,然后直接使用
apex://ClassName
目标(无需GenAiFunction)
/sf-ai-agentscript
/sf-integration
externalService://
设置命名凭证

✅ DEPLOYMENT CHECKLIST

✅ 部署检查清单

Configuration

配置

  • default_agent_user
    is valid Einstein Agent User
  • agent_name
    uses snake_case (no spaces)
  • default_agent_user
    是有效的Einstein Agent用户
  • agent_name
    使用蛇形命名法(无空格)

Syntax

语法

  • No mixed tabs/spaces
  • Booleans use
    True
    /
    False
  • Variable names use snake_case
  • 未混合使用制表符和空格
  • 布尔值使用
    True
    /
    False
  • 变量名使用蛇形命名法

Structure

结构

  • Exactly one
    start_agent
    block
  • At least one
    topic
    block
  • All transitions reference existing topics
  • 仅存在一个
    start_agent
  • 至少存在一个
    topic
  • 所有转换引用已存在的主题

Security

安全

  • Critical actions have
    available when
    guards
  • Session data uses
    linked
    variables (not
    mutable
    )
  • 关键动作有
    available when
    保护
  • 会话数据使用
    linked
    变量(而非
    mutable

Testing

测试

  • sf agent validate --source-dir ./my-agent
    passes
  • Preview mode tested before activation

  • sf agent validate --source-dir ./my-agent
    通过
  • 部署前已在预览模式中测试

🚀 MINIMAL WORKING EXAMPLE

🚀 最小可用示例

yaml
config:
  developer_name: "simple_agent"
  agent_description: "A minimal working agent example"
  agent_type: "AgentforceServiceAgent"  # or "AgentforceEmployeeAgent"
  default_agent_user: "agent_user@yourorg.com"

system:
  messages:
    welcome: "Hello! How can I help you today?"
    error: "Sorry, something went wrong."
  instructions: "You are a helpful customer service agent."

variables:
  customer_verified: mutable boolean = False

topic main:
  description: "Main conversation handler"
  reasoning:
    instructions: ->
      if @variables.customer_verified == True:
        | You are speaking with a verified customer.
        | Help them with their request.
      else:
        | Please verify the customer's identity first.
    actions:
      verify: @actions.verify_customer
        description: "Verify customer identity"
        set @variables.customer_verified = @outputs.verified

start_agent entry:
  description: "Entry point for all conversations"
  reasoning:
    instructions: |
      Greet the customer and route to the main topic.
    actions:
      go_main: @utils.transition to @topic.main
        description: "Navigate to main conversation"

yaml
config:
  developer_name: "simple_agent"
  agent_description: "最小可用智能体示例"
  agent_type: "AgentforceServiceAgent"  # 或"AgentforceEmployeeAgent"
  default_agent_user: "agent_user@yourorg.com"

system:
  messages:
    welcome: "你好!今天我能为你提供什么帮助?"
    error: "抱歉,出现了一些问题。"
  instructions: "你是一个乐于助人的客户服务智能体。"

variables:
  customer_verified: mutable boolean = False

topic main:
  description: "主对话处理"
  reasoning:
    instructions: ->
      if @variables.customer_verified == True:
        | 你正在与已验证客户对话。
        | 请协助处理他们的请求。
      else:
        | 请先验证客户身份。
    actions:
      verify: @actions.verify_customer
        description: "验证客户身份"
        set @variables.customer_verified = @outputs.verified

start_agent entry:
  description: "所有对话的入口点"
  reasoning:
    instructions: |
      问候客户并路由到主主题。
    actions:
      go_main: @utils.transition to @topic.main
        description: "导航到主对话"

📖 OFFICIAL RESOURCES

📖 官方资源

📚 SOURCES & ACKNOWLEDGMENTS

📚 来源与致谢

This skill draws from multiple authoritative sources:
SourceContribution
trailheadapps/agent-script-recipes20 reference recipes across 4 categories, AGENT_SCRIPT.md rules document, variable patterns, action target catalog
Salesforce Official DocumentationCore syntax, API references, deployment guides
TDD Validation (this skill)13 validation agents confirming current-release syntax compatibility
Tribal knowledge interviewsCanvas View bugs, VS Code limitations, credit consumption patterns
agentforce.guideUnofficial but useful examples (note: some patterns don't compile in current release)
@kunello (PR #20)Prompt template
"Input:fieldName"
binding syntax, context-aware description overrides,
{!@actions.X}
instruction reference patterns, callback behavior notes, error pattern catalog
⚠️ Note on Feature Validation: Some patterns from external sources (e.g.,
always_expect_input:
,
label:
property, certain action properties on transitions) do NOT compile in Winter '26. The
before_reasoning:
/
after_reasoning:
lifecycle hooks ARE valid but require direct content (no
instructions:
wrapper) - see the Lifecycle Hooks section for correct syntax. This skill documents only patterns that pass TDD validation.

本技能参考了多个权威来源:
来源贡献
trailheadapps/agent-script-recipes4个分类下的20个参考示例、AGENT_SCRIPT.md规则文档、变量模式、动作目标目录
Salesforce官方文档核心语法、API参考、部署指南
本技能的TDD验证13个验证智能体,确认当前版本语法兼容性
行业经验访谈Canvas视图问题、VS Code限制、积分消耗模式
agentforce.guide非官方但实用的示例(注意:部分模式在当前版本无法编译)
@kunello (PR #20)提示模板
"Input:fieldName"
绑定语法、上下文感知描述覆盖、
{!@actions.X}
指令引用模式、回调行为说明、错误模式目录
⚠️ 功能验证说明:部分来自外部来源的模式(例如
always_expect_input:
label:
属性、转换动作的某些属性)在Winter '26版本中无法编译
before_reasoning:
/
after_reasoning:
生命周期钩子有效,但需要直接内容(无
instructions:
包装器)- 请查看生命周期钩子部分的正确语法。本技能仅记录通过TDD验证的模式。

🏷️ VERSION HISTORY

🏷️ 版本历史

VersionDateChanges
1.7.02026-02-09CRITICAL FIX: apex:// works directly, GenAiFunction NOT needed for Agent Script. Removed false "Known Issue" claiming
apex://ClassName
doesn't work (actions-reference.md line 393). Rewrote "Action Type 2: Apex Actions" section to document two deployment paths (AiAuthoringBundle uses
apex://
directly; Agent Builder UI needs GenAiFunction). Added "Two-Level Action System" explanation (topic
actions:
block defines with
target:
,
reasoning.actions:
invokes via
@actions.name
). Fixed GenAiFunction XML templates to use correct API v65.0 schema (removed invalid
<capability>
,
<genAiFunctionParameters>
,
<genAiFunctionInputs>
,
<genAiFunctionOutputs>
elements; added
input/schema.json
+
output/schema.json
bundle pattern). Fixed
apex-action.agent
template to use
apex://ClassName
(not
ClassName.MethodName
). Fixed
topic-with-actions.agent
to remove incorrect "with/set not supported in AiAuthoringBundle" warning. Fixed troubleshooting table entries. Updated SKILL.md "Registering Flow Actions" section to clarify AiAuthoringBundle vs Agent Builder UI paths. Confirmed against
trailheadapps/agent-script-recipes
(zero GenAiFunction/GenAiPlugin in official recipes).
1.6.02026-02-07Content migration from former sf-ai-agentforce-legacy: Migrated 28 template files across 5 categories (agents/, components/, patterns/, metadata/, apex/) from the former legacy skill (now
sf-ai-agentforce
). Created
resources/actions-reference.md
(602 lines) with exhaustive action type reference, GenAiFunction metadata, escalation routing, and Flow/Apex/API patterns. Merged topic design patterns into
resources/fsm-architecture.md
. Merged advanced decision trees into
docs/patterns-quick-ref.md
. Added Tier 4 Templates section to Document Map. The former legacy skill directory is now
sf-ai-agentforce
— repurposed for standard Agentforce platform content (Agent Builder, PromptTemplate, Models API).
1.5.02026-02-06Action patterns & prompt template docs (from @kunello PR #20): Added
resources/action-prompt-templates.md
documenting
generatePromptResponse://
input binding syntax (
"Input:fieldName"
), grounded data integration, output handling, and
run
keyword limitation workaround. Added
resources/action-patterns.md
covering context-aware action description overrides (beginner/advanced mode),
{!@actions.X}
instruction references for guided LLM action selection, input binding decision matrix, callback success-only behavior, and additional error patterns. Updated Common Issues table with 3 new error entries (wrong protocol, unquoted Input: params, missing type annotations). Added Document Map entries and cross-reference after Action Chaining section. Content consolidated from @kunello's 8-file contribution against Agent Script Recipes.
1.3.02026-01-20Lifecycle hooks validated: Added full documentation for
before_reasoning:
and
after_reasoning:
with CORRECT syntax (content directly under block, NO
instructions:
wrapper). Added "Features NOT Valid in Current Release" section documenting 7 features that appear in docs/recipes but don't compile (label on topics/actions, always_expect_input, action properties on transitions). Updated validation_agents count to 13. Confirmed
@utils.transition
only supports
description:
property.
1.2.02026-01-20Gap analysis vs agent-script-recipes: Expanded Action Target Protocols from 7 to 16 (with validation status indicators), added Variable vs Action I/O Type Matrix, added lifecycle hooks note with TDD validation caveat, added Sources & Acknowledgments section, documented future/planned features notice. TDD validation confirmed
label:
IS reserved (SKILL.md was correct),
before_reasoning:
/
after_reasoning:
syntax from recipes does NOT compile in current release
1.1.02026-01-20"Ultimate Guide" tribal knowledge integration: Added
complex_data_type_name
mapping table, Canvas View corruption bugs, Reserved field names, Preview mode workarounds, Credit consumption table, Supervision vs Handoff clarification, Action output flags for zero-hallucination routing, Latch variable pattern, Loop protection guardrails, Token/size limits, Progress indicators, Connection block escalation patterns, VS Code limitations, Language block quirks. Added 4 new templates: flow-action-lookup, prompt-rag-search, deterministic-routing, escalation-pattern
1.0.42026-01-19Progressive testing validation (Quiz_Master, Expense_Calculator, Order_Processor): Added constraints for no top-level
actions:
block, no
inputs:
/
outputs:
in reasoning.actions, expanded nested-if guidance with flattening approach, added new SyntaxError entries to common issues
1.0.32026-01-19Added Einstein Agent User interview requirement - mandatory user confirmation when creating new agents
1.0.22026-01-19Major corrections from GitHub reference: Fixed block order (config→system), added Helper Topic Pattern, transition vs delegation, expression operators (+/- only), naming rules (80 char max), slot-filling
...
syntax, post-action directives (@actions.* only)
1.0.12026-01-19Added syntax constraints from 0-shot testing: no nested if, one available when per action, reserved action names
1.0.02026-01Initial release with 8-module coverage
版本日期变更
1.7.02026-02-09关键修复:apex://直接生效,Agent Script无需GenAiFunction。移除了声称
apex://ClassName
不生效的错误“已知问题”(actions-reference.md第393行)。重写“动作类型2:Apex动作”部分,记录两种部署路径(AiAuthoringBundle直接使用
apex://
;Agent Builder UI需要GenAiFunction)。添加“两级动作系统”说明(主题
actions:
块定义带
target:
的动作,
reasoning.actions:
通过
@actions.name
调用)。修复GenAiFunction XML模板以使用正确的API v65.0 schema(移除无效的
<capability>
<genAiFunctionParameters>
<genAiFunctionInputs>
<genAiFunctionOutputs>
元素;添加
input/schema.json
+
output/schema.json
包模式)。修复
apex-action.agent
模板以使用
apex://ClassName
(而非
ClassName.MethodName
)。修复
topic-with-actions.agent
以移除错误的“AiAuthoringBundle不支持with/set”警告。修复故障排除表条目。更新SKILL.md“注册Flow动作”部分,明确AiAuthoringBundle与Agent Builder UI路径。与
trailheadapps/agent-script-recipes
确认(官方示例中无GenAiFunction/GenAiPlugin)。
1.6.02026-02-07从原sf-ai-agentforce-legacy迁移内容:从原旧技能(现为
sf-ai-agentforce
)迁移了5个分类下的28个模板文件(agents/、components/、patterns/、metadata/、apex/)。创建了
resources/actions-reference.md
(602行),包含详尽的动作类型参考、GenAiFunction元数据、升级路由和Flow/Apex/API模式。将主题设计模式合并到
resources/fsm-architecture.md
。将高级决策树合并到
docs/patterns-quick-ref.md
。在文档地图中添加第四层级模板部分。原旧技能目录现为
sf-ai-agentforce
— 重新用于标准Agentforce平台内容(Agent Builder、PromptTemplate、Models API)。
1.5.02026-02-06动作模式与提示模板文档(来自@kunello PR #20):添加
resources/action-prompt-templates.md
,记录
generatePromptResponse://
输入绑定语法(
"Input:fieldName"
)、基于事实的数据集成、输出处理和
run
关键字限制解决方法。添加
resources/action-patterns.md
,涵盖上下文感知动作描述覆盖(入门/高级模式)、用于引导LLM动作选择的
{!@actions.X}
指令引用、输入绑定决策矩阵、仅成功回调行为和其他错误模式。在常见问题表中添加3个新错误条目(错误协议、未加引号的Input:参数、缺失类型注解)。在文档地图中添加条目,并在动作链部分添加交叉引用。内容整合自@kunello针对Agent Script Recipes的8文件贡献。
1.3.02026-01-20生命周期钩子已验证:添加
before_reasoning:
after_reasoning:
的完整文档,包含正确语法(内容直接放在块下,无
instructions:
包装器)。添加“当前版本不支持的功能”部分,记录7个出现在文档/示例中但无法编译的功能(主题/动作上的label、always_expect_input、转换动作上的动作属性)。更新验证智能体数量至13个。确认
@utils.transition
仅支持
description:
属性。
1.2.02026-01-20与agent-script-recipes的差距分析:将动作目标协议从7个扩展到16个(带验证状态指示器),添加变量与动作I/O类型矩阵,添加带TDD验证注意事项的生命周期钩子说明,添加来源与致谢部分,记录未来/计划功能通知。TDD验证确认
label:
是保留字段(SKILL.md正确),示例中的
before_reasoning:
/
after_reasoning:
语法在当前版本无法编译
1.1.02026-01-20“终极指南”行业经验整合:添加
complex_data_type_name
映射表、Canvas视图损坏问题、保留字段名称、预览模式解决方法、积分消耗表、监督与移交模式澄清、零幻觉路由的动作输出标志、锁存变量模式、循环保护机制、令牌/大小限制、进度指示器、连接块升级模式、VS Code限制、语言块特性。添加4个新模板:Flow动作查询、提示RAG搜索、确定性路由、升级模式
1.0.42026-01-19渐进式测试验证(Quiz_Master、Expense_Calculator、Order_Processor):添加禁止顶层
actions:
块、reasoning.actions中禁止
inputs:
/
outputs:
的约束,扩展嵌套if指南并添加拆分方法,在常见问题中添加新的SyntaxError条目
1.0.32026-01-19添加Einstein Agent用户访谈要求 - 创建新智能体时必须确认用户
1.0.22026-01-19GitHub参考文档的主要修正:修复块顺序(config→system),添加辅助主题模式、转换与委托、表达式运算符(仅+/-)、命名规则(最大80字符)、槽位填充
...
语法、动作后指令(仅@actions.*)
1.0.12026-01-19添加0-shot测试得出的语法约束:禁止嵌套if、每个动作仅一个available when、保留动作名称
1.0.02026-01初始版本,包含8个模块内容
",