Files
GenAudioBookInfo/wiki/OpenRouter.md
Dmitriy Fofanov 41fb62f62e Добавлены страницы вики для GenAudioBookInfo: Home, Installation, Makefile, OpenRouter, Output Structure, TorrAPI и Sidebar.
Создана структура документации, описывающая функциональность, установку, использование CLI, архитектуру и интеграции с TorrAPI и OpenRouter.
Добавлены примеры конфигурации и метаданных, а также описание структуры выходных данных.
2026-02-23 13:19:39 +03:00

138 lines
5.5 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 (LLM интеграция)
GenAudioBookInfo поддерживает опциональную нормализацию метаданных через LLM с помощью [OpenRouter](https://openrouter.ai/) — унифицированного API-шлюза к сотням AI-моделей.
---
## Зачем нужно LLM
Теги в аудиофайлах и имена папок часто содержат:
- Инициалы вместо полного имени: `Акунин Б.``Акунин Борис`
- Неправильный порядок: `Борис Акунин``Акунин Борис`
- Лишние символы, транслитерацию, опечатки
- Номера серий и части в названии
LLM нормализует автора в формат `Фамилия Имя` и очищает название книги.
---
## Настройка
### 1. Получить API ключ
Зарегистрируйтесь на [openrouter.ai](https://openrouter.ai/) и создайте API ключ в личном кабинете.
### 2. Добавить в `config.yaml`
```yaml
openrouter:
api_key: sk-or-v1-xxxxxxxxxxxxxxxxxxxxxxxxxxxx
model: openai/gpt-4o-mini
```
### Или через переменную окружения
```bash
export OPENROUTER_API_KEY=sk-or-v1-xxxx
./genaudiobookinfo
```
Переменная `OPENROUTER_API_KEY` проверяется если `api_key` в конфиге пуст.
---
## Настройки в `config.yaml`
```yaml
openrouter:
api_key: sk-or-v1-xxxx # API ключ (или env OPENROUTER_API_KEY)
base_url: https://openrouter.ai/api/v1
timeout: 30s # Таймаут HTTP запроса
model: openai/gpt-4o-mini # Идентификатор модели
max_retries: 3 # Ретраи при ошибках API
retry_backoff: 2s # Начальная задержка backoff
retry_backoff_max: 30s # Максимальная задержка backoff
prompt: | # Системный промпт
Ты эксперт по русскоязычным аудиокнигам...
```
---
## Промпт
Промпт определяет, как LLM должна обработать метаданные. Требования к промпту:
1. Отвечать **только JSON** без дополнительного текста.
2. Формат ответа: `{"author": "Фамилия Имя", "title": "Название"}`.
3. Автор в формате `Фамилия Имя` (не инициалы).
### Пример промпта
```yaml
prompt: |
Ты эксперт по русскоязычным аудиокнигам.
Тебе дадут сырые данные об аудиокниге (автор и название).
Твоя задача — нормализовать их:
1. Автор: формат "Фамилия Имя" (полное имя, без инициалов)
2. Название: убрать номера частей, лишние скобки, год
Верни ответ строго в JSON формате:
{"author": "Фамилия Имя", "title": "Чистое название"}
Только JSON, никакого лишнего текста.
```
---
## Выбор модели
OpenRouter предоставляет доступ к сотням моделей.
Формат: `provider/model-name`.
Рекомендуемые модели для нормализации текста:
| Модель | Стоимость | Качество |
|---|---|---|
| `openai/gpt-4o-mini` | низкая | хорошее |
| `openai/gpt-4o` | средняя | отличное |
| `anthropic/claude-3-haiku` | низкая | хорошее |
| `google/gemini-flash-1.5` | очень низкая | хорошее |
| `meta-llama/llama-3.1-8b-instruct:free` | бесплатно | среднее |
Полный список: [openrouter.ai/models](https://openrouter.ai/models)
---
## Поведение при ошибках
| Ситуация | Действие |
|---|---|
| API ключ не задан | LLM выключен, книга обрабатывается с исходными тегами |
| Ошибка HTTP | Ретрай до `max_retries` раз с backoff |
| Невалидный JSON в ответе | WARN в лог, используются исходные теги |
| Пустые поля в ответе | LLM результат игнорируется, используются исходные теги |
| Таймаут запроса | WARN в лог, используются исходные теги |
LLM-ошибки **не прерывают** обработку книги — конвейер продолжается с оригинальными данными.
---
## Архитектура интеграции
```
usecase/scan_audiobooks.go
▼ (если llmClient != nil)
domain.LLMClient.NormalizeMetadata(rawAuthor, rawTitle)
infrastructure/openrouter_client.go
OpenRouterClient.NormalizeMetadata()
├── HTTP POST /chat/completions
│ Authorization: Bearer <api_key>
│ {"model": "...", "messages": [...]}
└── разбор JSON {"author": "...", "title": "..."}
```
`LLMClient` — интерфейс в `domain/llm.go`. Легко заменить на любой другой LLM провайдер.