Всем привет! Если Вы решили подключить в свою разработку на .NET Core поддержку GigaChat, то эта статья для Вас.
Небольшое признание про эту статью
Это мой первый пост на хабре, где я расскажу про свой первый опыт разработки для NuGet и впервые использовал GitHub в качестве Системы контроля версий. Не смотря на десятилетний опыт в разработке ранее не занимался подобными публикациями «для народа».
Но после полугодичного отдыха решил опробовать себя чуть в новой роли. Поэтому критику принимаю, но только обоснованную 🙂
В конце 2023 года я решил в один из своих пет-проектов добавить поддержку GigaChat. Выбор может показаться странным, на фоне YandexGPT и ChatGPT. Но я провел с каждым из них примерно десяток тестов, и, на мое удивление, под мои нужды самые релевантные ответы для рунета дал именно GigaChat.
Что проверял у ИИ
Мне нужно было получить по 5 ассоциаций связанных с запрашиваемым словом. ChatGPT давал ассоциации «западные» или «шаблонные». YandexGPT выдавал не 5 слов, а несколько абзацев в качестве ответа. Да и YandexGPT самый «боязливый» из всех как будто — многие вопросы он считает «нетолерантными», на которые остальные дают ответы, если правильно их разогреть. А вот GigaChat давал наиболее приемлемые для русского слуха ассоциации — поэтому выбор пал на него.
И я решил тогда создать dll для работы с ГигаЧатом. А заодно появились мысли поделиться ей — для этого провел доработку библиотеки и ниже представлю, как с ней работать.
Предварительные требования и шаги
1) Получить ключ разработчика.
Для этого нужно зарегистрироваться на сайте разработчиков сбера https://developers.sber.ru/. Далее в рабочем пространстве создать Проект, в котором нужно выбрать «GigaChat API».
Далее я активировал бесплатный некоммерческий тариф
И получил код, который далее используется для подключения к GigaChat API

2) Скачать сертификат минцифры https://developers.sber.ru/docs/ru/gigachat/certificates
Тут все как обычно, скачал, установил
3) Скачать с NuGet библиотеку GigaChatAdapter.
Со временем планирую назвать её GigaChatAdapter .NET Core так как написана под Core
Работа с библиотекой GigaChatAdapter .NET Core
Перехожу к основной части.
Работу в целом можно разделить на 4 части, как часто происходит с подобными API:
-
Авторизация
-
Основная бизнесовая часть (в данном случае общение с ИИ)
-
Настройки
-
Пример
Вопрос к знатокам хабра
Как сделать чтобы этот список-план, написанный чуть выше, превратился в меню на внутренние заголовки, которые указаны у меня ниже?
-
Авторизация
Чтобы авторизоваться необходимо создать экземпляр авторизации и отправить свои авторизационные данные, а также указать scope (персональное использование, или коммерческое). Если все удачно, то вернется 200 ОК с токеном доступа, который, кстати, дается на 30 минут и который потребуется для отправки запросов, то будет установлен статус Authorization.AuthorizationSuccess == true.
Если же была ошибка на уровне Http или на уровне сервиса GigaChat, то Authorization.AuthorizationSuccess == false, а текст ошибки можно найти в Authorization.ErrorTextIfFailed
Если по какой-то причине возникает ошибка, которой нет в поле ErrorTextIfFailed, то тогда можно углубиться в экземпляр Authorization, получить свойство LastResponse, в нем хранятся HttpResponse (а через него можно выйти и на httpRequest, если нужно) и GigaChatResponse.
using GigaChatAdapter; //Укажите аутентификационные данные из личного кабинета string authData = "{Авторизационные данные из скрины выше}"; //Запуск авторизации в гигачате Authorization auth = new Authorization(authData, GigaChatAdapter.Auth.RateScope.GIGACHAT_API_PERS); var authResult = await auth.SendRequest(); if (authResult.AuthorizationSuccess) { /// Общение с ИИ } else { Console.WriteLine(authResult.ErrorTextIfFailed); }
-
Общение с ИИ
Для отправки запроса нужно создать экземпляр Completion и через него отправить вопрос к ИИ. Ниже в коде это сделано в цикле, чтобы общение было продолжительным, пока не будет закрыто консольное приложение. При этом обращаю внимание, что перед вызовом желательно использовать обновление токена (строка 12) в случае, если у него закончился срок жизни. Т.е. если Вы не хотите контролировать время действия токена, то за Вас это сделает метод UpdateToken(). Он обновляется только в случае, если токен пустой, или не было еще запросов на авторизацию, или же истек срок действия токена. Если же Вам нужно в любом случае обновить его, то тогда в метод можно передать параметр Force = true, и токен обновится при любом раскладе.
Ответы от гигачата приходят в виде объекта «массив данных объекта Choices», поэтому берется последний ответ из всего массива.
if (authResult.AuthorizationSuccess) { Completion completion = new Completion(); Console.WriteLine("Напишите запрос к модели. В ином случае закройте окно, если дальнейшую работу с чатботом необходимо прекратить."); while (true) { //Чтение промпта с консоли var prompt = Console.ReadLine(); //Обновление токена, если он просрочился await auth.UpdateToken(); //отправка промпта var result = await completion.SendRequest(auth.LastResponse.GigaChatAuthorizationResponse?.AccessToken, prompt); if (result.RequestSuccessed) { Console.WriteLine(result.GigaChatCompletionResponse.Choices.LastOrDefault().Message.Content); } else { Console.WriteLine(result.ErrorTextIfFailed); } } }
Отдельно выделю работу с историей чата. Она хранится не у ИИ, а у Вас, пока жив экземпляр сompletion. По умолчанию история сохраняется в поле Сompletion.History (как вопросы, так и ответы) и отправляется вместе с запросом каждый раз. Её можно сериализовать и сохранить куда угодно. При последующих сессиях эту историю можно достать, десериализовать, установить в объект Completion (оно доступно для изменения) и продолжать чатиться с ИИ с историей.
Сompletion.History = {Ваша история}
Если Вы не хотите использовать историю чата, тогда в методе SendRequest() нужно указать аргумент useHistory = false. Тогда вопрос отправляется без истории, он не сохраняется в истории равно как и ответ ИИ.
var result = await completion.SendRequest(auth.LastResponse.GigaChatAuthorizationResponse?.AccessToken, prompt, false);
-
Настройки
GigaChat имеет несколько параметров для настройки ответов. Есть количество ответов, рандомизатор ответов, порог релевантности ответов, ограничения на использование токенов. Подробнее можно найти в описании документации GigaChat’а https://developers.sber.ru/docs/ru/gigachat/api/reference
Чтобы использовать свои настройки, а не дефолтные, необходимо создать экземпляр объекта CompletionSettings и передать его в метод completion.SendRequest().
CompletionSettings settings = new CompletionSettings("GigaChat:latest", 2, null, 4); var result = await completion.SendRequest(auth.LastResponse.GigaChatAuthorizationResponse?.AccessToken, prompt, true, settings);
Единственный минус заключается в том, что указывать нужно все настройки при создании экземпляра CompletionSettings. Это связано с тем, что если разработчик вдруг не передает какие-либо параметры, то можно читать двояко:
-
Установить настройку в дефолтное состояние
-
Не менять предыдущую настройку
Поэтому решил что лучше обязать разработчика каждый раз указывать все настройки.
-
Пример использования
Привожу полный код небольшого примера для консольного приложения на .NET Core. Так как он небольшой, не делю его на методы, читается (имхо) и так легко. Его можно копипастить (выполнив предварительные шаги, указанные в статье ранее)
using GigaChatAdapter; using System.Text; //Настройка для работы консоли с кириллицей Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Console.InputEncoding = Encoding.GetEncoding(1251); Console.OutputEncoding = Encoding.GetEncoding(1251); //Укажите аутентификационные данные из личного кабинета string authData = "{Ваш код}"; //Запуск авторизации в гигачате Authorization auth = new Authorization(authData, GigaChatAdapter.Auth.RateScope.GIGACHAT_API_PERS); var authResult = await auth.SendRequest(); if (authResult.AuthorizationSuccess) { Completion completion = new Completion(); Console.WriteLine("Напишите запрос к модели. В ином случае закройте окно, если дальнейшую работу с чатботом необходимо прекратить."); //RU while (true) { //Чтение промпта с консоли var prompt = Console.ReadLine(); //Обновление токена, если он просрочился await auth.UpdateToken(); //Установка доп.настроек CompletionSettings settings = new CompletionSettings("GigaChat:latest", 2, null, 4); //Отправка промпта (с историей) var result = await completion.SendRequest(auth.LastResponse.GigaChatAuthorizationResponse?.AccessToken, prompt, true, settings); if (result.RequestSuccessed) { foreach (var it in result.GigaChatCompletionResponse.Choices) { Console.WriteLine(it.Message.Content); } } else { Console.WriteLine(result.ErrorTextIfFailed); } } } else { Console.WriteLine(authResult.ErrorTextIfFailed); }
Проблемы и дальнейшее развитие
На текущий момент проблема заключается в том, что в исходном коде у меня присутствует описание всех методов и полей. Можно найти на ГитХабе. Но когда я загрузил сборку через NuGet, у меня в ней пропали все комментарии к методам и свойствам, что печально сказывается на юзабильности.
UPD: проблема с отсутствием комментариев в коде решена, спасибо откликнувшимся!
Кроме того пока не понимаю, могу ли поменять отображаемое в NuGet название, добавив к нему .NET Core, или оно теперь окончательное?
Сейчас библиотека не поддерживает потоковую передачу, которой обладает сам сервис GigaChat. Если будет такая необходимость — займусь. Но пока не вижу смысла тратить на это время в виду наличия других тем для разработки.
Если будет кто-то желающий помочь с развитием библиотеки — велкам 🙂
ссылка на оригинал статьи https://habr.com/ru/articles/785242/
Добавить комментарий