
Агент ИИ, который интерпретирует документы, поэтому вам не нужно: полное руководство по сборке
27 июня 2025 г.Узнайте, как построить агент ИИ для поиска, поиска и обобщения научно -исследовательских документов
Для исследователей оставаться в курсе последних результатов, сродни поиску иглы в стоге сена. Представьте себе помощника по AI, который не только извлекает наиболее актуальные документы, но и суммирует ключевые идеи и отвечает на ваши конкретные вопросы, все в режиме реального времени.
Эта статья углубляется в построение такого агента исследований искусственного интеллекта с использованием сложных возможностей встроенного документа SuperLinked. Интегрируя семантическую и временную актуальность, мы устраняем необходимость в сложной реанкинге, обеспечивая эффективное и точное извлечение информации.
TL; DR:
Создайте агента по исследованию ИИ в реальном времени, используя векторный поиск SuperLinked. Он пропускает сложные тряпичные трубопроводы, напрямую внедряя и запрашивая документы - проводя исследования быстрее, проще и умнее.
(Хотите прыгнуть прямо в код?Проверьте открытый исходный код на GitHub
В этой статье показано, как построить систему агента, используя агент ядра для обработки запросов. Если вы хотите следовать и запустить код в браузер,Вот
Где начать создавать систему научно -исследовательской помощи?
Традиционно, создание такой системы включает в себя сложность и значительные инвестиции в ресурсы. Системы поиска обычно получают начальный широкий набор документов, основанных на актуальности, и впоследствии применяют вторичный процесс повторного переработки для уточнения и повторного порядка. В то время как реэранкирование повышает точность, оно значительно увеличивает вычислительную сложность, задержку и накладные расходы из -за первоначального требуемого извлечения данных. Superlinked обращается к этой сложности, объединяя структурированные числовые и категориальные встроения с семантическими текстовыми вставками, обеспечивающими комплексные мультимодальные векторы. Этот метод значительно повышает точность поиска, сохраняя информацию, специфичную для атрибута в каждом внедрении.
Создайте агентскую систему с помощью сверхвязывания
Этот агент ИИ может сделать три основных вещах:
- Найдите документы: Поиск исследовательских работ по темам (например, «квантовые вычисления»), а затем ранжируйте их по релевантности и рецензии.
- Суммируйте документы: сформировать полученные документы в понимание размером с укус.
- Ответьте на вопросы: Извлеките ответы непосредственно из конкретных исследовательских работ на основе целевых пользовательских запросов.
SuperLinked устраняет необходимость в методах повторного ранжирования, поскольку он улучшает актуальность поиска вектора. Будет использована рекордная пропускная способность Superlinked, которая специально кодирует временные метаданные, приоритетные недавние документы во время поиска и устраняя необходимость в вычислительном рефанкировании. Например, если две статьи имеют одинаковую актуальность - самая последняя, будет ранжироваться выше.
Шаг 1: Настройка набора инструментов
%pip install superlinked
Чтобы сделать вещи проще и модульнее, я создал абстрактный класс инструментов. Это упростит процесс создания и добавления инструментов
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"
Шаг 2: Понимание набора данных
В этом примере используется набор данных, содержащий приблизительно 10 000 исследовательских работ AI, доступных наКэгглПолем Чтобы облегчить это, просто запустите ячейку ниже, и она автоматически загрузит набор данных в ваш рабочий каталог. Вы также можете использовать свои собственные источники данных, такие как исследовательские работы или другой академический контент. Если вы решите сделать это, все, что вам нужно сделать, это немного настроить дизайн схемы и обновить имена столбцов.
import pandas as pd
!wget --no-check-certificate 'https://drive.google.com/uc?export=download&id=1FCR3TW5yLjGhEmm-Uclw0_5PWVEaLk1j' -O arxiv_ai_data.csv
На данный момент, чтобы все было немного быстрее, мы будем использовать меньшую подмножество бумаг, чтобы просто ускорить ситуацию, но не стесняйтесь попробовать пример, используя полный набор данных. Важным техническим деталем здесь является то, что временные метки из набора данных будут преобразованы из строковых временных метров (например, '1993-08-01 00: 00: 00+00: 00') в объекты Pandas DateTime. Это преобразование необходимо, потому что оно позволяет нам выполнять операции даты/времени.
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']
Понимание столбцов набора данных
Ниже приведен краткий обзор ключевых столбцов в нашем наборе данных, который будет важен в предстоящих шагах:
published
: Дата публикации исследовательской работы.summary
: Аннотация статьи, предоставляя краткий обзор.entry_id
: Уникальный идентификатор для каждой статьи от Arxiv.
Для этой демонстрации мы специально сосредоточены на четырех столбцах:entry_id
Вpublished
Вtitle
, иsummary
Полем Чтобы оптимизировать качество поиска, заголовок и резюме объединяются в единый комплексный текстовый столбец, который составляет ядро нашего процесса встраивания и поиска.
Примечание по индексации Superlinked Indexer: индексация SuperLinked в памяти хранит наш набор данных непосредственно в RAM, что делает поиск исключительно быстрым, что идеально подходит для поиска в реальном времени и быстрого прототипирования. Для этого доказательства концепции с 1000 исследовательских работ, используя подход в памяти значительно повышает производительность запроса, устраняя задержки, связанные с доступом к диску.
Шаг 3: Определение схемы сверхвязывания
Чтобы продвинуться вперед, в схеме необходимо сопоставить наши данные. Мы настроили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()
Определение сверхвязываемого пространства для эффективного поиска
Основной шаг в организации и эффективном запросе нашего набора данных включает определение двух специализированных векторных пространств: TextsImilalitySpace и реконструкция.
- TextSimiLastrySpace
АTextSimilaritySpace
предназначен для кодирования текстовой информации, такой как названия и рефераты исследовательских работ в векторы. Преобразовая текст в встраивания, это пространство значительно повышает легкость и точность семантических поисков. Он оптимизирован специально для эффективного обработки более длинных текстовых последовательностей, обеспечивая точные сравнения сходства между документами.
text_space = sl.TextSimilaritySpace(
text=sl.chunk(paper.text, chunk_size=200, chunk_overlap=50),
model="sentence-transformers/all-mpnet-base-v2"
)
- Рекордсменное пространство
The 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
)
Подумайте о Recyspace как о фильтре, основанном на времени, аналогично сортировке ваших электронных писем по дате или просмотру постов в Instagram с самыми новыми. Это помогает ответить на вопрос: «Насколько свежа эта бумага?»
- Меньшие Timedeltas (например, 365 дней) позволяют получить более гранулированный, ежегодный рейтинг времени.
- Большие временные рамки (например, 1095 дней) создают более широкие периоды времени.
А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
Эти пространства являются ключом к тому, чтобы сделать набор данных более доступным и эффективным. Они допускают как поиск на основе контента, так и на основе времени, и действительно полезны в понимании актуальности и рецензии исследовательских работ. Это обеспечивает мощный способ организации и поиска набора данных на основе контента и времени публикации.
Шаг 4: Создание индекса
Далее, пространства сливаются в индекс, который является ядром поисковой системы:
paper_index = sl.Index([text_space, recency_space])
Затем DataFrame сопоставлен с схемой и загружается партиями (10 бумаг за раз) в магазин в памяти:
# 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])
Исполнитель в памяти-это то, почему здесь сияет сверхвязывание-1000 бумаг, которые плотно прилегают к оперативной памяти, а запросы летают без узких мест ввода/вывода.
Шаг 5: Создание запроса
Следующим является создание запроса. Здесь создается шаблон для создания запросов. Чтобы управлять этим, нам нужен шаблон запроса, который может сбалансировать как актуальность, так и рецензию. Вот как это выглядело бы:
# 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"))
)
Это позволяет нам выбрать, следует ли расставить приоритеты содержимого (Actuance_weight) или Recency (Recency_weight) - очень полезная комбинация для потребностей нашего агента.
Шаг 6: Строительные инструменты
Теперь наступает часть инструмента.
Мы будем создавать три инструмента ...
Retrieval Tool
: Этот инструмент создан путем подключения к индексу SuperLinked, позволяя ему вытащить 5 лучших бумаг на основе запроса. Он уравновешивает актуальность (1,0 веса) и резиденцию (0,5 веса) для достижения цели «найти документы». Мы хотим найти документы, которые имеют отношение к запросу. Итак, если запрос: «Какие квантовые вычислительные документы были опубликованы в период с 1993 по 1994 год?», То инструмент поиска извлечет эти документы, суммирует их один за другим и вернет результаты.
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
Далее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()
Наконец, у нас есть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()
Шаг 7: Построение агента ядра
Следующим является агент ядра. Он функционирует как центральный контроллер, обеспечивая плавную и эффективную работу. Выступая в качестве основного компонента системы, агент ядра координирует связь, направляя запросы в соответствии с их намерением, когда несколько агентов работают одновременно. В таких системах, как этот, агент ядра напрямую использует соответствующие инструменты для эффективного управления задачами.
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'."
На этом этапе были настроены все компоненты системы исследовательских агентов. Теперь система может быть инициализирована путем предоставления агента ядра соответствующими инструментами, после чего система исследовательских агентов будет полностью работой.
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)
Теперь давайте проверим систему ..
# Test query print(kernel_agent.process_query("Find papers on quantum computing in last 10 years"))
Запуск этого активирует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...
Давайте попробуем еще один запрос, на этот раз давайте сделаем обобщение.
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.
Я надеюсь, что этот пример был полезен для разработки агентов ИИ и агентских систем. Большая часть функциональности поиска, продемонстрированная здесьрепозиторийДля будущих ссылок, когда для ваших агентов искусственного интеллекта необходимы точные возможности поиска!
Вынос
Код ноутбука
- Комбинирование семантической и временной значимости устраняет сложную переосмысление при сохранении точности поиска для исследовательских работ.
- Штрафы на основе времени (OTED_FILTER = -0,25) приоритет в недавнем исследовании, когда работы имеют аналогичную актуальность контента.
- Модульная архитектура на основе инструментов позволяет специализированным компонентам выполнять различные задачи (поиск, суммирование, вопрос о ответах) при сохранении сплоченности системы.
- Загрузка данных в небольших партиях (batch_size = 10) с отслеживанием прогресса улучшает стабильность системы при обработке больших наборов данных исследования.
- Регулируемые веса запроса позволяют пользователям сбалансировать актуальность (1,0) и рецензию (0,5) на основе конкретных потребностей в исследованиях.
- Компонент, отвечающий вопросам, грациозно разлагается на общие знания, когда контекст, специфичный для бумаги, недоступен, предотвращая тупиковую пользовательскую опыт.
Регулярно вновь вмешательство в обширное количество опубликованных исследовательских работ может быть сложным и трудоемким. Агент -помощник AI Assistant, способный эффективно найти соответствующие исследования, суммировать ключевые идеи и отвечать на конкретные вопросы из этих документов, может значительно упростить этот процесс.
Участники
- Випул Махешвари, автор
- Филип Макрадули, рецензент
Оригинал