7.5 KiB
Техническое Задание: Внедрение гибридной AI-модели (OpenAI для диаграмм, Ollama для текста)
1. Общее описание
Целью является доработка AI-агента для использования гибридной модели генерации. Основной синтез текстового отчёта по-прежнему будет выполняться с помощью локального сервиса Ollama. Для опциональной и более сложной задачи — извлечения структурированных данных и генерации диаграмм — будет использоваться API OpenAI.
Этот подход позволяет использовать сильные стороны каждой модели:
- Ollama: Экономичная и быстрая генерация основного текста отчёта.
- OpenAI: Высокая точность в следовании инструкциям для генерации идеально отформатированного JSON и SVG-кода для диаграмм.
2. Обновлённая схема работы
- Сбор данных: Бэкенд получает
learningsотdeep-researchAPI. - Параллельный запуск двух AI-задач:
- Ветка A (Текст -> Ollama):
learningsотправляются в ваш существующийOllamaAnalyticsServiceдля синтеза основного текста отчёта в Markdown. - Ветка B (Диаграммы -> OpenAI):
learningsотправляются в новый сервис (OpenAiChartService), который делает два последовательных вызова к API OpenAI:- Извлечь из текста данные для диаграмм в формате JSON.
- Превратить этот JSON в SVG-код диаграммы.
- Ветка A (Текст -> Ollama):
- Конвертация SVG: SVG-код, полученный от OpenAI, конвертируется в PNG-изображение на стороне Java.
- Финальная сборка 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}ко всем запросам.- Методы:
public Mono<String> getChartDataJson(List<String> learnings): Принимаетlearnings, использует Промпт №1 (для извлечения данных) и возвращаетMonoсо строкой, содержащей JSON-массив.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. План действий
- Добавить
openai.api.keyв вашapplication.properties. - Создать новый класс
OpenAiChartService.java. Он будет похож наOllamaAnalyticsService, но настроен для работы с API OpenAI (другой URL, заголовок авторизации, другая структура JSON-запроса). - Обновить
ReportSynthesisService.java, чтобы он использовалOllamaAnalyticsServiceдля текста иOpenAiChartServiceдля диаграмм, как показано в примере выше. - Перезапустить ваше Java-приложение.