Files
marketing-parser/Техническое Задание: Внедрение гибридной AI-модели (OpenAI для диаграмм, Ollama для текста).md
T
2025-10-06 19:22:37 +05:00

7.5 KiB
Raw Blame History

Техническое Задание: Внедрение гибридной AI-модели (OpenAI для диаграмм, Ollama для текста)

1. Общее описание

Целью является доработка AI-агента для использования гибридной модели генерации. Основной синтез текстового отчёта по-прежнему будет выполняться с помощью локального сервиса Ollama. Для опциональной и более сложной задачи — извлечения структурированных данных и генерации диаграмм — будет использоваться API OpenAI.

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

  • Ollama: Экономичная и быстрая генерация основного текста отчёта.
  • OpenAI: Высокая точность в следовании инструкциям для генерации идеально отформатированного JSON и SVG-кода для диаграмм.

2. Обновлённая схема работы

  1. Сбор данных: Бэкенд получает learnings от deep-research API.
  2. Параллельный запуск двух AI-задач:
    • Ветка A (Текст -> Ollama): learnings отправляются в ваш существующий OllamaAnalyticsService для синтеза основного текста отчёта в Markdown.
    • Ветка B (Диаграммы -> OpenAI): learnings отправляются в новый сервис (OpenAiChartService), который делает два последовательных вызова к API OpenAI:
      1. Извлечь из текста данные для диаграмм в формате JSON.
      2. Превратить этот JSON в SVG-код диаграммы.
  3. Конвертация SVG: SVG-код, полученный от OpenAI, конвертируется в PNG-изображение на стороне Java.
  4. Финальная сборка PDF: ResearchPdfService объединяет текст отчёта (от Ollama) и изображения диаграмм (от OpenAI) в единый PDF-файл.

3. Требования к реализации

3.1. Конфигурация

В ваш файл application.properties (или application.yml) необходимо добавить API-ключ для OpenAI:

# application.properties

# ... ваши существующие настройки Ollama ...
ollama.model=llama3:8b-instruct

# --- НОВЫЕ НАСТРОЙКИ ДЛЯ OPENAI ---
openai.api.key=sk-...(ваш API ключ от OpenAI)...
openai.api.url=https://api.openai.com/v1/chat/completions
openai.model.name=gpt-4-turbo # Рекомендуемая модель для работы с JSON и SVG

3.2. Создание нового сервиса: OpenAiChartService

Необходимо создать новый Spring-сервис, отвечающий за взаимодействие с OpenAI.

  • WebClient: Сервис должен содержать собственный WebClient, настроенный на openai.api.url и автоматически добавляющий заголовок Authorization: Bearer ${openai.api.key} ко всем запросам.
  • Методы:
    1. public Mono<String> getChartDataJson(List<String> learnings): Принимает learnings, использует Промпт №1 (для извлечения данных) и возвращает Mono со строкой, содержащей JSON-массив.
    2. public Mono<String> getChartSvg(String jsonData): Принимает JSON с данными для одной диаграммы, использует Промпт №2 (для генерации SVG) и возвращает Mono со строкой SVG-кода.

3.3. Модификация оркестратора: ReportSynthesisService

Этот сервис теперь будет управлять вызовами к обоим AI-сервисам.

  • Зависимости: ReportSynthesisService теперь должен инжектировать (@Autowired) и OllamaAnalyticsService, и новый OpenAiChartService.
  • Метод synthesizeReportAndCharts:
    • Ветка текста (textMono) по-прежнему вызывает ollamaAnalyticsService для генерации отчёта.
    • Ветка диаграмм (chartsMono) теперь будет вызывать openAiChartService.

Пример обновлённой логики для chartsMono:

// ... внутри ReportSynthesisService ...

// Ветка B: Генерация диаграмм через OpenAI
Mono<List<byte[]>> chartsMono = openAiChartService.getChartDataJson(aggregatedLearnings)
    .flatMap(jsonArrayString -> {
        String cleanJsonArray = extractJsonArray(jsonArrayString);
        if (cleanJsonArray == null || cleanJsonArray.equals("[]")) {
            return Mono.just(Collections.emptyList()); // Если данных нет, возвращаем пустой список
        }

        try {
            List<ChartData> chartDataList = objectMapper.readValue(cleanJsonArray, new TypeReference<List<ChartData>>() {});

            // Превращаем список задач в поток (Flux) и выполняем их последовательно
            return Flux.fromIterable(chartDataList)
                .concatMap(chartData ->
                    openAiChartService.getChartSvg(objectMapper.writeValueAsString(chartData))
                )
                .map(this::extractSvgCode)
                .map(SvgToPngConverter::convert)
                .filter(Objects::nonNull)
                .collectList();

        } catch (IOException e) {
            return Mono.error(e);
        }
    });

3.4. Промпты для OpenAI

Промпты остаются теми же, что и в предыдущем ТЗ, так как модели OpenAI отлично их понимают.

  • Промпт №1 (Извлечение данных): Просит вернуть JSON-массив объектов с данными для диаграмм или пустой массив [], если данных нет.
  • Промпт №2 (Генерация SVG): Просит на основе одного JSON-объекта вернуть только SVG-код.

4. План действий

  1. Добавить openai.api.key в ваш application.properties.
  2. Создать новый класс OpenAiChartService.java. Он будет похож на OllamaAnalyticsService, но настроен для работы с API OpenAI (другой URL, заголовок авторизации, другая структура JSON-запроса).
  3. Обновить ReportSynthesisService.java, чтобы он использовал OllamaAnalyticsService для текста и OpenAiChartService для диаграмм, как показано в примере выше.
  4. Перезапустить ваше Java-приложение.