Начало работы

В этом разделе показано, как добавить работающий AI-чат в приложение: включить server push, подключить модель и добавить компонент.

Предварительные требования

Установите дополнение, как описано в разделе Установка.

Включение server push

Ответы поступают по одному токену и из другого потока, а не из того, который обработал запрос, поэтому в приложении должен быть включен server push. Добавьте @Push к классу приложения:

@Push
@SpringBootApplication
public class AiChatEx1Application implements AppShellConfigurator {

Без этого компоненты отображаются, но ничего из того, что формирует ответ, не доходит до браузера.

Подключение модели

Чат сам не взаимодействует с моделью. Он запрашивает у приложения одну функцию: получив запрос, вернуть ответ в виде потока текста. Эта функция называется LLMProvider, и чат не может отвечать, пока она не задана.

В этом примере используется Ollama, которая запускает модель локально и не требует API-ключа. Добавьте для нее стартер Spring AI:

implementation 'org.springframework.ai:spring-ai-starter-model-ollama'

И настройте его в application.properties:

spring.ai.model.chat=ollama
spring.ai.ollama.base-url=${OLLAMA_BASE_URL:http://localhost:11434}
spring.ai.ollama.chat.model=${OLLAMA_CHAT_MODEL:qwen3:8b}
spring.ai.ollama.init.pull-model-strategy=never

Затем задайте чату провайдер. Spring AI автоматически настраивает ChatClient.Builder, с помощью которого экран создает свой клиент:

@Autowired
private ChatClient.Builder chatClientBuilder;

private ChatClient chatClient;

@Subscribe
public void onInit(final InitEvent event) {
    chatClient = chatClientBuilder.build();
}

@Install(to = "chat", subject = "llmProvider")
private Flux<String> llmProvider(final LLMProvider.LLMRequest request) {
    return chatClient.prompt()
            .user(request.userMessage())
            .stream()
            .content();
}

В примере провайдер объявлен с помощью @Install, что является обычным способом в экране. setLlmProvider(…​) делает то же самое из кода, если чат создается программно.

LLMProvider находится в пакете com.vaadin.flow.component.ai.provider, а не в пакете Jmix.

Запрос содержит не только текст, который ввел пользователь: в нем также есть системный промпт и прикрепленные файлы. Провайдер решает, что из этого передать модели. То, что он не читает, не отправляется. Метод выше передает только сообщение, и этого достаточно для чата, в котором нет ни системного промпта, ни вложений. См. Системный промпт и Отправка файлов модели.

Всё приведенное выше относится к Ollama только в части стартера и свойств. Чтобы использовать OpenAI, Anthropic, Azure OpenAI или любую другую модель Spring AI, замените эти две части, а метод провайдера оставьте без изменений.

Добавление чата

Объявите компонент в дескрипторе экрана. Задайте ему ширину и высоту. Чат без них подстраивает размер под свое содержимое, что в корневом макете экрана дает узкую колонку:

<aichat:aiChat id="chat" width="100%" height="100%"/>

Это вся конфигурация. Чат хранит диалог в памяти, отображает ответы, и больше ему для работы ничего не нужно:

Работающий чат

Если модель недоступна, приложение запускается как обычно, и экран открывается без ошибок. Сбой проявляется при первом сообщении: в чате отображается неудачная генерация, а не ошибка при запуске.

Что дальше

Чат выше хранит диалог в памяти, поэтому он теряется при закрытии экрана. В разделе aiChat описано, как связать чат с собственной сущностью сообщения, сохранять диалог, управлять генерацией и настраивать части, из которых он состоит.

Компоненты, из которых он состоит, можно использовать и отдельно: aiMessageList для отображения диалога или самостоятельного управления им, aiMessageInput для ввода сообщения и aiCodeBlock для показа кода в любом месте приложения.