docs: Update docs for the correctness (#13)
This commit is contained in:
1 parent
8dba55272c
commit
51a783f93a
60 files changed
+2456
-380
No files matched your search
@@ -0,0 +1,6 @@
|
||||
---
|
||||
title: Руководства
|
||||
weight: 3
|
||||
---
|
||||
|
||||
Пошаговые инструкции и руководства по реализации функций в Quetza.
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
title: Интеграция разговорного ИИ
|
||||
weight: 4
|
||||
---
|
||||
|
||||
**Цель:** Интегрировать большие языковые модели (LLM), управляя контекстом и ограничениями тайм-аута Discord.
|
||||
|
||||
## 1. Стратегия управления контекстом
|
||||
|
||||
Разговоры требуют истории, чтобы быть связными.
|
||||
|
||||
- **Область видимости (Scoping):** `Map<GuildID, Map<UserID, Message[]>>`
|
||||
- **Ключ гильдии (Guild Key):** Предотвращает утечки между серверами.
|
||||
- **Ключ пользователя (User Key):** Предотвращает путаницу между пользователями в публичных каналах.
|
||||
- **Жизненный цикл:** Реализуйте "скользящее окно" (например, последние 50 сообщений) для предотвращения разрастания контекста.
|
||||
|
||||
## 2. Потоковая передача ответов
|
||||
|
||||
LLM работают медленно, а Discord требует быстрых ответов (тайм-аут 3 секунды).
|
||||
|
||||
{{% steps %}}
|
||||
|
||||
### Шаг 1: Отложенное взаимодействие (Defer Interaction)
|
||||
|
||||
Немедленно вызовите `interaction.deferReply()`. Это даст вам 15 минут.
|
||||
|
||||
### Шаг 2: Вызов LLM
|
||||
|
||||
Асинхронно вызовите ваш ИИ-сервис.
|
||||
|
||||
### Шаг 3: Редактирование ответа
|
||||
|
||||
Когда данные поступят, используйте `interaction.editReply(content)`.
|
||||
{{% /steps %}}
|
||||
|
||||
## 3. Пример реализации
|
||||
|
||||
```typescript
|
||||
// commands/chat.ts
|
||||
export async function execute(interaction, controller) {
|
||||
// 1. Отложить ответ
|
||||
await interaction.deferReply();
|
||||
|
||||
// 2. Обработка
|
||||
const history = controller.getHistory(interaction.guildId, interaction.user.id);
|
||||
const response = await aiService.generate(interaction.options.getString('prompt'), history);
|
||||
|
||||
// 3. Ответ
|
||||
await interaction.editReply(response);
|
||||
controller.updateHistory(interaction.guildId, interaction.user.id, response);
|
||||
}
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> **Затраты на API:**
|
||||
> API ИИ часто тарифицируются по токенам. Внедрите строгие лимиты запросов (rate limits) для пользователей в вашем Контроллере, чтобы предотвратить злоупотребления.
|
||||
@@ -0,0 +1,77 @@
|
||||
---
|
||||
title: Развертывание и эксплуатация
|
||||
weight: 2
|
||||
---
|
||||
|
||||
**Цель:** Настроить, развернуть и мониторить экземпляр бота Quetza.
|
||||
|
||||
## 1. Подготовка окружения
|
||||
|
||||
Quetza полагается на переменные окружения для конфигурации. **Никогда** не сохраняйте их в систему контроля версий.
|
||||
|
||||
| Переменная | Описание | Обязательно |
|
||||
| :--- | :--- | :--- |
|
||||
| `DISCORD_TOKEN` | Токен бота из Discord Developer Portal | **Да** |
|
||||
| `CLIENT_ID` | ID приложения для регистрации slash-команд | **Да** |
|
||||
| `LLAMA_API_KEY` | Требуется при использовании модуля ИИ | Нет |
|
||||
|
||||
## 2. Стратегии развертывания
|
||||
|
||||
{{< tabs >}}
|
||||
{{< tab name="Docker (Рекомендуется)" >}}
|
||||
**Docker** обеспечивает стабильное окружение выполнения.
|
||||
|
||||
1. **Сборка** образа:
|
||||
|
||||
```bash
|
||||
docker build -t quetza-bot .
|
||||
```
|
||||
|
||||
2. **Запуск** контейнера:
|
||||
```bash
|
||||
docker run -d \
|
||||
--env-file .env \
|
||||
--name quetza \
|
||||
quetza-bot
|
||||
```
|
||||
{{< /tab >}}
|
||||
{{< tab name="Из исходников (Source)" >}}
|
||||
Развертывание **из исходников** полезно для разработки.
|
||||
|
||||
1. **Установка** зависимостей:
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
|
||||
2. **Сборка** проекта:
|
||||
|
||||
```bash
|
||||
pnpm build
|
||||
```
|
||||
|
||||
3. **Запуск** бота:
|
||||
```bash
|
||||
pnpm start
|
||||
```
|
||||
{{< /tab >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
## 3. Операционный мониторинг
|
||||
|
||||
После запуска используйте следующие механизмы для проверки работоспособности:
|
||||
|
||||
- **Логи:** Проверьте стандартный вывод (логи Docker) на наличие ошибок инициализации.
|
||||
- **Команда `/ping`:** Проверяет задержку сети и отзывчивость API.
|
||||
- **Команда `/modules`:** Перечисляет все загруженные модули, чтобы подтвердить доступность функций.
|
||||
|
||||
> [!WARNING]
|
||||
> **Ограничение масштабирования:**
|
||||
> Quetza следует модели "один экземпляр на один токен". Не запускайте несколько экземпляров с одним и тем же токеном, так как это вызовет конфликты WebSocket.
|
||||
|
||||
---
|
||||
|
||||
**См. также:**
|
||||
|
||||
- [Документация Docker](https://docs.docker.com/)
|
||||
- [Discord Developer Portal](https://discord.com/developers/applications)
|
||||
@@ -0,0 +1,105 @@
|
||||
---
|
||||
title: Процесс разработки модуля
|
||||
weight: 1
|
||||
---
|
||||
|
||||
**Цель:** Создать новую функцию для бота Quetza путем реализации самодостаточного модуля.
|
||||
|
||||
## 1. Фаза концептуализации
|
||||
|
||||
Перед написанием кода определите архитектуру модуля:
|
||||
|
||||
- **Простая команда:** Требуется только папка `commands/` (например, служебные команды).
|
||||
- **Реактивная логика:** Нужна папка `events/` для прослушивания жизненного цикла Discord (например, приветственные сообщения).
|
||||
- **Функция с состоянием:** Требуется **Контроллер** (Controller) для управления состоянием на разных серверах (например, музыкальный плеер).
|
||||
|
||||
## 2. Создание структуры
|
||||
|
||||
Создайте структуру директорий модуля. Наличие этих файлов запускает автоматическое обнаружение.
|
||||
|
||||
{{< filetree/container >}}
|
||||
{{< filetree/folder name="src" state="open" >}}
|
||||
{{< filetree/folder name="modules" state="open" >}}
|
||||
{{< filetree/folder name="my-feature" state="open" >}}
|
||||
{{< filetree/file name="module.ts" >}}
|
||||
{{< filetree/folder name="commands" >}} {{< /filetree/folder >}}
|
||||
{{< filetree/folder name="events" >}} {{< /filetree/folder >}}
|
||||
{{< filetree/folder name="lib" >}} {{< /filetree/folder >}}
|
||||
{{< /filetree/folder >}}
|
||||
{{< /filetree/folder >}}
|
||||
{{< /filetree/folder >}}
|
||||
{{< /filetree/container >}}
|
||||
|
||||
## 3. Шаги реализации
|
||||
|
||||
{{% steps %}}
|
||||
|
||||
### Шаг 1: Создание манифеста
|
||||
|
||||
Создайте `module.ts` для объявления модуля.
|
||||
|
||||
```typescript
|
||||
// src/modules/my-feature/module.ts
|
||||
export const name = 'my-feature';
|
||||
export const description = 'Добавляет крутые возможности';
|
||||
// Опционально: export const controller = new MyFeatureController();
|
||||
```
|
||||
|
||||
### Шаг 2: Реализация команд
|
||||
|
||||
Создайте файлы команд в папке `commands/`. Каждый файл экспортирует данные и функцию-исполнитель (executor).
|
||||
|
||||
```typescript
|
||||
// src/modules/my-feature/commands/ping.ts
|
||||
import { SlashCommandBuilder } from 'discord.js';
|
||||
|
||||
export const data = new SlashCommandBuilder().setName('ping').setDescription('Отвечает Pong!');
|
||||
|
||||
export async function execute(interaction) {
|
||||
await interaction.reply('Pong!');
|
||||
}
|
||||
```
|
||||
|
||||
### Шаг 3: Реализация событий (Опционально)
|
||||
|
||||
Создайте обработчики событий в `events/` для отслеживания состояния Discord.
|
||||
|
||||
```typescript
|
||||
// src/modules/my-feature/events/ready.ts
|
||||
import { Events } from 'discord.js';
|
||||
|
||||
export const name = Events.ClientReady;
|
||||
export const once = true;
|
||||
|
||||
export function execute(client) {
|
||||
console.log(`Ready! Logged in as ${client.user.tag}`);
|
||||
}
|
||||
```
|
||||
|
||||
### Шаг 4: Определение контроллера (Опционально)
|
||||
|
||||
Для логики, требующей сохранения состояния, реализуйте контроллер в папке `lib/` и экспортируйте его в `module.ts`.
|
||||
|
||||
### Шаг 5: Валидация
|
||||
|
||||
Перезапустите бота.
|
||||
|
||||
1. Проверьте логи на наличие "Loaded module: my-feature".
|
||||
2. Убедитесь, что команда `/ping` появилась в Discord.
|
||||
|
||||
{{% /steps %}}
|
||||
|
||||
## Шаблоны интеграции
|
||||
|
||||
| Паттерн | Сценарий использования | Компоненты |
|
||||
| :--- | :--- | :--- |
|
||||
| **Простая команда** | Утилиты без состояния (Ping, Бросок кубиков) | Только `commands/` |
|
||||
| **Сервис с состоянием** | Музыка, RPG, Экономика | `commands/` + `lib/Controller` |
|
||||
| **Событийно-ориентированный** | Автомодерация, Логирование | Только `events/` |
|
||||
| **Гибридный** | Сложные функции (ИИ-чат) | Все компоненты |
|
||||
|
||||
---
|
||||
|
||||
**См. также:**
|
||||
|
||||
- [Руководство Discord.js: Slash-команды](https://discordjs.guide/creating-your-bot/slash-commands.html)
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
title: Интерактивные голосовые функции
|
||||
weight: 3
|
||||
---
|
||||
|
||||
**Цель:** Реализовать сложные голосовые взаимодействия, которые учитывают границы серверов (гильдий) и управляют временными ресурсами.
|
||||
|
||||
## 1. Стратегия ограничения ресурсов
|
||||
|
||||
Голосовые функции **ОБЯЗАТЕЛЬНО** должны быть ограничены рамками Гильдии (Guild).
|
||||
|
||||
- **Паттерн:** Контроллер поддерживает `Map<GuildID, Player>`.
|
||||
- **Поведение:**
|
||||
- **Подключение (Join):** Создать Player для `Гильдии A`, если он еще не существует.
|
||||
- **Отключение (Leave):** Уничтожить Player и освободить соединения.
|
||||
- **Изоляция:** Команды в `Гильдии B` никогда не влияют на `Гильдию A`.
|
||||
|
||||
## 2. Оркестрация команд
|
||||
|
||||
Голосовые функции требуют набора команд, координируемых через Контроллер.
|
||||
|
||||
| Команда | Действие | Логика Контроллера |
|
||||
| :--- | :--- | :--- |
|
||||
| `/join` | Подключиться к каналу | `createPlayer(guildId, channelId)` |
|
||||
| `/play` | Добавить трек в очередь | `getPlayer(guildId).enqueue(track)` |
|
||||
| `/stop` | Отключиться | `destroyPlayer(guildId)` |
|
||||
|
||||
## 3. Сохранение состояния
|
||||
|
||||
Аудиосессии эфемерны.
|
||||
|
||||
- **Временное состояние:** Активный аудиопоток (Теряется при отключении).
|
||||
- **Постоянное состояние:** Очередь / Плейлист (Сохраняется в Контроллере до перезапуска).
|
||||
|
||||
> [!TIP]
|
||||
> **Устойчивость:** Разделяйте логику _Очереди_ и логику _Голосового соединения_. Это позволяет боту переподключаться без потери плейлиста пользователя.
|
||||
|
||||
## 4. Пример реализации
|
||||
|
||||
```typescript
|
||||
// lib/MusicController.ts
|
||||
class MusicController {
|
||||
private players = new Map<string, AudioPlayer>();
|
||||
|
||||
getPlayer(guildId: string): AudioPlayer {
|
||||
if (!this.players.has(guildId)) {
|
||||
this.players.set(guildId, new AudioPlayer());
|
||||
}
|
||||
return this.players.get(guildId);
|
||||
}
|
||||
|
||||
destroyPlayer(guildId: string) {
|
||||
this.players.get(guildId)?.disconnect();
|
||||
this.players.delete(guildId);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**См. также:**
|
||||
|
||||
- [Руководство Discord.js Voice](https://discordjs.guide/voice/)
|
||||
Reference in new issue
Block a user