PocketSkye commited on
Commit
13bd1bd
·
verified ·
1 Parent(s): f36f286

Upload 3 files

Browse files
Files changed (3) hide show
  1. retriever.py +139 -0
  2. summarizer.py +74 -0
  3. synthesizer.py +90 -0
retriever.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from langchain.chat_models import ChatOpenAI
3
+ from langchain.chains import RetrievalQA
4
+ from langchain.memory import ConversationBufferMemory
5
+ from langchain.prompts import PromptTemplate
6
+ from langchain.agents import initialize_agent, AgentType
7
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
8
+ from langchain.embeddings.huggingface import HuggingFaceEmbeddings
9
+ from langchain.vectorstores import FAISS
10
+ from langchain.tools import Tool
11
+ from langchain.tools import DuckDuckGoSearchRun
12
+ from langchain_core.documents import Document
13
+
14
+
15
+ from dotenv import load_dotenv
16
+ import os
17
+
18
+ load_dotenv()
19
+
20
+ apikey = os.getenv("MISTRAL_API_KEY")
21
+
22
+ llm = ChatOpenAI(
23
+ openai_api_key=apikey,
24
+ openai_api_base="https://api.mistral.ai/v1",
25
+ model="mistral-medium"
26
+ )
27
+
28
+ prompt_template = PromptTemplate(
29
+ input_variables=["user_prompt"],
30
+ template="""You are a retriever agent tasked with creating an efficient search small query to retrieve academic papers from arxiv relevant to a user’s request. Based on the user’s input prompt, generate a concise and precise search query (a string of keywords or phrases) that will be used by the function `retrieve_and_extract_papers(query: str, max_papers: int = 3) -> str` to fetch up to 3 relevant papers. The query should focus on key concepts, avoid ambiguity, and prioritize relevance to ensure the extracted text is suitable for summarization.
31
+
32
+ User Input Prompt: {user_prompt}
33
+
34
+ Instructions:
35
+ 1. Identify the core concepts, topics, or questions in the user prompt.
36
+ 2. Formulate a search query using relevant keywords or short phrases.
37
+ 3. Exclude overly broad or irrelevant terms to improve precision.
38
+ 4. Output only the search query as a string.
39
+
40
+ Example:
41
+ - User Prompt: "Recent advancements in large language models for natural language processing"
42
+ - Search Query: "large language models NLP advancements"
43
+
44
+ Generate the search query for the provided user prompt.
45
+ """
46
+ )
47
+
48
+
49
+ search_tool = DuckDuckGoSearchRun()
50
+ tools = [
51
+ Tool(
52
+ name="WebSearch",
53
+ func=search_tool.run,
54
+ description="Useful for fetching up-to-date healthcare information from the web.Use it rarely"
55
+ ),
56
+ ]
57
+
58
+ retriever_agent = initialize_agent(
59
+ tools=tools,
60
+ agent_type=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
61
+ llm=llm,
62
+ verbose=True,
63
+ prompt=prompt_template
64
+ )
65
+
66
+
67
+
68
+ import arxiv
69
+ import pdfplumber
70
+ import requests
71
+ import os
72
+ from typing import List
73
+ embedding_model = HuggingFaceEmbeddings(model_name="BAAI/bge-base-en-v1.5")
74
+ def retrieve_and_extract_papers(query: str, max_papers: int = 3) -> str:
75
+ """
76
+ Retrieves research papers from arXiv, downloads PDFs, extracts text,
77
+ and returns a single string with papers separated by '---pprN: Title'.
78
+
79
+ Args:
80
+ query: Search query (e.g., "diffusion models 2024")
81
+ max_papers: Number of papers to retrieve (default: 3)
82
+
83
+ Returns:
84
+ Single string with extracted text from PDFs, separated by '---pprN: Title'
85
+ """
86
+ # Initialize arXiv client
87
+ client = arxiv.Client()
88
+ search = arxiv.Search(
89
+ query=query,
90
+ max_results=max_papers,
91
+ sort_by=arxiv.SortCriterion.Relevance
92
+ )
93
+
94
+ papers = list(client.results(search))
95
+ if not papers:
96
+ return "No papers found for the query."
97
+
98
+ # Create temporary directory for PDFs
99
+ temp_dir = "temp_papers"
100
+ os.makedirs(temp_dir, exist_ok=True)
101
+
102
+ # Process each paper and collect extracted text
103
+ formatted_texts = []
104
+ for i, paper in enumerate(papers, 1):
105
+ try:
106
+ # Download PDF
107
+ pdf_url = paper.pdf_url
108
+ response = requests.get(pdf_url)
109
+ pdf_path = os.path.join(temp_dir, f"paper_{i}.pdf")
110
+
111
+ with open(pdf_path, 'wb') as f:
112
+ f.write(response.content)
113
+
114
+ # Extract text from PDF
115
+ text = ""
116
+ with pdfplumber.open(pdf_path) as pdf:
117
+ for page in pdf.pages:
118
+ page_text = page.extract_text()
119
+ if page_text:
120
+ text += page_text + "\n"
121
+
122
+ # Append formatted text with separator including paper title
123
+ separator = f"---ppr{i}: {paper.title}"
124
+ formatted_texts.append(f"{separator}\n{text}")
125
+
126
+ # Clean up: Remove the downloaded PDF
127
+ os.remove(pdf_path)
128
+
129
+ except Exception as e:
130
+ print(f"Error processing paper {i} ({paper.title}): {e}")
131
+ formatted_texts.append(f"---ppr{i}: {paper.title}\nError: Could not process paper.")
132
+
133
+ # Clean up: Remove temporary directory if empty
134
+ if os.path.exists(temp_dir) and not os.listdir(temp_dir):
135
+ os.rmdir(temp_dir)
136
+
137
+ # Join all texts into a single string
138
+ return "\n".join(formatted_texts)
139
+
summarizer.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from langchain.chat_models import ChatOpenAI
3
+ from langchain.chains import RetrievalQA
4
+ from langchain.memory import ConversationBufferMemory
5
+ from langchain.prompts import PromptTemplate
6
+ from langchain.agents import initialize_agent, AgentType
7
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
8
+ from langchain.embeddings.huggingface import HuggingFaceEmbeddings
9
+ from langchain.vectorstores import FAISS
10
+ from langchain.tools import Tool
11
+ from langchain.tools import DuckDuckGoSearchRun
12
+ from langchain_core.documents import Document
13
+ from langchain_community.vectorstores import FAISS
14
+ from langchain_community.embeddings import HuggingFaceEmbeddings
15
+ from dotenv import load_dotenv
16
+
17
+ load_dotenv()
18
+
19
+ apikey = os.getenv("MISTRAL_API_KEY")
20
+
21
+ embedding_model = HuggingFaceEmbeddings(model_name="BAAI/bge-base-en-v1.5")
22
+ faiss_index = FAISS.load_local("faiss_index", embedding_model, allow_dangerous_deserialization=True)
23
+ retriever = faiss_index.as_retriever(search_kwargs={"k": 3})
24
+
25
+ llm = ChatOpenAI(
26
+ openai_api_key=apikey,
27
+ openai_api_base="https://api.mistral.ai/v1",
28
+ model="mistral-medium"
29
+ )
30
+
31
+ from langchain.prompts import PromptTemplate
32
+
33
+ prompt_template = PromptTemplate(
34
+ input_variables=["user_prompt", "retriever_query"],
35
+ template="""You are a summarizer agent tasked with generating a concise summary of academic papers retrieved from a RAG pipeline. Using the user’s prompt and the retriever query used for searching, fetch relevant document content with the RAG tool and summarize the key points, findings, or insights relevant to the user’s request.
36
+
37
+ User Input Prompt: {user_prompt}
38
+ Retriever Query: {retriever_query}
39
+
40
+ Instructions:
41
+ 1. Use the RAG tool to retrieve document content based on the retriever query.
42
+ 2. Analyze the user prompt to identify the focus or specific aspects of interest.
43
+ 3. Summarize the main ideas, results, or trends from the retrieved documents, excluding unnecessary details.
44
+ 4. Ensure the summary is clear, coherent, and no longer than 1500 words.
45
+ 5. If the RAG tool returns irrelevant or insufficient documents, note this briefly and provide a general response based on the prompt.
46
+ 6. Output only the summary as a string.
47
+
48
+ Example:
49
+ - User Prompt: "Recent advancements in large language models for natural language processing"
50
+ - Retriever Query: "large language models NLP advancements"
51
+ - Summary: "Recent advancements in large language models (LLMs) focus on improved efficiency and performance in NLP tasks. Techniques like fine-tuning and transformer architectures enhance accuracy in text generation and understanding."
52
+
53
+ Generate the summary for the provided user prompt and retriever query.
54
+ """
55
+ )
56
+ search_tool = DuckDuckGoSearchRun()
57
+
58
+ tools = [
59
+ Tool(
60
+ name="FAISSRetriever",
61
+ func=lambda query: "\n\n".join([doc.page_content for doc in retriever.invoke(query)]),
62
+ description="Fetches the top 3 relevant document chunks from a FAISS index containing academic paper content based on a query. Use for retrieving scholarly text for summarization."
63
+ ),
64
+ ]
65
+ summarizer_agent = initialize_agent(
66
+ tools=tools,
67
+ agent_type=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
68
+ llm=llm,
69
+ verbose=True,
70
+ prompt=prompt_template,
71
+ retriever=retriever
72
+ )
73
+
74
+
synthesizer.py ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from langchain.chat_models import ChatOpenAI
3
+ from langchain.chains import RetrievalQA
4
+ from langchain.memory import ConversationBufferMemory
5
+ from langchain.prompts import PromptTemplate
6
+ from langchain.agents import initialize_agent, AgentType
7
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
8
+ from langchain.embeddings.huggingface import HuggingFaceEmbeddings
9
+ from langchain.vectorstores import FAISS
10
+ from langchain.tools import Tool
11
+ from langchain.tools import DuckDuckGoSearchRun
12
+ from langchain_core.documents import Document
13
+
14
+ from dotenv import load_dotenv
15
+
16
+ load_dotenv()
17
+
18
+ apikey = os.getenv("MISTRAL_API_KEY")
19
+
20
+ llm = ChatOpenAI(
21
+ openai_api_key=apikey,
22
+ openai_api_base="https://api.mistral.ai/v1",
23
+ model="mistral-large-2411"
24
+ )
25
+
26
+ from langchain.prompts import PromptTemplate
27
+
28
+ prompt_template = PromptTemplate(
29
+ input_variables=["user_prompt", "summaries", "critiques"],
30
+ template="""You are a Synthesizer Agent assisting in generating a structured research overview for a given topic.
31
+ You are provided with:
32
+ 1. The user’s original prompt.
33
+ 2. A set of summaries extracted from multiple research papers.
34
+ 3. Critique analysis, including commentary on contradictions, outdated information, and biased claims, along with associated critique scores (from 1 to 5, where 5 is most critical).
35
+
36
+ Your task is to:
37
+ - Analyze the summaries to extract core findings and organize them into a clear, topic-wise outline.
38
+ - Incorporate the critiques along with their scores in a dedicated section to highlight research limitations or cautionary notes.
39
+
40
+ User Prompt:
41
+ {user_prompt}
42
+
43
+ Paper Summaries:
44
+ {summaries}
45
+
46
+ Critique Analysis (with scores):
47
+ {critiques}
48
+
49
+ Instructions:
50
+ 1. Begin with a concise introduction to the research topic based on the user prompt.
51
+ 2. Generate a structured outline capturing key themes, methodologies, findings, and notable contributions.
52
+ 3. Follow up with a \"Critical Reflections\" section that includes:
53
+ - A list of critical observations.
54
+ - Their corresponding critique scores.
55
+ - Any specific recommendations or warnings.
56
+ 4. Maintain a professional and academic tone throughout.
57
+ 5. The final response should be suitable for inclusion in a research literature review or academic discussion.
58
+
59
+ Output Format:
60
+ - **Introduction**
61
+ - **Outline**
62
+ - Theme 1: ...
63
+ - Theme 2: ...
64
+ - **Critical Reflections**
65
+ - Observation 1 (Score: X): ...
66
+ - Observation 2 (Score: X): ...
67
+ - Outdated or Contradictory Claims (if any): ...
68
+ - Recommendations: ...
69
+
70
+ Now generate the structured synthesis below:
71
+ """
72
+ )
73
+
74
+ search_tool = DuckDuckGoSearchRun()
75
+
76
+ tools = [
77
+ Tool(
78
+ name="WebSearch",
79
+ func=DuckDuckGoSearchRun().run,
80
+ description="Fetches up-to-date information from the web. Use for verifying claims or finding additional context."
81
+ ),
82
+ ]
83
+
84
+ synthesizer_agent = initialize_agent(
85
+ tools=tools,
86
+ agent_type=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
87
+ llm=llm,
88
+ verbose=True,
89
+ prompt=prompt_template
90
+ )