Внешний поиск ИИ агентов

Мы уже использовали файловый поиск, чтобы находить данные в текстовых базах знаний через RAG. По тому же принципу можно искать информацию и в интернете — для этого предназначен инструмент веб-поиска. Сейчас всё расскажу!В качестве практики вы можете повторить действия из урока. Полный код проекта доступен в репозитории на GitHub.

Зачем нужен внешний поиск

В задаче построения фитнес-ассистента один из типичных запросов — «А сколько стоит годовой абонемент в клуб в Москве?». Поскольку дополнительная информация об этом не загружалась, модель отвечает только на основе внутренних знаний. Вы можете выполнить код ниже и посмотреть, какой ответ выдаст LLM на такой запрос:

model = f"gpt://{folder_id}/qwen3-235b-a22b-fp8/latest"

res = client.responses.create(
    model = model,
    input = "Сколько в среднем стоит годовой абонемент на занятия в фитнес-клубе в Москве?"
) 

📚 Предполагается, что объект client для работы с OpenAI-совместимым клиентом уже создан, а переменная folder_id инициализирована. Полный пример доступен в репозитории на GitHub.Ответ модели может выглядеть правдоподобно, но не считается достоверным по двум причинам:

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

Инструмент веб-поиска

Инструмент веб-поиска позволяет модели выполнять запросы в интернет. Он вызывается только при необходимости: модель принимает решение сама, а затем формирует ответ на основе найденных данных. Принцип похож на файловый поиск, но источником информации служит интернет, а запросы проходят через поисковые сервисы Yandex.В Responses API модель способна запускать веб-поиск автоматически. Для этого при вызове модели нужно указать соответствующий инструмент:

system_prompt = """
Ты — профессиональный фитнес-ассистент. 
Отвечай как энергичный молодой человек со спортивным задором.
В случае необходимости осуществляй поиск в интернет".
"""

res_ws = client.responses.create(
    model = model,
    instructions = system_prompt,
    tools = [ { "type": "web_search" } ],
    input = "Сколько в среднем стоит годовой абонемент на занятия в фитнес-клубе в Москве?"
)

printx(res_ws.output_text) 

В этом примере в параметр tools добавлен инструмент веб-поиска. В системный промпт включено указание выполнять поиск в интернете, что повышает вероятность обращения модели к инструменту.После выполнения кода ответ будет более конкретным. Кроме того, изменяется длина объекта response.

print(f"Ответ без поиска: {len(res.output)}") # напечатает 1
print(f"Ответ с поиском: {len(res_ws.output)}") # напечатает 2 

Отдельная запись в ответе связана с вызовом инструмента веб-поиска — она находится в элементе response[0]. В этой записи указан поисковый запрос, сформулированный LLM. Он был отправлен в поисковый движок Яндекса, а результаты переданы модели для формирования финального ответа.

print(res_ws.output[0].action.query) 

Результат:

{"query": "Средняя стоимость годового абонемента в фитнес-клуб в Москве", "lang": "ru"} 

Окончательный ответ LLM содержится в res_ws.output[1]. Помимо текстового ответа LLM, этот объект содержит ссылки на все использованные источники в res_ws.output[1].content[0].annotations:

for x in res_ws.output[1].content[0].annotations:
    print(f"{x.title} - {x.url}") 

В ответ на это вы получите список заголовков веб-страниц и ссылок на них.

Учёт истории переписки

После получения списка средних цен на фитнес-клубы, следующим шагом может быть поиск самых недорогих вариантов. Запрос «А самый дешёвый?» недостаточен для формирования корректного поискового запроса, так как в нём не упоминаются фитнес-клубы. В такой ситуации модель использует контекст из истории переписки:

res_ws_2 = client.responses.create(
    model = model,
    previous_response_id = res_ws.id,
    tools = [ { "type": "web_search" } ],
    input = "А поищи самый дешёвый?"
)

printx(res_ws_2.output_text) 

В примере явно указан previous_response_idдля сохранения контекста переписки. Дополнительно задано указание «поищи», чтобы обеспечить повторный вызов инструмента веб-поиска. Без этого модель могла бы ограничиться предыдущими результатами, уже сохранёнными в контексте.Какой запрос модель сделала в интернет:

if len(res_ws_2.output)>1:
    print(res_ws_2.output[0].action.query)
else:
    print("Инструмент поиска не был вызван") 

Если всё прошло хорошо, ответ будет примерно таким:

{"query": "Самый дешёвый годовой абонемент в фитнес-клуб в Москве 2025", "lang": "ru"} 

Кастомизация инструмента поиска

Стоимость фитнеса обычно интересует в конкретном городе. Город можно указать в запросе, но есть альтернативный вариант — ограничить область веб-поиска выбранным регионом или доменами.Инструмент веб-поиска поддерживает следующие параметры:

  • filters — ограничивает область поиска. Возможны два варианта: список доменов (allowed_domains) или регион (user_location). При отсутствии фильтров поиск выполняется по всему интернету.
  • search_context_size — задаёт объём контекста, который модель получает из поиска. Допустимые значения: low, medium (по умолчанию), high. Увеличение объёма контекста повышает расход токенов, но позволяет получить более точный ответ. Как применять эти параметры:
response = client.responses.create(
    model=model,
    input="Сделай краткий обзор отзывов на World Class Fitness",
    tools=[
        {
            "type": "web_search",
            "filters": {
                "allowed_domains": [
                    "otzovik.com"
                ],
                "user_location": {
                    "region": "213", # Москва
                },
            },
            "search_context_size": "medium", # варианты: low | medium | high
        }
    ]
)
printx(response.output_text) 

Здесь есть явное указание для поискового инструмента ограничить поиск регионом Москва и использовать только сайт otzovik.com.📚 Подробнее изучить параметры веб-поиска можно в документации.

Особенности использования инструмента поиска

Инструмент веб-поиска повышает точность и актуальность ответов, но каждый его вызов тарифицируется отдельно. Дополнительно результаты поиска поступают в контекст модели как входные токены, что увеличивает стоимость обработки и снижает скорость ответа.Поиск стоит использовать, только если необходима актуальная или справочная информация либо требуется выборка данных из новостных источников. Для задач перевода, суммаризации или декомпозиции поиск, напротив, не приносит пользы и может ухудшить результат.Даже при указании инструмента в списке tools решение о его вызове принимает сама модель. Однако при коротком контексте модели сложно определить необходимость поиска, поэтому в системном промпте рекомендуется задавать явные критерии для использования инструмента интернет-поиска.

Добавление интернет-поиска к агентам на основе класса Agent

В предыдущем уроке вы рассмотрели фитнес-ассистента на основе расширенного класса Agent, которому можно передавать разные инструменты: Pydantic-классы для локальных функций и словарные описания для RAG-поиска. Такой ассистент способен искать данные во внутренней базе знаний и фиксировать информацию о выполненных упражнениях.Если требуется добавить ответы о средней стоимости абонементов в фитнес-клубы, можно включить инструмент веб-поиска. Для этого достаточно добавить его в список доступных инструментов:

web_search_tool = {
    "type" : "web_search"
}

instruction = """
Ты — опытный фитнес-тренер, задача которого — помочь мне тренироваться в зале. Ты можешь советовать упражнения, давать рекомендации по питанию и т. д. Отвечай на основе имеющейся дополнительной информации из файловой базы знаний, вызывая инструмент поиска `search_tool`. В случае если запрос касается упоминания абстрактных фитнес-клубов или новостей, используй поиск в интернет `web_search_tool`.
Ты также можешь вести дневник выполненных пользователем упражнений — для этого используй функцию `Exercise`. Чтобы показать список выполненных упражнений, используй `ListExercises`.
"""

fit_agent = Agent(instruction, [web_search_tool, search_tool, Exercise, ListExercises],tool_choice='required')

res = fit_agent("Сколько стоит годовой абонемент в фитнес-клуб в Санкт-Петербурге?")
printx(res.output_text) 

📚 В этом примере предполагается, что класс Agent и переменные search_tool, Exercise и ListExercisesопределены ранее. Полный код доступен в репозитории на GitHub.💡 В системный промпт также добавлены инструкции, в каких случаях стоит вызывать поискового ассистента.

Источник : https://practicum.yandex.ru/trainer/yc-ml-aiagents/lesson/e104cfb6-d071-4e34-9ade-832721af375b/

Рубрики: Uncategorized

0 комментариев

Добавить комментарий

Заполнитель аватара

Ваш адрес email не будет опубликован.