Custom Agents - Observed tool failure storm
Custom Tool Failure Storm
Query
let Evidence=materialize(CustomAgentInlineContent(1h));
CustomAgentSpans(1h)
| where Classification !in ('Excluded managed platform', 'Unattributed GenAI') and HasLineage
| where IsTool
| summarize EventCount=count(), FailedCalls=countif(Success == false),
SuccessfulCalls=countif(Success == true), arg_max(EventTime, *)
by _ResourceId, OperationId, AgentKey
| where EventCount >= 10 and 1.0 * FailedCalls / EventCount >= 0.8
| extend Signal='At least 10 observed tool spans; failure rate at least 80 percent'
| extend TimeGenerated=EventTime, ResourceId=_ResourceId, TraceId=OperationId,
EventCount=tolong(column_ifexists('EventCount', 1)),
SuccessfulCalls=tolong(column_ifexists('SuccessfulCalls', 0)),
FailedCalls=tolong(column_ifexists('FailedCalls', 0))
| project TimeGenerated, ResourceId, Agent, AgentId, AgentKey, AppRoleName,
TraceId, SpanId, Conversation, Model, Tool, TargetHost, ServerDisplay,
Signal, EventCount, SuccessfulCalls, FailedCalls,
TriggerSpanId=tostring(column_ifexists('TriggerSpanId', '')),
TriggerTime=todatetime(column_ifexists('TriggerTime', datetime(null))),
TriggerTool=tostring(column_ifexists('TriggerTool', '')),
TriggerToolResult=tostring(column_ifexists('TriggerToolResult', '')),
TriggerServerDisplay=tostring(column_ifexists('TriggerServerDisplay', '')),
TriggerTargetHost=tostring(column_ifexists('TriggerTargetHost', '')),
RiskyOutputKind=tostring(column_ifexists('RiskyOutputKind', '')),
RelatedToolResults=tolong(column_ifexists('RelatedToolResults', 0)),
MatchedIntentPrompt=tostring(column_ifexists('IntentPrompt', '')),
MatchedIntentSpanId=tostring(column_ifexists('IntentSpanId', ''))
| join kind=leftouter (Evidence
| project ResourceId=_ResourceId, TraceId=OperationId, SpanId, AgentKey, Prompt, Output, ToolArguments, ToolResult, InputMessages, OutputMessages,
EvidenceSource, PromptEvidenceOrigin, OutputEvidenceOrigin, PromptEvidenceSpanId, OutputEvidenceSpanId,
InputParseState, OutputParseState, ToolArgumentsState, ToolResultState)
on ResourceId, TraceId, SpanId, AgentKey
| extend Prompt=coalesce(MatchedIntentPrompt, Prompt),
PromptEvidenceOrigin=iff(isnotempty(MatchedIntentPrompt), 'Matched intent span: user role', PromptEvidenceOrigin),
PromptEvidenceSpanId=coalesce(MatchedIntentSpanId, PromptEvidenceSpanId)
| extend PreviewCharacters=toint(min_of(160, max_of(0, (1500 - string_size(tostring(bag_pack(
'AgentId', AgentId, 'AgentKey', AgentKey, 'TraceId', TraceId, 'SpanId', SpanId,
'Conversation', Conversation, 'ResourceId', ResourceId, 'Signal', Signal)))) / 12)))
| extend PromptPreview=substring(Prompt, 0, PreviewCharacters),
OutputPreview=substring(Output, 0, PreviewCharacters)
| extend EvidencePreviewStatus=case(PreviewCharacters == 0, 'Metadata exhausted preview budget; inspect full query results',
strlen(Prompt) > PreviewCharacters or strlen(Output) > PreviewCharacters, 'Inline evidence; previews shortened; full text in query results',
isempty(Prompt) and isempty(Output), 'No prompt/output captured or parsed; not a protection verdict',
'Inline evidence; full recorded text in query results')
| project TimeGenerated, ResourceId, Agent, AgentId, AgentKey, AppRoleName,
TraceId, SpanId, Conversation, Model, Tool, TargetHost, ServerDisplay,
Signal, EventCount, SuccessfulCalls, FailedCalls, Prompt, Output, ToolArguments, ToolResult, InputMessages, OutputMessages,
EvidenceSource, PromptEvidenceOrigin, OutputEvidenceOrigin, PromptEvidenceSpanId, OutputEvidenceSpanId,
InputParseState, OutputParseState, ToolArgumentsState, ToolResultState,
PromptPreview, OutputPreview, EvidencePreviewStatus, TriggerSpanId, TriggerTime, TriggerTool, TriggerToolResult,
TriggerServerDisplay, TriggerTargetHost, RiskyOutputKind, RelatedToolResults
| order by TimeGenerated descExplanation
This query is designed to detect a potential issue with tools used by custom agents in an application. Here's a simplified breakdown:
-
Purpose: The query identifies situations where a specific tool used by an agent has a high failure rate. Specifically, it looks for cases where there are at least 10 tool-related events (or "spans") within an hour, and 80% or more of these events are failures.
-
Data Sources: It uses data from Application Insights, specifically focusing on application requests and dependencies.
-
Frequency and Period: The query runs every hour and examines data from the past 14 days.
-
Conditions:
- It filters out certain types of classifications and only considers events that have lineage and are tool-related.
- It calculates the total number of events, successful calls, and failed calls for each resource, operation, and agent.
- It flags cases where there are at least 10 events and the failure rate is 80% or higher.
-
Output:
- The query generates a detailed report of these high-failure events, including metadata like agent details, trace IDs, and a preview of the prompt and output associated with the tool usage.
- It also provides a status on the evidence preview, indicating whether the full text is available or if only a shortened version is shown.
-
Alert and Incident Management:
- If the conditions are met, an alert is generated for each result.
- Incidents are created based on these alerts, with specific grouping configurations to manage them effectively.
-
Status and Configuration:
- The query is currently disabled (
enabled: false). - It is versioned as 1.2.0 and tagged for use with Sentinel-As-Code, AI, and custom agents.
- The query is currently disabled (
Overall, this query helps in monitoring and identifying potential tool failures in custom agents, allowing for proactive incident management.