关于 agentforce-observe
面向 Salesforce Agentforce 的技能,用于分析 Agent 会话、通过预览复现问题并改进 `.agent` 文件。可查询 Data Cloud 会话追踪;STDM 不可用时则使用本地测试和追踪作为替代。
主要功能
- 01分析 STDM 会话指标与对话
- 02使用测试套件和本地追踪作为替代
- 03通过 `sf agent preview` 复现对话
- 04编辑、验证并发布 `.agent` 文件
- 05管理 Agent Health Monitoring 警报
适用场景
- 01查找会话中的路由或工具调用问题
- 02在预览中复现有问题的对话
- 03STDM 不可用时检查本地追踪
- 04创建或查看 Agent 监控警报
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ forcedotcom/ sf-skills --skill agentforce-observe安装后在 Claude Code 中输入/agentforce-observe确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/apex/AgentforceOptimizeService.clsAgentforceOptimizeService.cls-meta.xmlreferences/ahm-alerts.mdimprove-reference.mdissue-classification.mdreproduce-reference.mdstdm-queries.mdstdm-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= STDMfindSessions和 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 agentCLI 命令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-generatereferences/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.md | STDM 查询流程、Apex 服务部署、响应解析 |
references/ahm-alerts.md | AHM 数据告警的创建/列出/更新/删除、触发历史、SDM/指标/Agent 发现、阈值架构、指标验证 |
references/issue-classification.md | 问题模式表、根因类别、结构分析检查项 |
references/reproduce-reference.md | Phase 2 预览流程、追踪诊断、分类标准 |
references/improve-reference.md | Phase 3 编辑、部署链路、验证、安全、测试用例 |
references/stdm-schema.md | DMO 字段架构、数据层级、质量说明、Agent 名称解析 |