Files
marketing-parser/Техническое Задание Внедрение гибридной AI-модели OpenAI для диаграмм Ollama для текста.md
2026-01-05 23:32:16 +05:00

104 lines
7.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
### **Техническое Задание: Внедрение гибридной 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:
```properties
# 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`:**
```java
// ... внутри 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-приложение.