Files
GenAudioBookInfo/docs/OPENROUTER.md
Dmitriy Fofanov 402ce7f4f1 Функция: реализованы консольный логгер и презентер для обработки аудиокниг
- Добавлен ConsoleLogger для подробного логирования этапов обработки аудиокниг в консоли.

- Введен ConsolePresenter для форматированного вывода результатов сканирования в консоль.

- Создан ProcessAudioBooksUseCase для обработки полного конвейера обработки аудиокниг, включая сканирование папок, извлечение метаданных, поиск торрентов и запись результатов.

- Реализована проверка LLM для улучшения метаданных.

- Добавлена ​​обработка ошибок и логирование на всех этапах обработки.
2026-02-20 00:35:43 +03:00

336 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# OpenRouter Integration
Модуль интеграции с [OpenRouter API](https://openrouter.ai/) для использования различных LLM моделей в проекте GenAudioBookInfo.
## Описание
OpenRouter предоставляет унифицированный API для доступа к различным языковым моделям (GPT-4, Claude, LLaMA и др.) через единый интерфейс, совместимый с OpenAI API.
## Архитектура
Модуль реализован в соответствии с Clean Architecture:
- **Domain Layer** (`internal/domain/`):
- `ports.go` - интерфейс `LLMClient`
- `llm.go` - доменные структуры `LLMRequest`, `LLMResponse`, `LLMMessage`
- **Infrastructure Layer** (`internal/infrastructure/`):
- `openrouter_client.go` - реализация HTTP клиента для OpenRouter API
## Конфигурация
Добавьте настройки в `config.yaml`:
```yaml
openrouter:
api_key: "sk-or-v1-..." # Ваш API ключ с https://openrouter.ai/keys
base_url: "https://openrouter.ai/api/v1" # Базовый URL (по умолчанию)
timeout: 60s # Таймаут запросов
model: "openai/gpt-3.5-turbo" # Модель по умолчанию
prompt: | # System prompt для валидации метаданных (опционально)
Ты — эксперт по метаданным аудиокниг.
Проверяй формат автора (Фамилия Имя) и чистоту названий.
```
### Получение API ключа
1. Зарегистрируйтесь на [openrouter.ai](https://openrouter.ai/)
2. Перейдите в раздел [Keys](https://openrouter.ai/keys)
3. Создайте новый API ключ
4. Добавьте ключ в `config.yaml` или переменную окружения `OPENROUTER_API_KEY`
## Использование
### Базовый пример
```go
package main
import (
"context"
"fmt"
"time"
"github.com/fofanov/genaudiobookinfo/internal/domain"
"github.com/fofanov/genaudiobookinfo/internal/infrastructure"
)
func main() {
// Создание клиента
client := infrastructure.NewOpenRouterClient(infrastructure.OpenRouterConfig{
APIKey: "sk-or-v1-...",
BaseURL: "https://openrouter.ai/api/v1",
Timeout: 60 * time.Second,
Model: "openai/gpt-3.5-turbo",
})
// Создание запроса
req := &domain.LLMRequest{
Model: "openai/gpt-3.5-turbo",
Messages: []domain.LLMMessage{
{
Role: "system",
Content: "Ты — полезный ассистент.",
},
{
Role: "user",
Content: "Привет! Как дела?",
},
},
Temperature: 0.7,
MaxTokens: 100,
}
// Выполнение запроса
ctx := context.Background()
resp, err := client.GenerateCompletion(ctx, req)
if err != nil {
panic(err)
}
// Получение ответа
if len(resp.Choices) > 0 {
fmt.Println(resp.Choices[0].Message.Content)
fmt.Printf("Использовано токенов: %d\n", resp.Usage.TotalTokens)
}
}
```
### Параметры запроса
#### LLMRequest
| Поле | Тип | Описание |
|------|-----|----------|
| `Model` | string | Идентификатор модели (например, `openai/gpt-4`) |
| `Messages` | []LLMMessage | История диалога |
| `Temperature` | float64 | Случайность генерации (0.0 - 2.0) |
| `MaxTokens` | int | Максимум токенов в ответе |
| `TopP` | float64 | Nucleus sampling параметр |
| `FrequencyPenalty` | float64 | Штраф за повторяющиеся токены |
| `PresencePenalty` | float64 | Штраф за уже встречавшиеся токены |
#### LLMMessage
| Поле | Тип | Описание |
|------|-----|----------|
| `Role` | string | Роль: `system`, `user`, или `assistant` |
| `Content` | string | Текст сообщения |
### Доступные модели
OpenRouter поддерживает множество моделей. Популярные варианты:
- **OpenAI**: `openai/gpt-4`, `openai/gpt-3.5-turbo`
- **Anthropic**: `anthropic/claude-3-opus`, `anthropic/claude-3-haiku`
- **Google**: `google/gemini-pro`
- **Meta**: `meta-llama/llama-3-70b-instruct`
- **Mistral**: `mistralai/mistral-7b-instruct`
Полный список: [openrouter.ai/docs#models](https://openrouter.ai/docs#models)
### Примеры использования
#### Анализ метаданных аудиокниги
```go
req := &domain.LLMRequest{
Model: "openai/gpt-4",
Messages: []domain.LLMMessage{
{
Role: "system",
Content: "Ты — эксперт по метаданным аудиокниг.",
},
{
Role: "user",
Content: "Нормализуй автора: Иванов Петр Сергеевич → формат 'Фамилия Имя'",
},
},
Temperature: 0.3,
MaxTokens: 50,
}
```
#### Генерация описания
```go
req := &domain.LLMRequest{
Model: "anthropic/claude-3-haiku",
Messages: []domain.LLMMessage{
{
Role: "system",
Content: "Создавай краткие описания книг на русском языке.",
},
{
Role: "user",
Content: fmt.Sprintf("Создай описание для: %s - %s", author, title),
},
},
Temperature: 0.7,
MaxTokens: 200,
}
```
#### Валидация метаданных
Модуль поддерживает автоматическую валидацию метаданных через метод `ValidateMetadata`:
```go
// Создание клиента с промптом валидации
client := infrastructure.NewOpenRouterClient(infrastructure.OpenRouterConfig{
APIKey: "sk-or-v1-...",
Model: "openai/gpt-3.5-turbo",
Prompt: validationPrompt, // см. config.yaml
})
// Валидация метаданных
result, err := client.ValidateMetadata(ctx, "Иванов Петр Сергеевич", "Путешествие. Книга 1")
if err != nil {
log.Fatal(err)
}
if result != nil {
if result.AuthorFixed {
fmt.Printf("Исправлен автор: %s\n", result.Author) // "Иванов Петр"
}
if result.TitleFixed {
fmt.Printf("Исправлено название: %s\n", result.Title) // "Путешествие"
}
fmt.Printf("Изменения: %s\n", result.Changes)
}
```
**Важно**: Валидация работает только если:
- Указан `api_key` в конфигурации
- Настроен `prompt` в конфигурации
Если `api_key` пустой, метод вернет `nil` и валидация не выполнится.
## Продвинутые возможности
### Контроль таймаутов
```go
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
resp, err := client.GenerateCompletion(ctx, req)
```
### Обработка ошибок
```go
resp, err := client.GenerateCompletion(ctx, req)
if err != nil {
if ctx.Err() == context.DeadlineExceeded {
fmt.Println("Таймаут запроса")
} else {
fmt.Printf("Ошибка API: %v\n", err)
}
return
}
if len(resp.Choices) == 0 {
fmt.Println("Пустой ответ от API")
return
}
```
### Настройка параметров генерации
```go
req := &domain.LLMRequest{
Model: "openai/gpt-3.5-turbo",
Messages: messages,
Temperature: 0.8, // Выше = более креативно
MaxTokens: 500, // Ограничение длины ответа
TopP: 0.9, // Nucleus sampling
FrequencyPenalty: 0.5, // Избегать повторов
PresencePenalty: 0.3, // Разнообразие тем
}
```
## Запуск примеров
В папке `examples/` находятся примеры использования:
### Базовое использование API
```bash
# Установите API ключ
export OPENROUTER_API_KEY="sk-or-v1-..."
# Запустите пример общего использования
go run examples/openrouter_example.go
```
### Валидация метаданных аудиокниг
```bash
# Запустите пример валидации метаданных
go run examples/validate_metadata_example.go
```
Этот пример демонстрирует:
- Исправление порядка "Имя Фамилия" → "Фамилия Имя"
- Удаление отчества из имени автора
- Очистку названий от номеров серий, томов, технических терминов
- Обработку различных вариантов некорректных метаданных
## Стоимость использования
OpenRouter работает по модели pay-as-you-go. Стоимость зависит от выбранной модели:
- GPT-3.5 Turbo: ~$0.002 / 1K токенов
- GPT-4: ~$0.03-0.06 / 1K токенов
- Claude 3 Haiku: ~$0.25 / 1M токенов
Следите за расходами на [openrouter.ai/activity](https://openrouter.ai/activity)
## Безопасность
⚠️ **Важно**: Никогда не коммитьте API ключи в репозиторий!
Используйте:
- Переменные окружения: `OPENROUTER_API_KEY`
- Файл `.env` (добавьте в `.gitignore`)
- Секреты CI/CD систем
## Лимиты и ограничения
- **Rate limiting**: OpenRouter имеет лимиты на количество запросов
- **Timeout**: Рекомендуется устанавливать таймаут 30-60 секунд
- **Max tokens**: Учитывайте лимиты контекста моделей (обычно 4K-128K токенов)
## Устранение неполадок
### Ошибка: "API key не указан"
Проверьте:
1. Ключ указан в `config.yaml`
2. Формат: `api_key: "sk-or-v1-..."`
3. Нет лишних пробелов или кавычек
### Ошибка: HTTP 401 Unauthorized
- Проверьте валидность API ключа на [openrouter.ai/keys](https://openrouter.ai/keys)
- Убедитесь, что ключ активен и не истёк
### Ошибка: HTTP 429 Too Many Requests
- Слишком много запросов, снизьте частоту
- Проверьте лимиты аккаунта
### Таймауты
- Увеличьте `timeout` в конфигурации
- Используйте более быстрые модели (например, `claude-3-haiku`)
- Уменьшите `max_tokens`
## Дополнительные ресурсы
- [OpenRouter Документация](https://openrouter.ai/docs)
- [Список моделей](https://openrouter.ai/docs#models)
- [Цены](https://openrouter.ai/docs#models)
- [API Reference](https://openrouter.ai/docs#api)