Zjistěte, jak vytvořit agenta AI pro získávání výzkumných dokumentů, vyhledávání a shrnutí
Zjistěte, jak vytvořit agenta AI pro získávání výzkumných dokumentů, vyhledávání a shrnutí
Pro výzkumníky je udržování aktuálního stavu s nejnovějšími poznatky podobné nalezení jehly v hnízdě.Představte si asistenta poháněného umělou inteligencí, který nejen získá nejrelevantnější články, ale také shrnuje klíčové poznatky a odpovídá na vaše konkrétní otázky, a to vše v reálném čase.
Tento článek se zabývá konstrukcí takového výzkumného agenta AI pomocí komplexních schopností vkládání dokumentů společnosti Superlinked.Integrací sémantické a časové relevance eliminujeme potřebu komplexního přerozdělování, což zajišťuje efektivní a přesné získávání informací.
Tento článek se zabývá konstrukcí takového výzkumného agenta AI pomocí komplexních schopností vkládání dokumentů společnosti Superlinked.Integrací sémantické a časové relevance eliminujeme potřebu komplexního přerozdělování, což zajišťuje efektivní a přesné získávání informací.TL;DR:
Vytvořte výzkumného agenta umělé inteligence v reálném čase pomocí vektorového vyhledávání společnosti Superlinked, který přeskočí složité potrubí RAG tím, že přímo vloží a dotazuje dokumenty, čímž bude výzkum rychlejší, jednodušší a chytřejší.
(Chcete skočit přímo na kód? Podívejte se na open source na GitHub zde. Připraveni vyzkoušet sémantické vyhledávání pro svůj vlastní případ použití agentů?
Podívejte se na open source na GithubuTento článek ukazuje, jak vytvořit systém agentů pomocí agenta jádra pro zpracování dotazů. Pokud chcete sledovat a spouštět kód v prohlížeči,here’s the
Kde začít s výzkumným asistentem?
Tradičně budování takového systému zahrnuje složitost a značné investice do zdrojů. Vyhledávací systémy obvykle vyhledávají počáteční širokou škálu dokumentů založených na relevanci a následně aplikují sekundární přerozdělovací proces k zdokonalování a přerozdělování výsledků. Zatímco přerozdělování zvyšuje přesnost, výrazně zvyšuje výpočetní složitost, latenci a přehodnocení kvůli rozsáhlému vyhledávání dat, které bylo původně požadováno. Superlinked řeší tuto složitost kombinací strukturovaných číselných a kategorických vkládání se sémantickým textovým vkládáním, což poskytuje komplexní multimodální vektory. Tato metoda výrazně zvyšuje přesnost vyhledávání zachováním atribut
Vytvořte agentový systém s Superlinked
Tento agent AI může dělat tři hlavní věci:
- Hledej papíry: Hledejte výzkumné práce podle tématu (např. „kvantové výpočetní techniky“) a poté je řadíte podle relevance a aktuálnosti.
- Shrnutí papírů: Shrnutí vyhledávaných papírů do pohledů velikosti kousku.
- Odpovědi na otázky: Odpovědi lze extrahovat přímo z konkrétních výzkumných prací na základě cílených dotazů uživatelů.
Superlinked eliminuje potřebu metody re-ranking, protože zlepšuje relevanci vektorového vyhledávání. Superlinked RecencySpace bude použit, který specificky kóduje časové metadata, upřednostňuje nedávné dokumenty během vyhledávání a eliminuje potřebu výpočetně nákladné re-ranking. Například, pokud dva papíry mají stejnou relevanci - ten, který je nejnovější bude hodnocena vyšší.
Krok 1: Nastavení toolboxu
%pip install superlinked
Aby bylo vše jednodušší a modulárnější, vytvořil jsem třídu abstraktních nástrojů, která zjednoduší proces budování a přidávání nástrojů.
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"
Krok 2: Pochopení databáze
Tento příklad používá datový soubor obsahující přibližně 10 000 výzkumných článků AI dostupných naKádrováChcete-li to usnadnit, jednoduše spusťte níže uvedenou buňku a automaticky stáhne datovou sadu do vaší pracovní adresáře. Můžete také použít své vlastní zdroje dat, jako jsou výzkumné články nebo jiný akademický obsah. Pokud se rozhodnete tak učinit, vše, co musíte udělat, je mírně upravit design schématu a aktualizovat názvy sloupců.
import pandas as pd
!wget --no-check-certificate 'https://drive.google.com/uc?export=download&id=1FCR3TW5yLjGhEmm-Uclw0_5PWVEaLk1j' -O arxiv_ai_data.csv
Prozatím budeme používat menší podskupinu papírů, abychom věci zrychlili, ale nezapomeňte si vyzkoušet příklad s použitím celé datové sady.Důležitým technickým detailem je, že časové razítka z datové sady budou převedeny z časových razítek řetězce (jako '1993-08-01 00:00:00+00:00') na datetime objekty pandy. Tato konverze je nezbytná, protože nám umožňuje provádět operace datum/čas.
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']
Pochopení datových sloupců
Níže je stručný přehled klíčových sloupců v naší datové sadě, které budou důležité v následujících krocích:
- Publikováno: Datum zveřejnění výzkumného dokumentu.
- Shrnutí: Abstrakt papíru, který poskytuje stručný přehled.
- entry_id: Jedinečný identifikátor pro každý papír z arXiv.
Pro tuto demonstraci se zaměřujeme konkrétně na čtyři sloupce:entry_id
, ,published
, ,title
, asummary
Pro optimalizaci kvality vyhledávání jsou název a shrnutí kombinovány do jediného, komplexního textového sloupce, který tvoří jádro našeho procesu vkládání a vyhledávání.
Poznámka k indexu Superlinked In-Memory: In-memory indexování společnosti Superlinked ukládá naše datové soubory přímo do paměti RAM, což činí vyhledávání mimořádně rychlým, což je ideální pro vyhledávání v reálném čase a rychlé prototypování.
Krok 3: Definování superlinkovaného schématu
Chcete-li jít dál, je zapotřebí schéma mapovat naše data.PaperSchema
v klíčových oblastech:
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()
Definování superlinkovaných prostor pro efektivní zpětné získávání
Nezbytným krokem při organizaci a efektivním vyhledávání datových souborů je definování dvou specializovaných vektorových prostorů: TextSimilaritySpace a RecencySpace.
- Textilní prostor
TytoTextSimilaritySpace
je navržen tak, aby kódoval textové informace – jako jsou tituly a abstrakty výzkumných prací – do vektorů. Převedením textu na vkládání tento prostor výrazně zvyšuje snadnost a přesnost sémantických vyhledávání. Je optimalizován speciálně pro efektivní zpracování delších textových sekvencí, což umožňuje přesné srovnání podobnosti mezi dokumenty.
text_space = sl.TextSimilaritySpace(
text=sl.chunk(paper.text, chunk_size=200, chunk_overlap=50),
model="sentence-transformers/all-mpnet-base-v2"
)
- Recenzní prostor
TytoRecencySpace
zachycuje časové metadata, zdůrazňující nedávnost výzkumných publikací. kódováním časových razítek tento prostor přiděluje větší význam novějším dokumentům.V důsledku toho výsledky vyhledávání přirozeně vyvažují relevanci obsahu s daty publikace, což přispívá k nedávným poznatkům.
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
)
Přemýšlejte o RecencySpace jako o filtru založeném na čase, podobném třídění vašich e-mailů podle data nebo prohlížení příspěvků na Instagramu s nejnovějšími nejprve.
- Menší časové úseky (například 365 dní) umožňují více granulární roční časové hodnocení.
- Větší časové úseky (například 1095 dní) vytvářejí širší časové období.
Tytonegative_filter
Pro jasnější vysvětlení, zvažte následující příklad, kde dva články mají stejný obsah relevance, ale jejich hodnocení bude záviset na jejich data publikace.
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
Tyto prostory jsou klíčem k tomu, aby byl datový soubor přístupnější a efektivnější. Umožňují jak vyhledávání založené na obsahu, tak vyhledávání založené na čase a jsou velmi užitečné pro pochopení relevance a aktuálnosti výzkumných prací.To poskytuje výkonný způsob, jak datový soubor organizovat a vyhledávat na základě obsahu i času publikování.
Krok 4: Vytvoření indexu
Následně jsou mezery sloučeny do indexu, který je jádrem vyhledávače:
paper_index = sl.Index([text_space, recency_space])
DataFrame je pak mapován do schématu a načten v dávkách (10 papírů najednou) do úložiště v paměti:
# 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])
Exekutor v paměti je důvodem, proč Superlinked zde září - 1000 papírů se hodí do paměti RAM a dotazy letí bez disků I / O.
Krok 5: Vytvoření dotazu
Následuje vytváření dotazu. To je místo, kde je vytvořena šablona pro vytváření dotazů. Chcete-li to spravovat, potřebujeme šablonu dotazu, která dokáže vyvážit jak relevanci, tak aktuálnost.
# 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"))
)
To nám umožňuje zvolit, zda upřednostnit obsah (relevance_váha) nebo aktuálnost (recency_váha) - velmi užitečná kombinace pro potřeby našeho agenta.
Krok 6: Stavební nástroje
Nyní přichází nástrojová část.
Budeme pracovat na třech nástrojích...
- Nástroj pro vyhledávání: Tento nástroj je vytvořen zapojením do indexu Superlinked, což mu umožňuje vytáhnout top 5 papírů na základě dotazu. Vyváží relevanci (1.0 hmotnost) a aktuálnost (0,5 hmotnost) k dosažení cíle „hledat papíry“. Co chceme, je najít papíry, které jsou relevantní pro dotaz. Takže pokud je dotaz: „Jaké kvantové výpočetní papíry byly publikovány mezi lety 1993 a 1994?“, pak nástroj pro vyhledávání tyto papíry vyhledá, shrne je jeden po druhém a vrátí výsledky.
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
Další nahoře jeSummarization Tool
Tento nástroj je určen pro případy, kdy je zapotřebí stručné shrnutí papíru.paper_id
, což je ID papíru, který je třeba shrnout.paper_id
není poskytnuta, nástroj nebude fungovat, protože tyto ID jsou požadavkem pro nalezení odpovídajících papírů v databázi.
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()
Konečně máme naQuestionAnsweringTool
Tento nástroj řetězceRetrievalTool
vyzvednout příslušné dokumenty a pak je použít k zodpovězení otázek. Pokud nejsou nalezeny žádné příslušné dokumenty, které by odpovídaly na otázky, poskytne odpověď založenou na obecných znalostech
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()
Krok 7: Vytvoření agenta jádra
Následuje jaderný agent. Funguje jako centrální ovladač, který zajišťuje hladký a efektivní provoz. Jako základní součást systému, jaderný agent koordinuje komunikaci směrováním dotazů podle jejich záměru, když více agentů pracuje současně. V systémech s jedním agentem, jako je tento, jaderný agent přímo používá příslušné nástroje k efektivnímu řízení úkolů.
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'."
V této fázi byly všechny součásti systému výzkumných agentů nakonfigurovány.Systém lze nyní inicializovat poskytnutím příslušných nástrojů jádrovému agentu, po kterém bude systém výzkumných agentů plně funkční.
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)
Pojďme si ten systém vyzkoušet...
# Test query print(kernel_agent.process_query("Find papers on quantum computing in last 10 years"))
Spuštění tohoto systému aktivujeRetrievalTool
Získá příslušné dokumenty na základě relevance i aktuálnosti a vrátí příslušné sloupce.Pokud vrácený výsledek zahrnuje sloupec souhrnu (ukazující, že dokumenty byly získány z datové sady), použije tyto souhrny a vrátí nám je.
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...
Pojďme zkusit další dotaz, tentokrát, pojďme udělat shrnutí jeden..
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.
Doufám, že tento příklad byl užitečný pro vývoj agentů AI a systémů založených na agentech.repozitářpro budoucí reference, když jsou pro vaše agenty AI zapotřebí přesné možnosti vyhledávání!
Vezměte
- Kombinace sémantické a časové relevance eliminuje složité přerozdělování při zachování přesnosti vyhledávání pro výzkumné práce.
- Tresty založené na čase (negative_filter=-0.25) upřednostňují nedávný výzkum, pokud mají články podobný obsah relevance.
- Modulární architektura založená na nástrojích umožňuje specializovaným komponentům zvládat odlišné úkoly (získávání, shromažďování, odpověď na otázky) při zachování soudržnosti systému.
- Ukládání dat v malých dávkách (batch_size=10) se sledováním pokroku zlepšuje stabilitu systému při zpracování velkých datových souborů výzkumu.
- Nastavitelné váhy dotazů umožňují uživatelům vyvážit relevanci (1.0) a aktuálnost (0.5) na základě specifických výzkumných potřeb.
- Součást odpovídání na otázky se elegantně degraduje na obecné znalosti, když není k dispozici papírový kontext, čímž se zabraňuje mrtvým uživatelským zkušenostem.
Aktualizace velkého počtu pravidelně publikovaných výzkumných článků může být náročná a časově náročná.Agentní pracovní postup asistenta AI, který je schopen efektivně lokalizovat relevantní výzkum, shrnout klíčové poznatky a odpovědět na konkrétní otázky z těchto článků, by mohl tento proces výrazně zjednodušit.
Přispěvatelé
- Vipul Maheshwari, autor
- Filip Makraduli, recenzent