Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Observability AI Assistant]: Summarise & recall #22

Merged
merged 6 commits into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Catch errors in recall
  • Loading branch information
dgieselaar committed Aug 3, 2023
commit 973c493cf02cf716052e389327ef33a2ef810c03
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { RegisterContextDefinition, RegisterFunctionDefinition } from '../.
import type { ObservabilityAIAssistantService } from '../types';
import { registerElasticsearchFunction } from './elasticsearch';
import { registerRecallFunction } from './recall';
import { registerSetupKbFunction } from './setup_kb';
import { registerSummarisationFunction } from './summarise';

export function registerFunctions({
Expand All @@ -29,4 +30,5 @@ export function registerFunctions({
registerElasticsearchFunction({ service, registerFunction });
registerSummarisationFunction({ service, registerFunction });
registerRecallFunction({ service, registerFunction });
registerSetupKbFunction({ service, registerFunction });
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import type { Serializable } from '@kbn/utility-types';
import type { RegisterFunctionDefinition } from '../../common/types';
import type { ObservabilityAIAssistantService } from '../types';

export function registerSetupKbFunction({
service,
registerFunction,
}: {
service: ObservabilityAIAssistantService;
registerFunction: RegisterFunctionDefinition;
}) {
registerFunction(
{
name: 'setup_kb',
contexts: ['core'],
description:
'Use this function to set up the knowledge base. ONLY use this if you got an error from the recall or summarise function, or if the user has explicitly requested it. Note that it might take a while (e.g. ten minutes) until the knowledge base is available. Assume it will not be ready for the rest of the current conversation.',
parameters: {
type: 'object',
properties: {},
},
},
({}, signal) => {
return service
.callApi('POST /internal/observability_ai_assistant/functions/setup_kb', {
signal,
})
.then((response) => ({ content: response as unknown as Serializable }));
}
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@
* 2.0.
*/

import dedent from 'dedent';
import { MessageRole } from '../../common';

export function getSystemMessage() {
return {
'@timestamp': new Date().toISOString(),
message: {
role: MessageRole.Assistant as const,
content: `You are a helpful assistant for Elastic Observability. Your goal is to help the Elastic Observability users to quickly assess what is happening in their observed systems. You can help them visualise and analyze data, investigate their systems, perform root cause analysis or identify optimisation opportunities.
content:
dedent(`You are a helpful assistant for Elastic Observability. Your goal is to help the Elastic Observability users to quickly assess what is happening in their observed systems. You can help them visualise and analyze data, investigate their systems, perform root cause analysis or identify optimisation opportunities.

You can use the "summarise" functions to store new information you have learned in a knowledge database. Once you have established that you did not know the answer to a question, and the user gave you this information, it's important that you create a summarisation of what you have learned and store it in the knowledge database. When you create this summarisation, make sure you craft it in a way that can be recalled with a semantic search later.

Expand All @@ -33,7 +35,7 @@ export function getSystemMessage() {

Note that any visualisations will be displayed ABOVE your textual response, not below.

Feel free to use Markdown in your replies.`,
Feel free to use Markdown in your replies.`),
},
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -245,26 +245,40 @@ export class ObservabilityAIAssistantClient implements IObservabilityAIAssistant
};

recall = async (query: string): Promise<{ entries: KnowledgeBaseEntry[] }> => {
const response = await this.dependencies.esClient.search<KnowledgeBaseEntry>({
index: this.dependencies.resources.aliases.kb,
query: {
bool: {
should: [
{
text_expansion: {
'ml.tokens': {
model_text: query,
model_id: '.elser_model_1',
},
} as unknown as QueryDslTextExpansionQuery,
},
],
filter: [...this.getAccessQuery()],
try {
const response = await this.dependencies.esClient.search<KnowledgeBaseEntry>({
index: this.dependencies.resources.aliases.kb,
query: {
bool: {
should: [
{
text_expansion: {
'ml.tokens': {
model_text: query,
model_id: '.elser_model_1',
},
} as unknown as QueryDslTextExpansionQuery,
},
],
filter: [...this.getAccessQuery()],
},
},
},
});
_source: {
excludes: ['ml.tokens'],
},
});

return { entries: response.hits.hits.map((hit) => hit._source!) };
return { entries: response.hits.hits.map((hit) => hit._source!) };
} catch (error) {
if (
(error instanceof errors.ResponseError &&
error.body.error.type === 'resource_not_found_exception') ||
error.body.error.type === 'status_exception'
) {
throwKnowledgeBaseNotReady(error.body);
}
throw error;
}
};

summarise = async ({
Expand Down