Добавлены страницы вики для GenAudioBookInfo: Home, Installation, Makefile, OpenRouter, Output Structure, TorrAPI и Sidebar.
Создана структура документации, описывающая функциональность, установку, использование CLI, архитектуру и интеграции с TorrAPI и OpenRouter. Добавлены примеры конфигурации и метаданных, а также описание структуры выходных данных.
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
# 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 провайдер.
|
||||
Reference in New Issue
Block a user