Различные AI-компании сейчас внедряют агентные AI-системы, способные проводить глубокие исследования по заданной теме и создавать комплексные отчёты, например Deep Research от OpenAI.
Агентные AI-системы, такие как Deep Research от OpenAI, предлагают автоматизированные конвейеры для сложных задач, таких как многоэтапный поиск и синтез. Однако большинство существующих решений являются закрытыми, их сложно настраивать, и они ограничивают контроль над поведением модели и обработкой данных.
Например, вы можете захотеть использовать другую LLM, собственного поискового провайдера или изменить то, как агент планирует и действует, чтобы получать определённые результаты.
Это подводит нас к интересному вопросу: можно ли создать собственный агент глубокого поиска с полной гибкостью, где вы можете использовать предпочитаемую AI-модель, интегрировать предпочитаемую поисковую систему и настраивать поведение агента? Ответ — да.
В этой статье вы узнаете, как создать собственного агента глубокого исследования с помощью Novita AI, LangChain и Tavily.
Что такое агентный рабочий процесс глубокого поиска?
Традиционный поиск часто отнимает много времени, так как обычно требует просмотра большого количества доступной информации в интернете и в итоге может не привести к инсайтам. Агентный рабочий процесс глубокого поиска решает эти проблемы с помощью AI-агентов, которые могут автономно рассуждать, принимать решения и координировать внешние инструменты в рамках рабочего процесса.
Этот рабочий процесс обычно включает:
-
Структурирование задачи: AI-агент разбивает тему на более мелкие задачи.
-
Планирование: Агент создаёт стратегии для выполнения каждой задачи, что помогает рабочему процессу определить последовательность выполнения.
-
Интеграция инструментов: Для сбора информации агент использует различные инструменты, такие как базы данных и веб-поисковики. Без этих инструментов агент не может выполнять ключевые действия в рамках рабочего процесса.
-
Синтез: Агент анализирует собранную информацию и объединяет её в связные данные.
-
Генерация отчёта: После синтеза данных агент создаёт структурированный отчёт, включающий резюме и цитаты.
Необходимые инструменты
Прежде чем перейти к практической части статьи, давайте настроим необходимые инструменты.
Novita AI
Для построения агентного рабочего процесса нам понадобится LLM, и Novita AI предоставляет доступный высокопроизводительный API, который даёт доступ к новейшим LLM, моделям генерации изображений и многому другому.
Войдите в Novita AI, чтобы начать. После входа перейдите в Settings > Key Management и следуйте инструкциям для создания API-ключа.
Обратите внимание: при регистрации Novita AI предоставит вам бесплатные кредиты для тестирования различных моделей, так что вам не нужно беспокоиться о покупке кредитов перед началом разработки или экспериментов.

Tavily
Tavily — это продвинутый веб-поисковый API, оптимизированный для AI-приложений. С помощью поискового инструмента Tavily мы можем дать нашему агенту доступ к интернету для сбора точной и непредвзятой информации. Перейдите на Tavily и сгенерируйте API-ключ.

LangChain
LangChain — это фреймворк с открытым исходным кодом, предназначенный для создания приложений с LLM. С помощью LangChain вы можете создать агентный рабочий процесс, который рассуждает пошагово, использует инструменты и взаимодействует с API. Для нашего агента глубокого исследования мы будем использовать LangChain для структурирования процесса исследования, использования таких инструментов, как веб-поиск, и синтеза всего в структурированный отчёт.

Google Colab
В этом руководстве мы будем создавать и тестировать агента глубокого поиска с помощью Google Colab. Colab позволяет писать и выполнять код Python в браузере без какой-либо настройки, что упрощает следование инструкциям.
Обзор рабочего процесса
Агентный глубокий поиск представляет собой комбинацию различных этапов рабочего процесса: от планирования задачи поиска до предоставления финального отчёта. Давайте пройдёмся по каждому шагу, чтобы понять, как работает приложение.

Планирование исследования
Это первый шаг рабочего процесса. Здесь агент анализирует тему и создаёт структурированный план исследования на основе контекста темы. Он разбивает широкую тему на целевые подтемы, такие как история, технические детали, плюсы и минусы, варианты использования и другое.
Это можно считать самой важной частью рабочего процесса, потому что без него агент может выполнять общие поиски и возвращать нерелевантные результаты.
Глубокий поиск
LLM ограничены своими обучающими данными и не могут получить доступ к текущим трендам. Например, если вы попросите агента без возможности поиска перечислить текущих игроков футбольной команды, он вернёт результаты на основе данных, на которых он обучался. Однако, поскольку эти результаты не содержат самых свежих обновлений, они могут быть уже не точны.
Использование Tavily для выполнения продвинутых веб-поисков даёт агенту доступ к самым последним и релевантным веб-источникам.
Управление источниками
Чтобы каждый фрагмент информации, который выдаёт агент, можно было привязать к надёжному источнику, важно отслеживать все источники. Эта часть рабочего процесса создаёт доверие у пользователей, которые хотят проверить утверждения или данные в финальном отчёте.
Синтез
Чтобы соединить разрозненные фрагменты информации, агент объединяет инсайты из всех исследованных аспектов в связный отчёт. Без этого этапа результат поиска может быть просто разрозненным набором данных.
Финальное форматирование
Даже если отчёт точен и хорошо исследован, плохое форматирование может затруднить его чтение. Требуется дополнительный шаг, чтобы обеспечить чистую структуру, единообразные заголовки, маркированные списки, интервалы и т.д.
Реализация агента глубокого поиска
Итак, вы уже поняли, что такое агентный рабочий процесс глубокого поиска. Теперь пришло время реализовать его в Google Colab.
Для начала выполним несколько ключевых шагов:
Шаг 1: Установка зависимостей
-q langchain langchain-openai tavily-python
Шаг 2: Импорт необходимых библиотек
# Импорт стандартных библиотек Python
import os # Для взаимодействия с переменными окружения
import re # Для регулярных выражений
import ast # Для безопасного разбора выражений Python из строк
# Модели и инструменты LangChain
from langchain_openai import ChatOpenAI # Интерфейс для взаимодействия с чат-моделями OpenAI
from langchain_community.utilities.tavily_search import TavilySearchAPIWrapper # Обеспечивает поиск через API Tavily
# Схема сообщений LangChain
from langchain.schema import SystemMessage, HumanMessage # Определяет типы сообщений, используемых в диалогах
# Компоненты агента LangChain
from langchain.agents import Tool, AgentExecutor, create_react_agent # Для построения и запуска агентных рабочих процессов с инструментами
# Шаблоны промптов LangChain
from langchain.prompts import PromptTemplate # Позволяет создавать переиспользуемые шаблоны промптов
# Память LangChain
from langchain.memory import ConversationBufferMemory # Помогает поддерживать состояние диалога между шагами
Шаг 3: Настройка переменных окружения
# Установка и получение переменных окружения
os.environ["NOVITA_API_KEY"] = "" # Замените на ваш реальный API-ключ Novita
os.environ["TAVILY_API_KEY"] = "" # Замените на ваш реальный API-ключ Tavily
# Загрузка API-ключей в переменные
novita_api_key = os.getenv("NOVITA_API_KEY")
tavily_api_key = os.getenv("TAVILY_API_KEY")
Шаг 4: Определение вспомогательной функции для LLM
Novita AI совместим с OpenAI, поэтому мы будем использовать модуль ChatOpenAI из LangChain для интеграции Novita AI с LangChain. Это означает, что мы можем общаться с Novita так же, как с моделями OpenAI.
Однако важно отметить, что нам нужно установить base_url, чтобы он указывал на конечную точку API Novita: https://api.novita.ai/v3/openai.
В этом рабочем процессе мы будем использовать модель llama-4-maverick-17b-128e-instruct-fp8, которая является мощным вариантом LLaMA 4, доработанным для выполнения инструкций.
# Вспомогательная функция для LLM
def llm(api_key,
model="meta-llama/llama-4-maverick-17b-128e-instruct-fp8",
temperature=0.7):
"""Создать экземпляр ChatOpenAI LLM с заданными параметрами."""
return ChatOpenAI(
model=model,
openai_api_key=api_key,
base_url="https://api.novita.ai/v3/openai",
temperature=temperature,
)
Создание агента-исследователя
Весь рабочий процесс глубокого исследования инкапсулирован в модульном классе AgenticResearcher. Этот класс будет управлять процессом генерации планов исследования, выполнения веб-поисков, синтеза результатов, форматирования итогового отчёта и запуска полного цикла исследования.
Мы инициализируем исследовательского агента с доступом к LLM через API Novita и инструментом веб-поиска через API Tavily. Затем мы определяем метод, который выполняет продвинутый веб-поиск по заданному запросу с помощью Tavily. Результаты форматируются для удобочитаемости, а сырые данные сохраняются для последующего использования.
class AgenticResearcher:
def __init__(self, novita_api_key, tavily_api_key, num_researchers=3, temperature=0.3):
"""Инициализация исследовательского агента с необходимыми API-ключами и параметрами."""
self.llm = llm(api_key=novita_api_key, temperature=temperature)
self.tavily_search =
TavilySearchAPIWrapper(tavily_api_key=tavily_api_key)
self.num_researchers = num_researchers
self.raw_search_results = []
def search(self, query):
"""Поиск информации в интернете по заданному запросу."""
try:
results = self.tavily_search.results(
query, max_results=7,
search_depth="advanced"
)
# Сохраняем сырые результаты для обработки цитат
self.raw_search_results.extend(results)
formatted = []
for r in results:
formatted += [
f"TITLE: {r.get('title','')}",
f"URL: {r.get('url','')}",
f"CONTENT:\
{r.get('content','')}",
"---"
]
return "\
".join(formatted) if formatted else "No results found"
except Exception as e:
return f"Search error: {str(e)}"
Создание планов исследования по нескольким аспектам
Всё ещё в рамках класса AgenticResearcher давайте создадим метод, который генерирует структурированный план исследования, разбивая тему на несколько различных аспектов с помощью LLM. Каждый аспект включает заголовок и конкретный поисковый запрос. Цель — изучить тему с разных сторон, чтобы обеспечить глубину и широту.
def create_research_plan(self, topic):
"""Создание структурированного плана исследования с несколькими аспектами для изучения."""
sys = "You are a planner that outputs Python lists of dicts."
hum = f"""
Create a comprehensive research plan for: {topic}
Identify {self.num_researchers} distinct aspects to investigate thoroughly.
Analyze the topic and determine the most relevant aspects to research based on its nature and domain.
Output exactly:
ASPECT {{'title': '...', 'search_query': '...'}}
"""
try:
resp = self.llm.invoke([SystemMessage(content=sys), HumanMessage(content=hum)])
aspects = []
for line in resp.content.splitlines():
if line.strip().startswith("ASPECT"):
m = re.search(r"\{.*\}", line)
if m:
try:
aspects.append(ast.literal_eval(m.group(0)))
except Exception as e:
print(f"Error parsing aspect: {e}")
if not aspects:
# Универсальные аспекты по умолчанию, работающие для разных доменов
default_aspects = [
{"title": "Overview and Key Information", "search_query": f"{topic} overview key facts"},
{"title": "Background and Context", "search_query": f"{topic} background history context"},
{"title": "Details and Specifications", "search_query": f"{topic} details specifics data"},
{"title": "Analysis and Significance", "search_query": f"{topic} analysis importance implications"}
]
aspects = default_aspects[:self.num_researchers]
return aspects
except Exception as e:
print(f"Error creating research plan: {e}")
return [{"title": f"{topic} research", "search_query": topic}]
Управление источниками и цитирование
Далее нам нужно обработать то, как рабочий процесс генерирует достоверные отчёты. Мы сделаем это, создав метод, который извлекает уникальные источники из сырых результатов поиска, гарантируя, что каждый источник будет процитирован.
def extract_sources(self):
"""Извлечение уникальных источников из сырых результатов поиска для цитирования."""
unique_sources = {}
for result in self.raw_search_results:
url = result.get('url', '')
if url and 'http' in url:
domain = url.split('/')[2] if len(url.split('/')) > 2 else url
if domain not in unique_sources:
unique_sources[domain] = url
return unique_sources
Синтез отчёта
Теперь, когда мы собрали сырую информацию из нескольких источников, следующий шаг — превратить этот неструктурированный ввод в подробный исследовательский отчёт. Мы напишем методы, которые синтезируют сырой текст в читаемый, организованный отчёт с заголовками, подзаголовками, ключевыми выводами и цитатами источников.
def synthesize(self, text):
"""Синтез сырого текста в подробные структурированные выводы с цитатами."""
sources = self.extract_sources()
sources_list = list(sources.keys())
sys = """You are an expert research synthesizer that creates detailed, structured reports.
For each claim or fact you include, add a citation to the source domain.
Use the exact domain names provided without modification.
Adapt your report structure to the topic's domain and nature."""
hum = f"""
INFORMATION TO SYNTHESIZE:
{text}
AVAILABLE SOURCE DOMAINS (use these exact names for citations):
{sources_list}
Create a comprehensive, detailed research report with:
1. Main findings with specific facts and figures
2. Structured information with clear headings and subheadings appropriate to the topic
3. Citations using the exact source domain names in square brackets [like.this]
4. Relevant data presented clearly and professionally
5. Format adapted to the specific nature of the topic (technical, historical, news event, etc.)
FORMAT THE REPORT PROFESSIONALLY AND THOROUGHLY WITHOUT ASSUMING ANY SPECIFIC DOMAIN.
"""
try:
return self.llm.invoke([SystemMessage(content=sys), HumanMessage(content=hum)]).content
except Exception as e:
return f"Synthesis error: {str(e)}"
Создание инструментов для агента
Чтобы сделать наш агентный рабочий процесс глубокого поиска функциональным, нам нужно определить инструменты. Инструменты дают агенту возможности выполнять определённые действия.
Основные инструменты, необходимые для этого рабочего процесса: «plan» (план) для разбивки темы и создания структурированного плана исследования, «search» (поиск) для выполнения глубокого веб-поиска и «synthesize» (синтез) для преобразования всех сырых результатов в организованный отчёт.
def get_tools(self):
"""Создать и вернуть список инструментов, доступных агенту."""
return [
Tool(
name="plan",
func=lambda t: str(self.create_research_plan(t)),
description="Create a detailed research plan with multiple aspects to investigate."
),
Tool(
name="search",
func=self.search,
description="Search the web thoroughly for a query and return comprehensive results."
),
Tool(
name="synthesize",
func=self.synthesize,
description="Transform raw text into detailed, structured findings with citations."
),
]
Создание исполнителя агента (Agent Executor)
Теперь, когда наши инструменты готовы, нужно связать всё вместе в AI-агента, используя ReAct-стиль промптов. Это помогает агенту планировать, выполнять действия с помощью определённых инструментов, наблюдать результаты и повторять цикл, пока не будет собрано достаточно данных для создания финального исследовательского отчёта.
def get_agent_executor(self):
"""Создать и вернуть исполнителя агента с инструментами и памятью."""
tools = self.get_tools()
template = """You are an autonomous research agent specialized in producing comprehensive, detailed reports on any topic.
{tool_names}
TOOLS:
{tools}
PREVIOUS CONVERSATIONS:
{chat_history}
When given a research topic (as {input}), follow this process:
1. Analyze the type of topic and create a research plan tailored to its domain
2. Search for comprehensive information on each aspect of the topic
3. Collect detailed, relevant information with sources
4. Synthesize everything into a professional, detailed report formatted appropriately for the topic
Follow exactly this format:
Question: {input}
Thought: (your reasoning here)
Action: the name of the tool to call, must be one of [{tool_names}]
Action Input: the input to the tool
Observation: (the tool's output)
... (repeat Thought/Action/Action Input/Observation as needed)
When you have gathered comprehensive information, output:
Final Answer: (your final, detailed research report with structured sections, appropriate formatting, specific details, and citations)
BEGIN WITH A THOROUGH PLAN!
{agent_scratchpad}
"""
prompt = PromptTemplate(
template=template,
input_variables=["input", "agent_scratchpad", "tools", "tool_names", "chat_history"]
)
# Создание низкоуровневого агента
agent = create_react_agent(
llm=self.llm,
tools=tools,
prompt=prompt
)
# Оборачиваем в исполнителя с памятью
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
agent_executor = AgentExecutor.from_agent_and_tools(
agent=agent,
tools=tools,
verbose=True,
memory=memory,
max_iterations=18,
early_stopping_method="generate",
handle_parsing_errors=True
)
return agent_executor
Финальное форматирование отчёта
После того как исследовательский агент завершил глубокий поиск, результат может быть информативным, но не презентабельным. Этот дополнительный шаг помогает сделать финальный отчёт более отшлифованным. Для этого мы попросим LLM выступить в роли экспертного редактора, чтобы улучшить итоговый отчёт.
def format_final_report(self, raw_report):
"""Добавить финальное форматирование к отчёту, чтобы сделать его более профессиональным."""
sys = """You are an expert editor that improves research reports.
Keep all the factual content, citations, and structure intact.
Just improve the formatting, organization, and readability."""
hum = f"""
Here is a research report that needs final formatting improvements:
{raw_report}
Please improve the formatting and presentation while preserving all:
1. Facts and figures
2. Citations
3. Content organization
4. Statistical data
Make it look professional with proper headings, spacing, and layout.
"""
try:
improved = self.llm.invoke([SystemMessage(content=sys), HumanMessage(content=hum)]).content
return improved
except Exception as e:
# Если форматирование не удалось, возвращаем исходный отчёт
return raw_report
Собираем всё вместе
Давайте объединим весь рабочий процесс в один конвейер, который координирует весь поток исследования. Это будет точка входа, позволяющая агенту выполнить полный процесс исследования, а затем отформатировать финальный отчёт.
def run(self, topic):
"""Запустить процесс исследования по заданной теме."""
try:
# Сброс сохранённых результатов поиска
self.raw_search_results = []
# Запуск агента
executor = self.get_agent_executor()
raw_report = executor.invoke({"input": topic})["output"]
# Форматирование финального отчёта
final_report = self.format_final_report(raw_report)
return final_report
except Exception as e:
return f"Research failed: {str(e)}"
Запуск исследовательского агента
Теперь, когда мы построили агентный рабочий процесс глубокого поиска, давайте протестируем его и посмотрим, насколько хорошо он справляется с реальной исследовательской задачей.
Мы создадим экземпляр исследовательского агента и попросим его сгенерировать подробный отчёт по актуальной теме.
# Создание объекта исследователя
researcher = AgenticResearcher(novita_api_key, tavily_api_key, num_researchers=3)
# Запуск тестового исследования
topic = "What are the most promising climate tech startups in 2025?"
report = researcher.run(topic)
# Вывод исследовательского отчёта
print("\
" + "="*60)
print(f"📝 DETAILED RESEARCH REPORT: {topic}")
print("="*60)
print(report)
print("="*60 + "\
")
Результат:
Агентный глубокий рабочий процесс разбил тему и создал план исследования, выполнил интернет-поиск для получения релевантной информации, синтезировал собранные данные и, наконец, вернул структурированный отчёт на основе поискового запроса.
Заключение
Поздравляем с созданием собственного агентного рабочего процесса глубокого поиска! Теперь вы можете исследовать любую тему и получать подробный отчёт по вашему запросу.
Давайте кратко подведём итоги того, что вы сделали:
В этой статье вы узнали, как построить агента глубокого поиска, который может разбивать сложные темы, генерировать план исследования, выполнять интернет-поиск и синтезировать все результаты в структурированный отчёт.
Весь этот рабочий процесс был реализован с помощью:
- Novita AI в качестве провайдера LLM
- LangChain для агентного фреймворка
- Tavily в качестве поисковой системы реального времени
Не стесняйтесь пробовать агента на разных темах, чтобы проверить его возможности!
Это лишь одно из множества захватывающих AI-приложений, возможных благодаря современным мощным моделям. Посетите Novita LLM Playground, чтобы попробовать другие лучшие новейшие AI-модели; кто знает, возможно, ваша следующая отличная AI-идея начнётся именно там.
Novita AI — это облачная AI-платформа, которая предоставляет разработчикам простой способ развёртывания AI-моделей с помощью нашего простого API, а также предлагает доступную и надёжную GPU-инфраструктуру для построения и масштабирования.
