Observability

Snowflake AI Observability provides monitoring and tracing capabilities for CoCo. You can use it to review prompt history, trace agent execution, and attribute credit consumption to individual prompts or sessions.

Observability works the same way across all three CoCo surfaces: CoCo in Snowsight, CoCo Desktop, and the CoCo CLI. Each surface emits the same span records to the same event table and uses the same access model. The surface that originated a request is recorded in the INTERFACE column of the usage views described in Cost attribution.

What’s tracked

Every CoCo interaction emits span-level records into the SNOWFLAKE.LOCAL.AI_OBSERVABILITY_EVENTS event table. Each user prompt is one turn, which corresponds to one OpenTelemetry trace (trace_id). That trace is made up of spans, including:

  • CodingAgentRun: Top-level span for the turn. One record per turn.
  • CodingAgent.Step-0: The primary model-call span for the turn. Contains the user prompt, model response, token counts, tool selection, latency, and a request_id.

Additional spans can capture planning, tool execution, SQL, chart generation, response generation, inputs and outputs, and user feedback. For the same terms applied to Cortex Agents, see Terminology.

Accessing observability data

For Cortex Agents, External Agents, and Cortex Search services, use GET_AI_OBSERVABILITY_EVENTS with the matching agent_type. That is the recommended path: results are scoped to the object and enforce privileges on it. See AI_OBSERVABILITY_EVENTS table.

CoCo doesn’t use a separate object type in that function. To query CoCo spans, filter SNOWFLAKE.LOCAL.AI_OBSERVABILITY_EVENTS by RECORD:name (for example CodingAgent.Step-0). That direct-table path is typical for CoCo and usually requires AI_OBSERVABILITY_READER or another admin role, as described in the LOCAL schema reference.

Example: List recent prompts

SELECT
    TIMESTAMP,
    RESOURCE_ATTRIBUTES['snow.user.name']::STRING AS user_name,
    RESOURCE_ATTRIBUTES['snow.session.role.primary.name']::STRING AS role_name,
    RECORD_ATTRIBUTES['snow.ai.observability.agent.planning.model']::STRING AS model,
    RECORD_ATTRIBUTES['snow.ai.observability.agent.planning.duration']::INT AS latency_ms,
    RECORD_ATTRIBUTES['snow.ai.observability.agent.planning.status']::STRING AS status
  FROM SNOWFLAKE.LOCAL.AI_OBSERVABILITY_EVENTS
  WHERE RECORD_TYPE = 'SPAN'
    AND RECORD:name::STRING = 'CodingAgent.Step-0'
  ORDER BY TIMESTAMP DESC;

Cost attribution

To attribute credit consumption to individual prompts, join the event table to SNOWFLAKE_COCO_USAGE_HISTORY on REQUEST_ID. That view covers all three CoCo surfaces and reports which one served the request in its INTERFACE column:

SELECT
    obs.TIMESTAMP AS event_time,
    obs.RESOURCE_ATTRIBUTES['snow.user.name']::STRING AS user_name,
    usage.INTERFACE,
    obs.RECORD_ATTRIBUTES['snow.ai.observability.agent.planning.model']::STRING AS model,
    usage.TOKEN_CREDITS
  FROM SNOWFLAKE.LOCAL.AI_OBSERVABILITY_EVENTS obs
    JOIN SNOWFLAKE.ACCOUNT_USAGE.SNOWFLAKE_COCO_USAGE_HISTORY usage
      ON obs.RECORD_ATTRIBUTES['snow.ai.observability.agent.planning.request_id']::STRING
         = usage.REQUEST_ID
  WHERE obs.RECORD_TYPE = 'SPAN'
    AND obs.RECORD:name::STRING = 'CodingAgent.Step-0'
  ORDER BY obs.TIMESTAMP DESC;

To attribute cost for a single turn, group on TRACE['trace_id']:

SELECT
    obs.TRACE['trace_id']::STRING AS trace_id,
    obs.RESOURCE_ATTRIBUTES['snow.user.name']::STRING AS user_name,
    COUNT(*) AS step_count,
    SUM(usage.TOKEN_CREDITS) AS total_credits
  FROM SNOWFLAKE.LOCAL.AI_OBSERVABILITY_EVENTS obs
    JOIN SNOWFLAKE.ACCOUNT_USAGE.SNOWFLAKE_COCO_USAGE_HISTORY usage
      ON obs.RECORD_ATTRIBUTES['snow.ai.observability.agent.planning.request_id']::STRING
         = usage.REQUEST_ID
  WHERE obs.RECORD_TYPE = 'SPAN'
    AND obs.RECORD:name::STRING = 'CodingAgent.Step-0'
  GROUP BY 1, 2
  ORDER BY total_credits DESC;

To scope either query to one surface, filter on usage.INTERFACE (cli, desktop, or snowsight). You can also query the per-surface views directly: CORTEX_CODE_SNOWSIGHT_USAGE_HISTORY, CORTEX_CODE_DESKTOP_USAGE_HISTORY, and CORTEX_CODE_CLI_USAGE_HISTORY.

Important

Use the usage views, not the event table, as the source of truth for credits and tokens. Trace delivery to AI_OBSERVABILITY_EVENTS is best effort, so join results can under-report cost. For details, see AI_OBSERVABILITY_EVENTS.

Access control

CoCo span queries use direct SELECT on AI_OBSERVABILITY_EVENTS because there is no CoCo-specific agent_type for the observability table functions. Grant SNOWFLAKE.AI_OBSERVABILITY_READER only when this role needs that direct-table access (for example operators running the examples above). For retention deletes, grant SNOWFLAKE.AI_OBSERVABILITY_ADMIN. For the recommended access model for agents, search services, and External Agents, see AI_OBSERVABILITY_EVENTS table.

GRANT APPLICATION ROLE SNOWFLAKE.AI_OBSERVABILITY_READER
  TO ROLE <role_name>;

To join observability data with the usage views, the role also needs read access to the SNOWFLAKE database:

GRANT IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE
  TO ROLE <role_name>;

More information

For the AI Observability overview and links to every Cortex feature, see AI Observability with Snowflake Cortex. For TruLens datasets, metrics, and runs, see Snowflake AI Observability Reference. For the shared event table and GET_AI_* functions, see LOCAL schema.