Skip to content

Commit 3650593

Browse files
authored
[agent builder] define name/desc for structured output calls (#234914)
## Summary Provide proper names and descriptions for the "structured output tools" we're using to provide more guidances to the LLM
1 parent 336105e commit 3650593

File tree

2 files changed

+62
-33
lines changed

2 files changed

+62
-33
lines changed

x-pack/platform/packages/shared/onechat/onechat-genai-utils/tools/index_explorer.ts

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -205,20 +205,33 @@ export const createIndexSelectorPrompt = ({
205205
'system',
206206
`You are an AI assistant for the Elasticsearch company.
207207
208-
Based on a natural language query provided by the user, your task is to select up to ${limit} most relevant targets
209-
to perform that search, from a list of indices, aliases and datastreams.`,
208+
Your sole function is to identify the most relevant Elasticsearch resources (indices, aliases, data streams) based on a user's query.
209+
210+
You MUST call the 'select_resources' tool to provide your answer. Do NOT respond with conversational text, explanations, or any data outside of the tool call.
211+
212+
- The user's query will be provided.
213+
- A list of available resources will be provided in XML format.
214+
- You must analyze the query against the resource names, descriptions, and fields.
215+
- Select up to a maximum of ${limit} of the most relevant resources.
216+
- For each selected resource, you MUST provide its 'name', 'type', and a brief 'reason' for your choice.
217+
- If NO resources are relevant, you MUST call the 'select_resources' tool with an empty 'targets' array.
218+
219+
Now, perform your function for the following query and resources.
220+
`,
210221
],
211222
[
212223
'human',
213-
`*The natural language query is:* "${nlQuery}"
224+
`## Query
225+
226+
*The natural language query is:* "${nlQuery}"
214227
215-
## Available resources
216-
<resources>
217-
${resources.map(formatResource).join('\n')}
218-
</resources>
228+
## Available resources
229+
<resources>
230+
${resources.map(formatResource).join('\n')}
231+
</resources>
219232
220-
Based on the natural language query and the index descriptions, please return the most relevant indices with your reasoning.
221-
Remember, you should select at maximum ${limit} targets. If none match, just return an empty list.`,
233+
Based on the natural language query and the index descriptions, please return the most relevant indices with your reasoning.
234+
Remember, you should select at maximum ${limit} targets. If none match, just return an empty list.`,
222235
],
223236
];
224237
};
@@ -236,23 +249,26 @@ const selectResources = async ({
236249
}): Promise<SelectedResource[]> => {
237250
const { chatModel } = model;
238251
const indexSelectorModel = chatModel.withStructuredOutput(
239-
z.object({
240-
reasoning: z
241-
.string()
242-
.optional()
243-
.describe(
244-
'optional brief overall reasoning. Can be used to explain why you did not return any target.'
252+
z
253+
.object({
254+
reasoning: z
255+
.string()
256+
.optional()
257+
.describe(
258+
'optional brief overall reasoning. Can be used to explain why you did not return any target.'
259+
),
260+
targets: z.array(
261+
z.object({
262+
reason: z.string().describe('brief explanation of why this resource could be relevant'),
263+
type: z
264+
.enum([EsResourceType.index, EsResourceType.alias, EsResourceType.dataStream])
265+
.describe('the type of the resource'),
266+
name: z.string().describe('name of the index, alias or data stream'),
267+
})
245268
),
246-
targets: z.array(
247-
z.object({
248-
reason: z.string().describe('brief explanation of why this resource could be relevant'),
249-
type: z
250-
.enum([EsResourceType.index, EsResourceType.alias, EsResourceType.dataStream])
251-
.describe('the type of the resource'),
252-
name: z.string().describe('name of the index, alias or data stream'),
253-
})
254-
),
255-
})
269+
})
270+
.describe('Tool to use to select the relevant targets to search against'),
271+
{ name: 'select_resources' }
256272
);
257273

258274
const promptContent = createIndexSelectorPrompt({

x-pack/platform/plugins/shared/onechat/server/services/chat/utils/generate_title.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ export const generateTitle$ = ({
2525
}): Observable<string> => {
2626
return conversation$.pipe(
2727
switchMap((conversation) => {
28-
return defer(async () =>
29-
generateConversationTitle({
28+
return defer(async () => {
29+
return generateConversationTitle({
3030
previousRounds: conversation.rounds,
3131
nextInput,
3232
chatModel,
33-
})
34-
).pipe(shareReplay());
33+
});
34+
}).pipe(shareReplay());
3535
})
3636
);
3737
};
@@ -50,15 +50,28 @@ export const generateConversationTitle = async ({
5050
{ attributes: { [ElasticGenAIAttributes.InferenceSpanKind]: 'CHAIN' } },
5151
async (span) => {
5252
const structuredModel = chatModel.withStructuredOutput(
53-
z.object({
54-
title: z.string().describe('The title for the conversation'),
55-
})
53+
z
54+
.object({
55+
title: z.string().describe('The title for the conversation'),
56+
})
57+
.describe('Tool to use to provide the title for the conversation'),
58+
{ name: 'set_title' }
5659
);
5760

5861
const prompt: BaseMessageLike[] = [
5962
[
6063
'system',
61-
"'You are a helpful assistant. Assume the following messages is the start of a conversation between you and a user; give this conversation a title based on the content below",
64+
`You are a title-generation utility. Your ONLY purpose is to create a short, relevant title for the provided conversation.
65+
66+
You MUST call the 'set_title' tool to provide the title. Do NOT respond with plain text or any other conversational language.
67+
68+
Here is an example:
69+
Conversation:
70+
- User: "Hey, can you help me find out how to configure a new role in Kibana for read-only access to dashboards?"
71+
- Assistant: "Of course! To create a read-only role..."
72+
=> Your response MUST be a call to the 'set_title' tool like this: {"title": "Kibana Read-Only Role Configuration"}
73+
74+
Now, generate a title for the following conversation.`,
6275
],
6376
...conversationToLangchainMessages({ previousRounds, nextInput }),
6477
];

0 commit comments

Comments
 (0)