mcpField
S
service-agentforce-human-escalation-configure

service-agentforce-human-escalation-configure

github.com/forcedotcomAgent 工作流1.1k117 次安装1 天前更新
代码仓库

关于 service-agentforce-human-escalation-configure

用于配置和验证 Agentforce 通过 Omni-Channel 队列转接给人工坐席的 Salesforce 技能。支持 classic 和 NGA 编写模型,返回机器可读判定,并阻止向生产组织写入。

主要功能

  1. 01创建或采用人工队列
  2. 02配置 QueueBased 出站路由流
  3. 03验证 Agentforce 升级转接配置
  4. 04支持 classic 与 NGA 编写模型
  5. 05阻止写入生产组织
  6. 06返回机器可读判定

适用场景

  1. 01设置 Agentforce 转接至人工队列
  2. 02检查队列成员与路由就绪情况
  3. 03部署后验证升级转接配置
  4. 04记录供评估使用的失败阈值指令

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/forcedotcom/sf-skills --skill service-agentforce-human-escalation-configure

安装后在 Claude Code 中输入/service-agentforce-human-escalation-configure确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

assets/
escalation-thresholds.instructions.md
package.xml
sfdx-project.json
assets/force-app/main/default/flows/
Human_Escalation_Outbound_Flow.flow-meta.xml
references/
classifier-contracts.md
escalation-mechanism.md
failure-policy.md
nga-escalation.md
runtime-verification.md
scripts/
classify-agent-active.mjs
classify-nga-escalation.mjs
extract-outbound-route.mjs
patch-escalation-surfaces.mjs
verify-and-configure.sh
verify-escalation-config.mjs
scripts/tests/
__init__.py
_bootstrap.py
test_escalation_contracts.py

详细介绍

配置 Agentforce Agent → 人工升级

配置 Agentforce Agent,使其能够通过 Omni-Channel 队列将对话转交给人工 Agent。此技能会配置并验证升级相关界面,然后报告单个机器可读的 JSON 判定结果。它按开发者名称执行,具有幂等性,并且拒绝写入生产组织。它可以独立运行,也可以作为更大配置流程中的一个阶段(在创建并激活 Agent 之后)。

Agent、队列、出站流名称、路由上下文对象、服务通道和失败阈值均为输入,因此同一技能可用于各种场景(IT 员工支持、客户消息等)——调用方提供特定场景的标识符。

此技能是 Agent 到人工(出站)升级的权威配置方。service-agentforce-channel-configure 可在设置入站通道时一并配置基本出站流和 connection 块,但会将完整的升级配置和验证交由此技能处理。

坦诚说明:确定性配置、指令式策略与运行时行为的边界

Agentforce 中的升级由多种可验证性各不相同的配置组成:

  • 确定性配置(此技能通过 Metadata/Data API 写入和/或往返验证):升级主题(GenAiPlugin)上的 canEscalate=true;Agent 的 Messaging 规划器配置界面(GenAiPlannerBundle)上的 outboundRouteConfigs,其中同一配置块将 outboundRouteName 与 outboundRouteType=OmniChannelFlow 关联,并位于 Messaging 类配置界面上;具有非空 ActiveVersionId 的 QueueBased 出站 RoutingFlow;具有关联上下文对象的 QueueSobject、绑定到该队列的 QueueRoutingConfig,以及至少一名活跃的人工成员(没有成员的队列永远无法将升级请求路由给人工,因此永远不会达到 CONFIGURED);重新发布后处于 Active 状态的 Agent。
  • 指令/原生策略(以 Agent Script 指令的形式编写,不是元数据计数器):默认的连续两次失败阈值,以及按主题设置的覆盖值(例如,密码重置 = 一次失败)。元数据中没有记录失败轮次的字段——该阈值是指令文本,由 ADK 评估规则验证,而非通过运行时读取。请参阅 references/failure-policy.md。
  • 仅限运行时/手动验证:实际的对话触发条件、AgentWork 的创建,以及同一会话的上下文保留。这些无法通过无头方式执行——需要按文档进行手动测试并使用评估规则。请参阅 references/runtime-verification.md。

编写模型——经典版与新一代(NGA)

Salesforce 提供两种 Agentforce 编写模型。Phase 1b 会根据组织支持的元数据类型自动检测所用模型。路由基础设施(队列、QueueSobject、成员、QueueRoutingConfig、出站 RoutingFlow)在两种模型中完全相同;区别仅在于 Agent 侧的升级处理界面。

  • 经典版——组织公开 GenAiPlugin 和 GenAiPlannerBundle。Agent 界面包含主题上的 canEscalate 和规划器 Messaging 界面上的 outboundRouteConfigs。此界面在 Phase 4 中编写(手动编辑,或通过可选的 AUTHOR_SURFACES=1 阶段),并在 Phase 7 中进行往返验证。
  • nga——组织公开 AiAuthoringBundle(Agent Script),但不公开 GenAiPlannerBundle。没有 outboundRouteConfigs 元数据;Agent 界面是可访问的 @utils.escalate 操作(Service Agent),或创建记录操作(Employee Agent 无法使用 @utils.escalate),队列路由则完全由确定性路由部分承担。此技能会根据检索到的捆绑包验证该界面,并将其编写工作交由 agentforce-generate。
  • none——两种界面均未公开 → 技能会在任何写入前安全失败。

当两种模型同时存在时,可通过 AUTHORING_MODEL_OVERRIDE=classic|nga 固定检测结果。完整规则、Service 与 Employee 的区别,以及 NGA 判定结果集见 references/nga-escalation.md。

范围

  • 包含:启用升级主题(canEscalate);在 GenAiPlannerBundle 的 Messaging 界面中配置 outboundRouteConfigs;部署捆绑的 QueueBased 出站 RoutingFlow;创建或采用人工队列(为上下文对象配置 QueueSobject)及其 QueueRoutingConfig;编写失败阈值指令;重新发布并重新激活;以及确定性配置往返判定。支持幂等重复运行。
  • 不包含:创建或激活 Agent;入站渠道传输(MessagingChannel 上的 sessionHandlerAsa)和 Agent 的出站 connection 块(由 service-agentforce-channel-configure 负责);配置 Messaging 渠道本身(由 service-digital-engagement-channel-configure 负责);更广泛的 Omni-Channel 路由基础设施;升级场景之外的独立队列配置;以及对生产组织的任何写入。

输入

输入位置参数环境变量默认值
组织别名1(必填)——
Agent 开发者名称2AGENT_DEVELOPER_NAMESupport_Agent
队列开发者名称3QUEUE_DEVELOPER_NAMEHuman_Support_Queue
升级主题 API 名称4ESCALATION_TOPIC_API_NAME(未设置——界面未验证)
规划器捆绑包 API 名称5PLANNER_BUNDLE_API_NAME(未设置——界面未验证)
出站流开发者名称—FLOW_DEVELOPER_NAMEHuman_Escalation_Outbound_Flow
出站流标签—FLOW_LABEL将流名称中的 _ 替换为空格
上下文对象(路由的 sObject)—CONTEXT_OBJECTMessagingSession
服务渠道开发名称/标签—SERVICE_CHANNEL_DEV_NAME / SERVICE_CHANNEL_LABELsfdc_livemessage / Messaging
队列为空时要添加的人工成员—QUEUE_MEMBER_USERNAMES(未设置)
失败阈值(交接前连续失败的尝试次数)—DEFAULT_FAILURE_THRESHOLD2
已编写阈值指令(带外标志)—THRESHOLD_AUTHORED0

对于非 MessagingSession 上下文对象(例如 Case、VoiceCall),请传入相匹配的 SERVICE_CHANNEL_DEV_NAME / SERVICE_CHANNEL_LABEL。

前提条件

  1. 已安装 sf CLI 并通过身份验证,可访问目标组织(sf org display -o <alias> 显示 Connected)。所有调用都使用 --target-org <alias>。
  2. PATH 中有 node ≥ 18 和 jq(用于确定性分类器和 JSON 组装)。
  3. **Agent 存在,且其最新的 BotVersion 处于 Active 状态。**如果不满足,此技能会安全失败。
  4. **对于 MessagingSession 转交,必须存在一个处于 Active 状态的 MessagingChannel。**如果找不到,此技能会安全失败。其他上下文对象使用不同的传输方式,不受 MessagingChannel 限制。
  5. **Sandbox / trial CDO / Developer Edition 组织。**此技能拒绝在真实生产客户组织中配置升级处理。

如果某项前提条件不满足,sf 会显示原始错误——不要捏造状态;显示错误并停止。


工作流

阶段 0 — 生产环境写入保护(必需,首个写入门禁)

在进行任何写入之前,编排器会查询 Organization(IsSandbox、TrialExpirationDate、OrganizationType)并计算 safe_to_write。如果该组织是真实的生产客户组织,此技能会输出 status: "BLOCKED" 并停止。此保护在 scripts/verify-and-configure.sh 中强制执行——绝不可绕过。

阶段 1 — 前提条件(只读,安全失败)
  1. Agent 处于 Active 状态 — SOQL 查询 BotDefinition(以及最新的 BotVersion),由 scripts/classify-agent-active.mjs 进行确定性分类。未找到或未激活 → 阻止操作,并提供激活操作路径。
  2. 存在传输通道 — 对于 MessagingSession,执行 SOQL 查询 MessagingChannel WHERE IsActive=true;如果没有记录 → 阻止操作,并指向 service-digital-engagement-channel-configure。
阶段 2 — 人工队列(创建或采用)+ 成员

按 DeveloperName 查找队列。如果不存在,则部署一个 Queue(规范的 Metadata API 元素顺序:doesSendEmailToMembers、name、queueSobject),并为其添加一个 QueueSobject,其值为 CONTEXT_OBJECT。如果采用的队列缺少绑定,则通过 Data API 以增量方式添加上下文对象。如果 QueueRoutingConfig 不存在,则创建它并绑定到队列(Group.QueueRoutingConfigId),然后重新查询以确认绑定已保存。

**成员(人工路由能力):**队列必须至少有一名处于 Active 状态的人工成员,否则升级处理会路由到空队列。此技能会统计可解析为 Active 状态 User 的 GroupMember 记录数。如果没有此类记录,且你传入了 QUEUE_MEMBER_USERNAMES(逗号分隔的用户名),此技能会先根据用户名格式验证每个用户名,解析出 Active 状态的 User 并 POST GroupMember,然后重新统计。如果队列仍然没有 Active 状态的人工成员,判定结果为 INCOMPLETE,并在 missing 中包含 queueHasActiveDirectUserMember(存在直接的 Active 用户是具备人工路由能力的必要条件,但并非充分条件;完整的 Omni 权限集和在线状态资格只能在运行时验证)。如果没有符合条件的成员,此技能还会跳过 QueueRoutingConfig 绑定和出站流激活,从而绝不会将空队列接入路由。需要进行更完善的成员协调时,请使用经批准的 Omni 配置工作流。

阶段 3 — 出站 QueueBased RoutingFlow

部署随附的出站流模板 assets/force-app/main/default/flows/Human_Escalation_Outbound_Flow.flow-meta.xml,替换流名称/标签、队列 DeveloperName 和服务通道令牌。此流会在运行时按 DeveloperName 查找队列(可移植,不硬编码 Id)。部署后,FlowDefinitionView.ActiveVersionId 必须为非 null。

阶段 4 — 升级主题 + 规划器出站路由(由文档驱动的编辑)

这两项编辑需要按组织发现主题/捆绑包,因此需显式编写(检索 → 编辑 → 部署),然后在传入主题/捆绑包 API 名称时由编排器验证。请遵循 references/escalation-mechanism.md:

  1. 检索升级主题(GenAiPlugin),设置 <canEscalate>true</canEscalate>,然后部署。
  2. 检索 Agent 的 GenAiPlannerBundle,在 Messaging 规划器界面上添加 outboundRouteConfigs(escalationMessage、outboundRouteName=<FLOW_DEVELOPER_NAME>、outboundRouteType=OmniChannelFlow),然后部署。验证器会在 Messaging 类界面中同一个区块内关联名称和类型(通过 scripts/extract-outbound-route.mjs)——如果捆绑包中的名称正确,但 OmniChannelFlow 类型位于无关区块中,则无法通过验证。
阶段 5 — 失败阈值指令(原生策略)

失败阈值和任何按主题覆盖的设置都是指令,而非强制执行的计数器——没有元数据字段会统计失败轮次(参见 references/failure-policy.md)。编排器不会将这些内容写入 Agent;它只会将 DEFAULT_FAILURE_THRESHOLD(默认值为 2)渲染到本地指令模板 assets/escalation-thresholds.instructions.md 中——例如,在三次尝试的场景中传入 DEFAULT_FAILURE_THRESHOLD=3——并将该值作为裁定证据记录在 threshold.default_failures 下(同时记录 threshold.directive_rendered)。将渲染后的指令编写到 Agent 的 Agent Script 中是一个手动/带外步骤;在验证器运行时设置 THRESHOLD_AUTHORED=1,即可记录 threshold.authored=true。该指令通过评估验证,而非通过无头运行时读取,因此不会阻止确定性裁定。

阶段 6 — 重新发布 + 重新激活

完成阶段 4/5 的编辑后,重新发布并重新激活 Agent,使更改生效。对于手动编辑路径,这些是手动操作员命令;编排器本身仅在可选的 AUTHOR_SURFACES=1 流程中发布/停用/重新激活 Agent(参见“运行”):

sf agent validate authoring-bundle --api-name "$AGENT_DN" --target-org "$ORG" --json
sf agent publish  authoring-bundle --api-name "$AGENT_DN" --target-org "$ORG" --json
sf agent activate --api-name "$AGENT_DN" --target-org "$ORG"
阶段 7 — 确定性验证(单一 JSON 裁定)

编排器会对每个确定性界面执行往返操作,组装证据对象,并通过 scripts/verify-escalation-config.mjs 将其归类为以下三种状态之一,确保缺失的升级策略不会被误认为已完全配置:

  • CONFIGURED — 所有确定性界面均已满足,并且失败阈值指令已编写。
  • ROUTING_CONFIGURED_POLICY_PENDING — 路由和 Agent 升级界面已验证,但失败阈值指令(thresholdAuthored)尚未确认。请编写该指令(AUTHOR_SURFACES=1 / THRESHOLD_AUTHORED=1)并重新运行,以达到 CONFIGURED 状态。
  • INCOMPLETE — 一个或多个确定性界面缺失(参见 missing[])。

请注意,NGA 升级界面检测(scripts/classify-nga-escalation.mjs)属于建议性预检——它会在创作捆绑包中匹配可到达的 @utils.escalate / 创建记录操作,但无法证明从主题到运行时的可达性。应将通过 NGA 界面检查视为强烈信号,而非端到端运行时证明;请通过阶段 8 的运行时步骤确认实际交接。

阶段 8 — 运行时 / 手动验证(不属于无头范围)

通过实时对话确认对话触发条件、AgentWork 创建情况以及同一会话中的上下文保留——参见 references/runtime-verification.md。


运行

bash scripts/verify-and-configure.sh <org-alias> \
  [<agent-developer-name>] [<queue-developer-name>] \
  [<escalation-topic-api-name>] [<planner-bundle-api-name>]
  • 位置参数 2–5 也会从环境变量读取(见输入表)。其他场景输入仅通过环境变量提供:FLOW_DEVELOPER_NAME、FLOW_LABEL、CONTEXT_OBJECT、SERVICE_CHANNEL_DEV_NAME、SERVICE_CHANNEL_LABEL、QUEUE_MEMBER_USERNAMES。
  • PLAN_ONLY=1 会预览(只读)并在任何写入操作前停止。
  • THRESHOLD_AUTHORED=1 会将指令策略标记为已编写,用于判定结果。
  • AUTHOR_SURFACES=1(可选,仅运行模式)——按照 agentforce-generate/references/known-issues.md(Issue 18)中的 Agentforce 生命周期,确定性地编写两个由文档驱动的表面,而非手动编辑 XML:发布(重新生成已编译的包)→ 以元数据格式检索 GenAiPlugin 主题和 GenAiPlannerBundle(使用 --target-metadata-dir … --unzip)→ 停用 Agent(Agent 处于活动状态时部署会失败)→ 应用具备架构感知、遵循 XSD 顺序、无损且幂等的补丁(scripts/patch-escalation-surfaces.mjs),设置 canEscalate=true(位于 aiPluginUtterances 之后、description 之前),并插入 outboundRouteConfigs(outboundRouteType=OmniChannelFlow,位于 Messaging 类规划器表面的 <surface> 之前,并指向出站流)→ 使用 --metadata-dir 部署 → 激活(失败时安全关闭;绝不会无提示地让 Agent 保持停用状态)→ 重新读取最新的 BotVersion,确保判定结果反映刚编写的版本。此操作需要主题和/或包的 API 名称,仅在通过成员资格门槛后运行(绝不会为没有成员的队列配置路由),如果找不到安全且符合 XSD 顺序的补丁位置,则会拒绝(阻止操作),而非猜测。省略此项即可让技能保持为仅验证模式。
  • 仅当你传入 <escalation-topic-api-name> / <planner-bundle-api-name> 时,才会验证 canEscalate 和 outboundRouteConfigs 表面(它们通过 Phase 4 中由文档驱动的编辑编写)。

典型的两轮流程:先运行一次以创建队列、出站流和前置条件;执行由文档驱动的 Phase 4/5/6 编辑;然后传入主题和包的 API 名称以及 THRESHOLD_AUTHORED=1 重新运行,以达到 CONFIGURED。

输出约定

向标准输出写入单个 JSON 对象:

{
  "skill": "service-agentforce-human-escalation-configure",
  "status": "CONFIGURED",
  "agent": { "developer_name": "Support_Agent", "active": true },
  "queue": { "developer_name": "Human_Support_Queue", "id": "00G...", "active_direct_user_member_count": 1 },
  "outbound_flow": { "api_name": "Human_Escalation_Outbound_Flow", "active_version_id": "301..." },
  "escalation_topic": "Escalate_To_Human",
  "planner_bundle": "Support_Agent",
  "config_verification": {
    "verdict": "CONFIGURED",
    "deterministicPass": true,
    "directivePass": true,
    "checks": [],
    "missing": []
  },
  "next_steps": [],
  "manual_actions": [],
  "blocking_issue": null
}
  • status:CONFIGURED(所有确定性表面均已满足)、INCOMPLETE(存在一些 config_verification.missing),或 BLOCKED(输入/身份验证/生产环境/前置条件有误;退出码为 1)。
  • 对已配置的组织重新运行时不会执行任何操作,并返回 CONFIGURED(幂等)。

幂等性

现有队列、QueueSobject、QueueRoutingConfig、队列成员以及已激活的出站流都会被重用,而不会重新创建(仅当队列没有活动成员且提供了 QUEUE_MEMBER_USERNAMES 时,才会添加成员;已存在的成员保持不变)。由文档驱动的编辑(canEscalate、outboundRouteConfigs)仅在缺失时设置。针对已完全配置的组织再次运行时,不会执行任何写入操作,并返回 CONFIGURED。

分类器约定

在调查或更改上文所述的任何确定性 Node 分类器(scripts/classify-agent-active.mjs、scripts/verify-escalation-config.mjs、scripts/extract-outbound-route.mjs、scripts/classify-nga-escalation.mjs)之前,请阅读 references/classifier-contracts.md,了解每个分类器精确的输入/输出约定。

验证

更改此技能或其脚本后,请运行打包的升级约定测试:

python3 scripts/tests/test_escalation_contracts.py

评论

支持 Markdown