English translation is not available yet. Showing Russian content.

Как вы проектируете language representation для сложной задачи?

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

Language representation (языковое представление) — это способ, которым мы кодируем сложную задачу для LLM-агента: от простого текстового описания до формального языка с типами, ограничениями и примерами. Проектирование начинается с анализа когнитивных операций, которые должен выполнить агент, затем выбирается уровень абстракции (Level 0–3), определяется формализм (JSON, код, граф), добавляются few-shot примеры, и всё итеративно улучшается на основе логов выполнения. Правильное представление — ключ к надёжности и контролируемости агента.


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

Language representation — это структура и формат, в котором задача подаётся на вход LLM. В контексте Agentic RAG агент должен не просто ответить на вопрос, а выполнить последовательность действий (поиск, рассуждение, вызов инструментов). Представление должно однозначно передавать:

  • цель задачи;
  • доступные инструменты и их сигнатуры;
  • ограничения (constraints);
  • ожидаемый формат вывода.

Плохое представление приводит к неверному пониманию задачи агентом, пропуску шагов или генерации невалидных действий.


2. Анализ когнитивных операций задачи

Прежде чем выбирать формат, нужно разложить задачу на элементарные операции, которые должен выполнить агент. Например:

ЗадачаКогнитивные операции
Ответить на вопрос по документамПоиск → чтение → синтез
Спланировать поездкуСбор информации → проверка ограничений → генерация маршрута
Написать код по спецификацииАнализ требований → декомпозиция → генерация → тестирование

Для каждой операции нужно решить: будет ли она выполняться одним LLM-вызовом или разбита на несколько шагов (цепочка мыслей, вызов инструментов). Это определяет, насколько детальным должно быть представление.

Пример: Для задачи «Найти все статьи на тему X, опубликованные в 2024 году, и выдать краткое резюме» операции:

  1. Поиск по векторной БД с фильтром по году.
  2. Чтение top-3 результатов.
  3. Суммаризация каждого.
  4. Объединение в итоговый ответ.

Представление должно явно указать, что поиск — это вызов инструмента search_documents(query, year_filter), а не просто текстовый запрос.


3. Уровни абстракции (Level 0–3)

Выбор уровня абстракции определяет, насколько формальным будет представление.

УровеньОписаниеПример
Level 0Свободный текст без структуры«Найди статьи 2024 года и сделай резюме»
Level 1Структурированный текст с секциямиЦель: ... Инструменты: ... Ограничения: ...
Level 2Формальный язык (JSON, YAML) с ключами и значениями{"task": "search", "query": "...", "year": 2024}
Level 3Исполняемый код или DSL (domain-specific language)result = search(query, year=2024); summarize(result)

Рекомендация Для сложных задач с несколькими шагами и инструментами начинать с Level 2 (JSON) — он легко парсится, валидируется и позволяет добавлять типы. Level 3 (код) даёт максимальную выразительность, но требует осторожности с безопасностью и отладкой.


4. Определение формализма: код, типы, constraints

После выбора уровня нужно задать конкретную схему представления.

4.1 Формат данных

  • JSON — универсален, поддерживается всеми LLM, легко валидируется через JSON Schema.
  • YAML — более читаем для человека, но сложнее парсится.
  • Код (Python, псевдокод) — позволяет использовать переменные, циклы, вызовы функций; требует sandbox для выполнения.

4.2 Типы и constraints

Использование типов (строки, числа, enum) и ограничений (диапазоны, обязательные поля) снижает вероятность ошибок генерации. Например, для поля year можно задать type: integer, minimum: 1900, maximum: 2030.

Инструмент Pydantic (Python) или Zod (TypeScript) позволяет описать схему и валидировать вывод LLM.

from pydantic import BaseModel, Field
from typing import List, Literal

class SearchAction(BaseModel):
    action: Literal["search"] = "search"
    query: str = Field(..., min_length=1)
    year: int = Field(..., ge=1900, le=2030)

class SummarizeAction(BaseModel):
    action: Literal["summarize"] = "summarize"
    document_ids: List[int] = Field(..., min_length=1)

class AgentOutput(BaseModel):
    steps: List[SearchAction | SummarizeAction]

4.3 Constraints (ограничения)

  • Обязательные поля — чтобы агент не пропустил важные параметры.
  • Формат вывода — например, «ответ должен быть в виде JSON-массива объектов».
  • Безопасность — запрет на выполнение опасных операций (если используется код).

5. Few-shot примеры в выбранном формализме

Даже самое чёткое описание может быть неверно интерпретировано LLM. Few-shot примеры (2–5 штук) показывают агенту, как именно нужно структурировать ответ.

Пример для задачи поиска и суммаризации:

Пользователь: Найди статьи про квантовые вычисления за 2023 год.
Агент (правильный вывод):
{
  "steps": [
    {"action": "search", "query": "квантовые вычисления", "year": 2023},
    {"action": "summarize", "document_ids": [1, 2, 3]}
  ]
}

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


6. Итеративное улучшение

Проектирование representation — это цикл:

  1. Создать прототип — выбрать уровень и формат.
  2. Запустить на тестовых задачах — собрать логи выполнения.
  3. Проанализировать ошибки — где агент понял задачу неверно?
    • Пропустил шаг → добавить обязательное поле.
    • Неверный формат → уточнить инструкцию или добавить пример.
    • Нарушил ограничение → ужесточить схему валидации.
  4. Обновить representation — изменить промпт, схему, примеры.
  5. Повторить.

Метрики для оценки

  • Success rate — доля задач, выполненных полностью корректно.
  • Schema compliance — доля ответов, прошедших валидацию.
  • Average steps — оптимальное количество шагов (не слишком много, не слишком мало).

7. Интеграция с RAG: динамическое формирование representation

В Agentic RAG представление задачи может зависеть от контекста, полученного из retrieval. Например:

  • Если в документах найдена информация о доступных API, агент должен использовать именно эти инструменты.
  • Если задача требует специфических знаний, representation может включать извлечённые факты.

Динамическое представление строится на лету: сначала retrieval находит релевантные документы, затем они вставляются в промпт вместе с инструкцией и схемой. Это позволяет агенту адаптироваться к разным сценариям.


8. Пример проектирования для задачи «Планирование путешествия»

Разберём по шагам.

8.1 Анализ когнитивных операций

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

8.2 Выбор уровня

Level 2 (JSON) — достаточно структуры, не требует выполнения кода.

8.3 Формализм и типы

{
  "type": "object",
  "properties": {
    "steps": {
      "type": "array",
      "items": {
        "oneOf": [
          {"$ref": "#/definitions/SearchFlights"},
          {"$ref": "#/definitions/SearchHotels"},
          {"$ref": "#/definitions/CheckVisa"},
          {"$ref": "#/definitions/GenerateItinerary"}
        ]
      }
    }
  },
  "definitions": {
    "SearchFlights": {
      "type": "object",
      "properties": {
        "action": {"enum": ["search_flights"]},
        "origin": {"type": "string"},
        "destination": {"type": "string"},
        "date": {"type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$"}
      },
      "required": ["action", "origin", "destination", "date"]
    },
    ...
  }
}

8.4 Few-shot примеры

Включить 2–3 примера с разными сценариями (прямой рейс, с пересадкой, нет билетов).

8.5 Итеративное улучшение

После тестов может выясниться, что агент забывает проверять визу — добавить обязательный шаг check_visa перед генерацией маршрута.


9. Инструменты и best practices

  • Pydantic / Zod — для описания схем и валидации.
  • LangChain / LlamaIndex — встроенные инструменты для структурированного вывода (например, with_structured_output).
  • Guidance / LMQL — библиотеки, которые ограничивают генерацию LLM заданной грамматикой.
  • Logging — записывать все сгенерированные representation и результаты валидации для анализа.

Best practices

  • Начинать с простого (Level 1–2), усложнять по мере необходимости.
  • Всегда добавлять хотя бы один few-shot пример.
  • Использовать валидацию на стороне приложения, а не полагаться на LLM.
  • Для критических задач использовать Level 3 (код) с sandbox-исполнением.

10. Связь с другими аспектами Agentic RAG

Language representation тесно связано с:

  • Prompt engineering — представление — это часть промпта.
  • Tool use — сигнатуры инструментов должны быть частью representation.
  • Planning — если задача разбивается на подзадачи, representation должно поддерживать иерархию.
  • Observability — логи representation помогают отлаживать поведение агента.

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

Задача Создать агента, который по описанию пользователя генерирует SQL-запрос к базе данных, выполняет его и возвращает результат.

Инструменты Python, LangChain, Pydantic, SQLite.

Шаги:

  1. Определить когнитивные операции: понять запрос → сгенерировать SQL → выполнить → отформатировать ответ.
  2. Выбрать Level 2 (JSON) для шагов: {"action": "generate_sql", "description": "..."} и {"action": "execute_sql", "query": "..."}.
  3. Описать схему через Pydantic с ограничениями (только SELECT, запрет DROP).
  4. Добавить 3 few-shot примера в промпт.
  5. Реализовать валидацию SQL перед выполнением.
  6. Запустить на 10 тестовых запросах, собрать логи, исправить ошибки (например, агент иногда генерирует UPDATE — добавить constraint).

Ожидаемый результат Агент с success rate > 80% на тестовом наборе, все сгенерированные SQL проходят валидацию.


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

ВопросТема
181Проектирование архитектуры AI-агента
182Планирование и декомпозиция задач
183Инструменты и их описание для агента
185Наблюдаемость и логирование агентов
188Обработка ошибок и fallback-стратегии
190Оценка качества работы агента

Навигация