Изучите практический подход к анализу больших массивов данных с помощью LLM-моделей.
Делиться

В приложениях GenAI контекст действительно решает всё. Качество результатов работы LLM тесно связано с качеством и объемом предоставляемой информации. На практике многие реальные сценарии использования требуют огромного контекста: генерация кода на основе больших кодовых баз, запросы к сложным системам знаний или даже долгие, запутанные беседы во время поиска идеального места для отдыха (все мы через это проходили).
К сожалению, модели с длительным контекстом (LLM) могут эффективно работать только с ограниченным объемом контекста. И дело не только в жестких ограничениях контекстного окна, особенно сейчас, когда передовые модели поддерживают сотни тысяч или даже миллионы токенов. И эти ограничения продолжают расти. Более серьезная проблема — это явление, известное как «разложение контекста» , когда производительность модели снижается по мере увеличения длины контекста.
Этот эффект наглядно продемонстрирован в статье «RULER: Каков реальный размер контекста ваших языковых моделей с длинным контекстом?» Хсие и др. Авторы представляют RULER, новый бенчмарк для оценки производительности в условиях длинного контекста, и тестируют ряд моделей. Результаты показывают устойчивую закономерность: по мере увеличения длины контекста производительность значительно снижается во всех моделях. Во многих случаях эффективная длина контекста (при которой производительность остается сопоставимой с Llama 2–7B) составляет лишь около 50% от заявленного контекстного окна или даже меньше.

В своей недавней статье «Рекурсивные языковые модели» Чжан и др. предлагают перспективный подход к решению проблемы «разрушения контекста». В этой статье я хотел бы подробнее рассмотреть эту идею и изучить, как она работает на практике, используя недавно добавленную в DSPy поддержку этой стратегии вывода.
Рекурсивные языковые модели
Рекурсивные языковые модели (РЛМ) были введены для решения проблемы снижения производительности по мере увеличения длины контекста и для обеспечения возможности работы ЛЛМ с очень большими контекстами (до двух порядков превышающими собственное контекстное окно модели). Это становится все более важным по мере того, как мы внедряем ЛЛМ для задач, связанных с обработкой сотен миллионов токенов.
Уже существует несколько подходов к обработке задач с длительным горизонтом планирования. Наиболее распространенный из них (с которым вы, вероятно, сталкивались при использовании агентов кода, таких как Cursor) — это суммирование контекста . В этой схеме контекст разговора или работы многократно суммируется по мере приближения к пределу контекста модели. Однако на практике это часто оказывается неэффективным: важные детали и тонкие нюансы из предыдущих шагов, как правило, теряются, поскольку модель «забывает» старую информацию, чтобы освободить место для новых токенов.
Рекурсивные языковые модели используют другой, удивительно элегантный подход. Вместо того чтобы каждый раз передавать всю подсказку языковой модели, подсказка рассматривается как набор переменных, доступных в среде REPL (цикл чтения-вычисления-печати) Python. Модель оснащена инструментами, позволяющими ей проверять эти переменные или рекурсивно вызывать себя для программно выбранных фрагментов.

Другими словами, RLM побуждают LLM писать код, который создает собственные подзадачи, а затем решает эти подзадачи путем рекурсивного вызова самого себя. Это перекладывает бремя от умещения всего в один запрос на структурирование проблемы таким образом, чтобы модель могла более надежно ориентироваться в больших контекстах.
Авторы оценили свой подход на нескольких задачах с длительным горизонтом планирования, где модели RLM показали хорошие результаты как на моделях GPT-5, так и на Qwen-3.

Результаты выглядят чрезвычайно многообещающими. Модели RLM (с подвызовами или без них) неизменно превосходят другие подходы во всех задачах. Посмотрим, как это будет работать на практике.
Применение RLM на практике
Один из распространенных сценариев, где длинный контекст действительно проявляет себя наилучшим образом, — это ответы на вопросы, касающиеся обширной базы знаний. Именно это мы и попробуем здесь. Я взял все статьи, которые опубликовал на Towards Data Science, и загрузил их в один файл Markdown. К моему удивлению, это составляет почти 1,5 МБ текста. Надеюсь, этого будет достаточно для того, чтобы модель смогла разобраться в нём.
К счастью, в DSPy недавно появилась реализация подхода вывода на основе рекурсивных языковых моделей. Это означает, что нам не нужно ничего создавать самостоятельно; нам просто нужна версия DSPy 3.1.2 или новее.
pip install dspy —upgrade
Начнём с загрузки набора данных.
with open('articles.md', 'r') as f: articles = f.read()
Далее проверим, сколько токенов оно содержит.
import anthropic client = anthropic.Anthropic(api_key=config['ANTHROPIC_API_KEY']) # Подсчет токенов для сообщений token_count = client.messages.count_tokens( model=»claude-sonnet-4-5″, messages=[ {«role»: «user», «content»: articles} ] ) print(f»Входные токены: {token_count.input_tokens}») # Входные токены: 386768
В нашем контексте содержится почти 400 тысяч токенов. Claude Sonnet 4.5 поддерживает контекстное окно в 200 тысяч токенов, поэтому обработка всего набора данных за один запрос нецелесообразна. Именно здесь RLM становится полезным.
Для использования DSPy нам сначала нужно настроить языковую модель. Как обсуждалось ранее, RLM использует код для взаимодействия с подсказкой, поэтому она лучше всего работает с моделями, обладающими сильными навыками программирования. По этой причине в этом примере я буду использовать модель Claude, поскольку она, как известно, хорошо справляется с задачами, связанными с кодом.
lm = dspy.LM('anthropic/claude-sonnet-4-5', api_key=config['ANTHROPIC_API_KEY']) dspy.configure(lm=lm)
Далее мы инициализируем RLM, указывая его сигнатуру. В данном случае я передаю полный набор статей вместе с вопросом и ожидаю, что модель выделит ключевые тренды и вернет их в виде списка строк.
rlm = dspy.RLM('articles, question -> trends: list[str]')
Здесь я использую Claude Sonnet 4.5 как для основной модели, так и для рекурсивных подвызовов. DSPy также позволяет использовать меньшую модель для подвызовов с помощью параметра sub_lm, что может помочь снизить затраты.
Теперь мы можем выполнить RLM и получить доступ к полю трендов в выходных данных.
output = rlm( articles = articles, question = '''Каковы были основные тенденции ИИ 2025 года на основе предоставленных статей? Обращайте внимание на содержание, а не только на заголовки.''' ) print('n'.join(output.trends)) # Агентный ИИ и автономные системы: модели саморефлексии, итеративное улучшение с помощью циклов обратной связи (Self-Refine, Reflexion, CRITIC) и LLM как механизмы рассуждений, способные автономно планировать и выполнять задачи # Многоагентные системы ИИ: эволюция от отдельных агентов к командам специализированных агентов с различными ролями, использующих такие фреймворки, как LangGraph, CrewAI и AutoGen для оркестрации # Контекстная инженерия и RAG: переход от статических подсказок к динамической генерации с дополненным поиском (RAG), адаптивным системам памяти и самосовершенствующимся контекстам, которые учатся на опыте без переобучения # Протоколы стандартизации: появление протокола контекста модели (MCP) для стандартизации инструмента LLM интеграция и протокол связи агентов (ACP) для межагентной связи, снижающий сложность интеграции # Использование инструментов LLM и вызов функций: LLM, оснащенные возможностью вызова внешних инструментов, выполнения SQL-запросов, просмотра веб-страниц и взаимодействия с API через структурированные механизмы вызова функций # Готовые к производству фреймворки ИИ: Зрелая экосистема, включающая LangGraph, DSPy, LangChain, NeMo Agent Toolkit, CrewAI и AutoGen, ориентированная на переход от прототипа к производству со встроенной возможностью мониторинга # Оценка и мониторинг LLM: Шаблоны оценки LLM в качестве судьи, комплексные системы метрик (Ragas, DeepEval, Evidently), оценка траекторий и непрерывный мониторинг как важная производственная инфраструктура # Программирование вместо подсказок: Переход к декларативной разработке ИИ на основе кода с использованием таких фреймворков, как DSPy, и подходов, управляемых конфигурацией (на основе YAML), заменяющих разработку подсказок # Взаимодействие фреймворков: Инструменты, разработанные для интеграции между несколькими фреймворками, а не для создания изолированных систем, позволяющие создавать компонуемые архитектуры ИИ Используйте лучшие возможности различных экосистем # Локальное и экономичное развертывание LLM: запуск небольших эффективных моделей локально (Llama, Ollama) для снижения затрат на API и проведения экспериментов, с акцентом на компромисс между стоимостью, качеством и задержкой # SQL-агенты и автоматизация анализа данных: агенты LLM, специализирующиеся на задачах анализа данных, генерации и выполнении SQL-запросов, с возможностью замены или дополнения традиционных рабочих процессов аналитика данных # Повышение качества и точности в производстве: методы повышения точности LLM, включая логическое мышление, структурированные результаты посредством вызова функций и итеративное уточнение для критически важных бизнес-приложений
Выполнение заняло около трех минут, и в результате получилось на удивление правдоподобное обобщение основных тем моих статей. Однако мы здесь не для того, чтобы изучать сами тренды. Более интересный вопрос заключается в том, как RLM вообще удалось это сделать. Поэтому давайте разберемся подробнее.
RLM под капотом
Естественно, самое интересное — это понять, что на самом деле происходит «под капотом».
Реализация RLM
Как обсуждалось ранее, ключевая идея рекурсивных языковых моделей заключается в том, что длинные контексты рассматриваются как часть внешней среды, а не передаются непосредственно в модель в виде единого запроса. Вместо этого языковая модель пишет код на Python для программного анализа, декомпозиции и рекурсивного вызова под-языковых моделей для более мелких фрагментов данных.
В общих чертах, данная реализация имеет несколько основных характеристик:
- В нем используется изолированная интерактивная среда Python REPL (цикл чтения-выполнения-печати), которая позволяет LLM исследовать большие контексты посредством выполнения кода.
- LLM работает в привычном для агентных систем цикле: он пишет код на Python, наблюдает за результатом, а затем решает, что делать дальше.
- Он может выполнять рекурсивные подвызовы (фактически вызывая самого себя), используя такие инструменты, как llm_query() и llm_query_batched(), для семантического анализа небольших фрагментов.
- Как только модель будет удовлетворена результатом, она завершает процесс, вызывая функцию SUBMIT() с полученными данными.
Подсказки
Чтобы действительно понять, как это работает, мне кажется полезным изучить фактические сообщения, отправляемые в LLM и получаемые от него. DSPy упрощает это с помощью следующей команды.
# Проверка исходных вызовов LLM — показывает фактические подсказки, отправленные модели dspy.inspect_history(n=39)
Это обеспечивает нам полную прозрачность информации о том, какие данные передавались модели на каждом этапе.
Начнём с системного сообщения. Оно определяет входные переменные, доступные модели (как указано в сигнатуре RLM), и перечисляет функции, которые модель может вызывать, такие как print, рекурсивные вызовы LLM и утилиты стандартной библиотеки.
Примечательно, что модуль RLM также позволяет предоставлять доступ к пользовательским функциям в REPL Python через параметр tools при инициализации RLM. В этом примере я использовал только функции по умолчанию, но в более сложных конфигурациях это может стать мощным инструментом расширения.
Ваши поля ввода: 1. `variables_info` (строка): Метаданные о переменных, доступных в REPL. 2. `repl_history` (история REPL): Предыдущие выполнения кода в REPL и их результаты. 3. `iteration` (строка): Текущий номер итерации (с индексом от 1) из max_iterations. Ваши поля вывода: 1. `reasoning` (строка): Пошагово обдумайте: что вам известно? Что осталось? Спланируйте свои следующие действия. 2. `code` (строка): Код Python для выполнения. Все взаимодействия будут структурированы следующим образом, с заполнением соответствующих значений. [[ ## variables_info ## ]] {variables_info} [[ ## repl_history ## ]] {repl_history} [[ ## iteration ## ]] {iteration} [[ ## reasoning ## ]] {reasoning} [[ ## code ## ]] {code} [[ ## completed ## ]] Следуя этой структуре, ваша задача: имея поля `articles` и `question`, получить значения из поля `trends`. Вам необходимо получить следующие выходные данные, имея входные данные `articles` и `question`: — {trends} # примечание: полученное значение должно соответствовать схеме JSON: {«type»: «array», «items»: {«type»: «string»}} У вас есть доступ к среде REPL Python. Напишите код на Python, и он будет выполнен. Вы увидите результат, а затем напишете дополнительный код, основываясь на полученных знаниях. Это итеративный процесс. Доступные функции: — Переменные: `articles`, `question` (ваши входные данные) — `llm_query(prompt)` — запрос к под-LLM (~500K символов) для семантического анализа — `llm_query_batched(prompts)` — одновременный запрос к нескольким запросам (значительно быстрее при одновременном выполнении нескольких запросов) — `print()` — ВСЕГДА выводите результат — `SUBMIT(trends)` — отправляйте окончательный результат после завершения — Стандартные библиотеки: re, json, collections, math и т. д. ВАЖНО: Это ИТЕРАТИВНЫЙ процесс. Каждый написанный вами блок кода будет выполнен, вы увидите результат, а затем решите, что делать дальше. НЕ пытайтесь решить все задачи за один шаг. 1. СНАЧАЛА ИЗУЧИТЕ ДАННЫЕ — Изучите свои данные, прежде чем обрабатывать их. Выведите примеры, проверьте типы/длины, разберитесь в структуре. 2. ИТЕРАЦИЯ — Пишите небольшие фрагменты кода, наблюдайте за результатами, а затем решайте, какие шаги предпринять дальше. Состояние сохраняется между итерациями. 3. ПРОВЕРКА ПЕРЕД ОТПРАВКОЙ — Если результаты кажутся неверными (нули, пустые значения, неожиданные результаты), пересмотрите свой подход. 4. ИСПОЛЬЗУЙТЕ llm_query ДЛЯ СЕМАНТИКИ — Сопоставление строк находит, ГДЕ находятся данные; llm_query понимает, ЧТО означают данные. 5. МИНИМИЗИРУЙТЕ ПОВТОРНЫЙ ВВОД (ВХОДНЫЕ И ВЫХОДНЫЕ ДАННЫЕ) — Когда значения длинные, точные или подвержены ошибкам (идентификаторы, числа, коды, кавычки), обращайтесь к ним через переменные и выполняйте анализ/вычисления в коде вместо повторного ввода. Используйте небольшие, целенаправленные выводные сообщения для проверки корректности, но избегайте ручного копирования, когда переменные могут содержать точное значение. 6. ОТПРАВКА ТОЛЬКО ПОСЛЕ ПРОВЕРКИ РЕЗУЛЬТАТОВ — Отправка немедленно завершает текущий запуск. Если вам необходимо проверить выведенные данные, выполните операцию за один шаг, просмотрите результат, а затем вызовите функцию SUBMIT на следующем шаге. У вас есть максимум 50 вызовов sub-LLM. После завершения вызовите функцию SUBMIT() с полученными данными.
Давайте также рассмотрим первое сообщение пользователя, отправленное в LLM. Оно дает модели общее представление о входных переменных: их типах, длине (чтобы модель знала, сколько данных она может прочитать за один раз) и предварительный просмотр содержимого для понимания структуры.
[[ ## variables_info ## ]] [1] ««« Переменная: `articles` (доступ к ней в вашем коде) Тип: str Общая длина: 1 392 921 символ Предварительный просмотр: «` — title: «Агентный ИИ из первых принципов: размышления» date: «2025-10-24T12:00:00-05:00» category: «Агентный ИИ» read_time: «21 мин чтения» url: «https://towardsdatascience.com/agentic-ai-from-first-principles-reflection/» — Третий закон Артура Кларка гласит, что «*любая достаточно развитая технология неотличима от магии*». Именно так считают многие современные фреймворки ИИ. Такие инструменты, как GitHub Copilot, Claude Desktop, OpenAI Operator и Perplexity Comet, автоматизируют повседневную жизнь… «` »»» [2] ««« Переменная: `question` (доступ к ней в вашем коде) Тип: str Общая длина: 114 символов Предварительный просмотр: «` Каковы были основные тенденции ИИ в 2025 году, исходя из предоставленных статей? Обращайте внимание на содержание, а не только на заголовки. «` »»» [3] ««« Переменная: `verbose` (доступ к ней в вашем коде) Тип: bool Общая длина: 4 символа Предварительный просмотр: «` True «` »»» [[ ## repl_history ## ]] Вы еще не взаимодействовали со средой REPL. [[ ## итерация ## ]] 1/20 Ответьте соответствующими полями вывода, начиная с поля `[[ ## рассуждения ## ]]`, затем `[[ ## код ## ]]` и заканчивая маркером для `[[ ## завершено ## ]]`.
Вот первоначальный ответ модели, соответствующий формату, указанному в сообщении пользователя.
[[ ## рассуждения ## ]] Мне нужно проанализировать статьи, чтобы определить основные тенденции в области ИИ на 2025 год. Давайте начнем с изучения данных: 1. Сначала я изучу структуру и содержание переменной `articles`, чтобы понять, с чем я работаю. 2. Мне нужно будет просмотреть несколько статей, а не только заголовки, чтобы понять фактическое содержание. 3. Затем я использую семантический анализ (llm_query) для извлечения и выявления тенденций. 4. Наконец, я составлю список тенденций. Давайте начнем с изучения данных о статьях, чтобы увидеть их структуру и понять, что доступно. [[ ## код ## ]] # Сначала разберемся со структурой статей print(«Тип статей:», type(articles)) print(«nДлина статей:», len(articles)) print(«n» + «=»*80) print(«Первые 2000 символов:») print(articles[:2000]) print(«n» + «=»*80) # Посмотрим, сможем ли мы определить структуру — похоже, статьи разделены # Попробуем разделить и посчитать их article_separator = «—nЗаголовок:» article_parts = articles.split(article_separator) print(f»nНайденное количество частей статьи: {len(article_parts)}») print(f»Длина первой части: {len(article_parts[0])} (вероятно, пустая или заголовок)») print(f»Длина второй части: {len(article_parts[1]) len(article_parts) > 1 else 0}») [[ ## завершено ## ]]
Исходные данные позволили нам получить четкое представление о том, как LLM взаимодействует с внутренней средой. Далее рассмотрим траекторию, по которой LLM двигался, чтобы достичь конечного результата.
Траектория
Для структурированного представления траектории мы можем просмотреть файл output.trajectory. Это даст доступ к каждому шагу рассуждений модели, сгенерированному ею коду и результирующим результатам. По сути, это обеспечит всесторонний обзор всех взаимодействий REPL.
# Изучаем полную траекторию — это показывает все взаимодействия REPL. for i, step in enumerate(output.trajectory): print(f»n{'='*60}») print(f»STEP {i+1}») print(f»{'='*60}») print(f»n📝 REASONING:n{step['reasoning']}») print(f»n💻 CODE:n{step['code']}») print(f»n📤 OUTPUT:n{step['output'][:1000]}{'…' if len(step['output']) > 1000 else ''}»)
Полный лог также можно найти на GitHub.
Анализ траектории помогает нам понять основные закономерности, которые использует LLM для решения задачи. В данном случае для получения окончательного ответа потребовалось 13 шагов.
Первым шагом, как и ожидалось, стало изучение переменной «статьи»: анализ ее структуры и получение представления об имеющихся данных. Это первоначальное исследование закладывает основу для всех последующих рассуждений и подзапросов.
# Сначала разберемся со структурой статей print(«Тип статей:», type(articles)) print(«nДлина статей:», len(articles)) print(«n» + «=»*80) print(«Первые 2000 символов:») print(articles[:2000]) print(«n» + «=»*80) # Давайте посмотрим, сможем ли мы определить структуру — похоже, статьи разделены # Давайте попробуем разделить и посчитать их article_separator = «—nЗаголовок:» article_parts = articles.split(article_separator) print(f»nНайденное количество частей статьи: {len(article_parts)}») print(f»Длина первой части: {len(article_parts[0])} (вероятно, пустая или заголовок)») print(f»Длина второй части: {len(article_parts[1]) если len(article_parts) > 1 иначе 0}»)
Далее, студент магистратуры обнаружил, что всего было 40 статей, каждая из которых была отделена символом —ntitle:, и что каждая статья содержала поля метаданных, такие как заголовок, дата, категория, время прочтения и URL, за которыми следовало основное содержание. Уже само определение такой структуры в текстовом файле размером 1,5 МБ является значительным достижением.
Основываясь на этом понимании, магистрант проанализировал статьи и составил краткое изложение заголовков статей и основных тем.
# Преобразование статей в структурированный формат import re # Разделение по разделителю статей raw_articles = articles.split(«—ntitle:») # Обработка каждой статьи (пропуск первого пустого элемента) parsed_articles = [] for i, raw_article in enumerate(raw_articles[1:], 1): # Пропуск первого пустого элемента # Добавление обратно «title:», удаленного при разделении raw_article = «title:» + raw_article # Извлечение метаданных с помощью регулярных выражений title_match = re.search(r'title:s*»([^»]*)»', raw_article) date_match = re.search(r'date:s*»([^»]*)»', raw_article) category_match = re.search(r'category:s*»([^»]*)»', raw_article) # Поиск начала контента (после второго «—«) content_start = raw_article.find(«—«, 10) # Пропускаем первую часть content = raw_article[content_start+3:].strip() if content_start != -1 else «» parsed_articles.append({ 'index': i, 'title': title_match.group(1) if title_match else «Unknown», 'date': date_match.group(1) if date_match else «Unknown», 'category': category_match.group(1) if category_match else «Unknown», 'content': content, 'content_length': len(content) }) print(f»Успешно разобрано {len(parsed_articles)} статейn») print(«=»*80) print(«Пример статей (заголовки и категории):») print(«=»*80) for i, article in enumerate(parsed_articles[:10], 1): print(f»{i}. [{article['category']}] {article['title']}») print(f» Длина содержимого: {article['content_length']} символов») print()
После анализа статей программа LLM решила сосредоточиться исключительно на контенте, связанном с ИИ, поскольку в вопросе конкретно спрашивалось о тенденциях в области ИИ.
# Давайте сосредоточимся на статьях, связанных с ИИ (категории AI, Agentic AI, LLM Applications, ChatGPT) # и проведем стратегический отбор, чтобы понять тенденции, основанные на контенте. ai_related = [a for a in parsed_articles if a['category'] in [ 'Artificial Intelligence', 'Agentic AI', 'LLM Applications', 'ChatGPT', 'Deep Learning' ]]
Далее, магистерская программа определила ключевые статьи, на которых хотела сосредоточиться. Это был субъективный выбор, основанный на релевантности и содержании. Для детального анализа использовались рекурсивные подзапросы, обрабатывающие каждую статью программно.
Для эффективного управления рабочей нагрузкой модель LLM разделила статьи на две группы и обрабатывала их последовательно. Для каждой статьи она также обрезала контент до первых 15 000 символов. Эта стратегия позволила модели обрабатывать большой объем текста, не выходя за пределы контекстного окна, и при этом извлекать наиболее важные выводы из каждой статьи.
# Создание подсказок для извлечения тенденций ИИ из содержимого статьи # Я включу значительную часть содержимого каждой статьи для анализа prompts_batch1 = [] for i, article in enumerate(selected_for_analysis[:8]): # Первая партия из 8 # Берем первые ~15K символов содержимого, чтобы оставаться в пределах ограничений LLM, получая при этом суть content_sample = article['content'][:15000] prompt = f»»»Проанализируйте эту статью об ИИ 2025 года и определите основные тенденции, технологии, методологии или концепции ИИ, которые в ней обсуждаются. Название статьи: {article['title']} Содержание статьи (отрывок): {content_sample} На основе приведенного выше содержимого перечислите ключевые тенденции, технологии или концепции ИИ, обсуждаемые в этой статье. Сосредоточьтесь на: — Новых упомянутых фреймворках, инструментах или методологиях — Новые тенденции в разработке ИИ (например, агентный ИИ, многоагентные системы) — Важных методах или подходах — Вопросах производства/развертывания Предоставьте краткий список 3-5 основных тенденций/концепций из этой статьи.»»» prompts_batch1.append(prompt) print(f»Создано {len(prompts_batch1)} подсказок для первой партии») print(«nОбработка первой партии статей…») # Запрос первой партии results_batch1 = llm_query_batched(prompts_batch1) print(f»nПолучено {len(results_batch1)} результатов») print(«nРезультаты из первой партии:») print(«=»*80) for i, (article, result) in enumerate(zip(selected_for_analysis[:8], results_batch1), 1): print(f»n{i}. {article['title']}») print(«-«*80) print(result) print()
Наконец, LLM еще раз просмотрел полный список статей, выявил дополнительные релевантные темы и обработал их с помощью рекурсивных подзапросов аналогичным образом. После получения всей информации он синтезировал результаты в переменную trends_2025 (список строк, представляющих основные тенденции в области ИИ) и представил ее в качестве окончательного ответа.
##### ШАГ 12 ##### # Теперь давайте обобщим все результаты и составим исчерпывающий список тенденций в области ИИ. # Я проанализирую все результаты и создам структурированное резюме. print(«СИНТЕЗ ВСЕХ РЕЗУЛЬТАТОВ ИЗ 20 ПРОАНАЛИЗИРОВАННЫХ СТАТЕЙ») print(«=»*80) print(«nНа основе глубокого контент-анализа 20 статей, посвященных ИИ, за 2025 год,») print(«Вот основные выявленные тенденции в области ИИ:n») # Составление исчерпывающего списка тенденций trends_2025 = [ «Агентный ИИ и автономные системы: модели саморефлексии, итеративное улучшение посредством обратной связи (Self-Refine, Reflexion, CRITIC) и LLM как механизмы рассуждения, способные автономно планировать и выполнять задачи», «Многоагентные системы ИИ: эволюция от отдельных агентов к командам специалистов с различными ролями, с использованием таких фреймворков, как LangGraph, CrewAI и AutoGen for оркестровка», «Контекстная инженерия и RAG: переход от статической подсказки к динамической генерации с расширенным поиском (RAG), адаптивным системам памяти и самосовершенствующимся контекстам, которые учатся на опыте без переобучения», «Протоколы стандартизации: появление протокола контекста модели (MCP) для стандартизации интеграции инструментов LLM и протокола связи агентов (ACP) для межагентной связи, что снижает сложность интеграции», «LLM, использующие инструменты, и вызов функций: LLM, оснащенные возможностью вызывать внешние инструменты, выполнять SQL-запросы, просматривать веб-страницы и взаимодействовать с API через структурированные механизмы вызова функций», «Готовые к производству фреймворки ИИ: зрелая экосистема, включающая LangGraph, DSPy, LangChain, NeMo Agent Toolkit, CrewAI и AutoGen, ориентированная на переход от прототипа к производству со встроенной наблюдаемостью», «Оценка и наблюдаемость LLM: шаблоны оценки LLM как судьи, комплексные системы метрик (Ragas, DeepEval, «Программирование вместо подсказок: переход к декларативной разработке ИИ на основе кода с использованием таких фреймворков, как DSPy, и подходов, основанных на конфигурации (на основе YAML), заменяющих разработку на основе подсказок», «Взаимодействие фреймворков: инструменты, предназначенные для интеграции с различными фреймворками, а не для создания изолированных систем, позволяющие создавать компонуемые архитектуры ИИ, использующие лучшие возможности различных экосистем», «Локальное и экономически эффективное развертывание LLM: запуск меньших эффективных моделей локально (Llama, Ollama) для снижения затрат на API и проведения экспериментов, с акцентом на компромисс между стоимостью, качеством и задержкой», «SQL-агенты и автоматизация анализа данных: агенты LLM, специализирующиеся на задачах анализа данных, генерирующие и выполняющие SQL-запросы, с применением для замены или дополнения традиционных рабочих процессов аналитика данных», «Повышение качества и точности производства: методы повышения точности LLM, включая логическое мышление, структурированные результаты посредством вызова функций и итеративное уточнение». критически важных для бизнеса приложений» ] print(«ОСНОВНЫЕ ТРЕНДЫ ИИ 2025 ГОДА:») print(«=»*80) for i, trend in enumerate(trends_2025, 1): print(f»n{i}. {trend}») print(«n» + «=»*80) print(f»nВсего выявлено трендов: {len(trends_2025)}») print(«nЭти тренды основаны на контент-анализе статей, охватывающих:») print(«- Агентные системы ИИ и шаблоны проектирования») print(«- Многоагентные архитектуры и фреймворки») print(«- Развертывание и оценка в производственной среде») print(«- Новые протоколы и стандартизация») print(«- Использование инструментов и интеграция с внешними системами») print(«- Экономически эффективные и точные приложения LLM») ##### ШАГ 13 ##### # Отправьте окончательный список трендов ИИ на 2025 год SUBMIT(trends_2025)
Мы видим, что модель оказалась довольно креативной: она поняла структуру нашего контента, проанализировала статьи и использовала рекурсивные вызовы для обработки каждой из них по отдельности. Однако в этом анализе был один существенный пробел. Она полностью проигнорировала фильтрацию по году, хотя метаданные для каждой статьи явно содержали дату публикации.
Чтобы решить эту проблему, я повторил просьбу, на этот раз подчеркнув важность фильтрации по 2025 году, чтобы гарантировать, что модель будет фокусироваться только на статьях этого года.
output2 = rlm( articles = articles, question = '''Каковы были основные тенденции ИИ в 2025 году на основе предоставленных статей? Обращайте внимание на содержание, а не только на заголовки. Не забудьте отфильтровать по году, эта информация присутствует в метаданных каждой статьи.''' )
На этот раз модель учитывала год и выполняла более сложный анализ, используя регулярные выражения для извлечения даты публикации каждой статьи.
import re from datetime import datetime # Разделяем статьи по разделителю «—» в начале блоков метаданных # Шаблон: — с последующими метаданными, затем — с последующим содержимым article_blocks = re.split(r'n—n', articles) print(f»Всего найдено блоков статей: {len(article_blocks)}») print(«n» + «=»*80) # Давайте рассмотрим структуру — статьи, кажется, начинаются с «—ntitle:» # Попробуем другой подход — найдем все статьи по их шаблону метаданных article_pattern = r'—ntitle: «(.*?)»ndate: «(.*?)»ncategory: «(.*?)»nread_time: «(.*?)»nurl: «(.*?)»n—n(.*?)(?=n—ntitle:|$)' matches = re.findall(article_pattern, articles, re.DOTALL) print(f»Статьи найдены с помощью регулярного выражения: {len(matches)}») if len(matches) > 0: print(«nМетаданные первой статьи:») print(f»Заголовок: {matches[0][0]}») print(f»Дата: {matches[0][1]}») print(f»Категория: {matches[0][2]}») print(f»Предварительный просмотр контента (первые 200 символов): {matches[0][5][:200]}»)
Затем система отфильтровала статьи по году и выявила 13 статей, опубликованных в 2025 году.
# Анализ статей и фильтрация по 2025 году articles_2025 = [] for match in matches: title, date_str, category, read_time, url, content = match # Извлечение года из строки даты (формат: «2025-10-24T12:00:00-05:00») year = date_str.split('-')[0] if year == «2025»: articles_2025.append({ 'title': title, 'date': date_str, 'category': category, 'content': content.strip() }) print(f»Всего статей: {len(matches)}») print(f»Статьи за 2025 год: {len(articles_2025)}») print(«n» + «=»*80) print(«Статьи за 2025 год:») print(«=»*80) for i, article in enumerate(articles_2025, 1): print(f»n{i}. {article['title']}») print(f» Дата: {article['date']}») print(f» Категория: {article['category']}») print(f» Длина контента: {len(article['content'])} символов»)
Затем, используя рекурсивные подзапросы, система проанализировала эти 13 статей и составила обновленный список тенденций. На этот раз задача была выполнена правильно. Как и во многих других примерах, это подчеркивает важность постановки четких, конкретных вопросов и определения критериев и действий, которым мы хотим научить модель.
Агентный ИИ и многоагентные системы: создание автономных агентов ИИ, способных к многошаговому рассуждению, использованию инструментов, планированию и рефлексии, часто с участием нескольких специализированных агентов, совместно работающих над сложными задачами. Агенты кода: агенты ИИ, которые выполняют вызовы инструментов с использованием реального кода (Python) вместо вызовов инструментов на основе JSON, что позволяет создавать динамические функции и достигать более высоких показателей успешности с меньшим количеством шагов. Протокол контекста модели (MCP): протокол стандартизации Anthropic для подключения приложений ИИ к внешним инструментам и источникам данных, снижающий сложность интеграции с M*N до M+N и позволяющий использовать многократно используемые, независимые от фреймворков компоненты. Протокол связи агентов (ACP): новый открытый протокол под эгидой Linux Foundation для стандартизации связи между агентами ИИ через RESTful API, обеспечивающий совместимость между различными фреймворками. Шаблоны рефлексии и самосовершенствования: LLM-ы, анализирующие и улучшающие свои собственные результаты с помощью итеративных циклов обратной связи, включая самообратную связь, вербальное обучение с подкреплением и интерактивную критику инструментов, достигающие повышения точности на 10-30%. Распространение экосистемы фреймворков: множество конкурирующих фреймворков, включая LangGraph, smolagents, CrewAI, DSPy и NeMo Agent Toolkit, с растущим акцентом на совместимость и декларативные подходы к конфигурации. Готовая к производству инфраструктура LLM: переход от прототипов к решению проблем «второго дня», таких как доступ к API, наблюдаемость, мониторинг, фреймворки оценки и развертывание в масштабе. Параметрически эффективная тонкая настройка (PEFT) и LoRA: методы настройки LLM путем обновления только небольших подмножеств параметров, обеспечивающие оптимизацию для конкретных задач при одновременном снижении вычислительных затрат и возможности развертывания в локальной среде. Расширенная тонкая настройка с помощью экспертов по памяти: модель Lamini's Mixture of Memory Experts (MoME) с использованием ~1 миллиона адаптеров LoRA для почти идеальной фактической точности (95%) без потери конкретной информации. Переход от парадигмы подсказок к парадигме программирования: фреймворки, такие как DSPy, рассматривают задачи LLM как модульное программирование, а не как ручное создание подсказок, со структурированными сигнатурами и многократно используемыми компонентами. Оценка и обеспечение качества LLM: Комплексные оценочные системы (Evidently, DeepEval, MLFlow, LangSmith) для тестирования, мониторинга и обеспечения надежности в производственной среде, особенно в регулируемых отраслях. RAG (Retrieval-Augmented Generation): предоставление соответствующего контекста и баз знаний для повышения точности LLM и обеспечения специализированных возможностей агентов. Использование и оркестрация инструментов: системы ИИ динамически выбирают и выполняют инструменты из нескольких источников со стандартизированными определениями инструментов и средствами контроля безопасности. Декларативная конфигурация на основе YAML: определение рабочих процессов, моделей и поведения агентов LLM с помощью конфигурационных файлов, а не исключительно на основе кода. Интерпретируемый ИИ и системы на основе правил: использование деревьев решений, извлеченных правил и прозрачных моделей в качестве альтернативы подходам «черного ящика» для обеспечения соответствия требованиям, объяснимости и быстрого развертывания в регулируемых отраслях.
Краткое содержание
Пришло время подвести итоги и осмыслить полученные знания. В этой статье мы рассмотрели RLM (рекурсивные языковые модели) — новую стратегию вывода, которая позволяет LLM обрабатывать контексты, в два порядка превышающие стандартное контекстное окно, одновременно решая проблему «порчи контекста».
Меня искренне восхищает этот подход. В статье предлагается простой, но элегантный метод обработки подсказок как переменных в среде Python, что напоминает мне мой любимый агентный фреймворк smolagents от HuggingFace. Я считаю, что этот метод особенно эффективен, потому что LLM-ы обучались на таком большом количестве кода, что программирование для них стало родным языком. Использование кода в качестве интерфейса для рассуждений и рекурсии — это одновременно практично и эффективно.
В целом, рекурсивные языковые модели предлагают практичный и элегантный способ расширить границы длины контекста, что делает их более способными к решению сложных, масштабных задач. Однако четкие инструкции и продуманные рекомендации по-прежнему являются ключом к достижению наилучших результатов.
Спасибо за прочтение. Надеюсь, эта статья была для вас полезной. Помните совет Эйнштейна: «Важно не переставать задавать вопросы. Любопытство имеет свою собственную причину существования». Пусть ваше любопытство приведет вас к следующему великому открытию.
Ссылка
Данная статья основана на работе Чжана и др. «Рекурсивные языковые модели», опубликованной 31 декабря 2025 года.
Источник: towardsdatascience.com



























