Skip to content

Repository files navigation

YandexGPT Go SDK

YandexGPT Golang

Go Version License Go Report Card

Русский | English

pkg.go.dev/github.com/tigusigalpa/yandexgpt-go/v2

Go SDK для YandexGPT API с поддержкой генерации текста и изображений (YandexART).

Пакет берёт на себя работу с токенами, предоставляет методы для диалогов, одиночных запросов и Conversations API.

Примечание: Пакет использует yandex-cloud-client-go для управления облачной инфраструктурой Yandex Cloud (организации, облака, каталоги, авторизация).

Возможности

  • Генерация текста (YandexGPT, YandexGPT Lite, AliceAI LLM)
  • Генерация изображений (YandexART)
  • Conversations API — серверное хранение диалогов
  • Автоматическое управление OAuth/IAM токенами
  • Режим рассуждений (Chain of Thought)
  • Покрытие тестами

Установка

Установите пакет с помощью go get:

go get github.com/tigusigalpa/yandexgpt-go/v2

Настройка

1. Получение OAuth токена

Документация: OAuth-токен

Перейдите по ссылке для получения OAuth токена:

https://oauth.yandex.ru/authorize?response_type=token&client_id=1a6990aa636648e9b2ef855fa7bec2fb

2. Настройка окружения

Установите переменные окружения или передайте их напрямую в клиент:

export YANDEX_GPT_OAUTH_TOKEN=your_oauth_token_here
export YANDEX_GPT_FOLDER_ID=your_folder_id_here

3. Подготовка Yandex Cloud

Для подробных инструкций по настройке см. Руководство по настройке.


Использование

Базовое использование

package main

import (
    "fmt"
    "log"
    
    "github.com/tigusigalpa/yandexgpt-go/v2"
    "github.com/tigusigalpa/yandexgpt-go/v2/models"
)

func main() {
    // Создание клиента
    client, err := yandexgpt.NewClient("your_oauth_token", "your_folder_id")
    if err != nil {
        log.Fatal(err)
    }
    
    // Простой запрос
    response, err := client.GenerateText(
        "Расскажи о преимуществах языка программирования Go",
        models.YandexGPTLite,
        nil,
    )
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Println(response.Result.Alternatives[0].Message.Text)
}

Работа с диалогами

package main

import (
    "fmt"
    "log"
    
    "github.com/tigusigalpa/yandexgpt-go/v2"
    "github.com/tigusigalpa/yandexgpt-go/v2/models"
)

func main() {
    client, err := yandexgpt.NewClient("your_oauth_token", "your_folder_id")
    if err != nil {
        log.Fatal(err)
    }
    
    messages := []yandexgpt.Message{
        {
            Role: "system",
            Text: "Ты полезный помощник-программист",
        },
        {
            Role: "user",
            Text: "Как создать REST API на Go?",
        },
        {
            Role: "assistant",
            Text: "Для создания REST API на Go можно использовать стандартный пакет net/http...",
        },
        {
            Role: "user",
            Text: "А как добавить валидацию?",
        },
    }
    
    response, err := client.GenerateFromMessages(messages, models.YandexGPTLite, nil)
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Println(response.Result.Alternatives[0].Message.Text)
}

Conversations API

SDK поддерживает работу с Conversations API для управления диалогами и их элементами на стороне сервера Yandex Cloud.

Доступные методы:

Метод Описание
Create() Создание нового диалога
Get() Получение диалога по ID
Update() Обновление метаданных диалога
Delete() Удаление диалога
CreateItems() Добавление элементов в диалог
ListItems() Получение списка элементов диалога
GetItem() Получение одного элемента диалога
DeleteItem() Удаление элемента из диалога

Управление диалогами:

package main

import (
    "fmt"
    "log"

    "github.com/tigusigalpa/yandexgpt-go/v2"
)

func main() {
    client, err := yandexgpt.NewClient("your_oauth_token", "your_folder_id")
    if err != nil {
        log.Fatal(err)
    }

    // Создание диалога с метаданными
    conv, err := client.Conversations().Create(
        map[string]string{"title": "Техническая поддержка", "user_id": "12345"},
        nil,
    )
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Conversation ID: %s\n", conv.ID)

    // Получение диалога
    conv, err = client.Conversations().Get(conv.ID)
    if err != nil {
        log.Fatal(err)
    }

    // Обновление метаданных
    conv, err = client.Conversations().Update(conv.ID, map[string]string{
        "title":  "Обновлённый заголовок",
        "status": "active",
    })
    if err != nil {
        log.Fatal(err)
    }

    // Удаление диалога
    deleted, err := client.Conversations().Delete(conv.ID)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Deleted: %v\n", deleted.Deleted)
}

Управление элементами диалога:

package main

import (
    "fmt"
    "log"

    "github.com/tigusigalpa/yandexgpt-go/v2"
)

func main() {
    client, err := yandexgpt.NewClient("your_oauth_token", "your_folder_id")
    if err != nil {
        log.Fatal(err)
    }

    conversationID := "conv_123"

    // Добавление элементов в диалог
    items, err := client.Conversations().CreateItems(conversationID, []yandexgpt.ConversationItem{
        {
            Type: "message",
            Role: "user",
            Content: []yandexgpt.ConversationContentPart{
                {Type: "input_text", Text: "Привет! Как дела?"},
            },
        },
        {
            Type: "message",
            Role: "assistant",
            Content: []yandexgpt.ConversationContentPart{
                {Type: "output_text", Text: "Здравствуйте! Всё отлично, чем могу помочь?"},
            },
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    // Получение списка элементов (с пагинацией)
    limit := 20
    order := "asc"
    list, err := client.Conversations().ListItems(conversationID, &yandexgpt.ListItemsOptions{
        Limit: &limit,
        Order: &order,
    })
    if err != nil {
        log.Fatal(err)
    }

    for _, item := range list.Data {
        if len(item.Content) > 0 {
            fmt.Printf("%s: %s\n", item.Role, item.Content[0].Text)
        }
    }

    // Пагинация: получение следующей страницы
    if list.HasMore {
        nextList, _ := client.Conversations().ListItems(conversationID, &yandexgpt.ListItemsOptions{
            Limit: &limit,
            Order: &order,
            After: &list.LastID,
        })
        _ = nextList
    }

    // Получение одного элемента
    item, err := client.Conversations().GetItem(conversationID, items.FirstID)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Item: %s (%s)\n", item.ID, item.Role)

    // Удаление элемента
    _, err = client.Conversations().DeleteItem(conversationID, items.FirstID)
    if err != nil {
        log.Fatal(err)
    }
}

Генерация изображений с YandexART

package main

import (
    "encoding/base64"
    "fmt"
    "log"
    "os"
    
    "github.com/tigusigalpa/yandexgpt-go/v2"
)

func main() {
    client, err := yandexgpt.NewClient("your_oauth_token", "your_folder_id")
    if err != nil {
        log.Fatal(err)
    }
    
    // Генерация изображения
    result, err := client.GenerateImage(
        "Красивый закат над горами",
        nil,
        nil,
    )
    if err != nil {
        log.Fatal(err)
    }
    
    // Декодирование base64 изображения
    imageData, err := base64.StdEncoding.DecodeString(result.ImageBase64)
    if err != nil {
        log.Fatal(err)
    }
    
    // Сохранение в файл
    err = os.WriteFile("output.jpg", imageData, 0644)
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Println("Изображение сохранено в output.jpg")
}

Пользовательские параметры

package main

import (
    "fmt"
    "log"
    
    "github.com/tigusigalpa/yandexgpt-go/v2"
    "github.com/tigusigalpa/yandexgpt-go/v2/models"
)

func main() {
    client, err := yandexgpt.NewClient("your_oauth_token", "your_folder_id")
    if err != nil {
        log.Fatal(err)
    }
    
    options := &yandexgpt.CompletionOptions{
        Temperature: 0.8,
        MaxTokens:   1000,
    }
    
    response, err := client.GenerateText(
        "Напиши стихотворение о программировании",
        models.YandexGPT,
        options,
    )
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Println(response.Result.Alternatives[0].Message.Text)
}

Режим рассуждений

Режим рассуждений позволяет моделям выполнять цепочку рассуждений для решения сложных задач:

package main

import (
    "fmt"
    "log"
    
    "github.com/tigusigalpa/yandexgpt-go/v2"
    "github.com/tigusigalpa/yandexgpt-go/v2/models"
)

func main() {
    client, err := yandexgpt.NewClient("your_oauth_token", "your_folder_id")
    if err != nil {
        log.Fatal(err)
    }
    
    effortMedium := "medium"
    options := &yandexgpt.CompletionOptions{
        Temperature: 0.1,
        MaxTokens:   2000,
        ReasoningOptions: &yandexgpt.ReasoningOptions{
            Mode:   "ENABLED_HIDDEN",
            Effort: &effortMedium,
        },
    }
    
    response, err := client.GenerateText(
        "Решите логическую задачу: Если все розы - цветы, и некоторые цветы - красные, можно ли утверждать, что некоторые розы - красные?",
        models.YandexGPT,
        options,
    )
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Println(response.Result.Alternatives[0].Message.Text)
    
    // Проверка использования токенов рассуждения
    if response.Result.Usage.ReasoningTokens > 0 {
        fmt.Printf("Использовано токенов рассуждения: %d\n", response.Result.Usage.ReasoningTokens)
    }
}

Параметры режима рассуждений:

  • Mode: "DISABLED" (по умолчанию), "ENABLED_HIDDEN" (включает рассуждения без показа цепочки)
  • Effort: "low", "medium", "high" (управляет глубиной рассуждений, опционально)

Документация: Режим рассуждений в YandexGPT


Доступные модели

Модель Описание Константа Контекст
yandexgpt-lite Быстрая и экономичная модель models.YandexGPTLite 32K
yandexgpt Стандартная модель models.YandexGPT 32K
aliceai-llm Alice AI LLM - продвинутая разговорная модель models.AliceAI 32K

Полный список моделей: Модели генерации в Yandex AI Studio


Параметры генерации

type CompletionOptions struct {
    Stream           bool              // Потоковая передача (пока не поддерживается)
    Temperature      float64           // Креативность (0.0 - 1.0)
    MaxTokens        int               // Максимальное количество токенов
    ReasoningOptions *ReasoningOptions // Настройки режима рассуждений (опционально)
}

type ReasoningOptions struct {
    Mode   string  // "DISABLED", "ENABLED_HIDDEN"
    Effort *string // "low", "medium", "high" (опционально)
}

Обработка ошибок

package main

import (
    "errors"
    "fmt"
    "log"
    
    "github.com/tigusigalpa/yandexgpt-go/v2"
    "github.com/tigusigalpa/yandexgpt-go/v2/models"
)

func main() {
    client, err := yandexgpt.NewClient("your_oauth_token", "your_folder_id")
    if err != nil {
        log.Fatal(err)
    }
    
    response, err := client.GenerateText("Привет!", models.YandexGPTLite, nil)
    if err != nil {
        var authErr *yandexgpt.AuthenticationError
        var apiErr *yandexgpt.APIError
        
        switch {
        case errors.As(err, &authErr):
            fmt.Printf("Ошибка аутентификации: %v\n", err)
        case errors.As(err, &apiErr):
            fmt.Printf("Ошибка API: %v\n", err)
        default:
            fmt.Printf("Неизвестная ошибка: %v\n", err)
        }
        return
    }
    
    fmt.Println(response.Result.Alternatives[0].Message.Text)
}

Примеры

См. директорию examples для дополнительных примеров использования:


Сравнение моделей

Модель Скорость Качество Применение
YandexGPT Lite Высокая Хорошее Чат-боты, простые задачи, прототипы
YandexGPT Средняя Отличное Анализ, генерация статей, логические задачи
AliceAI LLM Средняя Очень хорошее Диалоги, ассистенты

Все модели поддерживают контекст 32K токенов.


Продвинутые возможности

Управление контекстом диалога

type DialogManager struct {
    client   *yandexgpt.Client
    messages []yandexgpt.Message
    maxHistory int
}

func NewDialogManager(client *yandexgpt.Client, systemPrompt string) *DialogManager {
    return &DialogManager{
        client: client,
        messages: []yandexgpt.Message{
            {Role: "system", Text: systemPrompt},
        },
        maxHistory: 10, // Хранить последние 10 сообщений
    }
}

func (dm *DialogManager) AddUserMessage(text string) error {
    dm.messages = append(dm.messages, yandexgpt.Message{
        Role: "user",
        Text: text,
    })
    
    // Ограничение истории для экономии токенов
    if len(dm.messages) > dm.maxHistory {
        // Сохраняем системное сообщение и последние N сообщений
        dm.messages = append(
            dm.messages[:1],
            dm.messages[len(dm.messages)-dm.maxHistory+1:]...,
        )
    }
    
    response, err := dm.client.GenerateFromMessages(
        dm.messages,
        models.YandexGPT,
        nil,
    )
    if err != nil {
        return err
    }
    
    assistantMessage := response.Result.Alternatives[0].Message.Text
    dm.messages = append(dm.messages, yandexgpt.Message{
        Role: "assistant",
        Text: assistantMessage,
    })
    
    return nil
}

Пакетная обработка запросов

Для обработки множества запросов используйте конкурентность:

func ProcessBatch(client *yandexgpt.Client, prompts []string) ([]string, error) {
    results := make([]string, len(prompts))
    errors := make([]error, len(prompts))
    
    var wg sync.WaitGroup
    semaphore := make(chan struct{}, 5) // Ограничение: 5 одновременных запросов
    
    for i, prompt := range prompts {
        wg.Add(1)
        go func(index int, text string) {
            defer wg.Done()
            semaphore <- struct{}{}
            defer func() { <-semaphore }()
            
            response, err := client.GenerateText(text, models.YandexGPTLite, nil)
            if err != nil {
                errors[index] = err
                return
            }
            results[index] = response.Result.Alternatives[0].Message.Text
        }(i, prompt)
    }
    
    wg.Wait()
    
    // Проверка ошибок
    for _, err := range errors {
        if err != nil {
            return results, err
        }
    }
    
    return results, nil
}

Работа с большими текстами

Для обработки текстов, превышающих лимит контекста:

func SummarizeLongText(client *yandexgpt.Client, longText string) (string, error) {
    // Разбиваем текст на части по ~3000 символов
    chunkSize := 3000
    var chunks []string
    
    for i := 0; i < len(longText); i += chunkSize {
        end := i + chunkSize
        if end > len(longText) {
            end = len(longText)
        }
        chunks = append(chunks, longText[i:end])
    }
    
    // Суммаризируем каждую часть
    var summaries []string
    for _, chunk := range chunks {
        response, err := client.GenerateText(
            fmt.Sprintf("Кратко перескажи следующий текст:\n\n%s", chunk),
            models.YandexGPT,
            &yandexgpt.CompletionOptions{Temperature: 0.3},
        )
        if err != nil {
            return "", err
        }
        summaries = append(summaries, response.Result.Alternatives[0].Message.Text)
    }
    
    // Финальная суммаризация
    finalPrompt := fmt.Sprintf(
        "Объедини следующие краткие пересказы в один связный текст:\n\n%s",
        strings.Join(summaries, "\n\n"),
    )
    
    response, err := client.GenerateText(finalPrompt, models.YandexGPT, nil)
    if err != nil {
        return "", err
    }
    
    return response.Result.Alternatives[0].Message.Text, nil
}

Лучшие практики

Оптимизация промптов

  • Чётко формулируйте задачу и формат ответа
  • Добавляйте примеры (few-shot)
  • Разделяйте инструкции и данные
// ❌ Плохой промпт
prompt := "Расскажи про Go"

// ✅ Хороший промпт
prompt := `Напиши краткое описание языка программирования Go (до 100 слов).
Включи следующие аспекты:
1. Основное назначение
2. Ключевые особенности
3. Популярные области применения

Формат: структурированный текст с подзаголовками.`

Управление температурой

  • 0.0-0.3: Детерминированные, точные ответы (анализ, классификация)
  • 0.4-0.7: Сбалансированные ответы (общие задачи)
  • 0.8-1.0: Креативные, разнообразные ответы (генерация контента)

Обработка ошибок и повторные попытки

func GenerateWithRetry(client *yandexgpt.Client, prompt string, maxRetries int) (string, error) {
    var lastErr error
    
    for attempt := 0; attempt < maxRetries; attempt++ {
        response, err := client.GenerateText(prompt, models.YandexGPT, nil)
        if err == nil {
            return response.Result.Alternatives[0].Message.Text, nil
        }
        
        lastErr = err
        
        // Экспоненциальная задержка
        backoff := time.Duration(math.Pow(2, float64(attempt))) * time.Second
        time.Sleep(backoff)
    }
    
    return "", fmt.Errorf("failed after %d attempts: %w", maxRetries, lastErr)
}

Кэширование результатов

type CachedClient struct {
    client *yandexgpt.Client
    cache  map[string]string
    mu     sync.RWMutex
}

func (cc *CachedClient) GenerateText(prompt string) (string, error) {
    // Проверяем кэш
    cc.mu.RLock()
    if cached, ok := cc.cache[prompt]; ok {
        cc.mu.RUnlock()
        return cached, nil
    }
    cc.mu.RUnlock()
    
    // Генерируем новый ответ
    response, err := cc.client.GenerateText(prompt, models.YandexGPT, nil)
    if err != nil {
        return "", err
    }
    
    result := response.Result.Alternatives[0].Message.Text
    
    // Сохраняем в кэш
    cc.mu.Lock()
    cc.cache[prompt] = result
    cc.mu.Unlock()
    
    return result, nil
}

Устранение неполадок

Ошибка аутентификации

Проблема: Authentication error: invalid OAuth token

Решение:

  1. Проверьте срок действия OAuth токена (действителен 1 год)
  2. Получите новый токен по ссылке
  3. Убедитесь, что токен правильно передан в клиент
// Проверка токена
if token == "" {
    log.Fatal("OAuth token is required")
}

Ошибка доступа к каталогу

Проблема: Permission denied for folder

Решение:

  1. Убедитесь, что у вас есть права на каталог в Yandex Cloud
  2. Проверьте правильность folder_id
  3. Назначьте роль ai.languageModels.user вашему аккаунту
yc resource-manager folder add-access-binding <folder-id> \
  --role ai.languageModels.user \
  --subject userAccount:<user-id>

Превышение лимита токенов

Проблема: Maximum token limit exceeded

Решение:

  1. Сократите длину промпта или истории диалога
  2. Используйте параметр MaxTokens для ограничения ответа
  3. Разбейте большой текст на части
options := &yandexgpt.CompletionOptions{
    MaxTokens: 1000, // Ограничение длины ответа
}

Медленные ответы

Проблема: Долгое время ответа API

Решение:

  1. Используйте YandexGPT Lite для простых задач
  2. Оптимизируйте длину промптов
  3. Рассмотрите кэширование частых запросов
  4. Используйте конкурентность для пакетной обработки

Низкое качество ответов

Проблема: Ответы не соответствуют ожиданиям

Решение:

  1. Улучшите формулировку промпта (добавьте примеры, контекст)
  2. Используйте YandexGPT вместо Lite для сложных задач
  3. Настройте температуру (понизьте для точности, повысьте для креативности)
  4. Добавьте системное сообщение с инструкциями

FAQ

Q: Нужен ли мне платный аккаунт Yandex Cloud?

A: Да, для использования YandexGPT API необходим аккаунт Yandex Cloud с привязанной платежной информацией. Доступен пробный период с бесплатными грантами.

Q: Какие лимиты на использование API?

A: Лимиты зависят от вашего тарифа. По умолчанию:

  • 200 запросов в минуту
  • 32K токенов контекста
  • Ограничения по количеству токенов в месяц согласно тарифу

Q: Поддерживается ли потоковая передача (streaming)?

A: В текущей версии SDK потоковая передача находится в разработке. Следите за обновлениями в CHANGELOG.md.

Q: Можно ли использовать SDK в production?

A: Да, SDK готов для использования в production. Рекомендуется:

  • Реализовать обработку ошибок и retry логику
  • Настроить мониторинг и логирование
  • Использовать кэширование для оптимизации
  • Следить за расходом токенов

Технические вопросы

Q: Как хранить OAuth токен безопасно?

A: Используйте переменные окружения или секретные хранилища:

// Из переменных окружения
token := os.Getenv("YANDEX_GPT_OAUTH_TOKEN")

// Из файла конфигурации (не коммитить в git!)
// Или используйте vault-системы (HashiCorp Vault, AWS Secrets Manager)

Q: Как отслеживать использование токенов?

A: Проверяйте поле Usage в ответе:

response, err := client.GenerateText(prompt, models.YandexGPT, nil)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Input tokens: %d\n", response.Result.Usage.InputTextTokens)
fmt.Printf("Output tokens: %d\n", response.Result.Usage.CompletionTokens)
fmt.Printf("Total tokens: %d\n", response.Result.Usage.TotalTokens)

Q: Можно ли использовать несколько моделей одновременно?

A: Да, просто указывайте нужную модель в каждом запросе:

// Быстрый ответ
quickResponse, _ := client.GenerateText(prompt, models.YandexGPTLite, nil)

// Детальный анализ
detailedResponse, _ := client.GenerateText(prompt, models.YandexGPT, nil)

Q: Как обрабатывать rate limiting?

A: Реализуйте exponential backoff и проверяйте заголовки ответа:

func handleRateLimit(err error) bool {
    var apiErr *yandexgpt.APIError
    if errors.As(err, &apiErr) {
        if apiErr.StatusCode == 429 { // Too Many Requests
            return true
        }
    }
    return false
}

Производительность

  • YandexGPT Lite быстрее в 2-3 раза
  • Ограничивайте историю диалога 10-15 сообщениями
  • Обрабатывайте независимые запросы конкурентно
  • Кэшируйте частые запросы

Мониторинг производительности

type MetricsCollector struct {
    totalRequests   int64
    totalTokens     int64
    totalDuration   time.Duration
    mu              sync.Mutex
}

func (mc *MetricsCollector) TrackRequest(duration time.Duration, tokens int) {
    mc.mu.Lock()
    defer mc.mu.Unlock()
    
    mc.totalRequests++
    mc.totalTokens += int64(tokens)
    mc.totalDuration += duration
}

func (mc *MetricsCollector) GetStats() (avgDuration time.Duration, avgTokens float64) {
    mc.mu.Lock()
    defer mc.mu.Unlock()
    
    if mc.totalRequests == 0 {
        return 0, 0
    }
    
    avgDuration = mc.totalDuration / time.Duration(mc.totalRequests)
    avgTokens = float64(mc.totalTokens) / float64(mc.totalRequests)
    return
}

Оценка стоимости

Рассчитывайте стоимость использования:

func EstimateCost(inputTokens, outputTokens int, model string) float64 {
    // Примерные цены (проверяйте актуальные на сайте Yandex Cloud)
    var pricePerMillion float64
    
    switch model {
    case "yandexgpt-lite":
        pricePerMillion = 0.4 // $0.4 за 1M токенов
    case "yandexgpt":
        pricePerMillion = 1.2 // $1.2 за 1M токенов
    default:
        pricePerMillion = 1.2
    }
    
    totalTokens := float64(inputTokens + outputTokens)
    return (totalTokens / 1_000_000) * pricePerMillion
}

Безопасность

  • Храните токены в переменных окружения или секретных хранилищах
  • Регулярно обновляйте OAuth токены
  • Проверяйте пользовательский ввод перед отправкой в API
  • Не логируйте токены

Пример безопасной конфигурации

type SecureConfig struct {
    OAuthToken string
    FolderID   string
}

func LoadSecureConfig() (*SecureConfig, error) {
    token := os.Getenv("YANDEX_GPT_OAUTH_TOKEN")
    folderID := os.Getenv("YANDEX_GPT_FOLDER_ID")
    
    if token == "" || folderID == "" {
        return nil, errors.New("missing required environment variables")
    }
    
    // Валидация формата
    if len(token) < 20 {
        return nil, errors.New("invalid token format")
    }
    
    return &SecureConfig{
        OAuthToken: token,
        FolderID:   folderID,
    }, nil
}

Фильтрация контента

func SanitizeInput(input string) string {
    // Удаление потенциально опасных символов
    input = strings.TrimSpace(input)
    
    // Ограничение длины
    maxLength := 10000
    if len(input) > maxLength {
        input = input[:maxLength]
    }
    
    return input
}

Тестирование

Запуск тестов:

go test ./...

Запуск тестов с покрытием:

go test -cover ./...

Документация


Интеграция с фреймворками

Gin Web Framework

package main

import (
    "github.com/gin-gonic/gin"
    "github.com/tigusigalpa/yandexgpt-go/v2"
    "github.com/tigusigalpa/yandexgpt-go/v2/models"
)

func main() {
    client, _ := yandexgpt.NewClient(
        os.Getenv("YANDEX_GPT_OAUTH_TOKEN"),
        os.Getenv("YANDEX_GPT_FOLDER_ID"),
    )
    
    r := gin.Default()
    
    r.POST("/api/chat", func(c *gin.Context) {
        var req struct {
            Message string `json:"message"`
        }
        
        if err := c.BindJSON(&req); err != nil {
            c.JSON(400, gin.H{"error": err.Error()})
            return
        }
        
        response, err := client.GenerateText(req.Message, models.YandexGPT, nil)
        if err != nil {
            c.JSON(500, gin.H{"error": err.Error()})
            return
        }
        
        c.JSON(200, gin.H{
            "response": response.Result.Alternatives[0].Message.Text,
        })
    })
    
    r.Run(":8080")
}

Echo Framework

package main

import (
    "github.com/labstack/echo/v4"
    "github.com/tigusigalpa/yandexgpt-go/v2"
)

func main() {
    client, _ := yandexgpt.NewClient(
        os.Getenv("YANDEX_GPT_OAUTH_TOKEN"),
        os.Getenv("YANDEX_GPT_FOLDER_ID"),
    )
    
    e := echo.New()
    
    e.POST("/generate", func(c echo.Context) error {
        prompt := c.FormValue("prompt")
        
        response, err := client.GenerateText(prompt, models.YandexGPTLite, nil)
        if err != nil {
            return c.JSON(500, map[string]string{"error": err.Error()})
        }
        
        return c.JSON(200, map[string]string{
            "text": response.Result.Alternatives[0].Message.Text,
        })
    })
    
    e.Start(":8080")
}

gRPC сервис

type AIService struct {
    client *yandexgpt.Client
}

func (s *AIService) Generate(ctx context.Context, req *pb.GenerateRequest) (*pb.GenerateResponse, error) {
    response, err := s.client.GenerateText(
        req.Prompt,
        models.YandexGPT,
        &yandexgpt.CompletionOptions{
            Temperature: float64(req.Temperature),
            MaxTokens:   int(req.MaxTokens),
        },
    )
    if err != nil {
        return nil, err
    }
    
    return &pb.GenerateResponse{
        Text: response.Result.Alternatives[0].Message.Text,
        TokensUsed: int32(response.Result.Usage.TotalTokens),
    }, nil
}

Мониторинг и логирование

Интеграция с Prometheus

import (
    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promauto"
)

var (
    requestsTotal = promauto.NewCounterVec(
        prometheus.CounterOpts{
            Name: "yandexgpt_requests_total",
            Help: "Total number of YandexGPT requests",
        },
        []string{"model", "status"},
    )
    
    requestDuration = promauto.NewHistogramVec(
        prometheus.HistogramOpts{
            Name: "yandexgpt_request_duration_seconds",
            Help: "YandexGPT request duration",
        },
        []string{"model"},
    )
    
    tokensUsed = promauto.NewCounterVec(
        prometheus.CounterOpts{
            Name: "yandexgpt_tokens_used_total",
            Help: "Total tokens used",
        },
        []string{"model", "type"},
    )
)

func GenerateWithMetrics(client *yandexgpt.Client, prompt string, model string) (string, error) {
    start := time.Now()
    
    response, err := client.GenerateText(prompt, model, nil)
    
    duration := time.Since(start).Seconds()
    requestDuration.WithLabelValues(model).Observe(duration)
    
    if err != nil {
        requestsTotal.WithLabelValues(model, "error").Inc()
        return "", err
    }
    
    requestsTotal.WithLabelValues(model, "success").Inc()
    tokensUsed.WithLabelValues(model, "input").Add(float64(response.Result.Usage.InputTextTokens))
    tokensUsed.WithLabelValues(model, "output").Add(float64(response.Result.Usage.CompletionTokens))
    
    return response.Result.Alternatives[0].Message.Text, nil
}

Структурированное логирование

import "go.uber.org/zap"

type LoggingClient struct {
    client *yandexgpt.Client
    logger *zap.Logger
}

func (lc *LoggingClient) GenerateText(prompt string, model string) (string, error) {
    lc.logger.Info("generating text",
        zap.String("model", model),
        zap.Int("prompt_length", len(prompt)),
    )
    
    start := time.Now()
    response, err := lc.client.GenerateText(prompt, model, nil)
    duration := time.Since(start)
    
    if err != nil {
        lc.logger.Error("generation failed",
            zap.Error(err),
            zap.Duration("duration", duration),
        )
        return "", err
    }
    
    lc.logger.Info("generation completed",
        zap.Duration("duration", duration),
        zap.Int("tokens_used", response.Result.Usage.TotalTokens),
        zap.Int("response_length", len(response.Result.Alternatives[0].Message.Text)),
    )
    
    return response.Result.Alternatives[0].Message.Text, nil
}

Roadmap

Реализовано:

  • YandexGPT, YandexGPT Lite, AliceAI LLM
  • YandexART
  • Режим рассуждений (Chain of Thought)
  • Автоматическое управление токенами

В работе:

  • Потоковая передача ответов (Streaming)
  • Function Calling

Планируется:

  • Мультимодальность (изображения в промптах)
  • Асинхронные операции
  • Эмбеддинги
  • Интеграция с векторными БД

Вклад в проект

Баги, идеи, PR — всё принимается. Подробности в CONTRIBUTING.md.


Лицензия

MIT — см. LICENSE.


Ссылки

Документация Yandex Cloud:

Сообщество:

Связанные проекты:


Changelog

Все изменения в CHANGELOG.md.


Автор

Igor Sazonov

About

Мощный SDK на Golang для API YandexGPT с поддержкой генерации текста, диалогов и генерации изображений YandexART. Включает автоматическое управление токенами IAM, все модели YandexGPT (облегченная, стандартная, Alice AI), настраиваемые параметры автодополнения и комплексную обработку ошибок. Чистый, идиоматический код на Go

Topics

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages