Как стать автором
Обновить

Комментарии 9

Не может ли отсутствие символов быть результатом отсутствия этой галочки?

В вашем GigaChatAdapter.cspro не обнаружил тега DocumentationFile, который эти символы, вроде как, должен содержать.

Чтобы оставались комментарии к методам/свойствам/etc., нужно генерировать документацию, которая должна будет попасть в nuget пакет, включать так (в настройках проекта):

Либо в .csproj файле в блоке <PropertyGroup> добавить

<GenerateDocumentationFile>True</GenerateDocumentationFile>

О, спасибо!

Да, добавил эту галочку, выложил новую версию 1.0.4. Теперь появились комментарии в сборке :)

Полезная статья, развелось много моделей ИИ, про Сбер ранее и не слышал, спасибо! По поводу установки сертификата, этот процесс легко автоматизировать в несколько команд.

Для Windows (PowerShell):

Invoke-WebRequest "https://gu-st.ru/content/lending/russian_trusted_root_ca_pem.crt" -OutFile "$home\Downloads\russian_trusted_root_ca.cer" # скачать сертификат минцифры
Invoke-WebRequest "https://gu-st.ru/content/lending/russian_trusted_sub_ca_pem.crt" -OutFile "$home\Downloads\russian_trusted_sub_ca.cer"
Import-Certificate -FilePath "$home\Downloads\russian_trusted_root_ca.cer" -CertStoreLocation "Cert:\CurrentUser\Root" # установить сертификат минцифры
Import-Certificate -FilePath "$home\Downloads\russian_trusted_sub_ca.cer" -CertStoreLocation "Cert:\CurrentUser\CA"

Ubuntu (Bash):

wget https://gu-st.ru/content/lending/russian_trusted_root_ca_pem.crt
wget https://gu-st.ru/content/lending/russian_trusted_sub_ca_pem.crt
mkdir /usr/local/share/ca-certificates/russian_trusted
cp russian_trusted_root_ca_pem.crt russian_trusted_sub_ca_pem.crt /usr/local/share/ca-certificates/russian_trusted

В Ubuntu еще в конце для обновления списка сертификатов (забыл добавить):

update-ca-certificates -v

Опробовав модель, очень разочаровала, ответы сильно отличаются от тех, что отдает Web-версия. Можно получить что-то подходящее только запрос на 2-3, а то и 5, при этом продолжают тратиться токены...

Спасибо за скрипты для установки сертификатов!

По поводу модели - да, модель сырая достаточно. Ее ввели в эксплуатацию относительно недавно (месяца 2-3 назад), и она дорабатывается еще. Веб-версия чата имеет какие-то свои настройки и модель. Например, я просил в промпте "умножь это число на 5". Веб-версия отрабатывала корректно, а веб-апи возвращал

Пример ответа API
Пример ответа API

Плюс в декабре у сбера появилась модель GigaChat-Pro "с 29 миллиардами параметров" (тех.поддержка гигачата прислала). И где-то видел сообщение, что она бесплатна для фримиума до конца этого января, но может что-то поменялось с декабря. Название модели можно указать в настройках. Я пока ее не опробовал, отзыв о качестве не могу дать.

Я получал ответы такого же формата в тэгах, иногда из разряда "уточните ваш вопрос", за исключением когда можно выставить параметр для получения сразу 3-4 ответов, даже в таком случае через раз может быть один из таких ответов корректным и соответствовать Web-версии. Как мне кажется, могут помочь игры с параметрами temperature и top_p, но куда такое нестабильное решение внедрять мне не понятно.

Так и не нашел бесплатного варианта с API, пока что как альтернатива использую Selenium для интеграции в скрипты Web-версии сторонних и публичных моделей ChatGPT (пока тестирую, ищу самый стабильный вариант).

Если честно, не до конца осознал полезность данной статьи. По-сути Ваша библиотека реализует только запрос к эндпоинту завершения чата. Да и то, непонятно, например, почему запрос не обернут в тот же using (память передает привет!).

Про историю интересно, а как быть, если мы не просто сами хотим початиться с GigaChat, а строим какое-то приложение, где допустим есть несколько пользователей, тогда у них будет общая история чата?

Кроме того, библиотека не реализует множество других методов из GigaChat API (список моделей, кол-во токенов по тексту и т.д.). Также, GigaChat может отправлять сгенерированные картинки через завершение чата, это как-то обрабатывается данной библиотекой? Похоже, что нет. На гитхабе, и том же NuGet, есть другая прекрасная библиотека (ссылка на библиотеку), которая реализует все методы, которые есть на данный момент в GigaChat API, а также постоянно обновляется и имеет расписанную документацию.

using GigaChatAdapter;
using System.Text;

namespace GigaChatSolidExample
{
    public class Program
    {
        static async Task Main(string[] args)
        {
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            Console.InputEncoding = Encoding.GetEncoding(1251);
            Console.OutputEncoding = Encoding.GetEncoding(1251);

            string authData = "{Ваш код}";

            IAuthenticator authenticator = new Authenticator(authData, GigaChatAdapter.Auth.RateScope.GIGACHAT_API_PERS);
            var authResult = await authenticator.AuthorizeAsync();

            if (authResult.IsAuthorized)
            {
                ICompletionService completionService = new CompletionService();
                Console.WriteLine("Напишите запрос к модели. В ином случае закройте окно, если дальнейшую работу с чатботом необходимо прекратить.");

                while (true)
                {
                    var prompt = Console.ReadLine();

                    await authenticator.RefreshTokenAsync();

                    var settings = new CompletionSettings("GigaChat:latest", 2, null, 4);
                    var result = await completionService.CompleteAsync(authenticator.AccessToken, prompt, true, settings);

                    if (result.IsSuccessful)
                    {
                        foreach (var choice in result.Choices)
                        {
                            Console.WriteLine(choice.Content);
                        }
                    }
                    else
                    {
                        Console.WriteLine(result.ErrorMessage);
                    }
                }
            }
            else
            {
                Console.WriteLine(authResult.ErrorMessage);
            }
        }
    }

    interface IAuthenticator
    {
        bool IsAuthorized { get; }
        string AccessToken { get; }
        Task<bool> AuthorizeAsync();
        Task RefreshTokenAsync();
        string ErrorMessage { get; }
    }

    class Authenticator : IAuthenticator
    {
        private readonly string _authData;
        private readonly RateScope _rateScope;
        private bool _isAuthorized;
        private string _accessToken;
        private string _errorMessage;

        public Authenticator(string authData, RateScope rateScope)
        {
            _authData = authData;
            _rateScope = rateScope;
        }

        public bool IsAuthorized => _isAuthorized;

        public string AccessToken => _accessToken;

        public string ErrorMessage => _errorMessage;

        public async Task<bool> AuthorizeAsync()
        {
            try
            {
                var authorization = new Authorization(_authData, _rateScope);
                var authResult = await authorization.SendRequest();

                if (authResult.AuthorizationSuccess)
                {
                    _isAuthorized = true;
                    _accessToken = authResult.GigaChatAuthorizationResponse?.AccessToken;
                    return true;
                }
                else
                {
                    _errorMessage = authResult.ErrorTextIfFailed;
                    return false;
                }
            }
            catch (Exception ex)
            {
                _errorMessage = ex.Message;
                return false;
            }
        }

        public async Task RefreshTokenAsync()
        {
            try
            {
                var authorization = new Authorization(_authData, _rateScope);
                await authorization.UpdateToken();

                if (authorization.LastResponse != null && authorization.LastResponse.GigaChatAuthorizationResponse != null)
                {
                    _accessToken = authorization.LastResponse.GigaChatAuthorizationResponse.AccessToken;
                }
            }
            catch (Exception ex)
            {
                _errorMessage = ex.Message;
            }
        }
    }

    interface ICompletionService
    {
        Task<CompletionResult> CompleteAsync(string accessToken, string prompt, bool withHistory, CompletionSettings settings);
    }

    class CompletionService : ICompletionService
    {
        public async Task<CompletionResult> CompleteAsync(string accessToken, string prompt, bool withHistory, CompletionSettings settings)
        {
            try
            {
                var completion = new Completion();
                var result = await completion.SendRequest(accessToken, prompt, withHistory, settings);

                if (result.RequestSuccessed)
                {
                    return new CompletionResult(true, result.GigaChatCompletionResponse.Choices.Select(c => new Choice(c.Message.Content)).ToList(), null);
                }
                else
                {
                    return new CompletionResult(false, null, result.ErrorTextIfFailed);
                }
            }
            catch (Exception ex)
            {
                return new CompletionResult(false, null, ex.Message);
            }
        }
    }

    class CompletionResult
    {
        public bool IsSuccessful { get; }
        public List<Choice> Choices { get; }
        public string ErrorMessage { get; }

        public CompletionResult(bool isSuccessful, List<Choice> choices, string errorMessage)
        {
            IsSuccessful = isSuccessful;
            Choices = choices;
            ErrorMessage = errorMessage;
        }
    }

    class Choice
    {
        public string Content { get; }

        public Choice(string content)
        {
            Content = content;
        }
    }

    class CompletionSettings
    {
        public string Model { get; }
        public int MaxTokens { get; }
        public string Temperature { get; }
        public int N { get; }

        public CompletionSettings(string model, int maxTokens, string temperature, int n)
        {
            Model = model;
            MaxTokens = maxTokens;
            Temperature = temperature;
            N = n;
        }
    }
}

SOLID рефакторинг выполнен самим GigaChat. Код не тестировался и приведен ради ознакомления с идеями.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации