Skip to content

Commit fcb2614

Browse files
sorenlouvarturoliduenakibanamachine
authored andcommitted
[Obs AI] Improvements to tool descriptions and params (elastic#247723)
This PR makes various improvements the o11y tools: better descriptions, summary, and consistent terminology. ### Enhanced descriptions Added "When to use" guidance to help the LLM select the right tool (`get_alerts`, `get_anomaly_detection_jobs`, `get_correlated_logs`, `get_downstream_dependencies`, `get_services`) ### Simplified `get_correlated_logs` API - `logsFilter` → `kqlFilter` (consistent with other tools) - `interestingEventFilter` → `errorLogsOnly` ### Optional time range `get_downstream_dependencies` and `get_services` now defaults to last hour instead of requiring a time range --------- Co-authored-by: Arturo Lidueña <arturo.liduena@elastic.co> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
1 parent aec1686 commit fcb2614

File tree

15 files changed

+204
-194
lines changed

15 files changed

+204
-194
lines changed

x-pack/solutions/observability/plugins/observability_agent_builder/server/tools/get_alerts/tool.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,14 @@ export function createGetAlertsTool({
7777
const toolDefinition: BuiltinToolDefinition<typeof getAlertsSchema> = {
7878
id: OBSERVABILITY_GET_ALERTS_TOOL_ID,
7979
type: ToolType.builtin,
80-
description: `Retrieves Observability alerts within a specified time range. Supports filtering by status (active/recovered) and KQL queries to find specific alert instances.`,
80+
description: `Retrieves Observability alerts within a specified time range.
81+
82+
When to use:
83+
- Checking if there are active alerts for a service or host
84+
- Investigating what triggered during an incident
85+
- Finding alerts related to specific infrastructure or services
86+
87+
Supports filtering by status (active/recovered) and KQL queries.`,
8188
schema: getAlertsSchema,
8289
tags: ['observability', 'alerts'],
8390
availability: {
@@ -86,16 +93,15 @@ export function createGetAlertsTool({
8693
return getAgentBuilderResourceAvailability({ core, request, logger });
8794
},
8895
},
89-
handler: async (
90-
{
96+
handler: async (toolParams, { request }) => {
97+
const {
9198
start = DEFAULT_TIME_RANGE.start,
9299
end = DEFAULT_TIME_RANGE.end,
93100
kqlFilter,
94101
includeRecovered,
95102
query,
96-
},
97-
{ request }
98-
) => {
103+
} = toolParams;
104+
99105
try {
100106
const { alerts, selectedFields, total } = await getToolHandler({
101107
core,

x-pack/solutions/observability/plugins/observability_agent_builder/server/tools/get_anomaly_detection_jobs/tool.ts

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export interface GetAnomalyDetectionJobsToolResult {
3333
type: ToolResultType.other;
3434
data: {
3535
jobs: Awaited<ReturnType<typeof getToolHandler>>;
36-
totalReturned: number;
36+
total: number;
3737
message?: string;
3838
};
3939
}
@@ -72,8 +72,12 @@ export function createGetAnomalyDetectionJobsTool({
7272
const toolDefinition: BuiltinToolDefinition<typeof getAnomalyDetectionJobsSchema> = {
7373
id: OBSERVABILITY_GET_ANOMALY_DETECTION_JOBS_TOOL_ID,
7474
type: ToolType.builtin,
75-
description:
76-
'Retrieves Machine Learning anomaly detection jobs and their top anomaly records for a given time range. Use this to identify unusual patterns or outliers in observability data.',
75+
description: `Retrieves Machine Learning anomaly detection jobs and their top anomaly records.
76+
77+
When to use:
78+
- Investigating anomalies in logs, metrics, or traces
79+
- Finding outliers that might indicate problems
80+
- Answering "is anything behaving abnormally?"`,
7781
schema: getAnomalyDetectionJobsSchema,
7882
tags: ['observability', 'machine_learning', 'anomaly_detection'],
7983
availability: {
@@ -83,16 +87,17 @@ export function createGetAnomalyDetectionJobsTool({
8387
},
8488
},
8589
handler: async (
86-
{
87-
jobIds,
88-
limit: jobsLimit = DEFAULT_JOBS_LIMIT,
89-
start: rangeStart = DEFAULT_TIME_RANGE.start,
90-
end: rangeEnd = DEFAULT_TIME_RANGE.end,
91-
},
90+
toolParams,
9291
{ esClient, request }
9392
): Promise<{
9493
results: (GetAnomalyDetectionJobsToolResult | Omit<ErrorResult, 'tool_result_id'>)[];
9594
}> => {
95+
const {
96+
jobIds,
97+
limit: jobsLimit = DEFAULT_JOBS_LIMIT,
98+
start: rangeStart = DEFAULT_TIME_RANGE.start,
99+
end: rangeEnd = DEFAULT_TIME_RANGE.end,
100+
} = toolParams;
96101
const scopedEsClient = esClient.asCurrentUser;
97102
const mlClient = scopedEsClient.ml;
98103

@@ -109,28 +114,13 @@ export function createGetAnomalyDetectionJobsTool({
109114
rangeEnd,
110115
});
111116

112-
if (!mlJobs.length) {
113-
return {
114-
results: [
115-
{
116-
type: ToolResultType.other,
117-
data: {
118-
jobs: [],
119-
totalReturned: 0,
120-
message: 'No anomaly detection jobs found for the provided filters.',
121-
},
122-
},
123-
],
124-
};
125-
}
126-
127117
return {
128118
results: [
129119
{
130120
type: ToolResultType.other,
131121
data: {
132122
jobs: mlJobs,
133-
totalReturned: mlJobs.length,
123+
total: mlJobs.length,
134124
},
135125
},
136126
],
Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,54 @@
11
# get_correlated_logs
22

3-
Retrieves logs and their surrounding context based on shared correlation identifiers (e.g. trace.id). Can start from a specific log ID or find error logs within a time range to use as anchors. Returns chronologically sorted groups of logs, providing visibility into the sequence of events leading up to and following the anchor log.
3+
Retrieves log sequences around error events to understand what happened. By default, anchors on error logs (ERROR, WARN, FATAL, HTTP 5xx). Set `errorLogsOnly: false` to anchor on any (non-error) logs.
44

55
## Examples
66

77
### Find correlated logs for errors in the payment-service
88

9-
```
10-
POST kbn://api/agent_builder/tools/_execute
11-
{
12-
"tool_id": "observability.get_correlated_logs",
13-
"tool_params": {
14-
"logsFilter": "service.name: \"payment-service\""
15-
}
16-
}
17-
```
18-
19-
### Find correlated logs for a specific log ID
20-
21-
```
9+
```jsonc
2210
POST kbn://api/agent_builder/tools/_execute
2311
{
2412
"tool_id": "observability.get_correlated_logs",
2513
"tool_params": {
26-
"logId": "c8f9d2a1-4b3e-4a1c-9d8e-7f6a5b4c3d2e",
27-
"index": "logs-payment-service"
14+
"kqlFilter": "service.name: payment-service"
2815
}
2916
}
3017
```
3118

32-
### Limit the returned logs to specific fields only
19+
### Find correlated logs for slow requests (non-errors)
3320

34-
```
21+
```jsonc
3522
POST kbn://api/agent_builder/tools/_execute
3623
{
3724
"tool_id": "observability.get_correlated_logs",
3825
"tool_params": {
39-
"start": "now-15m",
40-
"end": "now",
41-
"logSourceFields": ["@timestamp", "message", "log.level", "service.name"],
42-
"maxSequences": 20
26+
"kqlFilter": "service.name: payment-service AND event.duration > 1000000",
27+
"errorLogsOnly": false
4328
}
4429
}
4530
```
4631

47-
### Specify non-standard correlation identifiers to correlate by
32+
### Find correlated logs for a specific log ID
4833

49-
```
34+
```jsonc
5035
POST kbn://api/agent_builder/tools/_execute
5136
{
5237
"tool_id": "observability.get_correlated_logs",
5338
"tool_params": {
54-
"correlationFields": ["my_custom_correlation_identifier"]
39+
"logId": "c8f9d2a1-4b3e-4a1c-9d8e-7f6a5b4c3d2e"
5540
}
5641
}
5742
```
5843

59-
### Find correlated logs for non-error events (e.g. slow transactions)
44+
### Use custom correlation fields
6045

61-
```
46+
```jsonc
6247
POST kbn://api/agent_builder/tools/_execute
6348
{
6449
"tool_id": "observability.get_correlated_logs",
6550
"tool_params": {
66-
"logsFilter": "service.name: \"payment-service\"",
67-
"interestingEventFilter": "event.duration > 1000000000"
51+
"correlationFields": ["my_custom_correlation_id"]
6852
}
6953
}
7054
```

x-pack/solutions/observability/plugins/observability_agent_builder/server/tools/get_correlated_logs/fetch_anchor_logs/fetch_anchor_logs.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ export async function getAnchorLogs({
1515
logsIndices,
1616
startTime,
1717
endTime,
18-
logsFilter,
19-
interestingEventFilter,
18+
kqlFilter,
19+
errorLogsOnly,
2020
correlationFields,
2121
logger,
2222
logId,
@@ -26,8 +26,8 @@ export async function getAnchorLogs({
2626
logsIndices: string[];
2727
startTime: number;
2828
endTime: number;
29-
logsFilter: string | undefined;
30-
interestingEventFilter: string | undefined;
29+
kqlFilter: string | undefined;
30+
errorLogsOnly: boolean;
3131
correlationFields: string[];
3232
logger: Logger;
3333
logId?: string;
@@ -49,8 +49,8 @@ export async function getAnchorLogs({
4949
logsIndices,
5050
startTime,
5151
endTime,
52-
logsFilter,
53-
interestingEventFilter,
52+
kqlFilter,
53+
errorLogsOnly,
5454
correlationFields,
5555
logger,
5656
maxSequences,

x-pack/solutions/observability/plugins/observability_agent_builder/server/tools/get_correlated_logs/fetch_anchor_logs/get_anchor_logs_for_time_range.ts

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { createHash } from 'crypto';
1010
import type { IScopedClusterClient, Logger } from '@kbn/core/server';
1111
import type { AggregationsAggregationContainer } from '@elastic/elasticsearch/lib/api/types';
1212
import { getTypedSearch } from '../../../utils/get_typed_search';
13-
import { kqlFilter, timeRangeFilter } from '../../../utils/dsl_filters';
13+
import { kqlFilter as buildKqlFilter, timeRangeFilter } from '../../../utils/dsl_filters';
1414
import type { AnchorLog } from '../types';
1515
import { DEFAULT_ERROR_SEVERITY_FILTER } from '../constants';
1616
import type { CorrelationFieldAggregations } from './types';
@@ -20,8 +20,8 @@ export async function getAnchorLogsForTimeRange({
2020
logsIndices,
2121
startTime,
2222
endTime,
23-
logsFilter,
24-
interestingEventFilter,
23+
kqlFilter,
24+
errorLogsOnly,
2525
correlationFields,
2626
logger,
2727
maxSequences,
@@ -30,8 +30,8 @@ export async function getAnchorLogsForTimeRange({
3030
logsIndices: string[];
3131
startTime: number;
3232
endTime: number;
33-
logsFilter: string | undefined;
34-
interestingEventFilter: string | undefined;
33+
kqlFilter: string | undefined;
34+
errorLogsOnly: boolean;
3535
correlationFields: string[];
3636
logger: Logger;
3737
maxSequences: number;
@@ -48,7 +48,7 @@ export async function getAnchorLogsForTimeRange({
4848
bool: {
4949
filter: [
5050
...timeRangeFilter('@timestamp', { start: startTime, end: endTime }),
51-
...kqlFilter(logsFilter),
51+
...buildKqlFilter(kqlFilter),
5252

5353
// must have at least one correlation field
5454
{
@@ -58,10 +58,8 @@ export async function getAnchorLogsForTimeRange({
5858
},
5959
},
6060

61-
// must be an interesting event (error by default, or match the provided filter)
62-
...(interestingEventFilter
63-
? kqlFilter(interestingEventFilter)
64-
: [DEFAULT_ERROR_SEVERITY_FILTER]),
61+
// filter by error severity (default) or include all logs
62+
...(errorLogsOnly ? [DEFAULT_ERROR_SEVERITY_FILTER] : []),
6563
],
6664
},
6765
},

x-pack/solutions/observability/plugins/observability_agent_builder/server/tools/get_correlated_logs/handler.ts

Lines changed: 19 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -16,50 +16,41 @@ import { parseDatemath } from '../../utils/time';
1616
import { DEFAULT_CORRELATION_IDENTIFIER_FIELDS, DEFAULT_LOG_SOURCE_FIELDS } from './constants';
1717
import { getAnchorLogs } from './fetch_anchor_logs/fetch_anchor_logs';
1818
import { getCorrelatedLogsForAnchor } from './get_correlated_logs_for_anchor';
19-
import type { LogSequence } from './types';
2019

21-
function getNoResultsMessage({
22-
sequences,
20+
export function getNoResultsMessage({
2321
logId,
24-
logsFilter,
25-
interestingEventFilter,
22+
kqlFilter,
23+
errorLogsOnly,
2624
correlationFields,
2725
start,
2826
end,
2927
}: {
30-
sequences: LogSequence[];
3128
logId: string | undefined;
32-
logsFilter: string | undefined;
33-
interestingEventFilter: string | undefined;
29+
kqlFilter: string | undefined;
30+
errorLogsOnly: boolean;
3431
correlationFields: string[];
3532
start: string;
3633
end: string;
37-
}): string | undefined {
38-
if (sequences.length > 0) {
39-
return undefined;
40-
}
41-
34+
}): string {
4235
const isUsingDefaultCorrelationFields =
4336
correlationFields === DEFAULT_CORRELATION_IDENTIFIER_FIELDS;
4437

4538
const correlationFieldsDescription = isUsingDefaultCorrelationFields
4639
? 'Matching logs exist but lack the default correlation fields (trace.id, request.id, transaction.id, etc.). Try using `correlationFields` for specifying custom correlation fields.'
4740
: `Matching logs exist but lack the custom correlation fields: ${correlationFields.join(', ')}`;
4841

49-
const isUsingDefaultEventFilter = !interestingEventFilter;
50-
const eventFilterDescription = isUsingDefaultEventFilter
51-
? 'The default `interestingEventFilter` (log.level: ERROR/WARN/FATAL, HTTP 5xx, syslog severity ≤3, etc.) did not match any documents.'
52-
: `The
53-
interestingEventFilter" option "${interestingEventFilter}" did not match any documents.`;
54-
5542
if (logId) {
5643
return `The log ID "${logId}" was not found, or the log does not have any of the ${correlationFieldsDescription}.`;
5744
}
5845

5946
const suggestions = [
6047
`No matching logs exist in this time range (${start} to ${end})`,
61-
...(logsFilter ? ['`logsFilter` is too restrictive'] : []),
62-
eventFilterDescription,
48+
...(kqlFilter ? ['`kqlFilter` is too restrictive'] : []),
49+
...(errorLogsOnly
50+
? [
51+
'No error logs found (errorLogsOnly=true filters for ERROR/WARN/FATAL, HTTP 5xx, etc.). Try errorLogsOnly=false to include all log levels.',
52+
]
53+
: []),
6354
correlationFieldsDescription,
6455
];
6556

@@ -74,8 +65,8 @@ export async function getToolHandler({
7465
esClient,
7566
start,
7667
end,
77-
logsFilter,
78-
interestingEventFilter,
68+
kqlFilter,
69+
errorLogsOnly = true,
7970
index,
8071
correlationFields = DEFAULT_CORRELATION_IDENTIFIER_FIELDS,
8172
logId,
@@ -91,8 +82,8 @@ export async function getToolHandler({
9182
esClient: IScopedClusterClient;
9283
start: string;
9384
end: string;
94-
logsFilter?: string;
95-
interestingEventFilter?: string;
85+
kqlFilter?: string;
86+
errorLogsOnly?: boolean;
9687
index?: string;
9788
correlationFields?: string[];
9889
logId?: string;
@@ -109,8 +100,8 @@ export async function getToolHandler({
109100
logsIndices,
110101
startTime,
111102
endTime,
112-
logsFilter,
113-
interestingEventFilter,
103+
kqlFilter,
104+
errorLogsOnly,
114105
correlationFields,
115106
logger,
116107
logId,
@@ -137,15 +128,5 @@ export async function getToolHandler({
137128
})
138129
);
139130

140-
const message = getNoResultsMessage({
141-
sequences,
142-
logId,
143-
logsFilter,
144-
interestingEventFilter,
145-
correlationFields,
146-
start,
147-
end,
148-
});
149-
150-
return { sequences, message };
131+
return { sequences };
151132
}

0 commit comments

Comments
 (0)