Как вы комбинируете несколько языков представления в одном пайплайне?
Краткий тезис
В сложных 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.
- Передавать промежуточные результаты в структурированном виде между шагами, чтобы следующий компонент мог их легко обработать.
Пример: пользователь просит «Найди все заказы за последний месяц, посчитай средний чек и выведи отчёт». Агент:
- NL → понимает запрос.
- Code (SQL) → извлекает данные из БД.
- Code (Python) → вычисляет средний чек.
- Structured (JSON) → сохраняет результат.
- NL → формирует ответ пользователю.
3. Архитектура пайплайна с мультиязыковым представлением
Типичный пайплайн Agentic RAG включает следующие этапы, на каждом из которых может использоваться свой язык:
- Понимание запроса (NL → NL или NL → Structured intent).
- Планирование (NL → Structured plan, например, список шагов в JSON).
- Выполнение подзадач (Code, SQL, вызовы API).
- Агрегация результатов (Structured → NL или Structured → Code).
- Генерация ответа (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. Понимание запроса | NL | LLM извлекает intent: «top_5_revenue», параметры: квартал, сравнение. |
| 2. Генерация SQL | Code (SQL) | Агент пишет SQL-запрос к БД продаж. |
| 3. Выполнение SQL | Code | Запрос выполняется, результат — таблица (structured). |
| 4. Расчёт изменений | Code (Python) | Вычисляется процент изменения по каждому товару. |
| 5. Формирование отчёта | Structured (JSON) | Результаты упаковываются в JSON с полями: товар, выручка, изменение. |
| 6. Генерация ответа | NL | LLM преобразует 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-файл с данными о продажах (дата, товар, цена, количество).
Шаги:
- Определить функции-инструменты:
- Настроить LLM (GPT-4) с описанием инструментов.
- Реализовать цикл: пользовательский запрос → LLM выбирает инструменты → выполнение → агрегация → ответ.
- Протестировать на запросах: «Сколько товаров продано в марте?», «Топ-3 товара по выручке», «Сравни продажи января и февраля».
Ожидаемый результат: Агент корректно выбирает query_csv для извлечения данных, calculate_statistics для расчётов, generate_report для структурирования и summarize_report для ответа. В логах видно переключение между NL (инструкции) и code (pandas).
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 189 | Планирование в Agentic RAG |
| 188 | Выбор инструментов агентом |
| 187 | Память агента (сохранение контекста) |
| 186 | Безопасность выполнения кода агентом |
| 185 | Оценка качества агента |
| 184 | Мультиагентные системы и координация |
Навигация
- Предыдущий: 189
- Следующий: 191
- Индекс: 00. Индекс разборов