mcpField
A
agentforce-observe

agentforce-observe

github.com/salesforceairesearchAgent 工作流117316 次安装7 周前更新
代码仓库

关于 agentforce-observe

面向 Salesforce Agentforce 团队的可观测性技能,通过会话轨迹或本地预览追踪问题,并复现和改进 Agent。它也支持分析会话指标、配置警报及检查 RAG 表现。

主要功能

  1. 01查询 STDM 会话数据
  2. 02无 STDM 时使用测试与本地轨迹
  3. 03预览复现问题对话
  4. 04分析会话指标与质量
  5. 05检查 RAG 表现
  6. 06创建和管理警报

适用场景

  1. 01分析生产会话中的 Agent 问题
  2. 02在缺少 STDM 时通过本地轨迹排查
  3. 03复现路由或操作调用故障
  4. 04监控 Agent 指标并管理警报

安装

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

$npx skills add https://github.com/salesforceairesearch/agentforce-adlc --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