mcpField
A
agentforce-observe

agentforce-observe

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

关于 agentforce-observe

面向 Salesforce Agentforce 的技能,用于分析 Agent 会话、通过预览复现问题并改进 `.agent` 文件。可查询 Data Cloud 会话追踪;STDM 不可用时则使用本地测试和追踪作为替代。

主要功能

  1. 01分析 STDM 会话指标与对话
  2. 02使用测试套件和本地追踪作为替代
  3. 03通过 `sf agent preview` 复现对话
  4. 04编辑、验证并发布 `.agent` 文件
  5. 05管理 Agent Health Monitoring 警报

适用场景

  1. 01查找会话中的路由或工具调用问题
  2. 02在预览中复现有问题的对话
  3. 03STDM 不可用时检查本地追踪
  4. 04创建或查看 Agent 监控警报

安装

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

$npx skills add https://github.com/forcedotcom/sf-skills --skill agentforce-observe

安装后在 Claude Code 中输入/agentforce-observe确认已加载。

包含的文件

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

assets/apex/
AgentforceOptimizeService.cls
AgentforceOptimizeService.cls-meta.xml
references/
ahm-alerts.md
improve-reference.md
issue-classification.md
reproduce-reference.md
stdm-queries.md
stdm-schema.md

详细介绍

Agentforce 可观测性

使用会话跟踪数据和实时预览测试来改进 Agentforce Agent。

三阶段工作流:

  • 观察——从 Data Cloud 查询 STDM 会话(如果可用),或在无法使用时运行测试套件并通过本地跟踪进行预览
  • 复现——使用 sf agent preview 实时模拟有问题的对话
  • 改进——直接编辑 .agent 文件,验证、发布并确认

平台说明

  • 以下 Shell 示例使用 bash 语法。在 Windows 上,使用 PowerShell 等效命令或 Git Bash。
  • 在 Windows 上,将 python3 替换为 python。
  • 将 /tmp/ 替换为 $env:TEMP\(PowerShell)或 %TEMP%(cmd)。
  • 如果未安装 jq,请将 jq 替换为 python -c "import json,sys; ..."。

路由

开始前收集以下信息:

  • Org 别名(必需)——必须已通过身份验证(否则运行 sf org login web)
  • Agent API 名称(预览和部署必需;如果未提供,请询问)
  • Agent 文件路径(可选)——.agent 文件的路径,通常为 force-app/main/default/aiAuthoringBundles/<AgentName>/<AgentName>.agent。如果未提供,则自动检测。
  • 会话 ID(可选)——分析指定会话;如果未提供,则查询最近 7 天的数据
  • 回溯天数(可选,默认值为 7)
  • 提醒负责人用户(可选,仅适用于提醒)——要列出/管理其提醒的用户;默认为当前用户

根据用户输入确定意图:

  • 未指定具体操作 -> 运行全部三个分析阶段:观察 -> 找出问题 -> 询问用户是否要复现和/或改进
  • “analyze” / “sessions” / “what's wrong” -> 仅运行第 1 阶段,然后建议后续步骤
  • “reproduce” / “test” / “preview” -> 运行第 2 阶段(如果尚未掌握问题,先运行第 1 阶段)
  • “fix” / “improve” / “update” -> 运行第 3 阶段(如果尚未掌握问题,先运行第 1 阶段)
  • “create alert” / “set up monitoring” / “alert me when” -> AHM(创建)
  • “list alerts” / “show my alerts” / “update alert” / “delete alert” -> AHM(列出 / 通过 PUT 更新 / 删除)
  • “get / list notifications” / “notifications for a specific alert” / “have my alerts fired” / “why isn't my alert firing” -> AHM:使用标头 X-UNS-Type-Filter: all 获取通知,并报告状态及列表;对于指定提醒,根据 targetPageRef.state.c__alertId 进行筛选(兼容 15/18 位 ID),而非使用 metricId(另加 Incidents 视图和指标验证)
解析 Agent 名称

在执行任何 STDM 查询之前,根据 Org 解析用户提供的 Agent 名称,以获取准确的 MasterLabel 和 DeveloperName:

sf data query --json \
  --query "SELECT Id, MasterLabel, DeveloperName FROM GenAiPlannerDefinition WHERE MasterLabel LIKE '%<user-provided-name>%' OR DeveloperName LIKE '%<user-provided-name>%'" \
  -o <org>
  • MasterLabel = STDM findSessions 和 Agent Builder UI 使用的显示名称(例如“Order Service”)
  • DeveloperName = 元数据中带版本后缀的 API 名称(例如“OrderService_v9”)
  • sf agent preview/activate/publish 的 --api-name 标志使用不带 _vN 后缀的 DeveloperName(例如“OrderService”)

保存以下值:

  • AGENT_MASTER_LABEL ——用于 findSessions() Agent 筛选
  • AGENT_API_NAME ——不带 _vN 后缀的 DeveloperName,用于 sf agent CLI 命令
  • PLANNER_ID ——此 Agent 的 Salesforce 记录 ID
定位 .agent 文件

第 1 步——在本地搜索:

find <project-root>/force-app/main/default/aiAuthoringBundles -name "*.agent" 2>/dev/null

如果用户提供了 Agent 文件路径,则直接使用该路径。否则,搜索与 AGENT_API_NAME 匹配的文件。

第 2 步——如果本地未找到,则从 Org 检索:

sf project retrieve start --json --metadata "AiAuthoringBundle:<AGENT_API_NAME>" -o <org>

已知错误:sf project retrieve start 会创建双重嵌套路径:force-app/main/default/main/default/aiAuthoringBundles/...。检索完成后立即修正:

if [ -d "force-app/main/default/main/default/aiAuthoringBundles" ]; then
  mkdir -p force-app/main/default/aiAuthoringBundles
  cp -r force-app/main/default/main/default/aiAuthoringBundles/* \
    force-app/main/default/aiAuthoringBundles/
  rm -rf force-app/main/default/main
fi

第 3 步——验证检索到的文件:

读取 .agent 文件,并确认其具有正确的 Agent Script 结构:

  • 包含 instructions: 的 system: 块
  • 包含 developer_name: 的 config: 块
  • 包含 reasoning: instructions: 的 start_agent 或 subagent 块
  • 每个子 Agent 都应有不同的 instructions: 内容(各子 Agent 的内容不能相同)

将解析后的路径保存为 AGENT_FILE,供第 3 阶段使用。


阶段 0:发现数据空间

运行任何 STDM 查询之前,先确定正确的 Data Cloud 数据空间 API 名称。

sf api request rest "/services/data/v63.0/ssot/data-spaces" -o <org>

注意:sf api request rest 是 Beta 命令——不要添加 --json(不支持该标志,添加后会导致错误)。

响应格式如下:

{
  "dataSpaces": [
    {
      "id": "0vhKh000000g3DjIAI",
      "label": "default",
      "name": "default",
      "status": "Active",
      "description": "Your org's default data space."
    }
  ],
  "totalSize": 1
}

name 字段是要传递给 AgentforceOptimizeService 的 API 名称。

决策逻辑:

  • 如果命令失败(例如 404 或权限错误),则回退到 'default',并注明这是一个假设。
  • 仅筛选 status: "Active" 的条目。
  • 如果恰好存在一个 Active 数据空间,则自动使用它,并向用户确认:“正在使用数据空间:<name>”。
  • 如果存在多个 Active 数据空间,则显示列表(标签 + 名称),并询问用户要使用哪一个。

将选定的 name 值保存为 DATA_SPACE,供后续所有步骤使用。

前置条件检查:STDM DMO

部署辅助类(步骤 1.0)后,运行快速探测,确认 Data Cloud 中存在 STDM 数据模型对象:

sf apex run -o <org> -f /dev/stdin << 'APEX'
ConnectApi.CdpQueryInput qi = new ConnectApi.CdpQueryInput();
qi.sql = 'SELECT ssot__Id__c FROM "ssot__AiAgentSession__dlm" LIMIT 1';
try {
    ConnectApi.CdpQueryOutputV2 out = ConnectApi.CdpQuery.queryAnsiSqlV2(qi, '<DATA_SPACE>');
    System.debug('STDM_CHECK:OK rows=' + (out.data != null ? out.data.size() : 0));
} catch (Exception e) {
    System.debug('STDM_CHECK:FAIL ' + e.getMessage());
}
APEX

如果 STDM_CHECK:FAIL: STDM 尚未激活。告知用户并切换到 阶段 1-ALT:

此组织中没有 STDM(Session Trace Data Model)。启用方法:Setup -> Data Cloud -> Data Streams,并确认“Agentforce Activity”处于活动状态。继续使用回退方案:测试套件 + 本地跟踪数据。

如果 STDM_CHECK:OK,则继续执行阶段 1(STDM 路径)。


阶段 1-ALT:在没有 STDM 的情况下观察(回退路径)

STDM 不可用时,使用测试套件和 sf agent preview --authoring-bundle 进行本地跟踪分析。

数据源使用时机优点缺点
STDM(阶段 1)历史生产环境分析真实用户数据、数据量大需要 Data Cloud,延迟 15 分钟
测试套件 + 本地跟踪数据(阶段 1-ALT)开发迭代、没有 STDM 的组织即时、包含完整 LLM 提示词、变量状态仅预览,不含真实用户数据
1-ALT.1 运行现有测试套件(如果有)
sf agent test list --json -o <org>
sf agent test run --json --api-name <TestSuiteName> --wait 10 --result-format json -o <org> | tee /tmp/test_run.json
JOB_ID=$(python3 -c "import json; print(json.load(open('/tmp/test_run.json'))['result']['runId'])")
sf agent test results --json --job-id "$JOB_ID" --result-format json -o <org>
1-ALT.2 从 .agent 文件推导测试话语(如果没有测试套件)

如果不存在测试套件,则推导测试话语:每个非入口子 Agent 一个(根据 description: 关键词),每个关键操作一个,一个护栏测试,以及一个多轮测试。

1-ALT.3 使用 --authoring-bundle 预览(本地跟踪数据)

通过预览运行每条测试话语,以生成本地跟踪文件:

sf agent preview start --json --authoring-bundle <BundleName> --simulate-actions -o <org> | tee /tmp/preview_start.json
SESSION_ID=$(python3 -c "import json; print(json.load(open('/tmp/preview_start.json'))['result']['sessionId'])")

sf agent preview send --json --session-id "$SESSION_ID" --authoring-bundle <BundleName> \
  --utterance "$UTT" -o <org> | tee /tmp/preview_response.json

sf agent preview end --json --session-id "$SESSION_ID" --authoring-bundle <BundleName> -o <org>

跟踪文件位置: .sfdx/agents/{BundleName}/sessions/{sessionId}/traces/{planId}.json

1-ALT.4 本地跟踪诊断
问题类型跟踪命令
子 Agent 路由错误jq -r '.plan[] | select(.type=="NodeEntryStateStep") | .data.agent_name' "$TRACE"
未调用操作jq -r '.plan[] | select(.type=="EnabledToolsStep") | .data.enabled_tools[]' "$TRACE"
遵循度低jq -r '.plan[] | select(.type=="ReasoningStep") | {category, reason}' "$TRACE"
变量捕获失败jq -r '.plan[] | select(.type=="VariableUpdateStep") | .data.variable_updates[]' "$TRACE"
指令含糊jq -r '.plan[] | select(.type=="LLMStep") | .data.messages_sent[0].content' "$TRACE"

DefaultTopic 跟踪数据的特殊情况: 使用 --authoring-bundle 时,即使路由正常,根级 .topic 字段通常也会显示 "DefaultTopic"。应始终使用 NodeEntryStateStep.data.agent_name 获取真实的子 Agent 调用链。

入口 Agent 直接作答(SMALL_TALK 模式): 如果 start_agent 跟踪数据显示 SMALL_TALK grounding,且转换工具可见但均未调用,则在 start_agent 指令中添加“你只是一个路由器。不要直接回答问题。”

1-ALT.5 分类并呈现

使用 references/issue-classification.md 中的类别对问题进行分类。呈现发现结果后,自动继续进行 Agent 配置证据分析。


阶段 1:观察——查询 STDM

有关 STDM 查询详情、Apex 服务部署和响应解析,请参阅 references/stdm-queries.md

1.0 部署辅助类(每个组织一次)

将 AgentforceOptimizeService Apex 类部署到组织中。先检查是否已部署:

sf data query --json --query "SELECT Id, Name FROM ApexClass WHERE Name = 'AgentforceOptimizeService'" -o <org>

如果尚未部署,请从技能目录复制并部署。完整步骤请参阅 references/stdm-queries.md。

1.1 查找会话

使用 findSessions() 查询近期会话。从 Apex 调试日志中解析 DEBUG|STDM_RESULT:。如果 findSessions 返回空结果,请切换到阶段 1-ALT。

1.2 获取对话详情

使用 getMultipleConversationDetails() 获取最多 5 个会话(按时间从近到远)。返回按轮次排列的数据,包含消息、步骤、主题和操作结果。

1.2b 获取 LLM 提示词/响应(可选)

检测到 LOW adherence 时,使用 getLlmStepDetails() 获取实际的 LLM 提示词和响应。

1.2c 获取聚合指标(建议的第一步)

使用 getAggregatedMetrics() 获取高级健康状况仪表板:会话率、热门意图、质量分布、RAG 平均值。

1.2d 获取时刻洞察(单会话详情)

使用 getMomentInsights() 获取每个会话的意图摘要、质量评分(1-5)和检索器指标。

1.2e 运行可观测性查询(RAG 深入分析)

使用 runObservabilityQuery() 进行针对性的 RAG 分析:KnowledgeGap、Hallucination、RetrievalQuality、AnswerRelevancy、Leaderboard。

1.3 重建对话

根据每个会话的 ConversationData JSON,按轮次呈现时间线。

1.4 识别问题

完整的问题模式表和分类类别:请参阅 references/issue-classification.md

检查每个会话是否存在:操作错误、子 Agent 路由错误、缺少操作、输入错误、变量捕获失败、没有转换、操作缓慢、LOW adherence、会话中止、无效子 Agent、发布偏差、无效中心反模式、入口直接作答以及安全问题。

语音 Agent(包含 modality voice: 块): 还需检查以下内容:

  • 响应冗长 — 标记任何超过 3 句话的 Agent 响应(语音 UX 反模式;也是静默/提示计时器的触发条件)
  • 响应中的视觉格式 — 语音无法呈现的列表、链接、Markdown
  • 缺少确认模式 — 修改数据的操作未复述关键细节
  • 缺少语音接线 — 语音 Agent 缺少关联的 VoiceCallId 变量(@VoiceCall.Id)或 connection customer_web_client: 块,或者有人添加了不存在的 connection voice: 块
  • 延迟反模式 — 对照 /agentforce-generate references/voice-latency-heuristics.md 中经过实地验证的模式,交叉检查跟踪步骤耗时:实时通话路径上的同步写入、将大量检索结果原样返回给推理 LLM、串联的外部调用、过度拆分的子 Agent 路由,以及没有确认短语的缓慢操作。延迟修复仅标记,除非属于纯指导性内容(确认短语、轮次长度、口语形式规则)。
  • TTS 乱码/缺少口语形式规则 — 操作输出或响应中出现价格、电话号码或 ID,但未提供口语形式指令规则。

优先级:P1 = 操作错误、路由错误、LOW adherence;P2 = 缺少操作、变量错误、知识缺口;P3 = 性能、会话中止、语音 UX 问题、语音延迟反模式。

1.5 呈现发现和 Agent 配置证据

呈现分析过的会话、按根因类别分组的问题以及提升估算。然后自动继续分析 .agent 文件,以确认根因。

完整的结构分析检查、交叉引用流程和发布偏差检测:请参阅 references/issue-classification.md

从组织中获取 .agent 文件,运行自动检查(子 Agent 数量与操作块的对比、无效中心检测、孤立操作、跨子 Agent 变量依赖),并将 STDM 症状与文件结构进行交叉检查。

阶段 2:复现——实时预览

完整的预览流程、追踪诊断命令和分类标准:请参阅 references/reproduce-reference.md

为阶段 1 中确认的每个问题构建一个测试场景。使用 --authoring-bundle 运行 sf agent preview 测试每个场景(生成本地追踪记录)。每个场景运行 3 次,并进行分类:

判定标准
[CONFIRMED]3 次运行中均出现相同故障
[INTERMITTENT]3 次运行中有 1 至 2 次出现故障
[NOT REPRODUCED]3 次运行均通过

只有 [CONFIRMED] 和 [INTERMITTENT] 问题会进入阶段 3。

关键命令:

sf agent preview start --json --authoring-bundle <Name> --simulate-actions -o <org>
sf agent preview send --json --session-id "$SID" --utterance "<text>" --authoring-bundle <Name> -o <org>
sf agent preview end --json --session-id "$SID" --authoring-bundle <Name> -o <org>

请在 Salesforce 项目目录中运行这些命令。start 需要通过 --authoring-bundle 指定一种操作模式(--simulate-actions 或 --use-live-actions);send 和 end 不接受该标志。

追踪记录位置: .sfdx/agents/{Name}/sessions/{sessionId}/traces/{planId}.json


阶段 3:改进——直接编辑 .agent 文件

关于预检、修复映射、指令原则、回归预防、部署链、验证、安全重新验证和创建测试用例的完整流程:请参阅 references/improve-reference.md

3.0 预检

编辑前,请确认所有操作目标都存在且已在组织中注册。如果缺少目标,请提供以下选项:部署存根、移除操作、通过 UI 注册,或仅进行路由修复。

3.1-3.3 映射问题、编辑并遵循指令原则

将每个已确认的问题映射到 .agent 文件中的修复位置(description、instructions、actions、bindings、transitions)。使用 Edit 工具进行针对性更改。遵循指令原则:明确指定操作、说明前置条件、严格限定范围,并且仅在 system: 中设置角色设定。

3.4 回归预防

编辑前建立基准。尽量减少编辑。每次编辑后立即测试。每个发布周期只进行一项修复。检查跨子 Agent 依赖关系。测试相邻子 Agent。

3.5 应用修复

读取 .agent 文件,使用 Edit 工具进行编辑,并显示差异。进行精确编辑时,请保留文件现有的结构缩进,避免生成混合风格的文件。生成新文件时使用 4 个空格。如果需要统一缩进,请将整个结构缩进转换作为单独的更改,并进行验证;不要只转换使用制表符缩进的文件中的一部分。

3.6 验证、部署、发布、激活
# Validate (dry run)
sf agent validate authoring-bundle --json --api-name <AGENT_API_NAME> -o <org>

# Publish (compile + deploy + activate)
sf agent publish authoring-bundle --json --api-name <AGENT_API_NAME> -o <org>

如果发布失败,请使用部署 + 激活作为备用方案(注意:此方案不完整——不会将 reasoning: actions: 传播到实时元数据)。

3.7 验证

修复后运行阶段 2 的场景。检查追踪记录中的路由、依据、工具和变量是否正确。24-48 小时后,重新运行阶段 1,并与基准进行比较。

3.7b 安全重新验证(必需)

对修改后的 .agent 文件重新进行安全审查(/agentforce-generate 的第 15 节)。撤销任何会引入 BLOCK 发现项的更改。

3.8 更新 Testing Center 测试用例

根据已确认的问题,以 Testing Center YAML 格式创建回归测试用例。使用 sf agent test create 部署,并验证所有先前失败的场景均已通过。

Agent 健康监控(AHM)

完整的 AHM 告警流程——POST 架构、枚举、SDM/指标/Agent 发现、阈值、指标验证、故障排查:请参阅 references/ahm-alerts.md

作为响应式 Observe 阶段的主动补充:当 Agent 指标(升级、转接等)超过阈值时,会触发 AHM 数据告警。通过针对 tableau/dataAlerts(dataAlertType: "agenthealthmonitoring")的 sf api request rest 执行——目前还没有 sf agent alert 子命令。dataspace 可复用 Phase 0。请先根据参考文档构建 POST 请求体,并发现 SDM、其 _mtc 指标 ID 和 Agent 筛选值,然后:

# List/describe -- resolve owner id first (required); single-alert GET is 405 => list + filter client-side
USER_ID=$(sf org display user --target-org <org> --json | python3 -c 'import sys,json;print(json.load(sys.stdin)["result"]["id"])')
sf api request rest "/services/data/v66.0/tableau/dataAlerts?ownerId=$USER_ID" -o <org>
# Create / PUT update-in-place / delete (204). PUT & DELETE are addressed by $ALERT_ID in the path; PUT takes the full POST-style body. Bodies per reference into a 0600 mktemp file.
sf api request rest "/services/data/v66.0/tableau/dataAlerts" -X POST -H "Content-Type: application/json" -b "@$body" -o <org>
sf api request rest "/services/data/v66.0/tableau/dataAlerts/$ALERT_ID" -X PUT -H "Content-Type: application/json" -b "@$body" -o <org>
sf api request rest "/services/data/v66.0/tableau/dataAlerts/$ALERT_ID" -X DELETE -o <org> --include
# Notifications REQUIRE header X-UNS-Type-Filter: all (else custom-types-only => AHM empty = false 0). Report status + list.
sf api request rest "/services/data/v66.0/connect/notifications/status" -H "X-UNS-Type-Filter: all" -o <org>
sf api request rest "/services/data/v66.0/connect/notifications"        -H "X-UNS-Type-Filter: all" -o <org>
# AHM notifications: type=templatized_data_alert; no per-alert endpoint. Attribute by alertId in targetPageRef.state.c__alertId (15/18-char-safe), NOT metricId (collides).

任何告警操作都要注意以下三个易导致静默失败的问题:

  • 阈值是原始的 0-1 比率,不是显示百分比——5% 是 "0.05","1" 表示 100%。
  • POST 字段名称/大小写与 GET 不同——POST 使用 utterance(而不是 alertName)和 PascalCase 的 type 判别字段,因此将 GET 响应复制回 POST 会失败。
  • 通知需要 X-UNS-Type-Filter: all——如果没有此项,connect/notifications* 只会返回自定义类型,因此 AHM 通知(类型为 templatized_data_alert)会返回空结果;空列表是假阴性,并不代表“从未触发”。

参考文件

参考文件内容
references/stdm-queries.mdSTDM 查询流程、Apex 服务部署、响应解析
references/ahm-alerts.mdAHM 数据告警的创建/列出/更新/删除、触发历史、SDM/指标/Agent 发现、阈值架构、指标验证
references/issue-classification.md问题模式表、根因类别、结构分析检查项
references/reproduce-reference.mdPhase 2 预览流程、追踪诊断、分类标准
references/improve-reference.mdPhase 3 编辑、部署链路、验证、安全、测试用例
references/stdm-schema.mdDMO 字段架构、数据层级、质量说明、Agent 名称解析

评论

支持 Markdown