Lær at opbygge en AI-agent til Research Paper Retrieval, Search og Summarization Lær at opbygge en AI-agent til Research Paper Retrieval, Search og Summarization For forskere er det at holde sig ajour med de nyeste resultater lig med at finde en nål i en hæk. Forestil dig en AI-drevet assistent, der ikke kun henter de mest relevante papirer, men også opsummerer nøgleindsigter og svarer på dine specifikke spørgsmål, alt i realtid. Denne artikel dykker ind i at konstruere en sådan AI-forskningsagent ved hjælp af Superlinkeds komplekse dokumentindlejringskapacitet.Ved at integrere semantisk og tidsmæssig relevans eliminerer vi behovet for kompleks omrangering, der sikrer effektiv og nøjagtig indhentning af information. Denne artikel dykker ind i at konstruere en sådan AI-forskningsagent ved hjælp af Superlinkeds komplekse dokumentindlejringskapacitet.Ved at integrere semantisk og tidsmæssig relevans eliminerer vi behovet for kompleks omrangering, der sikrer effektiv og nøjagtig indhentning af information. TL;DR: Opbyg en AI-forskningsagent i realtid ved hjælp af Superlinkeds vektorsøgning. Det overskrider komplekse RAG-rørledninger ved direkte at indlejre og forespørge dokumenter - hvilket gør forskning hurtigere, enklere og smartere. (Vil du hoppe direkte til koden? tjek den åbne kildekode på GitHub her. Klar til at prøve semantisk søgning for din egen agentisk brugssag? vi er her for at hjælpe.) Tag et kig på open source på GitHub . here Her er Her er Vi er her for at . help Hjælp Hjælp Denne artikel viser, hvordan man opbygger et agent system ved hjælp af en kernel agent til at håndtere forespørgsler. here’s the . Colab . Colab Colab Hvor skal man starte med at opbygge et forskningsassistentsystem? Traditionelt involverer opførelsen af et sådant system kompleksitet og betydelige ressourceinvesteringer. Søgesystemer henter typisk et indledende bredt sæt dokumenter baseret på relevans og anvender derefter en sekundær omrangeringsproces til at forfine og omordne resultaterne. Mens omrangering forbedrer nøjagtigheden, øger det betydeligt beregningsmæssig kompleksitet, latens og overhead på grund af den omfattende dataindsamling, der kræves i første omgang. Superlinked adresserer denne kompleksitet ved at kombinere strukturerede numeriske og kategoriske indlejringer med semantiske tekstindlejringer, hvilket giver omfattende multimodale vektorer. Denne metode forbedrer søgningens nøjagtighed betydeligt ved at bevare attribut-specifik information inden for hver indlejring. Byg et agent-system med Superlinked Denne AI agent kan gøre tre vigtigste ting: Find papirer: Søg efter forskningspapirer efter emne (f.eks. "quantum computing") og sorter dem derefter efter relevans og nyere tid. Summarize papers: Kondensér de hentede papirer til bid-større indsigter. Svarspørgsmål: Udtræk svar direkte fra de specifikke forskningspapirer baseret på målrettede brugerforespørgsler. Superlinked eliminerer behovet for re-rangering metoder, da det forbedrer vektor søgning relevans. Superlinked's RecencySpace vil blive brugt, som specifikt koder tidsmæssige metadata, prioritere nyere dokumenter under hentning, og eliminerer behovet for beregningsmæssigt dyr re-rangering. For eksempel, hvis to papirer har samme relevans - den, der er den nyeste vil rang højere. Trin 1: Opsætning af værktøjskassen %pip install superlinked For at gøre tingene nemmere og mere modulære skabte jeg en abstrakt værktøjsklasse. Dette vil forenkle processen med at opbygge og tilføje værktøjer import pandas as pd import superlinked.framework as sl from datetime import timedelta from sentence_transformers import SentenceTransformer from openai import OpenAI import os from abc import ABC, abstractmethod from typing import Any, Optional, Dict from tqdm import tqdm from google.colab import userdata # Abstract Tool Class class Tool(ABC): @abstractmethod def name(self) -> str: pass @abstractmethod def description(self) -> str: pass @abstractmethod def use(self, *args, **kwargs) -> Any: pass # Get API key from Google Colab secrets try: api_key = userdata.get('OPENAI_API_KEY') except KeyError: raise ValueError("OPENAI_API_KEY not found in user secrets. Please add it using Tools > User secrets.") # Initialize OpenAI Client api_key = os.environ.get("OPENAI_API_KEY", "your-openai-key") # Replace with your OpenAI API key if not api_key: raise ValueError("Please set the OPENAI_API_KEY environment variable.") client = OpenAI(api_key=api_key) model = "gpt-4" Trin 2: Forstå datasæt Dette eksempel bruger et datasæt, der indeholder ca. 10.000 AI-forskningsartikler tilgængelige på Du kan også bruge dine egne datakilder, såsom forskningspapirer eller andet akademisk indhold.Hvis du beslutter dig for at gøre det, skal du bare justere skemaets design lidt og opdatere kolonnenavne. Køge import pandas as pd !wget --no-check-certificate 'https://drive.google.com/uc?export=download&id=1FCR3TW5yLjGhEmm-Uclw0_5PWVEaLk1j' -O arxiv_ai_data.csv For nu, for at gøre tingene køre lidt hurtigere, vil vi bruge et mindre delsæt af papirerne bare for at fremskynde tingene, men føler dig fri til at prøve eksemplet ved hjælp af det fulde datasæt. En vigtig teknisk detalje her er, at timestamps fra datasættet vil blive konverteret fra string timestamps (som '1993-08-01 00:00:00+00:00') til pandas datetime objekter. Denne konvertering er nødvendig, fordi det giver os mulighed for at udføre dato/tid operationer. df = pd.read_csv('arxiv_ai_data.csv').head(100) # Convert to datetime but keep it as datetime (more readable and usable) df['published'] = pd.to_datetime(df['published']) # Ensure summary is a string df['summary'] = df['summary'].astype(str) # Add 'text' column for similarity search df['text'] = df['title'] + " " + df['summary'] Debug: Columns in original DataFrame: ['authors', 'categories', 'comment', 'doi', 'entry_id', 'journal_ref' 'pdf_url', 'primary_category', 'published', 'summary', 'title', 'updated'] Forstå datasætkolonnerne Nedenfor er en kort oversigt over de vigtigste kolonner i vores datasæt, som vil være vigtige i de kommende trin: Udgivet: Udgivelsesdato for forskningspapiret. Resumé: Abstrakten af papiret, der giver en kortfattet oversigt. entry_id: Den unikke identifikator for hvert papir fra arXiv. Til denne demonstration fokuserer vi specifikt på fire kolonner: , der , der og For at optimere søgningskvaliteten kombineres overskriften og sammenfatningen i en enkelt, omfattende tekstkolonne, som udgør kernen i vores indlejring og søgningsproces. entry_id published title summary En note om Superlinkeds In-Memory Indexer: Superlinkeds in-memory-indeksering gemmer vores datasæt direkte i RAM, hvilket gør hentning usædvanligt hurtig, hvilket er ideelt til realtidssøgninger og hurtig prototyping. Trin 3: Definer det overlinkede skema For at komme videre er der behov for et skema for at kortlægge vores data. med nøgleområderne: PaperSchema lass PaperSchema(sl.Schema): text: sl.String published: sl.Timestamp # This will handle datetime objects properly entry_id: sl.IdField title: sl.String summary: sl.String paper = PaperSchema() Definition af superlinkede rum til effektiv retrieval Et væsentligt skridt i at organisere og effektivt forespørge vores datasæt indebærer at definere to specialiserede vektorrum: TextSimilaritySpace og RecencySpace. Tekstlignende rum Den er designet til at kode tekstoplysninger – såsom titler og abstrakter af forskningspapirer til vektorer. Ved at konvertere tekst til indlejringer forbedrer dette rum betydeligt nemheden og nøjagtigheden af semantiske søgninger. Det er specielt optimeret til at håndtere længere tekstsekvenser effektivt, hvilket muliggør præcise sammenligninger af lighed mellem dokumenter. TextSimilaritySpace text_space = sl.TextSimilaritySpace( text=sl.chunk(paper.text, chunk_size=200, chunk_overlap=50), model="sentence-transformers/all-mpnet-base-v2" ) Recensionsrummet Den fanger tidsmæssige metadata, der understreger nyere forskningspublikationer. Ved at kode tidsstempler, tildeler dette rum større betydning til nyere dokumenter. Som følge heraf balancerer indhentningsresultaterne naturligt indholdsrelevans med udgivelsesdatoer, hvilket favoriserer nyere indsigt. RecencySpace recency_space = sl.RecencySpace( timestamp=paper.published, period_time_list=[ sl.PeriodTime(timedelta(days=365)), # papers within 1 year sl.PeriodTime(timedelta(days=2*365)), # papers within 2 years sl.PeriodTime(timedelta(days=3*365)), # papers within 3 years ], negative_filter=-0.25 ) Tænk på RecencySpace som et tidsbaseret filter, svarende til at sortere dine e-mails efter dato eller se Instagram-indlæg med de nyeste først. Mindre timedeltas (som 365 dage) giver mulighed for mere granulære, årlige tidsbaserede placeringer. Større timedeltas (som 1095 dage) skaber bredere tidsperioder. Den For at forklare det mere klart, overveje følgende eksempel, hvor to papirer har identisk indhold relevans, men deres placering vil afhænge af deres udgivelsesdato. negative_filter Paper A: Published in 1996 Paper B: Published in 1993 Scoring example: - Text similarity score: Both papers get 0.8 - Recency score: - Paper A: Receives the full recency boost (1.0) - Paper B: Gets penalized (-0.25 due to negative_filter) Final combined scores: - Paper A: Higher final rank - Paper B: Lower final rank Disse rum er nøglen til at gøre datasættet mere tilgængeligt og effektivt. De giver mulighed for både indholdsbaserede og tidsbaserede søgninger og er virkelig nyttige til at forstå relevansen og nyereheden af forskningspapirer. Dette giver en kraftfuld måde at organisere og søge gennem datasættet baseret på både indholdet og publiceringstiden. Trin 4: Opbygning af indeks Derefter fusioneres rummene til et indeks, som er søgemaskinens kerne: paper_index = sl.Index([text_space, recency_space]) DataFrame er derefter kortlagt til skemaet og indlæst i batches (10 papirer ad gangen) i en in-memory-lager: # Parser to map DataFrame columns to schema fields parser = sl.DataFrameParser( paper, mapping={ paper.entry_id: "entry_id", paper.published: "published", paper.text: "text", paper.title: "title", paper.summary: "summary", } ) # Set up in-memory source and executor source = sl.InMemorySource(paper, parser=parser) executor = sl.InMemoryExecutor(sources=[source], indices=[paper_index]) app = executor.run() # Load the DataFrame with a progress bar using batches batch_size = 10 data_batches = [df[i:i + batch_size] for i in range(0, len(df), batch_size)] for batch in tqdm(data_batches, total=len(data_batches), desc="Loading Data into Source"): source.put([batch]) In-memory-eksekutoren er grunden til, at Superlinked skinner her – 1.000 papirer passer fint i RAM, og forespørgsler flyver uden disk I/O flaskehalse. Trin 5: Opbygning af forespørgslen Dernæst er oprettelsen af forespørgslen. Dette er, hvor skabelonen til håndtering af forespørgsler oprettes. For at styre dette har vi brug for en forespørgselsskabelon, der kan balancere både relevans og nyere tid. Her er, hvordan det ville se ud: # Define the query knowledgebase_query = ( sl.Query( paper_index, weights={ text_space: sl.Param("relevance_weight"), recency_space: sl.Param("recency_weight"), } ) .find(paper) .similar(text_space, sl.Param("search_query")) .select(paper.entry_id, paper.published, paper.text, paper.title, paper.summary) .limit(sl.Param("limit")) ) Dette giver os mulighed for at vælge, om vi skal prioritere indholdet (relevance_weight) eller den seneste tid (recency_weight) - en meget nyttig kombination for vores agents behov. Trin 6: Byg værktøjer Nu kommer værktøjets del. Vi vil udvikle tre værktøjer ... Retrieval Tool : Dette værktøj er skabt ved at plugge ind i Superlinked's indeks, så det kan trække de 5 øverste papirer baseret på en forespørgsel. Det balancerer relevans (1.0 vægt) og nyere (0,5 vægt) for at opfylde målet "find papirer". Hvad vi vil, er at finde de papirer, der er relevante for forespørgslen. Så hvis forespørgslen er: "Hvilke kvantecomputer papirer blev udgivet mellem 1993 og 1994?", så vil hentningsværktøjet hente disse papirer, opsummere dem en efter en, og returnere resultaterne. class RetrievalTool(Tool): def __init__(self, df, app, knowledgebase_query, client, model): self.df = df self.app = app self.knowledgebase_query = knowledgebase_query self.client = client self.model = model def name(self) -> str: return "RetrievalTool" def description(self) -> str: return "Retrieves a list of relevant papers based on a query using Superlinked." def use(self, query: str) -> pd.DataFrame: result = self.app.query( self.knowledgebase_query, relevance_weight=1.0, recency_weight=0.5, search_query=query, limit=5 ) df_result = sl.PandasConverter.to_pandas(result) # Ensure summary is a string if 'summary' in df_result.columns: df_result['summary'] = df_result['summary'].astype(str) else: print("Warning: 'summary' column not found in retrieved DataFrame.") return df_result Næste gang er det den Dette værktøj er designet til tilfælde, hvor der er behov for en kortfattet sammenfatning af et papir. , hvilket er ID'et for det papir, der skal opsummeres. ikke leveres, vil værktøjet ikke fungere, da disse ID'er er et krav for at finde de tilsvarende papirer i datasættet. Summarization Tool paper_id paper_id class SummarizationTool(Tool): def __init__(self, df, client, model): self.df = df self.client = client self.model = model def name(self) -> str: return "SummarizationTool" def description(self) -> str: return "Generates a concise summary of specified papers using an LLM." def use(self, query: str, paper_ids: list) -> str: papers = self.df[self.df['entry_id'].isin(paper_ids)] if papers.empty: return "No papers found with the given IDs." summaries = papers['summary'].tolist() summary_str = "\n\n".join(summaries) prompt = f""" Summarize the following paper summaries:\n\n{summary_str}\n\nProvide a concise summary. """ response = self.client.chat.completions.create( model=self.model, messages=[{"role": "user", "content": prompt}], temperature=0.7, max_tokens=500 ) return response.choices[0].message.content.strip() Endelig har vi den Dette værktøj kæder at hente de relevante papirer og derefter bruge dem til at besvare spørgsmålene.Hvis der ikke findes relevante papirer til at besvare spørgsmålene, vil det give et svar baseret på generel viden QuestionAnsweringTool RetrievalTool class QuestionAnsweringTool(Tool): def __init__(self, retrieval_tool, client, model): self.retrieval_tool = retrieval_tool self.client = client self.model = model def name(self) -> str: return "QuestionAnsweringTool" def description(self) -> str: return "Answers questions about research topics using retrieved paper summaries or general knowledge if no specific context is available." def use(self, query: str) -> str: df_result = self.retrieval_tool.use(query) if 'summary' not in df_result.columns: # Tag as a general question if summary is missing prompt = f""" You are a knowledgeable research assistant. This is a general question tagged as [GENERAL]. Answer based on your broad knowledge, not limited to specific paper summaries. If you don't know the answer, provide a brief explanation of why. User's question: {query} """ else: # Use paper summaries for specific context contexts = df_result['summary'].tolist() context_str = "\n\n".join(contexts) prompt = f""" You are a research assistant. Use the following paper summaries to answer the user's question. If you don't know the answer based on the summaries, say 'I don't know.' Paper summaries: {context_str} User's question: {query} """ response = self.client.chat.completions.create( model=self.model, messages=[{"role": "user", "content": prompt}], temperature=0.7, max_tokens=500 ) return response.choices[0].message.content.strip() Trin 7: Opbygning af Kernel Agent Dernæst er Kernel Agent. Den fungerer som den centrale controller, der sikrer en glat og effektiv drift. Kernel Agent fungerer som kernekomponenten i systemet og koordinerer kommunikationen ved at rute forespørgsler efter deres hensigt, når flere agenter opererer samtidigt. I enkeltagent-systemer, som denne, bruger Kernel Agent direkte de relevante værktøjer til effektivt at styre opgaver. class KernelAgent: def __init__(self, retrieval_tool: RetrievalTool, summarization_tool: SummarizationTool, question_answering_tool: QuestionAnsweringTool, client, model): self.retrieval_tool = retrieval_tool self.summarization_tool = summarization_tool self.question_answering_tool = question_answering_tool self.client = client self.model = model def classify_query(self, query: str) -> str: prompt = f""" Classify the following user prompt into one of the three categories: - retrieval: The user wants to find a list of papers based on some criteria (e.g., 'Find papers on AI ethics from 2020'). - summarization: The user wants to summarize a list of papers (e.g., 'Summarize papers with entry_id 123, 456, 789'). - question_answering: The user wants to ask a question about research topics and get an answer (e.g., 'What is the latest development in AI ethics?'). User prompt: {query} Respond with only the category name (retrieval, summarization, question_answering). If unsure, respond with 'unknown'. """ response = self.client.chat.completions.create( model=self.model, messages=[{"role": "user", "content": prompt}], temperature=0.7, max_tokens=10 ) classification = response.choices[0].message.content.strip().lower() print(f"Query type: {classification}") return classification def process_query(self, query: str, params: Optional[Dict] = None) -> str: query_type = self.classify_query(query) if query_type == 'retrieval': df_result = self.retrieval_tool.use(query) response = "Here are the top papers:\n" for i, row in df_result.iterrows(): # Ensure summary is a string and handle empty cases summary = str(row['summary']) if pd.notna(row['summary']) else "" response += f"{i+1}. {row['title']} \nSummary: {summary[:200]}...\n\n" return response elif query_type == 'summarization': if not params or 'paper_ids' not in params: return "Error: Summarization query requires a 'paper_ids' parameter with a list of entry_ids." return self.summarization_tool.use(query, params['paper_ids']) elif query_type == 'question_answering': return self.question_answering_tool.use(query) else: return "Error: Unable to classify query as 'retrieval', 'summarization', or 'question_answering'." Systemet kan nu initialiseres ved at give Kernel Agent de relevante værktøjer, hvorefter Research Agent System vil være fuldt operationelt. retrieval_tool = RetrievalTool(df, app, knowledgebase_query, client, model) summarization_tool = SummarizationTool(df, client, model) question_answering_tool = QuestionAnsweringTool(retrieval_tool, client, model) # Initialize KernelAgent kernel_agent = KernelAgent(retrieval_tool, summarization_tool, question_answering_tool, client, model) Lad os nu teste systemet. # Test query print(kernel_agent.process_query("Find papers on quantum computing in last 10 years")) Denne funktion aktiverer den Det henter de relevante papirer baseret på både relevans og nyere tid, og returnerer de relevante kolonner.Hvis det returnerede resultat indeholder sammenfatningskolonnen (der angiver, at papirerne blev hentet fra datasættet), bruger det disse sammenfatninger og returnerer dem til os. RetrievalTool Query type: retrieval Here are the top papers: 1. Quantum Computing and Phase Transitions in Combinatorial Search Summary: We introduce an algorithm for combinatorial search on quantum computers that is capable of significantly concentrating amplitude into solutions for some NP search problems, on average. This is done by... 1. The Road to Quantum Artificial Intelligence Summary: This paper overviews the basic principles and recent advances in the emerging field of Quantum Computation (QC), highlighting its potential application to Artificial Intelligence (AI). The paper provi... 1. Solving Highly Constrained Search Problems with Quantum Computers Summary: A previously developed quantum search algorithm for solving 1-SAT problems in a single step is generalized to apply to a range of highly constrained k-SAT problems. We identify a bound on the number o... 1. The model of quantum evolution Summary: This paper has been withdrawn by the author due to extremely unscientific errors.... 1. Artificial and Biological Intelligence Summary: This article considers evidence from physical and biological sciences to show machines are deficient compared to biological systems at incorporating intelligence. Machines fall short on two counts: fi... Lad os prøve en anden forespørgsel, denne gang, lad os gøre en sammenfatning en.. print(kernel_agent.process_query("Summarize this paper", params={"paper_ids": ["http://arxiv.org/abs/cs/9311101v1"]})) Query type: summarization This paper discusses the challenges of learning logic programs that contain the cut predicate (!). Traditional learning methods cannot handle clauses with cut because it has a procedural meaning. The proposed approach is to first generate a candidate base program that covers positive examples, and then make it consistent by inserting cut where needed. Learning programs with cut is difficult due to the need for intensional evaluation, and current induction techniques may need to be limited to purely declarative logic languages. Jeg håber, at dette eksempel har været nyttigt for udviklingen af AI-agenter og agentbaserede systemer.Meget af den hentesystemfunktionalitet, der er demonstreret her, blev muliggjort af Superlinked, så overvej venligst at spille hovedrollen til fremtidig reference, når der er behov for nøjagtige indhentningskapaciteter for dine AI-agenter! Repositorier Tagetøj Notebook kode Ved at kombinere semantisk og tidsmæssig relevans elimineres kompleks omrangering, samtidig med at søgningsnøjagtigheden for forskningspapirer opretholdes. Tidsbaserede straffe (negative_filter=-0.25) prioriterer nyere forskning, når papirer har lignende indholdsrelevans. Modulær værktøjbaseret arkitektur gør det muligt for specialiserede komponenter at håndtere forskellige opgaver (genoprettelse, opsummering, spørgsmålssvar) samtidig med at systemets sammenhæng opretholdes. Indlæsning af data i små partier (batch_size=10) med fremskridtsporing forbedrer systemets stabilitet ved behandling af store forskningsdatasæt. Justerbare forespørgselsvægte giver brugerne mulighed for at balancere relevans (1.0) og nyere (0.5) baseret på specifikke forskningsbehov. Den spørgsmålssvarende komponent nedgraderer graciøst til generel viden, når papir-specifik kontekst ikke er tilgængelig, hvilket forhindrer dead-end brugeroplevelser. At holde sig ajour med det store antal forskningsartikler, der udgives regelmæssigt, kan være udfordrende og tidskrævende.En agentisk AI-assistent arbejdsproces, der er i stand til effektivt at lokalisere relevant forskning, opsummere nøgleindsigter og besvare specifikke spørgsmål fra disse papirer, kunne strømline denne proces betydeligt. Bidragere Vipul Maheshwari, forfatter Filip Makraduli, revisor