From 86d91bcb1205733d29f6f2c25cfe56d74e7f1d8e Mon Sep 17 00:00:00 2001 From: Adam Demjen Date: Mon, 28 Oct 2024 14:36:25 -0400 Subject: [PATCH] Improve function calling NB --- .../openai/function-calling.ipynb | 79 ++++++++++++------- 1 file changed, 49 insertions(+), 30 deletions(-) diff --git a/notebooks/integrations/openai/function-calling.ipynb b/notebooks/integrations/openai/function-calling.ipynb index 7c24cfe2..7e558a28 100644 --- a/notebooks/integrations/openai/function-calling.ipynb +++ b/notebooks/integrations/openai/function-calling.ipynb @@ -8,6 +8,14 @@ "# OpenAI function calling with Elasticsearch" ] }, + { + "cell_type": "markdown", + "id": "fd9c0775", + "metadata": {}, + "source": [ + "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/elastic/elasticsearch-labs/blob/main/notebooks/integrations/openai/function-calling.ipynb)" + ] + }, { "cell_type": "markdown", "id": "75f21771-cafe-496f-8aaf-7cc0f14f89ec", @@ -15,9 +23,9 @@ "source": [ "[Function calling](https://platform.openai.com/docs/guides/function-calling) in OpenAI refers to the capability of AI models to interact with external functions or APIs, allowing them to perform tasks beyond text generation. This feature enables the model to execute code, retrieve information from databases, interact with external services, and more, by calling predefined functions.\n", "\n", - "In this notebook we’re going to create two function: \n", - "`fetch_from_elasticsearch()` - Fetch data from Elasticsearch using natural language query. \n", - "`weather_report()` - Fetch a weather report for a particular location.\n", + "In this notebook we’re going to create two functions: \n", + "* `fetch_from_elasticsearch()` - Fetch data from Elasticsearch using natural language query. \n", + "* `weather_report()` - Fetch a weather report for a particular location.\n", "\n", "We'll integrate function calling to dynamically determine which function to call based on the user's query and generate the necessary arguments accordingly." ] @@ -40,28 +48,41 @@ "### Elastic\n", "\n", "Create an [Elastic Cloud deployment](https://www.elastic.co/search-labs/tutorials/install-elasticsearch/elastic-cloud) to get all Elastic credentials. \n", - "`ES_API_KEY`: [Create](https://www.elastic.co/search-labs/tutorials/install-elasticsearch/elastic-cloud#creating-an-api-key) an API key. \n", - "`ES_ENDPOINT`: [Copy](https://www.elastic.co/search-labs/tutorials/install-elasticsearch/elastic-cloud#finding-your-cloud-id) endpoint of Elasticsearch.\n", + "* `ES_API_KEY`: [Create](https://www.elastic.co/search-labs/tutorials/install-elasticsearch/elastic-cloud#creating-an-api-key) an API key. \n", + "* `ES_ENDPOINT`: [Copy](https://www.elastic.co/search-labs/tutorials/install-elasticsearch/elastic-cloud#finding-your-cloud-id) endpoint of Elasticsearch.\n", "\n", "### Open AI\n", "\n", - "`OPENAI_API_KEY`: Setup an [Open AI account and create a secret key](https://platform.openai.com/docs/quickstart). \n", - "`GPT_MODEL`: We’re going to use the `gpt-4o` model but you can check [here](https://platform.openai.com/docs/guides/function-calling) which model is being supported for function calling.\n", + "* `OPENAI_API_KEY`: Setup an [Open AI account and create a secret key](https://platform.openai.com/docs/quickstart). \n", + "* `GPT_MODEL`: We’re going to use the `gpt-4o` model but you can check [here](https://platform.openai.com/docs/guides/function-calling) which model is being supported for function calling.\n", "\n", "### Open-Meteo API\n", "\n", "We will use the [Open-Meteo API](https://open-meteo.com/). Open-Meteo is an open-source weather API and offers free access for non-commercial use. No API key required. \n", "\n", - "`OPEN_METEO_ENDPOINT`: `https://api.open-meteo.com/v1/forecast`\n", + "* `OPEN_METEO_ENDPOINT`: `https://api.open-meteo.com/v1/forecast`\n", "\n", "### Sample Data\n", - "After creating Elastic cloud deployment, Let’s [add sample flight data](https://www.elastic.co/guide/en/kibana/8.13/get-started.html#gs-get-data-into-kibana) on kibana. Sample data will be stored into the `kibana_sample_data_flights` index.\n", "\n", - "### Install depndencies\n", - "\n", - "```sh\n", - "pip install openai\n", - "```" + "After creating Elastic Cloud deployment, Let’s [add sample flight data](https://www.elastic.co/guide/en/kibana/8.13/get-started.html#gs-get-data-into-kibana) in Kibana. Sample data will be stored in the `kibana_sample_data_flights` index." + ] + }, + { + "cell_type": "markdown", + "id": "39087449", + "metadata": {}, + "source": [ + "## Install dependencies" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9fcc293b", + "metadata": {}, + "outputs": [], + "source": [ + "!pip install openai requests" ] }, { @@ -90,7 +111,7 @@ "id": "578a47e0-f9d7-49e5-a2b6-c417378392c3", "metadata": {}, "source": [ - "## Add Credentials" + "## Set credentials and configuration" ] }, { @@ -198,7 +219,7 @@ "metadata": {}, "outputs": [], "source": [ - "def build_query(nl_query):\n", + "def generate_elasticsearch_query(nl_query):\n", "\n", " index_mapping = get_index_mapping()\n", " ref_document = get_ref_document()\n", @@ -226,7 +247,7 @@ " }\n", " }\n", "\n", - " 2. User Query - airlines with the highest delays\n", + " 2. User Query - Airlines with the highest delays\n", " Elasticsearch Query DSL: \n", " {\n", " \"size\": 0,\n", @@ -273,18 +294,18 @@ " Index mapping:\n", " {index_mapping}\n", "\n", - " Reference elasticsearch document:\n", + " Reference Elasticsearch document:\n", " {ref_document}\n", "\n", - " Return single line Elasticsearch Query DSL according to index mapping for the below search query related to flights.:\n", + " Return single line Elasticsearch Query DSL according to index mapping for the below search query related to flights:\n", "\n", " {nl_query}\n", "\n", - " If any field has a `keyword` type, Just use field name instead of field.keyword.\n", + " If any field has a `keyword` type, just use field name instead of field.keyword.\n", "\n", - " Just return Query DSL without REST specification (e.g. GET, POST etc.) and json markdown format (e.g. ```json)\n", + " Just return Query DSL without REST specification (e.g. GET, POST etc.) and json markdown format (e.g. ```json).\n", "\n", - " few example of Query DSL\n", + " Few examples of Query DSL:\n", "\n", " {few_shots_prompt}\n", " \n", @@ -309,7 +330,7 @@ "id": "9678a30d-f2d9-457b-8a49-b41b409c8a73", "metadata": {}, "source": [ - "### Execute Query on Elasticsearch" + "### Execute Query in Elasticsearch" ] }, { @@ -321,19 +342,17 @@ "source": [ "def fetch_from_elasticsearch(nl_query):\n", "\n", - " query_dsl = build_query(nl_query)\n", + " query_dsl = generate_elasticsearch_query(nl_query)\n", " # print(f\"\"\"Query DSL: ==== \\n\\n {query_dsl}\"\"\")\n", "\n", " url = f\"\"\"{ES_ENDPOINT}/{ES_INDEX}/_search\"\"\"\n", "\n", - " payload = query_dsl\n", - "\n", " headers = {\n", " \"Content-type\": \"application/json\",\n", " \"Authorization\": f\"\"\"ApiKey {ES_API_KEY}\"\"\",\n", " }\n", "\n", - " resp = requests.request(\"GET\", url, headers=headers, data=payload)\n", + " resp = requests.request(\"GET\", url, headers=headers, data=query_dsl)\n", " resp = json.loads(resp.text)\n", " json_resp = json.dumps(resp, indent=4)\n", "\n", @@ -413,11 +432,11 @@ " \"properties\": {\n", " \"latitude\": {\n", " \"type\": \"string\",\n", - " \"description\": \"The latitude of a location with 0.01 degree\",\n", + " \"description\": \"The latitude of a location with 0.01 degree.\",\n", " },\n", " \"longitude\": {\n", " \"type\": \"string\",\n", - " \"description\": \"The longitude of a location with 0.01 degree\",\n", + " \"description\": \"The longitude of a location with 0.01 degree.\",\n", " },\n", " },\n", " \"required\": [\"latitude\", \"longitude\"],\n", @@ -430,7 +449,7 @@ " messages.append(\n", " {\n", " \"role\": \"system\",\n", - " \"content\": \"If no data received from any function. Just say there is issue fetching details from function(function_name).\",\n", + " \"content\": \"If no data received from any function, just say there is issue fetching details from function(function_name).\",\n", " }\n", " )\n", "\n",