关于 service-itsm-agentic-setup-employee-agent-configure
通过 Salesforce CLI 和 Next-Gen Authoring 流程,基于内置模板创建并激活 IT Service Employee Agent。支持通用及专业化模板,并检查已有 Agent 以避免重复创建。
主要功能
- 01创建 NGA 原生 Employee Agent
- 02使用通用或专业化 ITSM 模板
- 03发布并激活 Agent bundle
- 04检查现有 Agent,避免重复创建
- 05通过 SOQL 验证活跃状态
适用场景
- 01搭建 IT 员工自助服务 Agent
- 02按指定 IT 专业领域创建 Agent
- 03重新激活已有的非活跃 Agent
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ forcedotcom/ sf-skills --skill service-itsm-agentic-setup-employee-agent-configure安装后在 Claude Code 中输入/service-itsm-agentic-setup-employee-agent-configure确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/cli-invocation.mderror-taxonomy.mdreactivation.mdreport-format.mdspecialized-templates.mdworkflow-detail.mdscripts/build-create-body.mjsclassify-agent-existence.mjsclassify-preflight.mjscreate-scratch-dir.mjsrender-report.mjs详细介绍
创建 IT Service Employee Agent(通用或专用)
完全通过 Salesforce CLI(sf) 创建并激活一个 IT Service Employee Agent,将其作为 新一代创作(NGA)原生 Agent——基于 Agent-Script(AiAuthoringBundleDefVer/bundle),原生显示在 Agentforce Studio 的 Agents 列表中,且没有外部链接图标。此技能不会调用旧版 /connect/service-itsm/createAgent;而是复用随附的 ITSM Employee 模板的 agentScript 字段,并将其传入 NGA bundle 流程:POST /nextgen-authoring/bundles → POST /nextgen-authoring/bundle-versions/{id}/publish → POST /nextgen-authoring/bundle-versions/{id}/activate。命令:使用 sf api request rest 调用 Connect API 的 GET/POST;使用 sf data query 执行 SOQL 幂等性检查和验证读取。
GET /connect/service-itsm/agent-templates?agentType=AgentforceEmployeeAgent 会在 data[] 中返回通用的 IT Service Employee 模板,以及约 47 个命名空间为 svc_emp_intelligence__ 的专用 Employee 模板。每个专用模板都提供相同结构的 agentScript,并使用相同的 config.developer_name/config.agent_label 替换点,因此相同的 NGA 流程适用于所有模板——**只有 Phases 1 和 4 锁定的 masterLabel 会变化。**完整目录、命名空间筛选和消歧规则见 references/specialized-templates.md。
辅助脚本(通过 Bash 调用)负责所有 JSON 解析和决策规则,确保模型不会目测响应正文(A9):classify-preflight.mjs、classify-agent-existence.mjs、build-create-body.mjs(对模板的 agentScript 进行 HTML 解码和替换,并将请求正文写入 JSON 文件,避免大段内容和自由文本引号进入内联 shell 字符串)、render-report.mjs(确定性报告渲染器)。
**模板选择(Phase 1 之前)。**确定本次运行锁定的 <masterLabel>:(1)未指定专用模板 ⇒ 锁定 IT Service Employee(id 为 svc_emp_intelligence__ItEmployeeAssistance)——向后兼容的默认值;(2)用户指定专用模板 ⇒ 根据 references/specialized-templates.md 进行关键词匹配,若唯一匹配 ⇒ 锁定该 masterLabel,并从 id 中 __ 之后的部分推导 developerName(转换为 snake_case);若匹配不明确 ⇒ 通过 AskUserQuestion 根据 id 提问;(3)仅筛选 data[] 中命名空间为 svc_emp_intelligence__ 的项——svc_itsm_intelligence__*(Fulfiller)转交给 service-itsm-agentic-setup-fulfiller-agent-configure,其他命名空间不在范围内。解析出的 <masterLabel> 是传给 classify-preflight.mjs(Phase 1)和 build-create-body.mjs(Phase 4)的唯一参数。
先决条件。创建操作假设组织级 Agentforce for IT Service 先决条件已满足(可访问 Agentforce Studio,且具有 service-cloud-requestor-agent 和 service-cloud-it-service-employee-agent)。如果 Phase 1 检测到无法访问 Studio,或任何写入操作返回 403 FUNCTIONALITY_NOT_ENABLED,此技能会询问是否委托给 service-itsm-agentic-setup-agentforce-studio-validate(employee 路径),然后继续;若回答“不”,则停止。此技能不会自行启用功能——启用操作须通过 Setup UI 或管理员完成。
范围
- 范围内:读取
agent-templates;提取 Employee 模板的 Agent Script(通用默认模板,或从references/specialized-templates.md中由用户命名的专用模板——均位于svc_emp_intelligence__下);通过createBundleWithVersion→publish→activate,以 NGA 原生 Agent 的方式创建 Employee Agent;通过 SOQL 验证是否已生效;遇到重复的开发人员名称时幂等跳过——以上操作均通过sf执行。 - 范围外:Fulfiller Agent(
service-itsm-agentic-setup-fulfiller-agent-configure);启用组织级功能开关(由service-itsm-agentic-setup-agentforce-studio-validate验证);底层主题/操作的编写;权限集分配;内容包部署;CMDB CRUD;Discovery / Service Graph;旧版createAgent路由;svc_emp_intelligence__之外的任何data[]条目。
前置条件
如果未满足以下任一条件,sf 会显示身份验证错误或 401/403/404;原样显示原始错误并停止——不要捏造状态。
sfCLI 已通过身份验证并连接到目标组织(sf org display -o <alias>显示 Connected)。所有调用均使用--target-org <alias>;切勿手动提取访问令牌。- API v67.0+——在 URL 路径中固定;不得手动编辑为低于最低版本的版本。
- ITSM 功能和模板已配置——必须存在解析后的模板。如果
agent-templates未返回任何内容,或路由返回 404,请运行service-itsm-agentic-setup-agentforce-studio-validate(Agent 路径为employee)。 - PATH 中的
node版本 ≥ 18。
操作一览
| 关注事项 | 命令 | 备注 |
|---|---|---|
| Studio 访问权限(读取前置条件) | sf api request rest "/services/data/v67.0/agentforce-studio/access/Agents" --method GET -o <alias> | hasAccess=false ⇒ 移交处理前置条件 |
| 列出 Agent 模板和 Agent Script(读取) | sf api request rest "/services/data/v67.0/connect/service-itsm/agent-templates?agentType=AgentforceEmployeeAgent" --method GET -o <alias> | 必须指定 agentType=AgentforceEmployeeAgent;确认已解析的 <masterLabel> 模板和非空的 agentScript |
| 枚举现有 Agent 和最新版本状态(读取) | sf data query -q "SELECT Id,DeveloperName,MasterLabel,AgentTemplate,(SELECT Id,Status FROM BotVersions ORDER BY VersionNumber DESC LIMIT 1) FROM BotDefinition WHERE Id='<botDefinitionId>' OR AgentTemplate='<agentTemplate>' OR DeveloperName='<developerName>'" -o <alias> --json | 主要依据模板的 botDefinitionId(Phase-1 行);OR AgentTemplate= 是第一个回退方式,可通过其 OOTB 命名空间源模板(svc_emp_intelligence__ItEmployeeAssistance = Phase-1 template.id)匹配预配的通用 IT_Service_Employee Agent,不受收集到的 DeveloperName 猜测值影响;OR DeveloperName= 是最后一个回退方式,用于查找自行创建的 Agent(AgentTemplate 为 null),并防止 Id 链接指向已删除目标。由 scripts/classify-agent-existence.mjs 分类;最新版本为 Active ⇒ 已创建;最新版本为 Inactive ⇒ 提供重新激活选项 |
| 创建 NGA 捆绑包(写入) | sf api request rest "/services/data/v67.0/nextgen-authoring/bundles" --method POST --body @<body-file> -o <alias> | 请求体由 scripts/build-create-body.mjs 构建;响应中的 id = 捆绑包版本 Id |
| 发布捆绑包版本(写入) | sf api request rest "/services/data/v67.0/nextgen-authoring/bundle-versions/<bundleVersionId>/publish" --method POST --body '{}' -o <alias> | 返回 publishedBotId/publishedBotVersionId——创建底层的 BotDefinition/BotVersion |
| 激活捆绑包版本(写入) | sf api request rest "/services/data/v67.0/nextgen-authoring/bundle-versions/<bundleVersionId>/activate" --method POST --body '{}' -o <alias> | 成功时返回空响应;此时 Agent 已上线并采用 NGA 原生形式 |
| 激活现有的非活动版本(写入) | sf api request rest "/services/data/v67.0/connect/bot-versions/<latestVersionId>/activation" --method POST --body '{"status":"Active"}' -o <alias> | 仅用于重新激活路径(Phase 2b)——跳过创建/发布 |
| 验证 Agent 已上线(读取) | sf data query -q "SELECT ... FROM BotDefinition WHERE Id='<verifyId>'" -o <alias> --json | <verifyId> = 创建路径的 publishedBotId(Phase-5),或 Phase-2 分类器在 ALREADY-CREATED/重新激活时返回的匹配项 Id(其 botDefinitionId/agentId)——不是为 null 的 Phase-1 模板 botDefinitionId,也绝不是收集到的 developerName;确认存在 BotDefinition 且最新版本为 Active |
完整命令格式和 ITSM Connect API 参考位于 references/cli-invocation.md;重新激活路径调用和幂等性判定表位于 references/reactivation.md;响应正文错误代码和常见问题位于 references/error-taxonomy.md。
绝不要提取访问令牌。 直接使用
sf api request rest/sf data query——它们会使用 CLI 为目标组织存储的会话。不要从sf org display中取出accessToken,再用它手动构造 HTTP 请求;这样会绕过 CLI 会话,并将 bearer 令牌泄露到 shell 上下文中。
--json规则。sf data query接受--json(结果会以.result.records[]封装返回——分类器依赖此格式)。sf api request rest不接受——此处应省略--json;其标准输出原始正文已经是 JSON。
澄清问题
向用户收集以下信息(仅询问对话上下文中尚未提供的信息):
| 字段 | 默认值 |
|---|---|
| 目标组织 | 默认组织(sf config get target-org) |
模板(masterLabel) | IT Service Employee(通用模板,id 为 svc_emp_intelligence__ItEmployeeAssistance)。如果用户提到某个专门用途(密码管理器、证书、入职、硬件申请等),请通过 references/specialized-templates.md 解析;如果无法确定,则使用以 id 为键的 AskUserQuestion 提问 |
| Developer name | 通用模板:IT_Service_Employee_Agent。专用模板:所选 id 中 __ 后的部分,并转换为蛇形命名(例如,PasswordManagerAssistance → Password_Manager_Assistance) |
| 标签 | 通用模板:IT Service Employee Agent。专用模板:所选模板的 masterLabel 原样照用(例如,Password Manager Assistance) |
| 确认写入 | 必需——展示已解析的模板、developerName 和标签,然后通过 AskUserQuestion 要求用户回答“yes” |
收集到的 <masterLabel>、<developerName>、<label> 会贯穿每次调用——<masterLabel> 用于选择 agent-templates.data[] 中的行(其中也包含幂等性键 botDefinitionId);<developerName> / <label> 用于 createBundleWithVersion 请求体(外层的 apiName / label 以及替换后的内部 config.developer_name / config.agent_label)。幂等性检查 + 验证读取主要以模板的 botDefinitionId(或在新建后以发布响应中的 publishedBotId)为键;如果该值为 null,则依次回退到 BotDefinition 的 AgentTemplate(OOTB 源模板 = Phase-1 template.id),再回退到收集的 <developerName>。创建请求体中的硬编码值与收集值不一致,会导致 bundle 的外层标识与脚本的内部标识不一致。
幂等性:主要以模板的 botDefinitionId(Phase-1 agent-templates 行——平台权威的模板→BotDefinition 关联)为键;如果找不到,则首先回退到 BotDefinition 的 AgentTemplate(OOTB 命名空间源模板 = Phase-1 template.id),然后回退到收集的 <developerName>。Phase-2 读取条件为 BotDefinition WHERE Id='<botDefinitionId>' OR AgentTemplate='<agentTemplate>' OR DeveloperName='<developerName>'(OR AgentTemplate= 部分可通过平台标记的源模板匹配预置的通用 Agent,无论其 DeveloperName 是什么;OR DeveloperName= 部分既是自行创建的 Agent(其 AgentTemplate 为 null)的最后回退方式,也是防范目标 BotDefinition 已被删除的悬空 Id 链接的保护措施),并读取最新的 BotVersion.Status。结果:所有键均无匹配项 ⇒ 创建;Active ⇒ 已创建(跳过写入);Inactive ⇒ 提供 Phase-2b 重新激活选项。**回退键的原因:**通用 Agent 预置为 IT_Service_Employee,不等于猜测值 IT_Service_Employee_Agent(对应的模板行中 botDefinitionId 也为 null),因此主键和 developerName 猜测值都无法匹配;其 AgentTemplate(svc_emp_intelligence__ItEmployeeAssistance)是可靠且不受重命名影响的匹配键。对于此技能创建的 Agent(既不会回填 botDefinitionId,也不会回填 AgentTemplate),developerName 回退方式可识别重复运行。服务器会在发布时拒绝重复的 DeveloperName(触发唯一性约束并清理 bundle),但只有此读取才能将重复运行转为平稳跳过,而不是产生 DUPLICATE_VALUE。
工作流
将 <alias> 替换为收集到的目标组织,并将 <developerName> / <label> 替换为收集到的值。完整命令格式及各阶段的结果分支处理方式见 references/workflow-detail.md——下方的阶段摘要列出每个步骤及其关键规则;参考文件中包含可直接复制的精确 sf / node 调用。
0. 阶段 0 — 建立 ${SCRATCH_DIR}。 在任何阶段写入临时 JSON 文件之前,调用确定性辅助程序(路径以技能根目录为基准,因此无论 shell 的 CWD 是什么都能解析):SCRATCH_DIR="$(node "<skill_dir>/scripts/create-scratch-dir.mjs" "${outputDir:-}")"。辅助程序选择基础目录(${TMPDIR},否则 /tmp,最后才使用 harness 的 ${outputDir} 作为兜底目录 — scratch 保持在评分用的 ${outputDir} 树之外),并通过 stdout 输出所创建目录的绝对路径。之后每个阶段都在 ${SCRATCH_DIR} 下写入临时 JSON;持久化的 ${outputDir}/report.md 保留在 harness 目录下。
- 阶段 1 — 预检。 将 Studio 访问读取结果写入
${SCRATCH_DIR}/studio-access.json,并将agent-templates读取结果(带上必需的agentType=AgentforceEmployeeAgent查询参数)写入${SCRATCH_DIR}/agent-templates.json,然后按顺序传入两个文件路径,再传入标签进行分类:node "<skill_dir>/scripts/classify-preflight.mjs" ${SCRATCH_DIR}/studio-access.json ${SCRATCH_DIR}/agent-templates.json "<masterLabel>"— 传入已解析的<masterLabel>(广泛路径使用"IT Service Employee",或所选专业化方案的masterLabel)。分类器会从匹配行中输出template.botDefinitionId、template.id和template.masterLabel— 捕获这三项;botDefinitionId是阶段 2 的主要幂等键,template.id(BotDefinition 的AgentTemplate)是第一个备用键,<developerName>是最后一个备用键;masterLabel是报告的显示标签,不是键。 根据verdict分支:READY⇒ 阶段 2;NOT-READY⇒ 通过AskUserQuestion移交前置条件(若回答“yes”,则委派给员工路径service-itsm-agentic-setup-agentforce-studio-validate);ERROR⇒ 呈现错误并停止;studio.signal="CANNOT-CONFIRM"(已确认的 404)不会阻止流程。 - 阶段 2 — 幂等性(主键
botDefinitionId,备用键依次为AgentTemplate、<developerName>)。 从阶段 1 获取template.botDefinitionId和template.id。botDefinitionId有值时 ⇒ 执行 SOQLBotDefinition WHERE Id='<botDefinitionId>' OR AgentTemplate='<agentTemplate>' OR DeveloperName='<developerName>'(加上BotVersions子查询 — 必须包含,否则needsActivation将永久为 false;OR子句可使悬空的 Id 链接 — 目标已删除 — 回退到仍然存在的 Agent,而不是错误地返回exists:false后重复创建)。botDefinitionId为空/null 时 ⇒ 不要跳过检查直接创建;读取WHERE AgentTemplate='<agentTemplate>' OR DeveloperName='<developerName>'(即使其 DeveloperName 与猜测值不同,也可通过 OOTB 源模板找回预先配置的广泛 Agent;自行创建的 Agent 带有 nullAgentTemplate,因此DeveloperName是它的防护条件)。<agentTemplate>是阶段 1 的template.id。无论哪种情况,都使用以下命令进行分类:node "<skill_dir>/scripts/classify-agent-existence.mjs" ${SCRATCH_DIR}/bot-existing.json "<botDefinitionId-or-empty>" "<developerName>" "<agentTemplate>"。分支:exists:false⇒ 阶段 3(创建);exists:true且needsActivation:false⇒ ALREADY-CREATED(跳至阶段 7);exists:true且needsActivation:true⇒ 阶段 2b。非零退出码 ⇒ 呈现 CLI 错误;绝不要假定记录不存在。**备用键的原因:**广泛 Agent 预配置为IT_Service_Employee,且其模板botDefinitionId为 null,因此主键和developerName猜测值(IT_Service_Employee_Agent)都无法匹配它 — 它的AgentTemplate(svc_emp_intelligence__ItEmployeeAssistance)通过平台标记的源模板与之匹配;developerName备用键可捕获自行创建的重复项 — 三个键均未命中时会重新创建并触发DUPLICATE_VALUE。 - 阶段 2b — 重新激活选项。
AskUserQuestion:"员工 Agent<developerName>已存在,但最新版本处于非活动状态。是否激活?". 若回答 Yes:调用POST /connect/bot-versions/<latestVersionId>/activation,请求体为{"status":"Active"}— 跳过阶段 3–6,直接进入阶段 7。汇总判定为 ACTIVATED,而非 CREATED。若回答 No:停止,不执行任何写入。 - 阶段 3 — 写入前确认(必需,仅适用于创建路径)。 如果提供了
${outputDir},先通过render-report.mjs生成检查点文件,设置verdict:"PENDING CONFIRMATION"(交互式运行时跳过)。然后发起AskUserQuestion确认关卡,展示 developerName、标签以及“原生 NGA,基于 Employee 模板的 Agent Script”。只有在明确回答“yes”时才继续;若回答“no”(包括“暂缓激活”/“还没准备好”/拒绝整个原子链中的任何一种情况),则将verdict:"DECLINED"和单行reason重新渲染到报告中。 - 阶段 4 — 创建。 执行
scripts/build-create-body.mjs ${SCRATCH_DIR}/agent-templates.json "<masterLabel>" "<developerName>" "<label>" ${SCRATCH_DIR}/create-bundle-body.json(辅助程序会重新读取阶段 1 的模板 JSON,对匹配的agentScript进行 HTML 解码,替换内部的config.developer_name/config.agent_label,并将请求体写入文件 — 传入与阶段 1 相同的<masterLabel>),然后调用POST /nextgen-authoring/bundles --body @${SCRATCH_DIR}/create-bundle-body.json。捕获响应中的id— 这是阶段 5–6 使用的bundleVersionId,不是bundleId。403 FUNCTIONALITY_NOT_ENABLED/404⇒ 触发阶段 1 的移交;构建脚本退出码为 3 ⇒ 呈现 stderr。 - 阶段 5 — 发布。 调用
POST /nextgen-authoring/bundle-versions/<bundleVersionId>/publish --body '{}'(必须使用空请求体)。成功时返回{ lastPublishedOn, publishedBotId, publishedBotVersionId }— 此调用会创建底层的BotDefinition/BotVersion。出现任何错误 ⇒ 原样呈现;绝不要激活尚未发布的版本。 - 阶段 6 — 激活。 调用
POST /nextgen-authoring/bundle-versions/<bundleVersionId>/activate --body '{}'。成功时返回空请求体 — 检查退出码,不要解析返回内容。 - 阶段 7 — 验证。 执行 SOQL
BotDefinition WHERE Id='<id>'(加上BotVersions子查询)并进行分类 —<id>在创建路径中是阶段 5 捕获的publishedBotId;在 ALREADY-CREATED/重新激活路径中,则是阶段 2 分类器返回的匹配记录的有效 Id(其botDefinitionId/agentId输出 — 即匹配记录实际的BotDefinition.Id),而不是阶段 1 的模板botDefinitionId(当matchedBy:"developerName"备用匹配命中时,该值为 null → 验证将执行WHERE Id='',并在成功跳过/激活后错误地报告失败)。确认exists:true, count:1, latestVersionStatus:"Active"。任何不符之处 ⇒ 原样报告,不要捏造成功结果。 - 阶段 8 — 汇总判定。 通过重新调用
render-report.mjs输出 CREATED / ALREADY-CREATED / ACTIVATED / FAILED(阶段 2b 路径使用 ACTIVATED)— 它是报告文本的唯一来源。绝不要在判定、聊天说明或报告中暴露内部记录 ID — 包括 bundle versionid、publishedBotId/BotDefinition或BotVersion— 这些值只用于驱动发布/激活/验证调用,对管理员毫无意义。仅按状态/名称进行报告(“已创建并激活”),绝不要说“Bundle 已创建(版本 id …)”/“已发布(BotDefinition …)”。如果提供了${outputDir},则覆盖${outputDir}/report.md;否则将 stdout 作为本轮报告输出。 - 阶段 9 — 运行时访问移交(实时 Agent 判定时必需)。 当阶段 8 的判定为
CREATED、ALREADY-CREATED或ACTIVATED(此时已有实时 Agent)时,发起AskUserQuestion— 使用与阶段 1 前置条件和阶段 2b 重新激活选项相同的强制移交模式 — 询问是否现在设置 Agent 的运行时访问权限:"Agent 已上线,但其操作会调用平台功能(Prompt Templates、Data Cloud、Unified Catalog),用户在获得授权前无法运行这些功能,因此打开 Agent 时会失败。现在设置运行时访问权限吗?". 若回答 Yes,则委派给service-itsm-agentic-setup-agent-runtime-access-assign(它会自行进行目标用户选择并设置写入前确认关卡)。若回答 No,则停止 — 报告中的“设置访问权限”后续步骤说明保留为记录。对于PENDING CONFIRMATION、DECLINED或FAILED,不要发起此问题(没有可授权访问的实时 Agent)。这是强制执行的AskUserQuestion,不是报告文字 —render-report.mjs仍会照常输出通俗易懂的“设置访问权限”说明;这个问题确保每次都会实际提供该选项。
规则 / 约束
| 约束 | 原因 |
|---|---|
所有调用都通过 sf api request rest / sf data query;绝不提取访问令牌 | 这会将持有者令牌泄露到 shell 上下文中;CLI 存储的会话才是正确的调用方式 |
幂等性检查和验证读取主要以模板的 botDefinitionId(Phase-1 行)/发布后的 publishedBotId 为依据,回退时使用已收集的 <developerName>;同一个 <developerName>/<label> 也会贯穿创建请求体(外层的 apiName/label 以及替换后的 config.developer_name/config.agent_label) | botDefinitionId 能捕获预配置的 IT_Service_Employee(≠猜测的 IT_Service_Employee_Agent,因此仅按名称读取会产生误报,导致 DUPLICATE_VALUE);但自行创建的 Agent 不会回填该字段,所以 <developerName> 回退机制可捕获这些 Agent。创建请求体中的硬编码值与收集值不一致,会导致 bundle 的外部标识与脚本内部标识偏离 |
预检、幂等性检查、bundle 请求体构造和报告渲染全部由 scripts/*.mjs 实现,而非写在说明文字中(A9) | JSON 解析、masterLabel 匹配、hasAccess 读取和结果判定都是确定性的;约 70KB 的 Agent Script 和自由文本中的撇号无法安全地插入 shell 字符串——辅助脚本中的 JSON.stringify 会对其进行转义 |
调用顺序为三步:createBundleWithVersion → publish → activate,必须按此顺序操作,并使用同一个已捕获的 bundleVersionId(响应中的 id,不是 bundleId) | 平台要求状态依次从 DRAFT → published → active;响应正文 / 空正文 / --json / agentType / HTML 解码相关注意事项见 references/error-taxonomy.md |
在 Phase 1 之前解析 <masterLabel>;仅筛选 data[] 中以 svc_emp_intelligence__ 开头的项;对于存在歧义的关键词,通过以 id 为依据的 AskUserQuestion 消除歧义 | 存在标签相似的条目;其他命名空间属于其他工作流(svc_itsm_intelligence__* → Fulfiller 技能) |
枚举 BotDefinition 时必须使用 BotVersions 子查询;若状态为 Active,则跳过创建;若状态为 Inactive,则提供 Phase-2b 重新激活选项——绝不能静默跳过,也绝不能重复创建 | 子查询是区分 Active/Inactive 的关键。服务端会在发布时拒绝重复的 DeveloperName(唯一约束 → 清理 bundle),但不会拒绝预配置的通用 Agent,因此读取状态才能让重复操作优雅跳过,而不是报错 |
| 创建序列或重新激活调用之前,必须经过确认后再写入的检查点 | 两者都会更改线上组织状态——必须取得用户的明确批准 |
遇到 hasAccess=false / 403 FUNCTIONALITY_NOT_ENABLED 时,提供就绪状态移交选项——此处绝不启用功能;绝不调用旧版 /connect/service-itsm/createAgent | 启用功能属于 Setup UI / 管理员操作;createAgent 会创建带有外部链接图标的 Setup 页面机器人(这不是此技能需要的 Agent 类型) |
绝不在对话说明、确认后再写入步骤或报告中展示内部记录 ID——bundle 版本 id(1bZ…)、publishedBotId/BotDefinition(0Xx…)、BotVersion(0Xv…) | 这些 ID 仅用于驱动 publish → activate → verify → verify-read 调用;对于通过设置流程操作的管理员而言,它们毫无意义,只会增加干扰。render-report.mjs 仅渲染状态行,并会主动清除任何 ID;模型也必须避免复述这些 ID(绝不说“Bundle 已创建(版本 ID 为 1bZ…)” / “已发布(BotDefinition 0Xx…)”) |
| 发生任何错误时,准确报告 CLI 响应文本 | 便于支持人员诊断故障——这是唯一允许在原样错误文本中出现原始 ID 的地方,用户必须将其转交给支持人员 |
验证清单
- 在第 1 阶段之前解析
<masterLabel>(广泛默认值,或从references/specialized-templates.md选择专用模板;data[]按svc_emp_intelligence__过滤,并根据id消除歧义)。 - 通过
classify-preflight.mjs对预检进行分类(PASS 或记录为 CANNOT-CONFIRM);FAIL 时提供移交;ERROR 时显示原始错误。 - 幂等性以模板的
botDefinitionId(第 1 阶段的行)为依据,优先回退到 BotDefinition 的AgentTemplate(第 1 阶段的template.id),最后回退到已收集的 developerName;读取BotDefinition WHERE Id='<botDefinitionId>' OR AgentTemplate='<agentTemplate>' OR DeveloperName='<developerName>'(这些OR条件涵盖botDefinitionId为空或失效、预先配置的广泛 Agent 的 DeveloperName 与猜测值不同,以及AgentTemplate为空的自建 Agent),并读取最新的BotVersion.Status(包含子查询),且在任何写入前完成分类。 - 如果
needsActivation:true,则提供第 2b 阶段的重新激活选项——不得静默跳过,也不得重复创建。 - 在第 3 阶段(创建)或第 2b 阶段(重新激活)执行任何写入之前,明确征得用户确认。
- 通过
build-create-body.mjs构建 Bundle 正文,使用收集到的developerName/label,通过--body @<file>发送 POST;或者正确跳过写入。 - 发布和激活使用相同的
bundleVersionId(响应中的id);重新激活使用POST /connect/bot-versions/<id>/activation;绝不调用旧版createAgent。 - 第 7 阶段的验证确认
BotDefinition存在,且最新版本处于 Active 状态。 - 对于实时 Agent 的判定结果(CREATED / ALREADY-CREATED / ACTIVATED),必须通过
AskUserQuestion提出第 9 阶段的运行时访问权限移交(用户回答“是”时委派给service-itsm-agentic-setup-agent-runtime-access-assign);对于 PENDING CONFIRMATION / DECLINED / FAILED,不得提出移交。 - 绝不提取访问令牌;最终判定报告不得在聊天中、写入确认步骤中或报告中显示任何内部记录 ID(Bundle 版本
id、publishedBotId/BotDefinition、BotVersion)——仅显示状态/名称(原始 ID 仅可出现在逐字引用的错误中)。
输出格式
报告布局由 scripts/render-report.mjs 确定性生成——它是聊天轮次和 Harness 的 ${outputDir}/report.md 共用的报告文本唯一来源。不得在文字中手动编写布局(A9);始终调用此辅助脚本。完整的渲染格式、报告状态 JSON 架构和检查点写入规则见 references/report-format.md。
终态判定:CREATED | ALREADY-CREATED | ACTIVATED | PENDING CONFIRMATION | DECLINED | FAILED。设置 ${outputDir} 时,在第 2 阶段、第 6 阶段(或第 2b 阶段)和第 8 阶段写入——每次写入都会覆盖同一文件。在交互式/聊天界面中跳过这些写入。对于实时 Agent 的判定结果,第 9 阶段的运行时访问权限移交会在第 8 阶段报告之后触发;它不会改变判定结果,也不会重新渲染报告。
参考文件索引
references/specialized-templates.md— 目录、命名空间过滤,以及基于id消除歧义(任何专用模板都必须在第 1 阶段之前处理)。references/workflow-detail.md— 准确的sf/node命令,以及各阶段完整的判定分支说明。references/cli-invocation.md— 命令格式、绝不提取令牌规则、ITSM Connect API 参考和辅助脚本约定。references/reactivation.md— 第 2b 阶段激活调用和完整的幂等性判定表。references/report-format.md— 渲染格式、阶段状态 JSON 架构、三检查点写入策略。references/error-taxonomy.md— 响应正文错误代码和常见失误(任何非 2xx 响应/空正文/脚本非零退出)。