Как вы комбинируете несколько языков представления в одном пайплайне?

Краткий тезис

В сложных AI-агентах одна задача редко укладывается в один язык представления. Агент должен уметь переключаться между natural language (для понимания инструкций и общения), code (для вычислений и вызовов API) и structured formats (для обмена данными между шагами). Комбинирование этих языков позволяет агенту эффективно решать подзадачи, используя сильные стороны каждого, и строить гибкие, расширяемые пайплайны.


1. Термин: Язык представления (Representation Language)

Язык представления — это формальная или естественная система символов, используемая для описания данных, инструкций или знаний. В контексте AI-агентов выделяют три основных типа:

  • Natural Language (NL) — естественный язык (русский, английский). Используется для формулировки запросов, инструкций, объяснений и ответов.
  • Code — программный код (Python, SQL, JavaScript). Используется для точных вычислений, манипуляции данными, вызова внешних сервисов.
  • Structured Formats — структурированные данные (JSON, YAML, XML, таблицы, графы). Используются для передачи информации между компонентами пайплайна, хранения конфигураций и результатов.

Агент, работающий в Agentic RAG, должен уметь выбирать подходящий язык для каждой подзадачи, а иногда и комбинировать их в одном шаге.


2. Зачем комбинировать языки представления?

Каждый язык имеет свои сильные и слабые стороны:

ЯзыкСильные стороныСлабые стороны
Natural LanguageГибкость, понимание контекста, общение с человекомНеоднозначность, низкая точность для вычислений
CodeТочность, повторяемость, скорость выполненияТребует интерпретации, риск ошибок выполнения
Structured FormatsЧёткая структура, машинная читаемость, валидацияОграниченная выразительность, сложность описания процессов

Комбинирование позволяет:

  • Использовать NL для понимания сложных инструкций и генерации ответов.
  • Применять code для точных расчётов, обработки данных и вызова API.
  • Передавать промежуточные результаты в структурированном виде между шагами, чтобы следующий компонент мог их легко обработать.

Пример: пользователь просит «Найди все заказы за последний месяц, посчитай средний чек и выведи отчёт». Агент:

  1. NL → понимает запрос.
  2. Code (SQL) → извлекает данные из БД.
  3. Code (Python) → вычисляет средний чек.
  4. Structured (JSON) → сохраняет результат.
  5. NL → формирует ответ пользователю.

3. Архитектура пайплайна с мультиязыковым представлением

Типичный пайплайн Agentic RAG включает следующие этапы, на каждом из которых может использоваться свой язык:

  1. Понимание запроса (NL → NL или NL → Structured intent).
  2. Планирование (NL → Structured plan, например, список шагов в JSON).
  3. Выполнение подзадач (Code, SQL, вызовы API).
  4. Агрегация результатов (Structured → NL или Structured → Code).
  5. Генерация ответа (NL).

Агент принимает решение о выборе языка на основе:

  • Типа подзадачи (вычисление → code, поиск → NL + retrieval).
  • Доступных инструментов (function calling, code interpreter).
  • Контекста (предыдущие шаги, формат данных).

Пример архитектуры:

# Псевдокод агента, выбирающего язык
def execute_step(step_description, context):
    if "вычисли" in step_description or "посчитай" in step_description:
        return execute_code(step_description, context)
    elif "найди" in step_description or "поищи" in step_description:
        return retrieve_with_nl(step_description, context)
    else:
        return generate_nl_response(step_description, context)

4. Natural Language как универсальный интерфейс

Natural Language — основной язык взаимодействия с пользователем и между компонентами, если они основаны на LLM. Агент использует NL для:

  • Понимания инструкций: LLM парсит запрос и выделяет намерение.
  • Планирования: генерация последовательности шагов (часто в виде NL или структурированного плана).
  • Объяснения: ответ пользователю с пояснениями.

Однако NL не подходит для точных операций. Например, запрос «сложи 2.71828 и 3.14159» может быть выполнен LLM с ошибкой. Поэтому для таких операций агент переключается на code.


5. Code для вычислительной части

Code (Python, SQL, Bash) позволяет агенту выполнять точные, повторяемые операции. Основные сценарии:

  • Математические расчёты (статистика, агрегация).
  • Обработка данных (фильтрация, трансформация).
  • Вызов внешних API (HTTP-запросы, работа с БД).
  • Генерация отчётов (создание графиков, таблиц).

Агент может генерировать код на лету и выполнять его в изолированной среде (песочнице). Пример:

# Агент генерирует Python-код для вычисления среднего
code = """
import json
data = json.loads(input_data)
prices = [item['price'] for item in data if 'price' in item]
average = sum(prices) / len(prices) if prices else 0
result = {'average_price': average}
print(json.dumps(result))
"""
exec(code)

Безопасность: выполнение кода должно быть ограничено (Docker, subprocess с ограничениями, sandbox).


6. Structured Formats для обмена данными

Structured Formats (JSON, YAML, XML, таблицы) обеспечивают:

  • Чёткую структуру: поля, типы, вложенность.
  • Машинную читаемость: легко парсятся и валидируются.
  • Совместимость: могут передаваться между разными компонентами (LLM, code, БД).

Пример использования: агент получает от пользователя запрос, преобразует его в структурированное представление (intent + parameters), затем передаёт это в execution engine.

{
  "intent": "calculate_average",
  "parameters": {
    "field": "price",
    "source": "orders_table",
    "time_range": "last_month"
  }
}

Такой формат позволяет следующему шагу (например, SQL-генератору) однозначно понять, что делать.


7. Пример полного пайплайна: анализ продаж

Задача: «Покажи топ-5 товаров по выручке за прошлый квартал и сравни с предыдущим кварталом».

Шаги и языки представления:

ШагЯзыкОписание
1. Понимание запросаNLLLM извлекает intent: «top_5_revenue», параметры: квартал, сравнение.
2. Генерация SQLCode (SQL)Агент пишет SQL-запрос к БД продаж.
3. Выполнение SQLCodeЗапрос выполняется, результат — таблица (structured).
4. Расчёт измененийCode (Python)Вычисляется процент изменения по каждому товару.
5. Формирование отчётаStructured (JSON)Результаты упаковываются в JSON с полями: товар, выручка, изменение.
6. Генерация ответаNLLLM преобразует JSON в понятный текст: «Топ-5 товаров: ... Выручка выросла на ...».

Агент на каждом шаге выбирает язык, оптимальный для подзадачи.


8. Проблемы и решения при комбинировании языков

8.1 Как агент выбирает язык?

  • Rule-based: жёсткие правила (если запрос содержит «посчитай» → code).
  • LLM с инструментами: модель сама решает, какой инструмент (язык) использовать, через function calling или ReAct.
  • Few-shot examples: в промпт добавляются примеры выбора языка для похожих задач.

8.2 Обработка ошибок

  • Ошибки выполнения кода должны перехватываться, и агент должен попробовать другой подход (например, переписать код или запросить уточнение у пользователя).
  • Структурированные данные должны валидироваться перед передачей в следующий шаг.

8.3 Безопасность

  • Выполнение произвольного кода — риск. Используйте песочницы (Docker, gVisor, Pyodide).
  • Ограничьте доступ к файловой системе и сети.

8.4 Производительность

  • Генерация и выполнение кода занимает время. Для простых операций можно оставить NL.
  • Кэшируйте результаты повторяющихся вычислений.

9. Инструменты и фреймворки

  • OpenAI Function Calling / Tool Use — позволяет LLM вызывать предопределённые функции (code, API).
  • LangChain / LlamaIndex — поддерживают цепочки с разными языками (Python REPL, SQL, NL).
  • AutoGPT / BabyAGI — агенты, которые динамически генерируют код и планируют шаги.
  • Code Interpreter (ChatGPT) — встроенная песочница для выполнения Python.
  • ReAct — паттерн, где LLM чередует рассуждения (NL) и действия (code/API).

10. Оценка качества комбинирования

Как проверить, что агент правильно выбирает язык?

  • Accuracy выбора языка: для тестовых запросов проверяем, какой инструмент был вызван.
  • Success rate: доля задач, выполненных без ошибок.
  • Время выполнения: сравнение с baseline (только NL).
  • Качество ответа: оценка faithfulness, релевантности.

Метрики можно собирать в логах агента (какой шаг, какой язык, успех/ошибка).


Пет-проект для закрепления

Задача: Создать агента, который по NL-запросу извлекает данные из CSV-файла (имитация БД), выполняет анализ и возвращает структурированный отчёт (JSON) и NL-резюме.

Инструменты:

  • Python (библиотеки: pandas, json, openai).
  • LangChain или чистый OpenAI API с function calling.
  • Простой CSV-файл с данными о продажах (дата, товар, цена, количество).

Шаги:

  1. Определить функции-инструменты:
    • query_csv(column, condition) — возвращает отфильтрованные строки (structured).
    • calculate_statistics(data, operation) — вычисляет сумму, среднее, топ-N (code).
    • generate_report(stats) — формирует JSON-отчёт.
    • summarize_report(report) — генерирует NL-резюме.
  2. Настроить LLM (GPT-4) с описанием инструментов.
  3. Реализовать цикл: пользовательский запрос → LLM выбирает инструменты → выполнение → агрегация → ответ.
  4. Протестировать на запросах: «Сколько товаров продано в марте?», «Топ-3 товара по выручке», «Сравни продажи января и февраля».

Ожидаемый результат: Агент корректно выбирает query_csv для извлечения данных, calculate_statistics для расчётов, generate_report для структурирования и summarize_report для ответа. В логах видно переключение между NL (инструкции) и code (pandas).


Связь с другими вопросами

ВопросТема
189Планирование в Agentic RAG
188Выбор инструментов агентом
187Память агента (сохранение контекста)
186Безопасность выполнения кода агентом
185Оценка качества агента
184Мультиагентные системы и координация

Навигация