mcpField
S
service-itsm-agentic-setup-agentforce-studio-configure

service-itsm-agentic-setup-agentforce-studio-configure

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

关于 service-itsm-agentic-setup-agentforce-studio-configure

通过 Salesforce CLI 为 Fulfiller 或 Employee Agent 启用 Agentforce for IT Service 的前置功能。技能会检查当前状态,经明确确认后按依赖顺序启用,并验证结果。

主要功能

  1. 01启用 Salesforce Go 功能开关
  2. 02支持 Fulfiller 和 Employee 路径
  3. 03按依赖关系排序启用
  4. 04跳过已启用的开关
  5. 05写入前要求明确确认
  6. 06重新检查并报告各项结果

适用场景

  1. 01为创建 Fulfiller Agent 准备组织
  2. 02为创建 Employee Agent 准备组织

安装

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

$npx skills add https://github.com/forcedotcom/sf-skills --skill service-itsm-agentic-setup-agentforce-studio-configure

安装后在 Claude Code 中输入/service-itsm-agentic-setup-agentforce-studio-configure确认已加载。

包含的文件

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

references/
cli-invocation.md
scripts/
classify-enable-plan.mjs
classify-final-report.mjs
record-enable-result.mjs

详细介绍

启用 Agentforce for IT Service 的前提条件

完全通过 Salesforce CLI(sf) 启用 Agentforce for IT Service Salesforce Go 功能开关——Einstein Generative AI、Agentforce Studio、父级总开关以及特定路径的 Agent 模板(Fulfiller 或 Employee)。这些开关是创建 Fulfiller/Employee Agent 的前提条件;此可写入步骤通过 Setup Discovery POST /connect/setup/discovery/feature/{apiName}/enable Connect API 路由将其开启。每个开关都会以幂等方式启用(如果已为 ENABLED,则跳过),先启用依赖项,并且任何写入操作之前都需要明确确认。

步骤技能功能
1. 验证service-itsm-agentic-setup-agentforce-studio-validate读取开关 → READY / NOT-READY(不写入)
2. 配置(当前技能)service-itsm-agentic-setup-agentforce-studio-configure开启已禁用的开关
3. 创建 Agentservice-itsm-agentic-setup-fulfiller-agent-configure创建并激活 Fulfiller Agent

通常会从验证技能的 NOT-READY 报告转到此技能,但也可以直接运行。

辅助脚本 scripts/classify-enable-plan.mjs 会读取批量 /features/status 响应,并确定性地计算按依赖顺序排列的启用计划(写入之前)和每项功能最终的判定结果(写入之后)。这与验证技能的 classify-readiness.mjs 契约(编写标准 A9)一致:判定逻辑位于脚本中,而非说明文字中。

范围

  • 范围内:通过 POST .../feature/{apiName}/enable 启用 Einstein Generative AI(sales-cloud-einstein-generative-ai)、Agentforce Studio(sales-cloud-agent-studio)、父级总开关(service-cloud-agentforce-for-itsm)以及特定路径的模板(Fulfiller 使用 service-cloud-it-fulfiller-agent;Employee 使用 service-cloud-requestor-agent + service-cloud-it-service-employee-agent);在每次写入前后读取组织实时状态 /features/status;先启用依赖项;通过重新查询确认启用状态已生效;为每项功能显示 ENABLED / ALREADY-ENABLED / FAILED 判定结果。写入操作是幂等的——如果已为 ENABLED,则跳过。
  • 范围外:配置 Agentforce 许可证(Setup > Company Information > Permission Set Licenses);向用户分配权限集;创建、配置或激活 Agent(service-itsm-agentic-setup-fulfiller-agent-configure);不进行写入操作的只读前提条件验证(service-itsm-agentic-setup-agentforce-studio-validate);组织范围的多 Agent 编排开关(仅 Headless360 使用的偏好设置,不是 Connect 功能)。

选择哪条路径?

确定用户要启用的是 fulfiller Agent 还是 employee Agent 的前提条件。如果不明确,请询问(AskUserQuestion)——与验证技能使用相同的路径选择方式:

  • fulfiller → sales-cloud-einstein-generative-ai → sales-cloud-agent-studio → service-cloud-agentforce-for-itsm → service-cloud-it-fulfiller-agent
  • employee → sales-cloud-einstein-generative-ai → sales-cloud-agent-studio → service-cloud-agentforce-for-itsm → service-cloud-requestor-agent → service-cloud-it-service-employee-agent

Einstein Generative AI 是 Agentforce Studio 的依赖项,不是验证技能直接报告的开关之一,但如果尚未启用,则必须先启用——分类器会将其纳入两条路径的启用计划。


前提条件

与 validate 技能相同(两者使用相同的目标组织和 API 接口)。如果未满足,sf 会显示身份验证错误或 401/403/404;不要捏造状态——显示原始错误并停止。

  1. 已安装 sf CLI,并已通过身份验证连接到目标组织(sf org display -o <alias> 显示 Connected)。所有调用都使用 --target-org <alias>;绝不要手动提取或传递访问令牌。
  2. API v67.0+:connect/setup/discovery 功能 API 从 v67.0 起可用。版本固定在 URL 路径中;不要手动将其改为低于最低要求的版本。
  3. PATH 上的 node ≥ 18(用于运行分类脚本)。
  4. 组织拥有 Agentforce 许可证(accessCheck)——缺少许可证会显示为 403,或在读取结果中显示为 enableBlockedReasons。

操作一览

操作命令返回值
读取功能开关sf api request rest ".../connect/setup/discovery/features/status" --method POST --body '{"featureApiNames":[...]}' --target-org <alias>{items:[{apiName,status,enableBlockedReasons[],dependencyStatuses[]}]}
启用一个开关sf api request rest ".../connect/setup/discovery/feature/{apiName}/enable" --method POST --body '{}' --target-org <alias>{success:boolean} — 端点不需要有实际意义的请求体,但必须显式传入 --body '{}'(参见注意事项)

两者都是可通过 sf api request rest 访问的 Connect API 路由——无需 Headless360 分发器。完整命令格式、响应封装结构和错误分类见 references/cli-invocation.md。

绝不要提取访问令牌。 直接使用 sf api request rest——它会使用 CLI 中存储的目标组织会话。不要从 sf org display 中取出 accessToken,再用它手动构造 HTTP 请求。

重要:不要使用 IPCManagement updateOrgPref 来切换 Agent 偏好设置。 该控制器的写入允许列表会拒绝 Agent 偏好设置的 prefNames(Invalid prefName,500)。Setup Discovery 的 POST /feature/{apiName}/enable 端点是这些开关唯一正确的写入途径。


架构——启用流程的工作方式

步骤操作使用的工具
选择路径确定是 fulfiller 还是 employee(不明确时询问)AskUserQuestion
读取当前状态为该路径的开关提交 feature-status 批量请求,并保存到文件Bash(sf api request rest)
制定计划运行 scripts/classify-enable-plan.mjs <file> <agentType> [exitStatus] → 按依赖关系排序的 pending 列表Bash(node)
确认后写入展示准确的 pending 列表,并要求明确答复“yes”AskUserQuestion
启用对 order 中的每个 apiName,先重新读取并重新分类;未被阻止时提交 .../feature/{apiName}/enable 请求,并记录结果Bash(sf api request rest + node scripts/record-enable-result.mjs)
验证重新读取 /features/status,并再次运行分类器Bash(sf + node)
报告对 before/results/after 文件运行 scripts/classify-final-report.mjs → 得出最终结论Bash(node)

工作流

将 <alias> 替换为目标组织别名。<agentType> 为 fulfiller 或 employee。

阶段 1——读取当前状态
  1. 为所选路径需要的每个开关提交 feature-status 批量请求,并将标准输出捕获到文件中。不要添加 --json。将请求正文只写入一次临时文件,并在阶段 1、4 和 5 中通过 --body "$(cat ...)" 原样重复使用——不要重新输入、替换为 [...] 之类的占位符,也不要依赖 shell 变量,因为每次 Bash 调用都可能在全新的 shell 中运行,届时普通变量将会未定义:

    cat > /tmp/feature-status-body.json <<'EOF'
    {"featureApiNames":["sales-cloud-einstein-generative-ai","sales-cloud-agent-studio","service-cloud-agentforce-for-itsm","service-cloud-it-fulfiller-agent","service-cloud-requestor-agent","service-cloud-it-service-employee-agent"]}
    EOF
    
    sf api request rest "/services/data/v67.0/connect/setup/discovery/features/status" \
      --method POST \
      --body "$(cat /tmp/feature-status-body.json)" \
      --target-org <alias> > /tmp/enable-status-before.json 2>/tmp/enable-status-before.err
    echo $? > /tmp/enable-status-before.exit
    

    捕获退出状态——不要使用 || true 将其吞掉。

阶段 2 — 计划(辅助脚本)
  1. 对捕获的文件运行分类器,计算按依赖关系排序的启用计划,并保存其输出——阶段 6 使用此文件,而不是原始的 /features/status 响应:

    node "<skill_dir>/scripts/classify-enable-plan.mjs" /tmp/enable-status-before.json <agentType> "$(cat /tmp/enable-status-before.exit)" > /tmp/enable-plan-before.json
    

    它会打印 { agentType, readState, features, order, alreadyEnabled, pending, blocked, unconfirmed, verdict, reasons, rawError }。verdict: "ALL-ENABLED" 表示无需执行任何操作——跳到阶段 6。verdict: "NEEDS-ENABLE" 表示 pending(位于 order 中)列出了需要启用的项目。blocked 列出任何 pending 开关中 enableBlockedReasons 非空的项目,截至本次读取——如果某个开关仅因 order 中靠前的依赖项未启用而受阻,那么该依赖项启用后,这个开关就可以启用。因此,阶段 4 会在尝试每个开关前立即重新检查,而不会在整个循环中依赖这份快照。unconfirmed 列出响应中缺失或状态无法被此分类器识别的必需开关——当 unconfirmed 非空且 pending 为空时,verdict: "CANNOT-CONFIRM"(而非 "ALL-ENABLED")。readState: "error" ⇒ 显示 rawError 并停止;readState: "not-wired" ⇒ 报告 CANNOT-CONFIRM 并停止。

阶段 3 — 确认后再写入检查点(必需)
  1. 准确列出 pending 列表(排除 blocked 中的项目),并通过 AskUserQuestion 要求用户明确回答“是”后再继续。启用 org 偏好设置会修改 org 状态。**只有在用户明确回答“是”后才能进入阶段 4。**如果用户回答“否”,则停止并报告当前状态,不执行任何写入。
阶段 4 — 启用(先处理依赖项,每次切换前重新检查)
  1. 按顺序遍历 order(Einstein GenAI → Studio → 父项 → 子模板)。尝试启用每个 <apiName> 前,都要重新读取并重新分类——这样,阶段 2 中曾因 Studio/父项尚未启用而 blocked 的子项,就能在相应依赖项启用后变为可启用,而不会因为阶段 2 的快照而被永久放弃:

    sf api request rest "/services/data/v67.0/connect/setup/discovery/features/status" \
      --method POST \
      --body "$(cat /tmp/feature-status-body.json)" \
      --target-org <alias> > /tmp/enable-status-loop.json 2>/tmp/enable-status-loop.err
    echo $? > /tmp/enable-status-loop.exit
    node "<skill_dir>/scripts/classify-enable-plan.mjs" /tmp/enable-status-loop.json <agentType> "$(cat /tmp/enable-status-loop.exit)"
    

    检查该输出中 features["<apiName>"].signal 的值:

    • PASS → 已经是 ENABLED;无需操作,继续处理 order 中下一个 apiName。

    • FAIL 且 enableBlockedReasons 为空 → 现在启用:

      sf api request rest "/services/data/v67.0/connect/setup/discovery/feature/<apiName>/enable" \
        --method POST \
        --body '{}' \
        --target-org <alias> > /tmp/enable-<apiName>.json 2>/tmp/enable-<apiName>.err
      node "<skill_dir>/scripts/record-enable-result.mjs" /tmp/enable-<apiName>.json <apiName> /tmp/enable-results.json
      

      /enable 端点本身不需要有意义的请求正文,但使用 sf api request rest --method POST 且完全不传 --body 标志会失败,并报错 Error (SfError): No 'mode' found in 'body' entry——务必显式传入 --body '{}'。record-enable-result.mjs 会读取响应,将其分类为 ENABLED/FAILED,并按 apiName 键将结果累积到 /tmp/enable-results.json 中——这是阶段 6 使用的确定性逐开关记录。

    • FAIL 且 enableBlockedReasons 非空 → 即使经过本轮重新检查,仍然受阻(这是实际阻碍,而非仅由顺序造成的阻碍,例如未获许可)——不要发送 POST;继续处理 order 中下一个 apiName,并让阶段 6 原样报告阻碍原因。

    • 对此 apiName 的读取结果为 CANNOT-CONFIRM / ERROR → 停止循环并显示读取失败;不要猜测剩余开关的状态。

    某个开关启用失败,不会阻止计划中的其他项目——继续循环。

阶段 5 — 验证启用状态
  1. 重新运行阶段 1 的读取(使用相同的 /tmp/feature-status-body.json),将结果写入新文件,并对其重新运行分类器,将输出保存供阶段 6 使用:

    sf api request rest "/services/data/v67.0/connect/setup/discovery/features/status" \
      --method POST \
      --body "$(cat /tmp/feature-status-body.json)" \
      --target-org <alias> > /tmp/enable-status-after.json 2>/tmp/enable-status-after.err
    echo $? > /tmp/enable-status-after.exit
    node "<skill_dir>/scripts/classify-enable-plan.mjs" /tmp/enable-status-after.json <agentType> "$(cat /tmp/enable-status-after.exit)" > /tmp/enable-plan-after.json
    

    verdict: "ALL-ENABLED" ⇒ order 中的每个开关都已确认是 ENABLED——成功。仍在 pending/blocked/unconfirmed 中的项目,需要阶段 6 准确分类(FAILED 与 CANNOT-CONFIRM)。

阶段 6 — 汇总判定(辅助脚本)
  1. 对阶段 2 分类器的输出(/tmp/enable-plan-before.json,而非原始的 /features/status 响应)、阶段 4 的累计结果(如果阶段 2 已为 ALL-ENABLED/CANNOT-CONFIRM/ERROR,且阶段 4 从未运行,则使用 -),以及阶段 5 分类器的输出(/tmp/enable-plan-after.json)运行最终汇总器:

    node "<skill_dir>/scripts/classify-final-report.mjs" /tmp/enable-plan-before.json /tmp/enable-results.json /tmp/enable-plan-after.json
    

    它会输出 { features: { <apiName>: { finalStatus, reason } }, order, overall, reasons },其中 finalStatus 为 ALREADY-ENABLED | ENABLED | FAILED | CANNOT-CONFIRM | ERROR,overall 为 SUCCESS | PARTIAL | FAILED | CANNOT-CONFIRM | ERROR。将其直接填入输出格式 — 不要在说明文字中重新推导各功能的判定结果或整体摘要(编写标准 A9)。当 overall: "SUCCESS" 时,引导用户前往 service-itsm-agentic-setup-fulfiller-agent-configure(fulfiller)或 service-itsm-agentic-setup-employee-agent-configure(employee)继续操作。


规则 / 约束

约束原因
仅通过 POST /connect/setup/discovery/feature/{apiName}/enable 启用IPCManagement 的 updateOrgPref 写入允许列表会拒绝 Agent prefNames(Invalid prefName)——这是唯一正确的写入路径
通过 POST /features/status 读取每项功能的实时状态,绝不使用扁平目录列表只有 /status 包含每个组织的 ENABLED/NOT_ENABLED、enableBlockedReasons[] 和 dependencyStatuses[]
按分类器的 order 先启用依赖项,再启用子项在 Einstein GenAI / Studio 之前启用子项会触发未满足的依赖项阻止原因
在阶段 4 循环中,每次切换前都要立即重新读取并分类,而不是在循环开始时只读取一次如果某个子项仅因先前某个依赖项尚未启用而处于 blocked 状态,那么该依赖项自己的 /enable 请求一旦生效,子项便可立即启用 — 如果只使用阶段 2 的单次快照,就会将其报告为 FAILED,尽管它实际上从未真正被阻止
幂等:跳过任何已处于 ENABLED 状态的项目的 /enable 请求分类器的 alreadyEnabled 列表具有权威性;启用已启用的功能虽会返回 {success:true},但属于多余操作
执行任何 /enable POST 之前,必须经过必需的写入确认检查点启用组织偏好设置会修改组织状态;用户必须明确批准准确的 pending 列表
绝不要尝试启用当前 enableBlockedReasons(重新检查后)非空的切换项非空的 enableBlockedReasons 表示写入会失败——应报告阻止原因,而不是发送注定失败的 POST
如果 unconfirmed 非空,即使 pending 为空,也使用 verdict: "CANNOT-CONFIRM"缺少必需切换项的响应,或状态无法识别时,不得仅因 pending 中没有剩余项目就报告为 ALL-ENABLED
分类和各切换项结果的记录由 scripts/classify-enable-plan.mjs、scripts/record-enable-result.mjs 和 scripts/classify-final-report.mjs 负责,并通过 Bash 调用 — 不得在说明文字中完成对固定功能状态使用确定性的决策表和汇总(编写标准 A9)
读写通过 sf api request rest 进行;绝不提取访问令牌sf api request rest 使用 CLI 中存储的 --target-org 会话
不要向 sf api request rest 传递 --json某些 Connect 端点不支持此参数;原始标准输出内容本身已是 JSON
这些是 Connect API 功能 — 使用 SF CLI,而非 Headless360存在对应的 Connect/Tooling 接口,因此优先使用 SF CLI(可避开 Headless360HostedMcpServer 的组织权限门控)

常见问题

问题解决方法
使用 sf api request rest --method POST,但不带 --body 标志时,会报错 No 'mode' found in 'body' entry/enable 端点本身不需要有意义的请求体,但 CLI 仍然要求提供该标志——请始终显式传入 --body '{}'(已在 CLI 2.140.6 和 2.145.6 上验证)
组织中无法使用某个功能 API 名称,或未获得该功能的许可没有可枚举有效名称的目录端点——Phase-1 的 /features/status 读取会通过 enableBlockedReasons[] 显示无法使用或未获许可的功能,无需尝试启用
/features/status 显示 NOT_ENABLED,且 dependencyStatuses[] 中有未满足的依赖项先启用列出的依赖项(先启用 Einstein GenAI,再启用 Studio;先启用 Studio,再启用父级/子级开关)
updateOrgPref → 500 Invalid prefName,针对的是 Agent 偏好设置写入路径错误——请改用 Setup Discovery 的 feature/{apiName}/enable 端点
sf api request rest 出现身份验证错误目标组织的会话需要重新进行身份验证(sf org login web)
将身份验证/权限/空请求体导致的读取失败视为“未接入”将捕获的 $? 作为分类器的第 3 个参数传入——只有确认的 404 才是 CANNOT-CONFIRM;其他情况都是 ERROR(显示 rawError 并停止)
因为 pending 为空而报告 ALL-ENABLED还要检查 unconfirmed——响应中缺少必需的开关,或其状态无法识别,都不代表已确认 ENABLED 或 NOT_ENABLED
根据前后 JSON 用文字重新推导每项功能/整体结论运行 scripts/classify-final-report.mjs——汇总逻辑是固定的比较逻辑(编写标准 A9),不是主观判断
在 Phase 1 中将功能状态请求体设为 shell 变量,并期望它在 Phase 4/5 中仍然存在每次 Bash 调用都可能在全新的 shell 中运行,变量会被取消设置,导致静默发送空请求体——请将其保存到 /tmp/feature-status-body.json 一次,并在每个阶段通过 --body "$(cat /tmp/feature-status-body.json)" 读取

验证清单

  • 已确定 Agent 路径(服务提供者/员工);如不明确,已询问用户。
  • Phase 1 已通过 sf api request rest 读取 /features/status,保存到文件,并捕获其退出状态。
  • 在进行任何写入之前,scripts/classify-enable-plan.mjs 已计算出 pending(按依赖项排序)、blocked 和 unconfirmed 列表。
  • 在 Phase-3 检查点,用户已明确确认准确的 pending 列表,然后才发送任何 /enable POST 请求。
  • Phase 4 在每个开关之前重新读取并重新分类,而不是对整个循环只执行一次——因此,较早启用依赖项后解除阻止的子项仍会尝试启用。
  • 每个已尝试的 /enable POST 请求的响应均通过 scripts/record-enable-result.mjs 记录,并在整个循环中累积。
  • 启用后已重新读取 /features/status,并重新运行分类器,以确认每项功能的最终结论。
  • scripts/classify-final-report.mjs(而非文字说明)已根据启用前/结果/启用后的文件计算每项功能的状态和整体摘要;从未提取访问令牌。

输出格式

以实时 Markdown 的形式输出报告——绝不可放在代码围栏内(围栏表格会显示原始 | 竖线,而不是表格)。这是阶段 1(基础),阶段 2(安装并激活 Agent)将在此基础上进行;每项状态只能是 ENABLED / ALREADY-ENABLED / FAILED / CANNOT-CONFIRM。请严格按以下格式排版:

Agentforce for IT Service — 阶段 1:启用平台功能(通过 service-itsm-agentic-setup-agentforce-studio-configure)

  • 组织: <org-alias>(API v67.0)
  • Agent 路径: fulfiller | employee
#平台功能状态
1Einstein Generative AI<status>
2Agentforce Studio<status>
3Agentforce for IT Service<status>
4<path-specific toggle(s)><status>

结论: SUCCESS | PARTIAL | FAILED | CANNOT-CONFIRM | ERROR

后续步骤:

  • 如果为 SUCCESS:"阶段 1(基础)已完成——继续阶段 2:通过 service-itsm-agentic-setup-fulfiller-agent-configure(fulfiller)/员工 Agent 技能安装并激活 <path> Agent。"
  • 如果为 PARTIAL/FAILED/CANNOT-CONFIRM/ERROR:列出受影响的开关及原因(enableBlockedReasons、状态未确认或读取错误),并给出修复步骤

将 scripts/classify-final-report.mjs 中的 overall 和每项功能的 finalStatus 原样填入 <status> 单元格——不要重新计算。除分类器的临时响应捕获文件外,不会生成其他文件。

行标签必须与分类器输出完全一致——绝不可添加 Requestor、Specialized 或 parent。


参考文件索引

文件何时读取
references/cli-invocation.md每个阶段——sf api request rest 读写调用的确切格式、响应封装、功能 API 名称、分类器约定及错误分类

评论

支持 Markdown