{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "collapsed": true, "id": "8xVCNjTd_gMs", "outputId": "644daaf8-dcd0-4f85-8244-f903d7975b5e" }, "outputs": [], "source": [ "!pip install gradio grandalf huggingface-hub langchain langchain-community langchain-core langchain-openai langgraph langgraph-checkpoint langgraph-checkpoint-postgres langgraph-checkpoint-sqlite langsmith openai psycopg pydantic pydantic_core tiktoken langchain-huggingface pymupdf4llm" ] }, { "cell_type": "markdown", "metadata": { "id": "vsujzwHTBtPN" }, "source": [ "# Systematic Review Automation System\n" ] }, { "cell_type": "markdown", "metadata": { "id": "qMta9MAbUz1B" }, "source": [ "A tool for automated academic literature review and synthesis\n", "\n", "## Introduction\n", "This system automates the process of creating systematic reviews of academic papers through a structured workflow. It handles everything from initial paper search to final draft generation using a directed graph architecture.\n", "\n", "## Use Cases\n", "\n", "**Primary Applications**\n", "- Conducting systematic literature reviews\n", "- Analyzing research trends across papers\n", "- Synthesizing findings from multiple studies\n", "- Creating comprehensive research summaries\n", "\n", "**Key Features**\n", "- Automated paper search and selection\n", "- PDF download and analysis\n", "- Section-by-section writing\n", "- Revision and critique cycles\n", "\n", "## Process Flow\n", "\n", "1. **Research Phase**\n", "- Topic planning and scoping\n", "- Automated paper search via Semantic Scholar\n", "- Smart paper selection (up to 3 papers - can be changed)\n", "- Automatic PDF retrieval\n", "\n", "2. **Analysis Phase**\n", "- PDF text extraction\n", "- Section-by-section analysis\n", "- Key finding identification\n", "- Cross-paper comparison\n", "\n", "3. **Writing Phase**\n", "- Automated section generation\n", "- Abstract (100-word limit)\n", "- Methods comparison\n", "- Results synthesis\n", "- APA reference formatting\n", "\n", "4. **Review Phase**\n", "- Quality assessment\n", "- Revision suggestions\n", "- Additional research triggers\n", "- Final draft preparation\n", "\n", "The system uses OpenAI's GPT models for text processing and maintains state through a graph-based workflow, ensuring systematic and thorough review generation." ] }, { "cell_type": "markdown", "metadata": { "id": "7YBGM7hNRSia" }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "id": "_b92uleGIv4s" }, "source": [ "## I. Flowchart Components Description" ] }, { "cell_type": "markdown", "metadata": { "id": "gHdOJKBmUvWB" }, "source": [ "### Nodes (Process Steps)\n", "\n", "1. **Initial Stages**\n", "- `_start_`: Beginning point of the process\n", "- `process_input`: Initial data processing stage\n", "- `planner`: Strategy development phase\n", "- `researcher`: Research coordination phase\n", "\n", "2. **Article Management**\n", "- `search_articles`: Article search and identification\n", "- `article_decisions`: Evaluation and selection of articles\n", "- `download_articles`: Retrieval of selected articles\n", "- `paper_analyzer`: In-depth analysis of papers\n", "\n", "3. **Writing Components**\n", "- `write_abstract`: Abstract composition\n", "- `write_conclusion`: Conclusion development\n", "- `write_introduction`: Introduction creation\n", "- `write_methods`: Methodology documentation\n", "- `write_references`: Reference compilation\n", "- `write_results`: Results documentation\n", "\n", "4. **Final Stages**\n", "- `aggregate_paper`: Combining all sections\n", "- `critique_paper`: Critical review phase\n", "- `revise_paper`: Revision process\n", "- `final_draft`: Final document preparation\n", "- `_end_`: Process completion\n", "\n", "## Edges (Connections)\n", "\n", "1. **Main Flow**\n", "- Solid arrows indicate direct progression between steps\n", "- Sequential flow from start through research phases\n", "- Parallel paths from paper_analyzer to writing components\n", "\n", "2. **Special Connections**\n", "- Dotted line with \"True\" label: Feedback loop to search_articles\n", "- \"revise\" connection: Loop between critique_paper and revise_paper\n", "- Multiple converging arrows into aggregate_paper from all writing components\n", "\n", "3. **Decision Points**\n", "- Branching at paper_analyzer to multiple writing tasks\n", "- Convergence at aggregate_paper from all writing components\n", "- Split path at critique_paper leading to either revision or final draft" ] }, { "cell_type": "markdown", "metadata": { "id": "jclcOF4PBrRd" }, "source": [ "## II. Imports\n", "- if you have postgres set up you can use that\n", "- we will use the MemorySaver() to store memory state" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "id": "1oMv72E5Ckdb" }, "outputs": [], "source": [ "from google.colab import userdata\n", "import os\n", "os.environ[\"OPENAI_API_KEY\"] = userdata.get('OPENAI_API_KEY')" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "id": "fdMhxiJFByvq" }, "outputs": [], "source": [ "from pydantic import BaseModel, Field\n", "from typing import TypedDict, Annotated, List, Dict, Any, Type\n", "import requests\n", "from langchain_core.tools import BaseTool\n", "\n", "from bs4 import BeautifulSoup\n", "import pymupdf4llm\n", "import sys\n", "from langchain_core.messages import AnyMessage, SystemMessage, HumanMessage, ToolMessage, AIMessage, ChatMessage\n", "\n", "import requests\n", "import ast\n", "import operator\n", "\n", "from langgraph.graph import StateGraph, END\n", "from langchain_openai import ChatOpenAI\n", "\n", "import os\n", "from uuid import uuid4\n", "from langgraph.checkpoint.postgres import PostgresSaver\n", "from langgraph.checkpoint.memory import MemorySaver\n", "from psycopg import Connection\n", "from langchain_huggingface import ChatHuggingFace, HuggingFaceEndpoint\n", "\n", "from tenacity import (\n", " retry,\n", " stop_after_attempt,\n", " wait_exponential,\n", " retry_if_exception_type\n", ")\n", "\n", "import openai\n", "from dotenv import load_dotenv\n", "_ = load_dotenv()" ] }, { "cell_type": "markdown", "metadata": { "id": "zuZhH9xFB2mO" }, "source": [ "## III. Academic Search Tool" ] }, { "cell_type": "markdown", "metadata": { "id": "2UkFeXa3UlE_" }, "source": [ "This tool helps researchers and students search for academic papers efficiently. It connects to the Semantic Scholar API and returns structured paper information.\n", "\n", "### Main Components\n", "\n", "**Input Parameters**\n", "- `topic`: Your research subject\n", "- `max_results`: Number of papers to retrieve (default: 20)\n", "\n", "**Output Format**\n", "Each paper result includes:\n", "- Title\n", "- Abstract\n", "- Author list\n", "- Publication year\n", "- PDF link (if openly accessible)\n", "\n", "## Key Features\n", "\n", "**Search Capabilities**\n", "- Connects to Semantic Scholar's database\n", "- Filters for open access papers\n", "- Returns structured, easy-to-process results\n", "\n", "## Notes\n", "- Only returns open access papers\n", "- Async operations not currently supported\n", "- Requires valid API connection\n", "- Results are paginated for efficiency\n", "\n", "This tool simplifies academic research by providing structured access to scholarly papers while handling common search and retrieval challenges automatically." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "id": "QD31tU5NBBcY" }, "outputs": [], "source": [ "class AcademicPaperSearchInput(BaseModel):\n", " topic: str = Field(..., description=\"The topic to search for academic papers on\")\n", " max_results: int = Field(20, description=\"Maximum number of results to return\")\n", "\n", "class AcademicPaperSearchTool(BaseTool):\n", " args_schema: type = AcademicPaperSearchInput # Explicit type annotation\n", " name: str = Field(\"academic_paper_search_tool\", description=\"Tool for searching academic papers\")\n", " description: str = Field(\"Queries an academic papers API to retrieve relevant articles based on a topic\")\n", "\n", " def __init__(self, name: str = \"academic_paper_search_tool\",\n", " description: str = \"Queries an academic paper API to retrieve relevant articles based on a topic\"):\n", " super().__init__()\n", " self.name = name\n", " self.description = description\n", "\n", " def _run(self, topic: str, max_results: int) -> List[Dict[str, Any]]:\n", " # Query an external academic API like arXiv, Semantic Scholar, or CrossRef\n", " search_results = self.query_academic_api(topic, max_results)\n", " # testing = search_results[0]['text'][:100]\n", "\n", " return search_results\n", "\n", " async def _arun(self, topic: str, max_results: int) -> List[Dict[str, Any]]:\n", " raise NotImplementedError(\"Async version not implemented\")\n", "\n", " def query_academic_api(self, topic: str, max_results: int) -> List[Dict[str, Any]]:\n", " base_url = \"https://api.semanticscholar.org/graph/v1/paper/search\"\n", " params = {\n", " \"query\": topic,\n", " \"limit\": max_results, # max_results\n", " \"fields\": \"title,abstract,authors,year,openAccessPdf\",\n", " \"openAccessPdf\" : True\n", " }\n", " try:\n", " while True:\n", " try:\n", " response = requests.get(base_url, params=params)\n", " print(response)\n", "\n", " if response.status_code == 200:\n", " papers = response.json().get(\"data\", [])\n", " formatted_results = [\n", " {\n", " \"title\" : paper.get(\"title\"),\n", " \"abstract\" : paper.get(\"abstract\"),\n", " \"authors\" : [author.get(\"name\") for author in paper.get(\"authors\", [])],\n", " \"year\" : paper.get(\"year\"),\n", " \"pdf\" : paper.get(\"openAccessPdf\"),\n", " }\n", " for paper in papers\n", " ]\n", "\n", " return formatted_results\n", " except:\n", " # raise ValueError(f\"Failed to fetch papers: {response.status_code} - {response.text}\")\n", " print((f\"Failed to fetch papers: {response.status_code} - {response.text}. Trying Again...\"))\n", " except KeyboardInterrupt:\n", " print(\"\\nOperation cancelled by user\")\n", " sys.exit(0) # Clean exit" ] }, { "cell_type": "markdown", "metadata": { "id": "rt0b1YgrA5kt" }, "source": [ "## IV. Prompts" ] }, { "cell_type": "markdown", "metadata": { "id": "dXA9zkOgUfpj" }, "source": [ "### Planning Phase Prompts\n", "\n", "**Planner Prompt**\n", "- Acts as initial architect of the review\n", "- Sets up structure based on standard academic components\n", "- Creates outline without conducting actual research\n", "- Focuses on organization and methodology planning\n", "\n", "**Research Prompt**\n", "- Generates 5 targeted search queries\n", "- Uses project plan to guide search strategy\n", "- Interfaces with academic paper search tool\n", "- Ensures comprehensive literature coverage\n", "\n", "**Decision Prompt**\n", "- Evaluates search results against project plan\n", "- Selects top 3 most relevant papers - this number can be changed as you see fit!\n", "- Returns only PDF URLs in JSON format\n", "- Streamlines paper selection process\n", "\n", "## Analysis Phase Prompts\n", "\n", "**Analyze Paper Prompt**\n", "- Breaks down papers into key sections\n", "- Provides section-specific analysis:\n", " - Abstract: Key points\n", " - Introduction: Research motivation\n", " - Methods: Technical details and mathematical analysis\n", " - Results: Statistical findings\n", " - Conclusions: Analysis and counterarguments\n", "- Includes metadata (title, year, authors, URL)\n", "\n", "## Writing Phase Prompts\n", "\n", "**Section-Specific Prompts:**\n", "- Abstract (100-word limit, overview)\n", "- Introduction (comprehensive background)\n", "- Methods (comparative analysis of approaches)\n", "- Results (cross-paper comparison)\n", "- Conclusions (synthesis and future directions)\n", "- References (APA formatting)\n", "\n", "## Review Phase Prompts\n", "\n", "**Critique Draft Prompt**\n", "- Evaluates publication readiness\n", "- Provides specific revision recommendations\n", "- Assesses need for additional research\n", "- Makes go/no-go publication decisions\n", "\n", "**Revise Draft Prompt**\n", "- Implements recommended changes\n", "- Refines paper based on critique\n", "- Ensures all feedback is addressed\n", "- Produces final manuscript version\n", "\n", "Each prompt works sequentially to build a comprehensive systematic review, from initial planning to final publication-ready manuscript." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "id": "Q85dRQrTAffc" }, "outputs": [], "source": [ "planner_prompt = '''You are an academic researcher that is planning to write a systematic review of Academic and Scientific Research Papers.\n", "\n", "A systematic review article typically includes the following components:\n", "Title: The title should accurately reflect the topic being reviewed, and usually includes the words \"a systematic review\".\n", "Abstract: A structured abstract with a short paragraph for each of the following: background, methods, results, and conclusion.\n", "Introduction: Summarizes the topic, explains why the review was conducted, and states the review's purpose and aims.\n", "Methods: Describes the methods used in the review.\n", "Results: Presents the results of the review.\n", "Discussion: Discusses the results of the review.\n", "References: Lists the references used in the review.\n", "\n", "Other important components of a systematic review include:\n", "Scoping: A \"trial run\" of the review that helps shape the review's method and protocol.\n", "Meta-analysis: An optional component that uses statistical methods to combine and summarize the results of multiple studies.\n", "Data extraction: A central component where data is collected and organized for analysis.\n", "Assessing the risk of bias: Helps establish transparency of evidence synthesis results.\n", "Interpreting results: Involves considering factors such as limitations, strength of evidence, biases, and implications for future practice or research.\n", "Literature identification: An important component that sets the data to be analyzed.\n", "\n", "With this in mind, only create an outline plan based on the topic. Don't search anything, just set up the planning.\n", "'''\n", "\n", "research_prompt = '''You are an academic researcher that is searching Academic and Scientific Research Papers.\n", "\n", "You will be given a project plan. Based on the project plan, generate 5 queries that you will use to search the papers.\n", "\n", "Send the queries to the academic_paper_search_tool as a tool call.\n", "'''\n", "\n", "decision_prompt = '''You are an academic researcher that is searching Academic and Scientific Research Papers.\n", "\n", "You will be given a project plan and a list of articles.\n", "\n", "Based on the project plan and articles provided, you must choose a maximum of 3 to investigate that are most relevant to that plan.\n", "\n", "IMPORTANT: You must return ONLY a JSON array of the PDF URLs with no additional text or explanation. Your entire response should be in this exact format:\n", "\n", "[\n", " \"url1\",\n", " \"url2\",\n", " \"url3\",\n", " ...\n", "]\n", "\n", "Do not include any other text, explanations, or formatting.'''\n", "\n", "analyze_paper_prompt = '''You are an academic researcher trying to understand the details of scientific and academic research papers.\n", "\n", "You must look through the text provided and get the details from the Abstract, Introduction, Methods, Results, and Conclusions.\n", "If you are in an Abstract section, just give me the condensed thoughts.\n", "If you are in an Introduction section, give me a concise reason on why the research was done.\n", "If you are in a Methods section, give me low-level details of the approach. Analyze the math and tell me what it means.\n", "If you are in a Results section, give me low-level relevant objective statistics. Tie it in with the methods\n", "If you are in a Conclusions section, give me the fellow researcher's thoughts, but also come up with a counter-argument if none are given.\n", "\n", "Remember to attach the other information to the top:\n", " Title :