From 905728293a55c861b0f569ac42a0ef1dd2b6f49d Mon Sep 17 00:00:00 2001 From: samelhousseini <108335186+samelhousseini@users.noreply.github.com> Date: Tue, 25 Jul 2023 12:17:26 +0400 Subject: [PATCH 1/2] Made the Cognitive Search Vector Store to be the default --- template.json | 3 ++- utils/env_vars.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/template.json b/template.json index b96434d..7475ba7 100644 --- a/template.json +++ b/template.json @@ -42,7 +42,8 @@ "allowedValues": [ "westeurope", "eastus", - "southcentralus" + "southcentralus", + "francecentral" ] }, "DeployNewRedisResource": { diff --git a/utils/env_vars.py b/utils/env_vars.py index 17b7a57..2ec5c4a 100644 --- a/utils/env_vars.py +++ b/utils/env_vars.py @@ -24,11 +24,11 @@ CONVERSATION_TTL_SECS = int(os.environ.get("CONVERSATION_TTL_SECS", "172800")) -USE_COG_VECSEARCH = int(os.environ.get("USE_COG_VECSEARCH", "0")) +USE_COG_VECSEARCH = int(os.environ.get("USE_COG_VECSEARCH", "1")) DATABASE_MODE = int(os.environ.get("DATABASE_MODE", "0")) -USE_REDIS_CACHE = int(os.environ.get("USE_REDIS_CACHE", "1")) +USE_REDIS_CACHE = int(os.environ.get("USE_REDIS_CACHE", "0")) PROCESS_IMAGES = int(os.environ.get("PROCESS_IMAGES", "0")) From 7287da906660b6b78c6bc385ec861200522ce8b4 Mon Sep 17 00:00:00 2001 From: samelhousseini <108335186+samelhousseini@users.noreply.github.com> Date: Tue, 25 Jul 2023 13:02:03 +0400 Subject: [PATCH 2/2] Updated the README and the ARM template --- README.md | 23 ++++++++++++----------- experiment.ipynb | 39 ++++++++++++++++++++++++++++++++++----- images/km-openai v2.jpg | Bin 0 -> 160924 bytes template.json | 2 +- utils/env_vars.py | 2 +- 5 files changed, 48 insertions(+), 18 deletions(-) create mode 100644 images/km-openai v2.jpg diff --git a/README.md b/README.md index 85ded3a..eacb390 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,9 @@
+ > **Note:** -> Please sign up here for the vector store feature (private preview) in Cognitive Search: [aka.ms/VectorSearchSignUp](aka.ms/VectorSearchSignUp) +> Redis is not used to store embeddings anymore, but now the Vector Store in Cognitive Search is used for the embeddings. Redis is still needed to store the user conversation history (chat session). Therefore, a Redis container (ACI) can be used instead of Redis Enterprise. The user can use redis.yml in the repo to create a Redis container.
@@ -24,13 +25,13 @@

- +



# Purpose -The purpose of this repo is to accelerate the deployment of a Python-based Knowledge Mining solution with OpenAI that will ingest a Knowledge Base, generate embeddings using the contents extracted, store them in a vector search engine (Redis), and use that engine to answer queries / questions specific to that Knowledge Base. +The purpose of this repo is to accelerate the deployment of a Python-based Knowledge Mining solution with OpenAI that will ingest a Knowledge Base, generate embeddings using the contents extracted, store them in a vector search engine (Cognitive Search), and use that engine to answer queries / questions specific to that Knowledge Base. The Cognitive Search component serves to make it easier to ingest a Knowledge Base with a variety of document formats. The Cognitive Services component connected to the Search makes it possible to have an enrichment pipeline. This pipeline can generate information based on images for example, which can be included at the time of generating embeddings. @@ -46,9 +47,9 @@ The below are the features of this solution: 1. Improved prompts and workflow handling with LangChain. The user should see improved search results in the form of better answers. -1. Using both Redis and Cognitive Search (Semantic Search) as tools for the LangChain Agent. Also, added Bing as a third search tool, which can be enabled or disabled. +1. Using Cognitive Search (Semantic Search and Vector Search) as tools for the LangChain Agent. Also, added Bing as a another search tool, which can be enabled or disabled. -1. The user can choose to skip Redis provisioning completely by keeping `REDIS_ADDR` blank in the configuration. However, that means that the session history cannot be cached, and each query/question is independent of the previous ones. +1. Redis is used only to cache some intermediate results, as well as caching the user conversation history. However, the user can choose to skip Redis provisioning completely by keeping `REDIS_ADDR` blank in the configuration. This means that the session history cannot be cached, and each query/question is independent of the previous ones. 1. Added filtering support in the Bot HTTP request API. This would be useful for things like multi-tenant demos, and filtering on docuemnts with an original source language. Use `"filter":"@field:value"` in the HTTP request e.g. `"filter":"@orig_lang:en"`. @@ -68,7 +69,7 @@ The below are the features of this solution: 1. Automatic translation from/to English using Cognitive Services, since OpenAI works best with English -1. The Cognitive Search ecosystem provides the potential to add a wide variety of custom skills, as well as access the native search capabilities which can complement the embedding search in Redis. +1. The Cognitive Search ecosystem provides the potential to add a wide variety of custom skills, as well as access the native search capabilities which can complement the embedding search. 1. Automatic deployment of the Azure Functions from this repo to the Function App @@ -89,7 +90,7 @@ Multiple Search Parameters have been added to control the behavior of the agent. 1. `enable_redis_search`: enables search with embeddings in Redis -1. `enable_cognitive_search`: enables semantic search and lookup in Cognitive Search. +1. `enable_cognitive_search`: enables vector search, semantic search and lookup in Cognitive Search. 1. `evaluate_step`: search text results sometimes have the answer to the question but the results might be so long that OpenAI completion call might miss that information (too much noise). `evaluate_step` was created to address this problem. This is a separate call to the OpenAI Completion API to identify the facts that are relevant only to the question. @@ -122,11 +123,11 @@ The below is a simple illustrative example. The knowledge base consists of the s Here are the results: -1. The One-Pass Agent searched Redis (or Cognitive Search) for the full question, and got all the top ranking results about Sherlock Holmes. The final answer is `"I'm sorry, I could not find any information about the Volcano Hotel in the provided context."` +1. The One-Pass Agent searched Cognitive Search for the full question, and got all the top ranking results about Sherlock Holmes. The final answer is `"I'm sorry, I could not find any information about the Volcano Hotel in the provided context."` -1. The Conversational-Chat-ReAct Agent gave a mixed bag of results. Because it has not been explicitly instructed in the prompt how many iterations it can do, sometimes it did one search in Redis (or Cognitive Search), and sometimes two searches. The first search is almost always about Sherlock Holmes, with the search string `"Sherlock Holmes country"`. If it did go for a second search iteration, then it looks for `"Volcano hotel country"`. The final answer is either `"Sherlock Holmes is a fictional character from the United Kingdom. However, I do not have information about the location of the Volcano hotel."` or, when it does 2 searches, then it gets `"The Volcano Hotel is located in Las Vegas, United States. Sherlock Holmes lived in London, England . Therefore, Sherlock Holmes did not live in the same country as the Volcano Hotel."`. +1. The Conversational-Chat-ReAct Agent gave a mixed bag of results. Because it has not been explicitly instructed in the prompt how many iterations it can do, sometimes it did one search in Cognitive Search, and sometimes two searches. The first search is almost always about Sherlock Holmes, with the search string `"Sherlock Holmes country"`. If it did go for a second search iteration, then it looks for `"Volcano hotel country"`. The final answer is either `"Sherlock Holmes is a fictional character from the United Kingdom. However, I do not have information about the location of the Volcano hotel."` or, when it does 2 searches, then it gets `"The Volcano Hotel is located in Las Vegas, United States. Sherlock Holmes lived in London, England . Therefore, Sherlock Holmes did not live in the same country as the Volcano Hotel."`. -1. The Zero-Shot-ReAct Agent really shines here because it is explicitly told that it can do multiple searches in the context of answering a single query. It first searches Redis (or Cognitive Search) for `"Sherlock Holmes country"`, and then searches again for `"Volcano hotel location"`, and gives the right answer every time: `"Sherlock Holmes lived in London, England, while the Volcano Hotel is located in Las Vegas, United States. They are not in the same country."`. +1. The Zero-Shot-ReAct Agent really shines here because it is explicitly told that it can do multiple searches in the context of answering a single query. It first searches Cognitive Search for `"Sherlock Holmes country"`, and then searches again for `"Volcano hotel location"`, and gives the right answer every time: `"Sherlock Holmes lived in London, England, while the Volcano Hotel is located in Las Vegas, United States. They are not in the same country."`.
@@ -208,7 +209,7 @@ Then install the required packages using the following command: 1. ARM: Adding Application Insights to the ARM template 1. Code: Adding a custom skill that processes csv files 1. Code: Adding a demo for HTML crawling -1. Code: Adding an embedding match filtering (in Redis) for filtering on metadata +1. Code: Adding an embedding match filtering (in Cognitive Search) for filtering on metadata 1. Integrating the features of the new repo from CogSearch PG into this one diff --git a/experiment.ipynb b/experiment.ipynb index 27ce67d..7f0ad46 100644 --- a/experiment.ipynb +++ b/experiment.ipynb @@ -54,9 +54,18 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The autoreload extension is already loaded. To reload it, use:\n", + " %reload_ext autoreload\n" + ] + } + ], "source": [ "import os\n", "from dotenv import load_dotenv\n", @@ -80,6 +89,26 @@ "%autoreload 2" ] }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'https://searchseh000000.search.windows.net'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "COG_SEARCH_ENDPOINT" + ] + }, { "attachments": {}, "cell_type": "markdown", @@ -92,15 +121,15 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Index km-openai-sem Deleted\n", - "Index km-openai-sem created\n", + "Index vec-index Deleted\n", + "Index vec-index created\n", "Index km-openai Deleted\n", "Index km-openai created\n", "Deleted Skillset - km-openai-skills\n", diff --git a/images/km-openai v2.jpg b/images/km-openai v2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b2a7fff6ac550b31974cbd0cecfb15cc4ba6a08d GIT binary patch literal 160924 zcmd>mbyQp3wr?m-DHJHK#R~Ugo-@lJfNlZfch?a_;j+TmshJl%zje+qg6AcZ!@RO&{ zcm)Im=-EUiMffDR`33lXy9gRCE-wCke2NDTDEJ=JJm&kSUw7XDL^$XY*ca$%jDUMY zXy`;}cbx!w000dW^=p6o!TbwT-QdtDC!rr#XA$9c)jZHs0I=i}idi(mvpyLyhQ`0lE%PXsE>l>R}+dIc6r)TFE zmsi*D-}FKQp#Pg%f6?qe=tYFm>mCLMItKP{dZFF(Ks9tC49v&8Si~~w*zcT382LWo zJbDqAQ}qLviC^Q0^u6;a9vQR1GRyIAs{Ki`Kc-l~zogk;6#J`QvjBW_G}Ppw69J?F zmvHvnk9hw|lM~U9f2XVhYJe#L0*65A*XoBzj3;;n34iOqBR zBsv#(On+YPN9NP4aepnZ;T>s?=x{*7|IgjTMD^3r$8w6gkPz#86OYuNWB%W6n#`Le zWl0L>0)R%T!pJO5MOgs1T1g(;_?Y_h`w2VNedhv+Z|<$ZQ~CTI zMOtE;VUP!}((|G8Jks+tJX@IVZ;MN7eCL=_$hD#2%I-cQ$A!iHlp4JOd^k~!cYvOq zgS3^Kua%F3PuPVNmX*8lRwcy}Ok9>DV34h6SfZXFXV?*4Rw1XMKY>i8+D@W*8_9;r zyYM27A&(l#fbgP%g$M-q;-)BfpvO%|Abg`jH;{Q{)@tg7l9Ptvv)u3}j~=PZ0{+`J zbrW?~q-lB}Job@8UG@>+cN*GPFfe(Rw1t0xd8p>~x8l%yGNQZjA}h7KQCBf{0EP^4 zWcw;ouIQL2%#Dl91nRnbUxZs_HY=$Q+uc!g2yoz8@nyv2vzLd*ErGu7oAkyDMSrfm zvfM`M43NplIW@*4`0V=WA@jrQy0jl*!xgK&cK~!9H~NRBij}m4FY5w;4I_$9fn27!70#Wn+~bL%dq z#QC*q3c@b&DwVY!vwBd%QrTu-afX3b=0UFnRi#7aZt7w|v231fQI~_o`W$4pk+*?`cNmu z*~`V6-+^#(z6D#swj80l}E_JI#ook{esGwG_ykU*p-Zxq7WHEIXL7x+^9*;wBR**yq&3=?6PFm13EK|6WA0Xmi+#Q+)!J&` zYiT>~F~z{h+kAlZupmi?$dIBW3FHn?QJ~pb@`4Yj&p8L*a!b_ZExO8GF`syP2qvD> zhOXF9J)4V{i3~Qm+U{w%WxoP;(y<-WRvY)&70P^w{}7i?Y^mxsjkby&?J~U81{N2( zK-nDU?wcm1{pPd%#@SJ$#;J1^UEQXt5xafgG@%*Eg~gSiJ3v#8qvGyxJ(S5;oLdDKyCSR5;W@n!vGw44{Mta6S(He~h*DQkDRZCs={fGaA0axvlV7@GJ z_(b-7l)!(&2&;MEtYrQ^<`CEnzwa_Hewj372X|1}s&socLZqr4(!`GT4x|6ZWjC

+nR#(lj+Udo>0)zqyF_U=(# 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