Важно! Для работы с агентами Yandex AI Studio нужно использовать версию Simple-Scada 2.7.6.0 или выше. Пример проекта можно скачать по ссылке. После скачивания, в скрипте "fldQuery_OnDoneInput" вместо "<API-ключ>" укажите свой API ключ, вместо "<MODEL_URI>" укажите ссылку на своего AI-агента.
В данной статье рассмотрим работу с текстовым AI-агентом Yandex AI Studio из Simple-Scada. Мы будем задавать вопросы AI-агенту и получать от него ответы в SCADA-систему. Перед началом работы нужно:
1.Зарегистрироваться в AI Studio и получить ключ к API, который необходим для выполнения запросов.
2.Создать в AI Studio нового текстового агента. После этого, в личном кабинете AI Studio можно будет увидеть ссылку на агента (model_uri), например: "gpt://b1gjekc2f5kf35cvvt4y/gpt-oss-20b". Эту ссылку будем использовать, чтобы обращаться к агенту.
Создадим новый проект в Simple-Scada. На странице разместим следующие объекты:
•Поле с именем "fldQuery" - в него пользователь будет вводить запрос для AI-агента.
•Текст с именем "txtResponse" - в него будут выводиться ответы AI-агента.
Выделим поле "fldQuery" и на событие OnDoneInput назначим следующий скрипт:
Вместо <MODEL_URI>, укажите ссылку на вашего AI-агента, например "gpt://b1gjekc2f5kf35cvvt4y/gpt-oss-20b". Вместо <API-ключ>, укажите ключ к API, который был получен при регистрации в AI Studio.
var
aHTTP: TM_HTTP;
aPOST: TM_HTTPPost;
begin
// если поле с запросом пустое, то просим пользователя
// ввести запрос и прерываем выполнение
if Trim(fldQuery.Text) = '' then
begin
txtResponse.Text := 'Сначала введите запрос!';
Exit;
end;
// формируем данные для POST запроса, указываем в них ссылку
// на AI-агента и текст запроса
aPost := TM_HTTPPost.Create(hptJSON);
aPost.Add('{' +
'"model": "<MODEL_URI>",' +
'"input": "' + fldQuery.Text + '"' +
'}');
// далее отправляем запрос на сервер AI Studio, указывая
// полученный ранее API ключ. Даем серверу AI Studio
// тридцать секунд на обработку запроса и ответ
aHTTP := RequestHTTP(8000, 30000);
aHTTP.ProtocolVersion := hpv1_1;
aHTTP.SetHeader('Content-Type', 'application/json');
aHTTP.SetHeader('Authorization', 'Api-Key <API-ключ>');
// выполняем POST запрос и отмечаем его тегом = 1
aHTTP.Post('https://ai.api.cloud.yandex.net/v1/responses', aPost, 1);
// выводим текст о том, что запрос сейчас выполняется и
// блокируем ввод в поле запроса до получения ответа
txtResponse.Text := 'запрос выполняется...';
fldQuery.Enabled := False;
end.
Данный скрипт отправляет запрос из поля fldQuery к AI-агенту с указанным model_uri. Обратите внимание на важные особенности:
1.В вызове RequestHTTP мы выделили 8 секунд на подключение к агенту и 30 секунд на обработку ответа. Дело в том, что AI-агент может довольно долго обрабатывать запрос и генерировать ответ, поэтому отводим до 30 секунд на ответ.
2.Сервер "ai.api.cloud.yandex.net" работает только по протоколу HTTP 1.1, поэтому мы указали в ProtocolVersion, что нужно использовать только HTTP 1.1.
3.В вызове "aHTTP.Post" мы присвоили запросу тег = 1. Этот тег будем использовать при обработке ответа (чтобы не спутать его с ответами на другие запросы).
Теперь создадим новый скрипт с типом события "Выполнен HTTP-запрос", в котором будем обрабатывать ответ от AI-агента:
var
I, J: Integer;
aAnswer: string;
aOutput, aContent, aOutputItem, aContentItem: TM_JSONNode;
begin
// в этом скрипте обрабатываем только ответ на запрос с тегом = 1
if Response.Tag <> 1 then
Exit;
// разрешаем ввод нового запроса в поле
fldQuery.Enabled := True;
// обработка успешного ответа сервера
if Response.Code = 200 then
begin
fldQuery.Text := '';
aAnswer := '';
aOutput := Response['output'];
if aOutput <> nil then
for I := 0 to aOutput.Count - 1 do
begin
aOutputItem := aOutput.Nodes[I];
aContent := aOutputItem['content'];
// игнорируем сообщения не являющиеся сообщением
// и сообщения с ролью не равной "assistant"
if (aOutputItem['type'].AsStr <> 'message') or
(aOutputItem['role'].AsStr <> 'assistant') or
(aContent = nil) then
Continue;
// собираем текст ответа из массива "content"
for J := 0 to aContent.Count - 1 do
begin
aContentItem := aContent.Nodes[J];
if aContentItem['type'].AsStr = 'output_text' then
aAnswer := aAnswer + aContentItem['text'].AsStr;
end;
end;
// заменяем "\n" и "<br>" в тексте ответа на перенос строки
aAnswer := StringReplace(aAnswer, '\n', #13#10, [rfReplaceAll]);
aAnswer := StringReplace(aAnswer, '<br>', #13#10, [rfReplaceAll]);
// выводим весь полученный от AI агента ответ
txtResponse.Text := aAnswer;
end else
txtResponse.Text := 'Сервер AI Studio вернул ошибку: ' + Response.Text;
end.
Ключевые моменты:
•Сервер AI Studio генерирует довольно сложный ответ в JSON формате. Данные ответа лежат в массиве "output", причем ответ может быть разбит на несколько частей. Нужно собрать все части, извлекая из них "content.text" в один большой ответ. Поэтому в коде выполняется проход в цикле по массиву "output" и в локальную переменную aAnswer собираются части ответа. При этом, нужно брать только те части, которые имеют тип "message" и роль "assistant", т.к. только они относятся к ответу.
•В ответе могут присутствовать символы переноса строки, например: "\n" или теги "<br>". Поэтому в коде мы заменяем их на "#13#10" (перенос строки, понятный SCADA-системе).
Теперь можно запустить проект, вводить запросы в поле fldQuery и видеть ответы AI-агента в скада-системе.