alexkueck commited on
Commit
ce0c292
1 Parent(s): 25715b2

Update utils.py

Browse files
Files changed (1) hide show
  1. utils.py +83 -51
utils.py CHANGED
@@ -278,62 +278,94 @@ def document_storage_chroma(splits):
278
  #HF embeddings--------------------------------------
279
  #Chroma.from_documents(documents = splits, embedding = HuggingFaceEmbeddings(model_name="sentence-transformers/all-mpnet-base-v2", model_kwargs={"device": "cpu"}, encode_kwargs={'normalize_embeddings': False}), persist_directory = PATH_WORK + CHROMA_DIR)
280
  return vectorstore, retriever
 
 
 
 
 
 
 
 
281
 
 
 
282
 
283
- """
284
- #Mongo DB die splits ablegen - vektorisiert...
285
- def document_storage_mongodb(splits):
286
- MongoDBAtlasVectorSearch.from_documents(documents = splits,
287
- embedding = OpenAIEmbeddings(disallowed_special = ()),
288
- collection = MONGODB_COLLECTION,
289
- index_name = MONGODB_INDEX_NAME)
290
- ############################################
291
- #dokumente in chroma db vektorisiert ablegen können - die Db vorbereiten daüfur
292
- def document_retrieval_chroma(llm, prompt):
293
- #OpenAI embeddings -------------------------------
294
- embeddings = OpenAIEmbeddings()
295
 
296
- #HF embeddings -----------------------------------
297
- #Alternative Embedding - für Vektorstore, um Ähnlichkeitsvektoren zu erzeugen - die ...InstructEmbedding ist sehr rechenaufwendig
298
- #embeddings = HuggingFaceInstructEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2", model_kwargs={"device": "cpu"})
299
- #etwas weniger rechenaufwendig:
300
- #embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-mpnet-base-v2", model_kwargs={"device": "cpu"}, encode_kwargs={'normalize_embeddings': False})
301
 
302
- #ChromaDb um die embedings zu speichern
303
- db = Chroma(embedding_function = embeddings, persist_directory = PATH_WORK + CHROMA_DIR)
304
- return db
305
 
306
- ############################################
307
- #dokumente in chroma db vektorisiert ablegen können - die Db vorbereiten daüfur
308
- #zweite Variante, passend zu rag_chain2 für generate_text_mit_bild- ohne llm vorher festlegen zu müssen
309
- def document_retrieval_chroma2():
310
- #OpenAI embeddings -------------------------------
311
- embeddings = OpenAIEmbeddings()
312
-
313
- #HF embeddings -----------------------------------
314
- #Alternative Embedding - für Vektorstore, um Ähnlichkeitsvektoren zu erzeugen - die ...InstructEmbedding ist sehr rechenaufwendig
315
- #embeddings = HuggingFaceInstructEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2", model_kwargs={"device": "cpu"})
316
- #etwas weniger rechenaufwendig:
317
- #embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-mpnet-base-v2", model_kwargs={"device": "cpu"}, encode_kwargs={'normalize_embeddings': False})
318
- #oder einfach ohne Langchain:
319
- #embeddings = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
320
-
321
- #ChromaDb um die embedings zu speichern
322
- db = Chroma(embedding_function = embeddings, persist_directory = PATH_WORK + CHROMA_DIR)
323
- print ("Chroma DB bereit ...................")
324
-
325
- return db
326
-
327
- ###########################################
328
- #dokumente in mongo db vektorisiert ablegen können - die Db vorbereiten daüfür
329
- def document_retrieval_mongodb(llm, prompt):
330
- db = MongoDBAtlasVectorSearch.from_connection_string(MONGODB_URI,
331
- MONGODB_DB_NAME + "." + MONGODB_COLLECTION_NAME,
332
- OpenAIEmbeddings(disallowed_special = ()),
333
- index_name = MONGODB_INDEX_NAME)
334
- return db
335
- """
336
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
337
 
338
 
339
  ###############################################
@@ -1120,7 +1152,7 @@ class GraphState(TypedDict):
1120
  #Methoden, um den Graph und die Zustände umzusetzen
1121
  ### Nodes ###
1122
  # die Knoten des Graphen definieren, die der Reihe noch (bzw. je nach Outcome des Vorgänger Knotens) durchlaufen werden
1123
- def retrieve(state):
1124
  """
1125
  Retrieve documents
1126
  Args:
 
278
  #HF embeddings--------------------------------------
279
  #Chroma.from_documents(documents = splits, embedding = HuggingFaceEmbeddings(model_name="sentence-transformers/all-mpnet-base-v2", model_kwargs={"device": "cpu"}, encode_kwargs={'normalize_embeddings': False}), persist_directory = PATH_WORK + CHROMA_DIR)
280
  return vectorstore, retriever
281
+
282
+ #Dokumente, die vom Retriever rausgesucht wurden auf Relevanz untersuchen
283
+ def grade_documents_direct(state):
284
+ print("---CHECK RELEVANCE---")
285
+ # Data model
286
+ class grade(BaseModel):
287
+ """Binary score for relevance check."""
288
+ binary_score: str = Field(description="Relevanz Bewertung 'ja' oder 'nein'")
289
 
290
+ # LLM
291
+ model = ChatOpenAI(temperature=0.3, model="gpt-4-0125-preview", streaming=True)
292
 
293
+ # Tool
294
+ grade_tool_oai = convert_to_openai_tool(grade)
 
 
 
 
 
 
 
 
 
 
295
 
296
+ # LLM with tool and enforce invocation
297
+ llm_with_tool = model.bind(
298
+ tools=[convert_to_openai_tool(grade_tool_oai)],
299
+ tool_choice={"type": "function", "function": {"name": "grade"}},
300
+ )
301
 
302
+ # Parser
303
+ parser_tool = PydanticToolsParser(tools=[grade])
 
304
 
305
+ # Prompt
306
+ prompt = PromptTemplate(
307
+ template="""Du bist ein Bewerter, der die Relevanz von einem erhaltenen Dokument zu einer Nutzeranfrage bewerten soll. \n
308
+ Hier ist das erhaltene Dokument: \n\n {context} \n\n
309
+ Hier ist die Nutzeranfrage: {question} \n
310
+ Wenn das erhaltene Dokument Keywörter oder semantische Bedeutung in Bezug auf die Nutzeranfrage hat, bewerte es als relevant. \n
311
+ Gib eine binäre Bewertung von 'ja' oder 'nein' Bewertung, um anzuzeigen ob das Dokuemnt relevant ist zur Nutzeranfrage oder nicht.""",
312
+ input_variables=["context", "question"],
313
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
314
 
315
+ # Chain
316
+ chain = prompt | llm_with_tool | parser_tool
317
+
318
+ # Score
319
+ filtered_docs = []
320
+ anzahl_relevant = 0
321
+ search = "nein" # Default do not opt for re-questioning to supplement retrieval
322
+ for d in documents:
323
+ score = chain.invoke({"question": question, "context": d.page_content})
324
+ grade = score[0].binary_score
325
+ if grade == "ja":
326
+ #search = "nein" # mind. ein relevantes Dokument -> keine Websuche nötig
327
+ print("---Bewertung: Dokument ist relevant---")
328
+ anzahl_relevant = anzahl_relevant +1
329
+ filtered_docs.append(d)
330
+ else:
331
+ print("---Bewertung: Dokument irrelevant---")
332
+ search = "ja" # mind ein Dokument irrelevant -> Frage umformulieren
333
+ continue
334
+ #wenn mehrheit der Dokumente relevant -> generieren starten damit
335
+ if (anzahl_relevant>= len(documents)/2):
336
+ search = "nein"
337
+ print("second trial grade_docs:.....................")
338
+ print(second_trial)
339
+ return filtered_docs
340
+
341
+
342
+ def transform_query_direct(query):
343
+ print("---TRANSFORM QUERY---")
344
+ state_dict = state["keys"]
345
+ question = state_dict["question"]
346
+ documents = state_dict["documents"]
347
+
348
+ # Create a prompt template with format instructions and the query
349
+ prompt = PromptTemplate(
350
+ template="""Du generierst Fragen, die optimiert sind für das Retrieval von Dokumenten. \n
351
+ Schaue auf den input und versuche die zugrundeliegende Absicht / Bedeutung zu bewerten. \n
352
+ Hier ist die ursprüngliche Frage:
353
+ \n ------- \n
354
+ {question}
355
+ \n ------- \n
356
+ Formuliere eine verbesserte Frage: """,
357
+ input_variables=["question"],
358
+ )
359
+
360
+ # Grader
361
+ model = ChatOpenAI(temperature=0, model="gpt-4-0125-preview", streaming=True)
362
+
363
+ # Prompt
364
+ chain = prompt | model | StrOutputParser()
365
+ better_question = chain.invoke({"question": question})
366
+ second_trial="ja"
367
+
368
+ return {"keys": {"documents": documents, "question": better_question, "second_trial" : second_trial}}
369
 
370
 
371
  ###############################################
 
1152
  #Methoden, um den Graph und die Zustände umzusetzen
1153
  ### Nodes ###
1154
  # die Knoten des Graphen definieren, die der Reihe noch (bzw. je nach Outcome des Vorgänger Knotens) durchlaufen werden
1155
+ def retrieve(state, retriever):
1156
  """
1157
  Retrieve documents
1158
  Args: