Agentforce Observe
Analyze production Agentforce agent behavior using session traces and Data Cloud, and manage Agent Health Monitoring (AHM) alerts. TRIGGER when: user queries STDM session data or Data Cloud trace records; investigates production agent failures, regressions, or performance issues; asks about session traces, conversation logs, or agent metrics; wants to reproduce a reported production issue in preview; runs findSessions or trace analysis queries; creates, lists, updates, or deletes an AHM data alert on an agent metric (escalation rate, deflection, etc.); asks why an alert is not firing or wants to check whether alerts have fired (notification counts, or the per-alert Incidents view). DO NOT TRIGGER when: user creates, modifies, or debugs .agent files during development (use agentforce-generate); writes or runs test specs (use agentforce-test); uses sf agent preview for local development iteration; deploys or publishes agents.
- Skill ID
- forcedotcom/sf-skills/agentforce-observe
- Publisher
- forcedotcom
- Repository
- sf-skills
- Installs
- 0
- Files
- 9
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
forcedotcom/sf-skills/agentforce-observeInstalls these files- SKILL.md
- assets/apex/AgentforceOptimizeService.cls
- assets/apex/AgentforceOptimizeService.cls-meta.xml
- references/ahm-alerts.md
- references/improve-reference.md
- references/issue-classification.md
- references/reproduce-reference.md
- references/stdm-queries.md
- references/stdm-schema.md
What this skill tells the agent
Agentforce Observability
Improve Agentforce agents using session trace data and live preview testing.
Three-phase workflow:
- Observe -- Query STDM sessions from Data Cloud (if available), OR run test suites + preview with local traces as fallback
- Reproduce -- Use
sf agent previewto simulate problematic conversations live - Improve -- Edit the
.agentfile directly, validate, publish, verify
Platform Notes
- Shell examples below use bash syntax. On Windows, use PowerShell equivalents or Git Bash.
- Replace
python3withpythonon Windows. - Replace
/tmp/with$env:TEMP\(PowerShell) or%TEMP%\(cmd). - Replace
jqwithpython -c "import json,sys; ..."if jq is not installed.
Routing
Gather these inputs before starting:
- Org alias (required) -- must be authenticated (else
sf org login web) - Agent API name (required for preview and deploy; ask if not provided)
- Agent file path (optional) -- path to the
.agentfile, typicallyforce-app/main/default/aiAuthoringBundles/<AgentName>/<AgentName>.agent. Auto-detect if not provided. - Session IDs (optional) -- analyze specific sessions; if absent, query last 7 days
- Days to look back (optional, default 7)
- Alert owner user (optional, alerts only) -- user whose alerts to list/manage; defaults to the current user
Determine intent from user input:
- No specific action -> run all three analysis phases: Observe -> surface issues -> ask if user wants to Reproduce and/or Improve
- "analyze" / "sessions" / "what's wrong" -> Phase 1 only, then suggest next steps
- "reproduce" / "test" / "preview" -> Phase 2 (run Phase 1 first if no issues in hand)
- "fix" / "improve" / "update" -> Phase 3 (run Phase 1 first if no issues in hand)
- "create alert" / "set up monitoring" / "alert me when" -> AHM (create)
- "list alerts" / "show my alerts" / "update alert" / "delete alert" -> AHM (list / update via PUT / delete)
- "get / list notifications" / "notifications for a specific alert" / "have my alerts fired" / "why isn't my alert firing" -> AHM: fetch notifications with header
X-UNS-Type-Filter: all, report status + list; for a specific alert, filter by alertId fromtargetPageRef.state.c__alertId(15/18-char-safe), not metricId (+ Incidents view + metric verify)
Resolve agent name
Before any STDM query, resolve the user-provided agent name against the org to get the exact MasterLabel and 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= display name used by STDMfindSessionsand Agent Builder UI (e.g. "Order Service")DeveloperName= API name with version suffix used in metadata (e.g. "OrderService_v9")- The
--api-nameflag forsf agent preview/activate/publishusesDeveloperNamewithout the_vNsuffix (e.g. "OrderService")
Store these values:
AGENT_MASTER_LABEL-- forfindSessions()agent filterAGENT_API_NAME--DeveloperNamewithout_vNsuffix, forsf agentCLI commandsPLANNER_ID-- the Salesforce record ID for this agent
Locate the .agent file
Step 1 -- Search locally:
find <project-root>/force-app/main/default/aiAuthoringBundles -name "*.agent" 2>/dev/nullIf the user provided an agent file path, use that directly. Otherwise, search for files matching AGENT_API_NAME.
Step 2 -- If not found locally, retrieve from the org:
sf project retrieve start --json --metadata "AiAuthoringBundle:<AGENT_API_NAME>" -o <org>Known bug:sf project retrieve startcreates a double-nested path:force-app/main/default/main/default/aiAuthoringBundles/.... Fix it immediately after retrieve:
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
fiStep 3 -- Validate the retrieved file:
Read the .agent file and verify it has proper Agent Script structure:
system:block withinstructions:config:block withdeveloper_name:start_agentorsubagentblocks withreasoning: instructions:- Each subagent should have distinct
instructions:content (not identical across subagents)
Store the resolved path as AGENT_FILE for Phase 3.
Phase 0: Discover Data Space
Before running any STDM query, determine the correct Data Cloud Data Space API name.
sf api request rest "/services/data/v63.0/ssot/data-spaces" -o <org>Note: sf api request rest is a beta command -- do not add --json (that flag is unsupported and causes an error).
The response shape is:
{
"dataSpaces": [
{
"id": "0vhKh000000g3DjIAI",
"label": "default",
"name": "default",
"status": "Active",
"description": "Your org's default data space."
}
],
"totalSize": 1
}The name field is the API name to pass to AgentforceOptimizeService.
Decision logic:
- If the command fails (e.g. 404 or permission error), fall back to
'default'and note it as an assumption. - Filter to only
status: "Active"entries. - If exactly one active Data Space exists, use it automatically and confirm to the user: "Using Data Space:
<name>". - If multiple active Data Spaces exist, show the list (label + name) and ask the user which to use.
Store the selected name value as DATA_SPACE for all subsequent steps.
Prerequisite check: STDM DMOs
After deploying the helper class (step 1.0), run a quick probe to verify the STDM Data Model Objects exist in Data Cloud:
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());
}
APEXIf `STDM_CHECK:FAIL`: STDM is not activated. Inform the user and switch to Phase 1-ALT:
STDM (Session Trace Data Model) is not available in this org. To enable: Setup -> Data Cloud -> Data Streams and verify "Agentforce Activity" is active. Proceeding with fallback: test suites + local traces.
If `STDM_CHECK:OK`, proceed to Phase 1 (STDM path).
Phase 1-ALT: Observe Without STDM (Fallback Path)
When STDM is not available, use test suites and sf agent preview --authoring-bundle with local trace analysis.
| Data source | When to use | Pros | Cons |
|---|---|---|---|
| STDM (Phase 1) | Historical production analysis | Real user data, volume | Requires Data Cloud, 15-min lag |
| Test suites + local traces (Phase 1-ALT) | Dev iteration, orgs without STDM | Instant, full LLM prompt, variable state | Preview only, no real user data |
1-ALT.1 Run existing test suite (if available)
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 Derive test utterances from .agent file (if no test suite)
If no test suite exists, derive utterances: one per non-entry subagent (from description: keywords), one per key action, one guardrail test, one multi-turn test.
1-ALT.3 Preview with --authoring-bundle (local traces)
Run each test utterance through preview to generate local trace files:
More from forcedotcom
Use this skill in a project
Open any RiverX project, search the Skills panel for forcedotcom/sf-skills/agentforce-observe, and install it in one click.
