Методологии | Архитектура корпоративных LLM hr-s.ru
1 / 27

АРХИТЕКТУРА
КОРПОРАТИВНЫХ LLM

Паттерны проектирования, антипаттерны и системные рабочие процессы для продакшн-развёртывания
Руководство архитектора
Технологии и Решения Переведено Технологии и Решения, hr-s.ru
Архитектура корпоративных LLM
2 / 27

Четыре домена ИИ-архитектуры

Извлечение структурированных данных

Большие объёмы, строгие схемы, пакетные конвейеры
⚙️⚙️
{
  "entity": "Order",
  "id": 101,
  "status": "confirmed",
  "items": ["A", "B"]
}

Оркестрация клиентской поддержки

Состояние, человек в контуре, ограничения политик
Оркестратор
ИИ-агент
Ревьюер

Продуктивность разработчика

Динамические задачи, итеративный контекст, продвинутое использование инструментов
$ help git commit

project/
├── src/
│   ├── components/
│   ├── utils/
│   └── styles/
├── index.js
└── package.json

Мультиагентные системы

Параллельная обработка, общая память, кросс-агентный синтез
Агент A
Агент B
Общая память
Агент C
Агент D
3 / 27

Иерархия ограничений архитектора

Иерархия ограничений — радарная диаграмма

Задержка

Снижается через параллелизацию и кэширование

Точность

Снижается через структурированные промежуточные представления и Few-Shot промпты

Стоимость

Снижается через Batch API и очистку контекста

Комплаенс

Обеспечивается через перехваты на уровне приложения (не промптами)

4 / 27

Маршрутизация по стоимости и SLA

Правило: Никогда не используйте real-time режим для асинхронных задач.
Входящие документы
SLA-фильтр
Срочное
(< 30 мин SLA)
Real-time
Messages API
Стандартные
отчёты
Batch API
очередь
Тип Решение
Срочные исключения Real-time Messages API
(высокая стоимость, мгновенная задержка)
Стандартные рабочие процессы Message Batches API
(экономия 50%)
Непрерывное поступление
(SLA 30 часов)
Отправка батчей каждые 6 часов
с документами из этого окна
5 / 27

Проектирование устойчивых схем

Антипаттерн: Хрупкое расширение

Непрерывное расширение enum при появлении граничных случаев.

// Хрупкая схема с ограниченным enum
{
  "type": "object",
  "properties": {
    "property_type": {
      "type": "string",
      "enum": ["house", "apartment",
               "condo", "townhouse"]
    }
  },
  "required": ["property_type"]
}

// Ошибка валидации:
// "property_type": "studio"
// "property_type": "converted warehouse"
ОШИБКА ВАЛИДАЦИИ — Неожиданные типы
Архитектурный паттерн: Устойчивый Catch-All

Добавьте значение «other» в enum вместе с полем-детализатором.

// Устойчивая схема с Catch-All
{
  "type": "object",
  "properties": {
    "property_type": {
      "type": "string",
      "enum": ["house", "apartment",
               "condo", "townhouse",
               "other"]
    },
    "property_type_detail": {
      "type": "string",
      "description": "Детали для 'other'"
    }
  },
  "required": ["property_type"]
}
УСПЕШНАЯ ВАЛИДАЦИЯ — Данные сохранены

Правило эволюции данных

Для изменяемых документов переработайте схему так, чтобы поля хранили несколько значений — каждое с источником и датой вступления в силу — вместо перезаписи оригинала.

6 / 27

Обеспечение математической согласованности

Проблема: 18% извлечений из счетов показывают несовпадение позиций с итогом из-за ошибок OCR или извлечения.

Пример: счёт-фактура

Пример счёта с ошибками OCR
Счёт #12345 от 2023-10-27
Плательщик: Acme Corp. | Поставщик: Services Inc.

Позиция 1: $120.50 (ошибка OCR: $120.5o)
Позиция 2: $85.00
Позиция 3: $45.25 (ошибка извлечения: $4.525)

Промежуточный итог: $250.75
Итого: $260.00
← Несовпадение!

Решение: избыточность в схеме

{
  "invoice_id": "12345",
  "line_items": [
    { "description": "Item 1", "amount": 120.50 },
    { "description": "Item 2", "amount": 85.00 },
    { "description": "Item 3", "amount": 4.525 }
  ],
  "calculated_total": 210.025, // Сумма модели
  "stated_total": 260.00,      // Из документа
  "currency": "USD"
}
Действие маршрутизации: Отправлять запись на проверку человеком ТОЛЬКО когда calculated_total != stated_total.
7 / 27

Нормализация и обработка null

Базовый промпт

Проблематичный вывод

Ввод: Извлеки количество участников и материалы.

{
  "attendee_count": "500",
  // ↑ Правдоподобная галлюцинация
  "materials": "cotton blend"
  // ↑ Несогласованный формат
}

Инструкция обработки null

Проблема: Когда поля допускают null, модели могут выдумать правдоподобные данные, если не получат явных инструкций.

Паттерн

Добавьте явную инструкцию: возвращать null, если данных нет в тексте.

{
  "attendee_count": null, // ✓ Корректно
  "materials": "cotton blend"
}

Нормализация формата

Проблема: «cotton blend» vs «Cotton/Polyester mix» — несогласованные форматы.

Решение: Few-Shot стандартизация

Предоставьте 2–3 полных примера ввод-вывод со стандартизированными форматами. Не полагайтесь только на temperature 0.

{
  "attendee_count": null, ✓
  "materials": "Cotton Blend"
  // ↑ Стандартизировано
}
8 / 27

Пределы автоматических повторов

Паттерн: Добавление конкретных ошибок валидации в промпт и повторный запрос решает большинство проблем за 2–3 попытки.
✓ Эффективно: ошибки форматирования
Эффективный цикл повторов
ИИ-генерация
Валидация
↓ Успех
✓ Вывод
↓ Ошибка
Промпт + сообщение
об ошибке → повтор

Исправление вложенных объектов vs плоских массивов. Разрешение строк с локально-зависимым форматированием.

✗ Неэффективно: отсутствующая информация
Неэффективный цикл повторов
ИИ-генерация
Валидация
↓ Снова ошибка…
Превышено макс. число попыток ✗
Исключение: Повторы наименее эффективны для отсутствующей информации (например, попытка извлечь полный список авторов, когда в источнике написано «и др.» со ссылкой на внешний документ). Умейте вовремя признать неудачу.
9 / 27

Калибровка Human-in-the-Loop

Требование

Автоматизировать извлечения с уверенностью модели >90%.

Реализация

Модель выдаёт field-level confidence scores. Привязывайте эту деталь к решению по снижению семантических ошибок.

Распределение оценок уверенности
⚠️ Критический шаг валидации: Проанализируйте точность по типу документа и полю, чтобы убедиться, что высокоуверенные извлечения работают стабильно по всем сегментам, а не только в среднем, перед развёртыванием.
10 / 27

Нулевая толерантность к нарушениям комплаенса

Ловушка: Надежда на эмфатические системные промпты («КРИТИЧЕСКАЯ ПОЛИТИКА: НИКОГДА не обрабатывать >$500») всё равно даёт 3% ошибок.
ИИ-агент
Перехват на
уровне
приложения
process_refund($847)
🔒 Эскалация на человека

Архитектурный стандарт

Реализуйте перехват на уровне приложения для вызовов инструментов.

Когда сумма операции превышает порог — блокируйте на стороне сервера и запускайте эскалацию.

Дискреция модели устраняется.

11 / 27

Возобновление асинхронных сессий

Проблема: Возобновление сессии через несколько часов приводит к тому, что модель уверенно сообщает устаревший статус (например, «Ожидаемое время решения: 24ч» из предыдущего вызова инструмента).

Ходы 1–32 (4 часа назад)

Ход пользователя
tool_result: {"status": "PENDING", "expected_resolution": "24h"}
Ход ассистента
tool_result: {"status": "PENDING"...}

Асинхронная пауза

Программный фильтр

tool_result → 🗑️ удалить

Ход 33 (возобновление)

Ход пользователя
Ход ассистента
tool_call → новый запрос
tool_result: {"status": "PROCESSED", "expected_resolution": "0h"}
Решение: Возобновляйте с полной историей диалога, но программно отфильтруйте предыдущие tool_result-сообщения. Оставьте только ходы человека/ассистента, чтобы агент был вынужден заново запросить данные при возобновлении. Это гарантирует, что возвращающиеся клиенты всегда получают свежую, актуальную информацию.
12 / 27

Очистка контекста инструментов

Раздувание: Повторные вызовы lookup_order заполняют контекстное окно подробными данными о доставке и оплате, когда нужен только статус возврата.
Очистка контекста инструментов

Сырой ответ API (40+ полей)

"shipping_address": {...},
"payment_method": {...},
"tracking_history": [...],
"order_total": ...,
"order_cost": ...,
"payment_history": [...],
"user_preferences": null,
...

Очищенный контекст

"items": [...],
"purchase_date": ...,
"return_window": ...,
"status": ...

Паттерн: фильтрация на стороне приложения

Извлекайте только релевантные поля (товары, дата покупки, окно возврата, статус) из каждого ответа заказа, удаляя избыточные подробности до передачи в диалог. Эта стратегия соответствует управлению множественными объёмными ответами инструментов в сессии поддержки.

13 / 27

Корректная обработка ошибок инструментов

Пользователь
Агент
Сервер инструментов
Tool Call (например, lookup_order)
{
  "isError": true,
  "errorCategory": "transient",
  "isRetryable": true
}
«Я испытываю задержку, попробуйте позже.»
● Антипаттерн: Бросать исключения приложения, которые обрушивают агента, или возвращать пустые строки.
● Правильный паттерн: Возвращать сообщение об ошибке в содержимом tool result с флагом isError: true.
14 / 27

Передача при эскалации

Ввод пользователя

«Хочу оператора СЕЙЧАС.»

Немедленная эскалация

Выполнить немедленно.
Не запрашивать уточнений.

Сложный вопрос по политике

Сбор контекста
(get_customer)

Сначала убедитесь, что
вызваны инструменты контекста.

Полезная нагрузка: структурированное резюме

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

{
  "customer_id": "CUST-847392",
  "root_cause": "Дублирование списаний из-за таймаута шлюза.",
  "amount": "847.00 USD",
  "recommended_action": "Одобрить возврат 847.00 USD и уведомить клиента."
}
15 / 27

Сжатие длинных сессий

Вызов: Одна сессия охватывает запрос на возврат, вопрос по подписке и обновление платежа за 48 ходов. Ограничения контекста становятся проблемой.
Нарративное резюме
решённых вопросов
Полная дословная история сообщений
Активная
проблема
← Сжато
Контекстное окно →
Текущее
● Стратегия: Суммируйте более ранние, решённые ходы в нарративное описание, сохраняя полную историю сообщений дословно только для активной, нерешённой проблемы.
16 / 27

Специфичность MCP-инструментов

Ловушка: Предоставление широкого кастомного инструмента (analyze_dependencies) наряду со встроенным Grep. Агент по умолчанию использует Grep.
Антипаттерн: монолитный инструмент
$ Agent execution...

Агент использует встроенный Grep для поиска импортов.
│
└→ {name: analyze_dependencies}
Паттерн архитектора: гранулярные инструменты
$ Agent execution...

Агент использует кастомный инструмент для зависимостей.
├→ - list_imports
├→ - resolve_transitive_deps
└→ - detect_circular_deps

Решение

Разбейте широкие инструменты на узкоспециализированные. Улучшите описания MCP-инструментов, чтобы явно указывать возможности, ожидаемые выходы и когда предпочитать их перед манипуляцией текстом. Это аналогично переходу на кастомные инструменты рефакторинга вместо стандартных Bash/sed.

17 / 27

Направленное исследование кодовой базы

Антипаттерн: Использование инструмента Read для последовательной загрузки тысяч строк кода.
Неэффективно и контексто-тяжело

Чтение всех 15 файлов последовательно → переполнение контекстного окна нерелевантными данными.

Процесс динамического исследования

Процесс динамического исследования
Узел 1: Анализ импортов
и базовых интерфейсов
Узел 2: Трассировка конкретных
реализаций
Узел 3: Динамическая генерация
подзадач по находкам

Стратегия: начинай широко, затем уточняй

Для архитектуры (800+ файлов):
Сначала прочти CLAUDE.md/README, затем спроси инженера о приоритетных файлах.
Для плавающих багов:
Пусть агент динамически генерирует подзадачи на основе того, что находит на каждом шаге.
18 / 27

Ветвление реальности

Проблема: Исследование двух различных подходов рефакторинга или стратегий тестирования в одном потоке запутывает агента и смешивает контексты.
Вчерашний
анализ

Ветка A: Выделение микросервиса

Извлечь
ядро логики
Определить
API-интерфейс
Создать
микросервис

Ветка B: Рефакторинг на месте

Упростить
методы
Оптимизировать
поток данных
Рефакторинг
аутентификации

Команда

Используйте fork_session для создания двух отдельных веток из базового анализа. Это позволяет независимое, глубокое исследование A/B-сценариев без контаминации контекста.

19 / 27

Паттерн «Черновик» (Scratchpad)

Деградация: В продолжительных сессиях исследования (30+ минут) накопленное раздувание токенов приводит к противоречивым ответам о ранних находках. Инженеры сообщают о необходимости повторять информацию о модулях.
Паттерн Scratchpad

Агент читает исходные файлы

📄 Исходный файл A
📄 Исходный файл B
📄 Исходный файл C

📝 Scratchpad.md

Ключевые находки:
- Структура модуля X
- API-эндпоинт Y
- Решение: использовать паттерн Z

Архитектурная карта:
...

Принятые решения:
...

→ Постоянная ссылка для последующих вопросов

Паттерн: Пусть агент активно ведёт scratchpad-файл, записывая ключевые находки, архитектурные карты и решения. Он обращается к этому плотному, структурированному файлу для последующих вопросов, вместо «сырой» истории сообщений.
20 / 27

Возобновление в динамичных средах

Сценарий: Инженер возобновляет сессию исследования, но 3 из 12 файлов, которые агент читал вчера, были изменены PR коллеги.

Стенограммы сессии (вчера)

📄 Файл A
📄 Файл B
📄 Файл C (оригинал)
📄 Файл D (оригинал)
📄 Файл E (оригинал)
📄 Файл L

Git Diff (ночные мержи)

PR коллеги: переименование утилитарных функций в 3 файлах.

Возобновлённая сессия (сегодня)

📄 Файл A
📄 Файл B
🔄 Файл C (изменён)
🔄 Файл D (изменён)
🔄 Файл E (изменён)
📄 Файл L

Действие

Возобновите сессию из прежней стенограммы, но явно сообщите агенту, какие конкретно файлы или функции изменились, для целенаправленного перечитывания. Не форсируйте полное перечитывание и не делайте вид, что ничего не изменилось.

resume_session --update_context={files:['File C', 'File D', 'File E'], changes:'renamed utility functions'}
21 / 27

Архитектура общей памяти

Антипаттерн: Передача полных логов разговоров по цепочке между подагентами. Это масштабирует токен-затраты экспоненциально.
Архитектура общей памяти
🔍

Агент веб-поиска

Запись находок →
🗄️
Общее
векторное хранилище
📊

Агент анализа документов

← Чтение находок
(семантический поиск)
Паттерн архитектора: Отвяжите состояние от вызова. Пусть подагенты индексируют свои результаты в общее векторное хранилище. При выполнении последующие агенты используют семантический поиск для извлечения только релевантных предыдущих находок. Эта архитектура предотвращает потерю состояния при сбое мультиагентного конвейера посередине обработки.
22 / 27

Принудительный порядок выполнения

Проблема Агент должен извлечь метаданные перед вызовом инструментов обогащения, но иногда вызывает обогащение первым, что приводит к ошибкам.
{
    "model": "claude-3-opus-20240229",
    "max_tokens": 1024,
    "messages": [
        {"role": "user", "content": "Извлеки метаданные из этой статьи и найди её DOI."}
    ],
    "tools": [
        {"name": "extract_metadata", "description": "..."},
        {"name": "lookup_citations", "description": "..."}
    ],
    "tool_choice": {"type": "tool", "name": "extract_metadata"}
}

Принуждение

Не надейтесь на «уговаривание» промптом. Используйте ограничения API. Установите tool_choice для первого API-вызова, чтобы гарантировать выполнение конвейера в нужном порядке. Это гарантирует, что структурированное извлечение метаданных происходит до любого поиска DOI или обогащения.

23 / 27

Структурированные промежуточные представления

Потеря: Передача сырого текста от финансового и новостного агентов к агенту синтеза приводит к тому, что таблицы теряют ясность, а новости — нарративную связность.
⚙️ Финансовый агент
(Structured JSON)
📰 Новостной агент
(Prose Summaries)
📋 Патентный агент
(Structured Lists)
Слой конвертации
форматов
Стандартизация в единое
промежуточное представление
{
 "claim": "...",
 "evidence": "...",
 "source": "...",
 "confidence": ...
}
📊 Агент синтеза
(Executive Briefings)
Правило цитирования: Чтобы избежать потери атрибуции, требуйте от всех подагентов выводить структурированные маппинги «утверждение → источник», которые агент синтеза обязан сохранять.
24 / 27

Параллелизация и кэширование

Последовательная обработка
Последовательная обработка 12 прецедентов: T0 → T+180с (3 мин)

Проблема: Последовательная обработка каждого прецедента в сложном юридическом деле занимает более 3 минут, создавая неприемлемую задержку.

Параллельное выполнение
Координатор
Подагент [1]
Подагент [2]
Подагент [3]
Подагент [4]
...
Синтез
+ кэш

T0 → T+30с

Параллелизм подагентов

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

Кэширование промптов

Когда итоговые сводки постоянно занимают 40+ секунд, передавая 80K+ токенов накопленных находок, включите кэширование промптов на подагенте синтеза для радикального снижения накладных расходов.

25 / 27

Целеориентированное делегирование

Ловушка: Передача веб-поисковому подагенту детальных пошаговых процедурных инструкций приводит к негибкому поведению: он пропускает возникающие темы или косвенные источники.
Процедурное микроменеджмент
Агент-координатор

Подагент веб-поиска

→ Шаг 1: Ищи X.
→ Шаг 2: Прочти Y.
→ Шаг 3: Извлеки Z.
Неудача / Упущенная ценность
Негибко, не адаптируется
Целеориентированное делегирование
Агент-координатор

Подагент веб-поиска

• Цель: Широта покрытия
• Критерий: Актуальность
Адаптивные, высокоценные результаты
Самостоятельная стратегия

Подход архитектора

Указывайте цели исследования и критерии качества, а не процедурные шаги. Пусть специализированный подагент сам определит стратегию поиска. Держите интерфейсы инструментов универсальными, но добавляйте enum-параметры (например, analysis_type: extraction | summarization) для направления поведения.

26 / 27

Справочная матрица архитектора

Извлечение данных Клиентская поддержка Продуктивность разработчика Мультиагентные системы
Раздувание токенов Фильтрация устаревших результатов Scratchpad-файл Общее векторное хранилище
Задержка Batch-маршрутизация Параллелизация и кэширование
Комплаенс / Контроль Перехваты на уровне приложения Принудительный tool_choice
Точность Избыточность в схеме Гранулярные MCP-инструменты Структурированные промежуточные представления
27 / 27

Чертёж продакшн-архитектуры

Чертёж продакшн-архитектуры
👤 Пользователь
Маршрутизатор
паттернов
Real-time ↗
Batch ↘
Интеллект на краях.
Строгая типизация в середине.

Слой выполнения

Гранулярные инструменты

Tool A
Tool B
Tool C
...

Перехваты приложения

🔒 Валидационные гарды
🔒 Применение политик
🔒 Проверка схем
Синтез
Агрегация результатов
Форматирование
Доставка

Управление состоянием (Очистка + Общий вектор)

Логика очистки
(pruning)
Общее векторное
хранилище (data)

💾 Управление контекстным окном

Общая память, поддерживающая жизненный цикл

— Руководство архитектора: Сертифицировано ✓ —