From 82e20611d26c297b090021a9622ff43338cad6e9 Mon Sep 17 00:00:00 2001 From: Dario Lopez Padial Date: Wed, 6 Dec 2023 12:55:37 +0100 Subject: [PATCH] Adding endpoints using the Tavily API and GPT3.5 to perform some comparisons --- doc/cron_etl_daily_public.sh | 2 +- requirements.txt | 1 + src/initialize.py | 6 +- src/service/main.py | 123 +++++++++++++++++++++++++++++++++++ 4 files changed, 129 insertions(+), 3 deletions(-) diff --git a/doc/cron_etl_daily_public.sh b/doc/cron_etl_daily_public.sh index 1bc2f39..ad1d920 100755 --- a/doc/cron_etl_daily_public.sh +++ b/doc/cron_etl_daily_public.sh @@ -11,4 +11,4 @@ export QDRANT_API_URL="" cd ia-boe/ source venv3.9/bin/activate pip install -r requirements.txt -python -m src.etls.etl_daily +python -m src.etls.boe.load.daily diff --git a/requirements.txt b/requirements.txt index ffce6b8..59acbf4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,6 +18,7 @@ supabase==1.0.2 pinecone-client==2.2.2 sentence_transformers==2.2.2 openai==1.2.3 +tavily-python==0.2.6 sendgrid==6.10.0 diff --git a/src/initialize.py b/src/initialize.py index 6e81ab7..defaccd 100644 --- a/src/initialize.py +++ b/src/initialize.py @@ -18,6 +18,7 @@ from qdrant_client import QdrantClient from qdrant_client.models import Distance, VectorParams from supabase.client import Client, create_client +from tavily import TavilyClient from src.utils import StandardSupabaseVectorStore @@ -44,12 +45,13 @@ def initialize_app(): config_loader = _init_config() vector_store = _init_vector_store(config_loader) openai_client = _init_openai_client() + tavily_client = TavilyClient(api_key=os.environ['TAVILY_API_KEY']) # retrieval_qa = _init_retrieval_qa_llm(vector_store, config_loader) logger.info("Initialized application") init_objects = collections.namedtuple( - "init_objects", ["config_loader", "vector_store", "openai_client"] + "init_objects", ["config_loader", "vector_store", "openai_client", "tavily_client"] ) - return init_objects(config_loader, vector_store, openai_client) + return init_objects(config_loader, vector_store, openai_client, tavily_client) def _init_config(): diff --git a/src/service/main.py b/src/service/main.py index 7599b70..7993ff6 100644 --- a/src/service/main.py +++ b/src/service/main.py @@ -41,6 +41,24 @@ async def semantic_search(input_query: str = DEFAULT_INPUT_QUERY): return docs +@APP.get("/semantic_search_tavily") +@timeit +async def semantic_search_tavily(input_query: str = DEFAULT_INPUT_QUERY): + logger = lg.getLogger(semantic_search_tavily.__name__) + logger.info(input_query) + docs = INIT_OBJECTS.tavily_client.search( + query=input_query, + search_depth="advanced", + include_domains=["https://www.boe.es/"], + max_results=10, + topic="general", + include_raw_content=False, + include_answer=False + ) + logger.info(docs) + return docs + + async def a_request_get(url): """Requests for sync/async load tests""" async with httpx.AsyncClient(timeout=10.0) as client: @@ -63,6 +81,62 @@ async def qa(input_query: str = DEFAULT_INPUT_QUERY): context_preprocessed = [ {"context": doc[0].page_content, "score": doc[1]} for doc in docs ] + messages = [ + {"role": "system", "content": INIT_OBJECTS.config_loader["prompt_system"]}, + { + "role": "system", + "content": INIT_OBJECTS.config_loader["prompt_system_context"], + }, + {"role": "system", "content": "A continuación se proporciona el contexto:"}, + {"role": "system", "content": str(context_preprocessed)}, + { + "role": "system", + "content": "A continuación se proporciona la pregunta del usuario:", + }, + {"role": "user", "content": input_query}, + ] + # logger.info(messages) + response = await INIT_OBJECTS.openai_client.chat.completions.create( + model=INIT_OBJECTS.config_loader["llm_model_name"], + messages=messages, + temperature=INIT_OBJECTS.config_loader["temperature"], + seed=INIT_OBJECTS.config_loader["seed"], + max_tokens=INIT_OBJECTS.config_loader["max_tokens"], + ) + answer = response.choices[0].message.content + logger.info(answer) + logger.info(response.usage) + + response_payload = dict( + scoring_id=str(uuid.uuid4()), + context=docs, + answer=answer, + ) + return response_payload + + +@APP.get("/qa_tavily") +@timeit +async def qa_tavily(input_query: str = DEFAULT_INPUT_QUERY): + logger = lg.getLogger(qa_tavily.__name__) + logger.info(input_query) + + # Getting context from internet browser (Tavily) + docs = INIT_OBJECTS.tavily_client.search( + query=input_query, + search_depth="advanced", + include_domains=["https://www.boe.es/"], + max_results=10, + topic="general", + include_raw_content=False, + include_answer=False + ) + + # Generate response using a LLM (OpenAI) + context_preprocessed = [ + {"context": doc['content'], "score": doc['score']} for doc in docs['results'] + ] + response = await INIT_OBJECTS.openai_client.chat.completions.create( model=INIT_OBJECTS.config_loader["llm_model_name"], messages=[ @@ -95,6 +169,55 @@ async def qa(input_query: str = DEFAULT_INPUT_QUERY): return response_payload +@APP.get("/qa_35") +@timeit +async def qa_35(input_query: str = DEFAULT_INPUT_QUERY): + logger = lg.getLogger(qa_35.__name__) + logger.info(input_query) + + # Getting context from embedding database (Qdrant) + docs = await INIT_OBJECTS.vector_store.asimilarity_search_with_score( + query=input_query, k=INIT_OBJECTS.config_loader["top_k_results"] + ) + + # Generate response using a LLM (OpenAI) + context_preprocessed = [ + {"context": doc[0].page_content, "score": doc[1]} for doc in docs + ] + messages = [ + {"role": "system", "content": INIT_OBJECTS.config_loader["prompt_system"]}, + { + "role": "system", + "content": INIT_OBJECTS.config_loader["prompt_system_context"], + }, + {"role": "system", "content": "A continuación se proporciona el contexto:"}, + {"role": "system", "content": str(context_preprocessed)}, + { + "role": "system", + "content": "A continuación se proporciona la pregunta del usuario:", + }, + {"role": "user", "content": input_query}, + ] + # logger.info(messages) + response = await INIT_OBJECTS.openai_client.chat.completions.create( + model='gpt-3.5-turbo', + messages=messages, + temperature=INIT_OBJECTS.config_loader["temperature"], + seed=INIT_OBJECTS.config_loader["seed"], + max_tokens=INIT_OBJECTS.config_loader["max_tokens"], + ) + answer = response.choices[0].message.content + logger.info(answer) + logger.info(response.usage) + + response_payload = dict( + scoring_id=str(uuid.uuid4()), + context=docs, + answer=answer, + ) + return response_payload + + @APP.get("/sleep") @timeit async def sleep():