import os import re import time from langchain_core.documents import Document from langchain_community.document_loaders import TextLoader from langchain.vectorstores import Chroma from langchain_text_splitters import CharacterTextSplitter from langchain import PromptTemplate, LLMChain from langchain.schema.runnable import RunnablePassthrough from langchain.schema import StrOutputParser from langchain_google_genai import ChatGoogleGenerativeAI from langchain_google_genai import GoogleGenerativeAIEmbeddings from langchain.chains.query_constructor.base import AttributeInfo from langchain.retrievers.self_query.base import SelfQueryRetriever from langchain.output_parsers import ResponseSchema, StructuredOutputParser from langchain.prompts import ChatPromptTemplate from langchain_core.runnables import RunnableLambda GOOGLE_API_KEY="" if "GOOGLE_API_KEY" not in os.environ: os.environ["GOOGLE_API_KEY"] = GOOGLE_API_KEY loader = TextLoader("/content/banco_de_questoes_v3.txt").load() gemini_embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001") # db = Chroma.from_documents(documents, gemini_embeddings) # vectorstore = Chroma.from_documents( # documents=documents, # embedding=gemini_embeddings, # persist_directory="./chroma_db" # ) # vectorstore_disk = Chroma( # persist_directory="./chroma_db", # embedding_function=gemini_embeddings # ) # retriever = vectorstore_disk.as_retriever(search_kwargs={"k": 10}) questions = list(map(lambda x: "##Questão" + x, loader[0].page_content.split("##Questão"))) def parse_question(question_str): # Extract content content_start = question_str.find('"""') + 3 content_end = question_str.rfind('"""', content_start) content = question_str[content_start:content_end].strip() # Extract correct option correct_option_start = question_str.find('opcao_correta=') + 15 correct_option_end = correct_option_start + 1 correct_option = question_str[correct_option_start:correct_option_end] # Extract metadata metadata_start = question_str.find("metadados=") + 10 metadata_end = question_str.find("}", metadata_start) + 1 metadata_str = question_str[metadata_start:metadata_end] metadata = eval(metadata_str) topico, assunto, dificuldade, tipo = metadata.values() return Document(page_content="##Questão\n" + content, metadata={"correct_option":correct_option, "topico":topico, "assunto":assunto, "dificuldade":dificuldade, "tipo":tipo}) # Lista para armazenar os documentos docs = [] for question in questions: try: docs.append(parse_question(question)) except Exception as e: print(e, question) docs[0] db = Chroma.from_documents(docs, gemini_embeddings) vectorstore = Chroma.from_documents( documents=docs, embedding=gemini_embeddings, persist_directory="./chroma_db" ) vectorstore_disk = Chroma( persist_directory="./chroma_db", embedding_function=gemini_embeddings ) metadata_field_info = [ AttributeInfo( name="topico", description="A materia escolar da qual a questão pertence.", type="string", ), AttributeInfo( name="assunto", description="O assunto da materia fornecida anteriormente.", type="string", ), AttributeInfo( name="dificuldade", description="O nivel de dificuldade para resolver a questao.", type="string", ), AttributeInfo( name="tipo", description="O tipo da questao. Pode ser ou Multipla Escolha ou Justificativa", type="string", ), ] document_content_description = "Questões de biologia" llm = ChatGoogleGenerativeAI(model="gemini-pro", temperature=0.7, top_p=1) retriever = SelfQueryRetriever.from_llm( llm, vectorstore, document_content_description, metadata_field_info, verbose=True ) print(len(retriever.get_relevant_documents("MMLU"))) llm_prompt_template = """Olá, sou uma IA treinada para gerar conteúdo educacional. Por favor, gere cinco questões de múltipla escolha sobre o seguinte tema: Instruções para cada questão: - Crie uma questão clara e relevante para o tema. - Forneça cinco opções de resposta, rotuladas de A) a E). - Apenas uma das opções de resposta deve ser correta. - Indique a resposta correta ao final de cada questão. Exemplo de uma questão: Tema: Fotossíntese Questão: Qual é o pigmento primário responsável pela fotossíntese nas plantas? Opções de Resposta: A) Clorofila B) Hemoglobina C) Mioglobina D) Citocromo E) Queratina Resposta Correta: A) Clorofila Context: {context} Question: {question} Answer: {format_questions_instructions} GIVE ME THE FIVE QUESTIONS SEPARATED IN AN ARRAY """ llm_prompt = PromptTemplate.from_template(llm_prompt_template) print(llm_prompt) questions_template = ChatPromptTemplate.from_template(template=llm_prompt_template) questions_chain = LLMChain(llm=llm, prompt=questions_template) questions_schema = ResponseSchema( name="questions", description="""Give the questions in json as an array""", ) questions_schemas = [questions_schema] questions_parser = StructuredOutputParser.from_response_schemas(questions_schemas) format_questions_instructions = questions_parser.get_format_instructions() print(format_questions_instructions) def get_questions(_dict): question = _dict["question"] context = _dict["context"] messages = questions_template.format_messages( context=context, question=question, format_questions_instructions=format_questions_instructions, ) chat = ChatGoogleGenerativeAI(model="gemini-pro") response = chat.invoke(messages) return questions_parser.parse(response.content) def format_docs(docs): return "\n\n".join(doc.page_content for doc in docs) # llm = ChatGoogleGenerativeAI(model="gemini-pro", temperature=0.7, top_p=1) rag_chain = ( {"context": retriever | RunnableLambda(format_docs), "question": RunnablePassthrough()} | RunnableLambda(get_questions) ) retriever start_time = time.time() assunto = "Bioquimica e Biofisica" query = f"Quero que você gere questões de biologia, sendo do assunto: {assunto}." print(rag_chain.invoke(f"""{query}""")) end_time = time.time() execution_time = end_time - start_time print(f"Tempo de execução: {execution_time:.2f} segundos.") assunto = "Bioquimica e Biofisica" query = f"Quero que você gere questões de biologia, sendo do assunto: {assunto}." res = rag_chain.invoke(f"""{query}""") res["questions"][0] docs = retriever.invoke(f"{query}") for doc in docs: print(doc) print() """###PIPELINE 2 """ class Document: def __init__(self, page_content, metadata): self.page_content = page_content self.metadata = metadata def parse_document(text): regex = r"Document\(\n\s+conteudo=\n\"{3}([^`]+?)\"{3}\n,\n\s+opcao_correta=\"(\w+)\"\,\n\s+metadados=\{([^}]+)\}\n\)" matches = re.finditer(regex, text, re.DOTALL) documents = [] for match in matches: page_content = match.group(1).strip() metadata_text = match.group(3).strip() metadata = {} metadata_entries = metadata_text.split(', ') for entry in metadata_entries: key, value = entry.split(': ') metadata[key.strip("'")] = value.strip("'") document = Document(page_content, metadata) documents.append(document) return documents with open('/content/banco_de_questoes_v2.txt', 'r', encoding='utf-8') as file: txt_data = file.read() docs = parse_document(txt_data) gemini_embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001") db = Chroma.from_documents(docs, gemini_embeddings) vectorstore = Chroma.from_documents( documents=docs, embedding=gemini_embeddings, persist_directory="./chroma_db" ) vectorstore_disk = Chroma( persist_directory="./chroma_db", embedding_function=gemini_embeddings ) metadata_field_info = [ AttributeInfo( name="topico", description="A materia escolar da qual a questão pertence.", type="string", ), AttributeInfo( name="assunto", description="O assunto da materia fornecida anteriormente.", type="string", ), AttributeInfo( name="dificuldade", description="O nivel de dificuldade para resolver a questao.", type="string", ), AttributeInfo( name="tipo", description="O tipo da questao. Pode ser ou Multipla Escolha ou Justificativa", type="string", ), ] document_content_description = "Questões de biologia" llm = ChatGoogleGenerativeAI(model="gemini-pro", temperature=0.7, top_p=1) retriever = SelfQueryRetriever.from_llm( llm, vectorstore, document_content_description, metadata_field_info, verbose=True ) retriever.invoke("Qual é a importância das células") """###PIPELINE 3 """ loader = TextLoader("/content/banco_de_questoes_v2.txt").load() gemini_embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001") text_splitter = CharacterTextSplitter(chunk_size=1024, chunk_overlap=0) documents = text_splitter.split_documents(loader) db = Chroma.from_documents(documents, gemini_embeddings) vectorstore = Chroma.from_documents( documents=documents, embedding=gemini_embeddings, persist_directory="./chroma_db" ) vectorstore_disk = Chroma( persist_directory="./chroma_db", embedding_function=gemini_embeddings ) metadata_field_info = [ AttributeInfo( name="topico", description="A materia escolar da qual a questão pertence.", type="string", ), AttributeInfo( name="assunto", description="O assunto da materia fornecida anteriormente.", type="string", ), AttributeInfo( name="dificuldade", description="O nivel de dificuldade para resolver a questao.", type="string", ), AttributeInfo( name="tipo", description="O tipo da questao. Pode ser ou Multipla Escolha ou Justificativa", type="string", ), ] document_content_description = "Questões de biologia" llm = ChatGoogleGenerativeAI(model="gemini-pro", temperature=0.7, top_p=1) retriever = SelfQueryRetriever.from_llm( llm, vectorstore, document_content_description, metadata_field_info, verbose=True ) print(len(retriever.get_relevant_documents("MMLU"))) llm_prompt_template = """Olá, sou uma IA treinada para gerar conteúdo educacional. Por favor, gere cinco questões de múltipla escolha sobre o seguinte tema: Instruções para cada questão: - Crie uma questão clara e relevante para o tema. - Forneça cinco opções de resposta, rotuladas de A) a E). - Apenas uma das opções de resposta deve ser correta. - Indique a resposta correta ao final de cada questão. Exemplo de uma questão: Tema: Fotossíntese Questão: Qual é o pigmento primário responsável pela fotossíntese nas plantas? Opções de Resposta: A) Clorofila B) Hemoglobina C) Mioglobina D) Citocromo E) Queratina Resposta Correta: A) Clorofila Context: {context} Question: {question} Answer: """ llm_prompt = PromptTemplate.from_template(llm_prompt_template) print(llm_prompt) def format_docs(docs): return "\n\n".join(doc.page_content for doc in docs) llm = ChatGoogleGenerativeAI(model="gemini-pro", temperature=0.7, top_p=1) rag_chain = ( {"context": retriever | format_docs, "question": RunnablePassthrough()} | llm_prompt | llm | StrOutputParser() ) start_time = time.time() assunto = "citologia" query = f"Preciso de cinco questões de biologia, sendo do assunto: {assunto}." print(rag_chain.invoke(f""" {query} """)) end_time = time.time() execution_time = end_time - start_time print(f"Tempo de execução: {execution_time:.2f} segundos.") docs = retriever.invoke(f"{query}") len(docs) print(docs)