This commit is contained in:
63
docs/README.md
Normal file
63
docs/README.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# 📚 Документация ChatBot
|
||||
|
||||
Добро пожаловать в документацию проекта **ChatBot** — интеллектуального Telegram-бота на базе AI (Ollama), написанного на .NET 9.
|
||||
|
||||
## 📖 Содержание
|
||||
|
||||
### 🎯 Основное
|
||||
- [Обзор проекта](./overview.md) - Общая информация о проекте
|
||||
- [Быстрый старт](./quickstart.md) - Запуск проекта за 5 минут
|
||||
- [Установка и настройка](./installation.md) - Подробная инструкция по установке
|
||||
- [Конфигурация](./configuration.md) - Настройка параметров бота
|
||||
|
||||
### 🏗️ Архитектура
|
||||
- [Архитектура проекта](./architecture/overview.md) - Общая архитектура
|
||||
- [Слои приложения](./architecture/layers.md) - Описание слоёв
|
||||
- [Модели данных](./architecture/data-models.md) - Структура данных
|
||||
- [Базы данных](./architecture/database.md) - Работа с PostgreSQL
|
||||
|
||||
### 💻 Разработка
|
||||
- [Структура проекта](./development/project-structure.md) - Организация кода
|
||||
- [Сервисы](./development/services.md) - Описание всех сервисов
|
||||
- [Telegram интеграция](./development/telegram-integration.md) - Работа с Telegram Bot API
|
||||
- [AI сервисы](./development/ai-services.md) - Интеграция с Ollama
|
||||
- [Dependency Injection](./development/dependency-injection.md) - Управление зависимостями
|
||||
|
||||
### 📝 API и интерфейсы
|
||||
- [Команды бота](./api/bot-commands.md) - Все доступные команды
|
||||
- [Интерфейсы сервисов](./api/service-interfaces.md) - Описание интерфейсов
|
||||
- [Health Checks](./api/health-checks.md) - Мониторинг здоровья
|
||||
|
||||
### 🧪 Тестирование
|
||||
- [Стратегия тестирования](./testing/strategy.md) - Подход к тестированию
|
||||
- [Unit тесты](./testing/unit-tests.md) - Модульное тестирование
|
||||
- [Integration тесты](./testing/integration-tests.md) - Интеграционное тестирование
|
||||
- [Покрытие кода](./testing/coverage.md) - Code coverage
|
||||
|
||||
### 🚀 Развертывание
|
||||
- [Docker развертывание](./deployment/docker.md) - Запуск в Docker
|
||||
- [CI/CD](./deployment/ci-cd.md) - Автоматизация сборки
|
||||
- [Мониторинг](./deployment/monitoring.md) - Логирование и мониторинг
|
||||
|
||||
### 🔧 Дополнительно
|
||||
- [FAQ](./faq.md) - Часто задаваемые вопросы
|
||||
- [Troubleshooting](./troubleshooting.md) - Решение проблем
|
||||
- [Contributing](./contributing.md) - Как внести вклад
|
||||
- [Changelog](./changelog.md) - История изменений
|
||||
|
||||
## 🔗 Быстрые ссылки
|
||||
|
||||
- [GitHub Repository](https://gitea.hsrv.site/mrleo1nid/ChatBot)
|
||||
- [Issues](https://gitea.hsrv.site/mrleo1nid/ChatBot/issues)
|
||||
- [Releases](https://gitea.hsrv.site/mrleo1nid/ChatBot/releases)
|
||||
|
||||
## 📞 Поддержка
|
||||
|
||||
Если у вас возникли вопросы или проблемы:
|
||||
1. Проверьте [FAQ](./faq.md)
|
||||
2. Изучите [Troubleshooting](./troubleshooting.md)
|
||||
3. Создайте [Issue](https://gitea.hsrv.site/mrleo1nid/ChatBot/issues)
|
||||
|
||||
## 📄 Лицензия
|
||||
|
||||
Проект распространяется под лицензией MIT. См. [LICENSE.txt](../LICENSE.txt) для подробностей.
|
||||
357
docs/api/bot-commands.md
Normal file
357
docs/api/bot-commands.md
Normal file
@@ -0,0 +1,357 @@
|
||||
# 🤖 Команды бота
|
||||
|
||||
Полное описание всех команд Telegram бота.
|
||||
|
||||
## 📋 Список команд
|
||||
|
||||
| Команда | Описание | Доступность |
|
||||
|---------|----------|-------------|
|
||||
| `/start` | Начать работу с ботом | Все пользователи |
|
||||
| `/help` | Показать справку | Все пользователи |
|
||||
| `/clear` | Очистить историю диалога | Все пользователи |
|
||||
| `/settings` | Показать текущие настройки | Все пользователи |
|
||||
| `/status` | Проверить статус бота | Все пользователи |
|
||||
|
||||
## 🔧 Детальное описание
|
||||
|
||||
### /start
|
||||
|
||||
**Описание:** Инициализация бота и приветствие пользователя.
|
||||
|
||||
**Использование:**
|
||||
```
|
||||
/start
|
||||
```
|
||||
|
||||
**Ответ:**
|
||||
```
|
||||
👋 Привет! Я готов к общению.
|
||||
|
||||
Просто напиши мне что-нибудь, и я отвечу.
|
||||
|
||||
Используй /help для списка команд.
|
||||
```
|
||||
|
||||
**Что происходит:**
|
||||
1. Создается новая сессия (если не существует)
|
||||
2. Загружается системный промпт
|
||||
3. Отправляется приветственное сообщение
|
||||
|
||||
**Реализация:**
|
||||
```csharp
|
||||
public class StartCommand : TelegramCommandBase
|
||||
{
|
||||
public override string Command => "start";
|
||||
public override string Description => "Начать работу с ботом";
|
||||
|
||||
public override async Task<ReplyInfo> ExecuteAsync(TelegramCommandContext context)
|
||||
{
|
||||
// Логика команды
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### /help
|
||||
|
||||
**Описание:** Показать список всех доступных команд.
|
||||
|
||||
**Использование:**
|
||||
```
|
||||
/help
|
||||
```
|
||||
|
||||
**Ответ:**
|
||||
```
|
||||
📖 Доступные команды:
|
||||
|
||||
/start - Начать работу с ботом
|
||||
/help - Показать эту справку
|
||||
/clear - Очистить историю диалога
|
||||
/settings - Показать текущие настройки
|
||||
/status - Проверить статус бота
|
||||
|
||||
💬 Просто напиши мне сообщение, и я отвечу!
|
||||
```
|
||||
|
||||
**Динамическая генерация:**
|
||||
Список команд генерируется автоматически через `CommandRegistry`:
|
||||
|
||||
```csharp
|
||||
var commands = _commandRegistry.GetAllCommands();
|
||||
foreach (var cmd in commands)
|
||||
{
|
||||
message += $"/{cmd.Command} - {cmd.Description}\n";
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### /clear
|
||||
|
||||
**Описание:** Очистить историю диалога с сохранением сессии.
|
||||
|
||||
**Использование:**
|
||||
```
|
||||
/clear
|
||||
```
|
||||
|
||||
**Ответ:**
|
||||
```
|
||||
🧹 История диалога очищена!
|
||||
|
||||
Можешь начать новый разговор.
|
||||
```
|
||||
|
||||
**Что происходит:**
|
||||
1. Вызывается `ChatService.ClearHistoryAsync(chatId)`
|
||||
2. Удаляются все сообщения из истории
|
||||
3. Сохраняется системный промпт
|
||||
4. Обновляется `LastUpdatedAt`
|
||||
|
||||
**Важно:**
|
||||
- Сессия не удаляется
|
||||
- Настройки модели сохраняются
|
||||
- История в БД обновляется
|
||||
|
||||
**Код:**
|
||||
```csharp
|
||||
public override async Task<ReplyInfo> ExecuteAsync(TelegramCommandContext context)
|
||||
{
|
||||
await _chatService.ClearHistoryAsync(context.ChatId);
|
||||
return new ReplyInfo { Text = "🧹 История диалога очищена!" };
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### /settings
|
||||
|
||||
**Описание:** Показать текущие настройки сессии.
|
||||
|
||||
**Использование:**
|
||||
```
|
||||
/settings
|
||||
```
|
||||
|
||||
**Ответ:**
|
||||
```
|
||||
⚙️ Текущие настройки:
|
||||
|
||||
🤖 Модель: gemma2:2b
|
||||
🌡️ Temperature: 0.9
|
||||
📝 Сообщений в истории: 5/30
|
||||
🗜️ Сжатие истории: Включено
|
||||
📊 Порог сжатия: 20 сообщений
|
||||
🎯 Цель сжатия: 10 сообщений
|
||||
```
|
||||
|
||||
**Информация:**
|
||||
- Используемая AI модель
|
||||
- Температура генерации
|
||||
- Количество сообщений в истории
|
||||
- Статус сжатия истории
|
||||
- Пороги компрессии
|
||||
|
||||
**Код:**
|
||||
```csharp
|
||||
var session = _chatService.GetSession(context.ChatId);
|
||||
if (session == null)
|
||||
return new ReplyInfo { Text = "Сессия не найдена" };
|
||||
|
||||
var info = $@"⚙️ Текущие настройки:
|
||||
🤖 Модель: {session.Model}
|
||||
📝 Сообщений: {session.GetMessageCount()}/{session.MaxHistoryLength}";
|
||||
|
||||
return new ReplyInfo { Text = info };
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### /status
|
||||
|
||||
**Описание:** Проверить статус бота и подключенных сервисов.
|
||||
|
||||
**Использование:**
|
||||
```
|
||||
/status
|
||||
```
|
||||
|
||||
**Ответ (все ОК):**
|
||||
```
|
||||
✅ Статус системы:
|
||||
|
||||
🤖 Telegram Bot: ✅ Работает
|
||||
🧠 Ollama AI: ✅ Подключен
|
||||
💾 База данных: ✅ Доступна
|
||||
|
||||
📊 Активных сессий: 5
|
||||
🕐 Время работы: 2ч 15м
|
||||
```
|
||||
|
||||
**Ответ (есть проблемы):**
|
||||
```
|
||||
⚠️ Статус системы:
|
||||
|
||||
🤖 Telegram Bot: ✅ Работает
|
||||
🧠 Ollama AI: ❌ Недоступен
|
||||
💾 База данных: ✅ Доступна
|
||||
|
||||
Обнаружены проблемы с подключением к Ollama.
|
||||
```
|
||||
|
||||
**Проверки:**
|
||||
1. **Telegram Bot** - Проверка `TelegramBotHealthCheck`
|
||||
2. **Ollama AI** - Проверка доступности API
|
||||
3. **Database** - Проверка подключения к PostgreSQL
|
||||
4. **Active Sessions** - Количество активных чатов
|
||||
5. **Uptime** - Время работы бота
|
||||
|
||||
**Health Checks:**
|
||||
```csharp
|
||||
var healthCheckService = _serviceProvider.GetRequiredService<HealthCheckService>();
|
||||
var result = await healthCheckService.CheckHealthAsync();
|
||||
|
||||
foreach (var entry in result.Entries)
|
||||
{
|
||||
var status = entry.Value.Status == HealthStatus.Healthy ? "✅" : "❌";
|
||||
message += $"{entry.Key}: {status}\n";
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Формат ответов
|
||||
|
||||
### ReplyInfo
|
||||
|
||||
Все команды возвращают `ReplyInfo`:
|
||||
|
||||
```csharp
|
||||
public class ReplyInfo
|
||||
{
|
||||
public string Text { get; set; } // Текст ответа
|
||||
public bool DisableNotification { get; set; } = false;
|
||||
public bool DisableWebPagePreview { get; set; } = false;
|
||||
}
|
||||
```
|
||||
|
||||
### Markdown форматирование
|
||||
|
||||
Поддерживаемые форматы:
|
||||
- `**bold**` - **жирный**
|
||||
- `*italic*` - *курсив*
|
||||
- `` `code` `` - `код`
|
||||
- Emoji - 🚀 ✅ ❌ ⚙️
|
||||
|
||||
## 🔄 Command Processing Flow
|
||||
|
||||
```
|
||||
User sends command
|
||||
↓
|
||||
TelegramBotService receives update
|
||||
↓
|
||||
TelegramMessageHandler validates
|
||||
↓
|
||||
TelegramCommandProcessor checks if command
|
||||
↓
|
||||
CommandRegistry finds handler
|
||||
↓
|
||||
Command.ExecuteAsync()
|
||||
↓
|
||||
Return ReplyInfo
|
||||
↓
|
||||
TelegramMessageSender sends response
|
||||
```
|
||||
|
||||
## 🛠️ Добавление новой команды
|
||||
|
||||
### 1. Создать класс команды
|
||||
|
||||
```csharp
|
||||
public class MyCommand : TelegramCommandBase
|
||||
{
|
||||
public override string Command => "mycommand";
|
||||
public override string Description => "Описание команды";
|
||||
|
||||
public override async Task<ReplyInfo> ExecuteAsync(TelegramCommandContext context)
|
||||
{
|
||||
// Ваша логика
|
||||
return new ReplyInfo
|
||||
{
|
||||
Text = "Ответ команды"
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Зарегистрировать в DI
|
||||
|
||||
В `Program.cs`:
|
||||
|
||||
```csharp
|
||||
builder.Services.AddScoped<ITelegramCommand, MyCommand>();
|
||||
```
|
||||
|
||||
### 3. Добавить в BotFather (опционально)
|
||||
|
||||
```
|
||||
/setcommands
|
||||
|
||||
start - Начать работу
|
||||
help - Справка
|
||||
mycommand - Описание
|
||||
```
|
||||
|
||||
## 🧪 Тестирование команд
|
||||
|
||||
```csharp
|
||||
[Fact]
|
||||
public async Task StartCommand_ShouldReturnWelcomeMessage()
|
||||
{
|
||||
// Arrange
|
||||
var command = new StartCommand();
|
||||
var context = new TelegramCommandContext
|
||||
{
|
||||
ChatId = 123,
|
||||
UserId = 456
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await command.ExecuteAsync(context);
|
||||
|
||||
// Assert
|
||||
result.Text.Should().Contain("Привет");
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 Статистика использования
|
||||
|
||||
Логирование команд:
|
||||
|
||||
```csharp
|
||||
_logger.LogInformation(
|
||||
"Command executed: {Command} by user {UserId} in chat {ChatId}",
|
||||
Command, context.UserId, context.ChatId
|
||||
);
|
||||
```
|
||||
|
||||
## 🔐 Безопасность
|
||||
|
||||
### Валидация контекста
|
||||
|
||||
```csharp
|
||||
if (context.ChatId <= 0)
|
||||
throw new ArgumentException("Invalid chat ID");
|
||||
```
|
||||
|
||||
### Rate Limiting (будущее)
|
||||
|
||||
Планируется добавить ограничение частоты команд.
|
||||
|
||||
## 📚 См. также
|
||||
|
||||
- [Telegram Integration](../development/telegram-integration.md)
|
||||
- [Сервисы](../development/services.md)
|
||||
- [Тестирование](../testing/unit-tests.md)
|
||||
369
docs/architecture/data-models.md
Normal file
369
docs/architecture/data-models.md
Normal file
@@ -0,0 +1,369 @@
|
||||
# 📊 Модели данных
|
||||
|
||||
Полное описание всех моделей и сущностей в ChatBot.
|
||||
|
||||
## 🗂️ Типы моделей
|
||||
|
||||
### 1. Domain Models (Доменные модели)
|
||||
- `ChatSession` - Основная модель сессии чата
|
||||
- `ChatMessage` - DTO для сообщений
|
||||
|
||||
### 2. Entity Models (Сущности БД)
|
||||
- `ChatSessionEntity` - Сущность сессии в БД
|
||||
- `ChatMessageEntity` - Сущность сообщения в БД
|
||||
|
||||
### 3. Configuration Models (Конфигурация)
|
||||
- `TelegramBotSettings`
|
||||
- `OllamaSettings`
|
||||
- `AISettings`
|
||||
- `DatabaseSettings`
|
||||
|
||||
## 📦 Domain Models
|
||||
|
||||
### ChatSession
|
||||
|
||||
Основная модель для работы с сессией чата.
|
||||
|
||||
```csharp
|
||||
public class ChatSession
|
||||
{
|
||||
public string SessionId { get; set; } // Уникальный ID
|
||||
public long ChatId { get; set; } // Telegram chat ID
|
||||
public string ChatType { get; set; } // Тип чата
|
||||
public string ChatTitle { get; set; } // Название
|
||||
public string Model { get; set; } // AI модель
|
||||
public DateTime CreatedAt { get; set; } // Создан
|
||||
public DateTime LastUpdatedAt { get; set; } // Обновлен
|
||||
public int MaxHistoryLength { get; set; } // Макс история
|
||||
}
|
||||
```
|
||||
|
||||
**Ключевые методы:**
|
||||
|
||||
#### Работа с сообщениями
|
||||
```csharp
|
||||
// Добавить сообщение (базовый)
|
||||
void AddMessage(ChatMessage message)
|
||||
|
||||
// Добавить с компрессией
|
||||
Task AddMessageWithCompressionAsync(ChatMessage message, int threshold, int target)
|
||||
|
||||
// Добавить user сообщение
|
||||
void AddUserMessage(string content, string username)
|
||||
Task AddUserMessageWithCompressionAsync(string content, string username, int threshold, int target)
|
||||
|
||||
// Добавить assistant сообщение
|
||||
void AddAssistantMessage(string content)
|
||||
Task AddAssistantMessageWithCompressionAsync(string content, int threshold, int target)
|
||||
|
||||
// Получить все сообщения
|
||||
List<ChatMessage> GetAllMessages()
|
||||
|
||||
// Количество сообщений
|
||||
int GetMessageCount()
|
||||
|
||||
// Очистить историю
|
||||
void ClearHistory()
|
||||
```
|
||||
|
||||
#### Управление компрессией
|
||||
```csharp
|
||||
void SetCompressionService(IHistoryCompressionService service)
|
||||
```
|
||||
|
||||
**Thread Safety:**
|
||||
Все операции с `_messageHistory` защищены `lock(_lock)`
|
||||
|
||||
**Управление историей:**
|
||||
- Автоматическое обрезание при превышении `MaxHistoryLength`
|
||||
- Сохранение system prompt при обрезке
|
||||
- Поддержка асинхронной компрессии
|
||||
|
||||
### ChatMessage (DTO)
|
||||
|
||||
```csharp
|
||||
public class ChatMessage
|
||||
{
|
||||
public ChatRole Role { get; set; } // user/assistant/system
|
||||
public string Content { get; set; } // Текст сообщения
|
||||
}
|
||||
```
|
||||
|
||||
**ChatRole enum:**
|
||||
```csharp
|
||||
public enum ChatRole
|
||||
{
|
||||
System, // Системный промпт
|
||||
User, // Сообщение пользователя
|
||||
Assistant // Ответ бота
|
||||
}
|
||||
```
|
||||
|
||||
## 💾 Entity Models
|
||||
|
||||
### ChatSessionEntity
|
||||
|
||||
Сущность для хранения в PostgreSQL.
|
||||
|
||||
```csharp
|
||||
public class ChatSessionEntity
|
||||
{
|
||||
public int Id { get; set; } // PK (auto-increment)
|
||||
public string SessionId { get; set; } // Unique, indexed
|
||||
public long ChatId { get; set; } // Indexed
|
||||
public string ChatType { get; set; } // Max 20 chars
|
||||
public string? ChatTitle { get; set; } // Max 200 chars
|
||||
public string Model { get; set; } // Max 100 chars
|
||||
public DateTime CreatedAt { get; set; } // Required
|
||||
public DateTime LastUpdatedAt { get; set; } // Required
|
||||
public List<ChatMessageEntity> Messages { get; set; } // Navigation property
|
||||
}
|
||||
```
|
||||
|
||||
**Индексы:**
|
||||
- `SessionId` - Unique index
|
||||
- `ChatId` - Index для быстрого поиска
|
||||
|
||||
**Constraints:**
|
||||
- `SessionId` - Required, MaxLength(50)
|
||||
- `ChatId` - Required
|
||||
- `ChatType` - Required, MaxLength(20)
|
||||
|
||||
**Relationships:**
|
||||
- One-to-Many с `ChatMessageEntity`
|
||||
- Cascade Delete - удаление сессии удаляет сообщения
|
||||
|
||||
### ChatMessageEntity
|
||||
|
||||
```csharp
|
||||
public class ChatMessageEntity
|
||||
{
|
||||
public int Id { get; set; } // PK
|
||||
public int SessionId { get; set; } // FK
|
||||
public string Content { get; set; } // Max 10000 chars
|
||||
public string Role { get; set; } // Max 20 chars
|
||||
public int MessageOrder { get; set; } // Порядок в диалоге
|
||||
public DateTime CreatedAt { get; set; } // Время создания
|
||||
|
||||
public ChatSessionEntity Session { get; set; } // Navigation property
|
||||
}
|
||||
```
|
||||
|
||||
**Индексы:**
|
||||
- `SessionId` - Index
|
||||
- `CreatedAt` - Index для сортировки
|
||||
- `(SessionId, MessageOrder)` - Composite index
|
||||
|
||||
**Constraints:**
|
||||
- `Content` - Required, MaxLength(10000)
|
||||
- `Role` - Required, MaxLength(20)
|
||||
|
||||
## ⚙️ Configuration Models
|
||||
|
||||
### TelegramBotSettings
|
||||
|
||||
```csharp
|
||||
public class TelegramBotSettings
|
||||
{
|
||||
public string BotToken { get; set; } = string.Empty;
|
||||
}
|
||||
```
|
||||
|
||||
**Validator:**
|
||||
```csharp
|
||||
RuleFor(x => x.BotToken)
|
||||
.NotEmpty()
|
||||
.MinimumLength(10);
|
||||
```
|
||||
|
||||
### OllamaSettings
|
||||
|
||||
```csharp
|
||||
public class OllamaSettings
|
||||
{
|
||||
public string Url { get; set; } = string.Empty;
|
||||
public string DefaultModel { get; set; } = string.Empty;
|
||||
}
|
||||
```
|
||||
|
||||
**Validator:**
|
||||
```csharp
|
||||
RuleFor(x => x.Url)
|
||||
.NotEmpty()
|
||||
.Must(BeValidUrl);
|
||||
|
||||
RuleFor(x => x.DefaultModel)
|
||||
.NotEmpty();
|
||||
```
|
||||
|
||||
### AISettings
|
||||
|
||||
```csharp
|
||||
public class AISettings
|
||||
{
|
||||
public double Temperature { get; set; } = 0.9;
|
||||
public string SystemPromptPath { get; set; } = "Prompts/system-prompt.txt";
|
||||
public int MaxRetryAttempts { get; set; } = 3;
|
||||
public int RetryDelayMs { get; set; } = 1000;
|
||||
public int RequestTimeoutSeconds { get; set; } = 180;
|
||||
|
||||
// Compression settings
|
||||
public bool EnableHistoryCompression { get; set; } = true;
|
||||
public int CompressionThreshold { get; set; } = 20;
|
||||
public int CompressionTarget { get; set; } = 10;
|
||||
public int MinMessageLengthForSummarization { get; set; } = 50;
|
||||
public int MaxSummarizedMessageLength { get; set; } = 200;
|
||||
|
||||
// Advanced
|
||||
public bool EnableExponentialBackoff { get; set; } = true;
|
||||
public int MaxRetryDelayMs { get; set; } = 30000;
|
||||
public int CompressionTimeoutSeconds { get; set; } = 30;
|
||||
public int StatusCheckTimeoutSeconds { get; set; } = 10;
|
||||
}
|
||||
```
|
||||
|
||||
**Validator:**
|
||||
```csharp
|
||||
RuleFor(x => x.Temperature)
|
||||
.GreaterThanOrEqualTo(0.0)
|
||||
.LessThanOrEqualTo(2.0);
|
||||
|
||||
RuleFor(x => x.MaxRetryAttempts)
|
||||
.GreaterThanOrEqualTo(1)
|
||||
.LessThanOrEqualTo(10);
|
||||
```
|
||||
|
||||
### DatabaseSettings
|
||||
|
||||
```csharp
|
||||
public class DatabaseSettings
|
||||
{
|
||||
public string ConnectionString { get; set; } = string.Empty;
|
||||
public bool EnableSensitiveDataLogging { get; set; } = false;
|
||||
public int CommandTimeout { get; set; } = 30;
|
||||
}
|
||||
```
|
||||
|
||||
**Validator:**
|
||||
```csharp
|
||||
RuleFor(x => x.ConnectionString)
|
||||
.NotEmpty();
|
||||
|
||||
RuleFor(x => x.CommandTimeout)
|
||||
.GreaterThanOrEqualTo(5)
|
||||
.LessThanOrEqualTo(300);
|
||||
```
|
||||
|
||||
## 🔄 Маппинг Entity ↔ Model
|
||||
|
||||
### Session Entity → Model
|
||||
|
||||
```csharp
|
||||
public ChatSession ToModel()
|
||||
{
|
||||
var session = new ChatSession
|
||||
{
|
||||
SessionId = this.SessionId,
|
||||
ChatId = this.ChatId,
|
||||
ChatType = this.ChatType,
|
||||
ChatTitle = this.ChatTitle ?? string.Empty,
|
||||
Model = this.Model,
|
||||
CreatedAt = this.CreatedAt,
|
||||
LastUpdatedAt = this.LastUpdatedAt
|
||||
};
|
||||
|
||||
// Восстановить сообщения
|
||||
foreach (var msg in Messages.OrderBy(m => m.MessageOrder))
|
||||
{
|
||||
session.AddMessage(new ChatMessage
|
||||
{
|
||||
Role = ParseRole(msg.Role),
|
||||
Content = msg.Content
|
||||
});
|
||||
}
|
||||
|
||||
return session;
|
||||
}
|
||||
```
|
||||
|
||||
### Session Model → Entity
|
||||
|
||||
```csharp
|
||||
public ChatSessionEntity ToEntity()
|
||||
{
|
||||
return new ChatSessionEntity
|
||||
{
|
||||
SessionId = this.SessionId,
|
||||
ChatId = this.ChatId,
|
||||
ChatType = this.ChatType,
|
||||
ChatTitle = this.ChatTitle,
|
||||
Model = this.Model,
|
||||
CreatedAt = this.CreatedAt,
|
||||
LastUpdatedAt = this.LastUpdatedAt,
|
||||
Messages = this.GetAllMessages()
|
||||
.Select((msg, index) => new ChatMessageEntity
|
||||
{
|
||||
Content = msg.Content,
|
||||
Role = msg.Role.ToString(),
|
||||
MessageOrder = index,
|
||||
CreatedAt = DateTime.UtcNow
|
||||
})
|
||||
.ToList()
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## 📐 Database Schema
|
||||
|
||||
```sql
|
||||
-- Таблица сессий
|
||||
CREATE TABLE chat_sessions (
|
||||
id SERIAL PRIMARY KEY,
|
||||
session_id VARCHAR(50) UNIQUE NOT NULL,
|
||||
chat_id BIGINT NOT NULL,
|
||||
chat_type VARCHAR(20) NOT NULL,
|
||||
chat_title VARCHAR(200),
|
||||
model VARCHAR(100),
|
||||
created_at TIMESTAMP NOT NULL,
|
||||
last_updated_at TIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_chat_sessions_session_id ON chat_sessions(session_id);
|
||||
CREATE INDEX idx_chat_sessions_chat_id ON chat_sessions(chat_id);
|
||||
|
||||
-- Таблица сообщений
|
||||
CREATE TABLE chat_messages (
|
||||
id SERIAL PRIMARY KEY,
|
||||
session_id INTEGER NOT NULL REFERENCES chat_sessions(id) ON DELETE CASCADE,
|
||||
content VARCHAR(10000) NOT NULL,
|
||||
role VARCHAR(20) NOT NULL,
|
||||
message_order INTEGER NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_chat_messages_session_id ON chat_messages(session_id);
|
||||
CREATE INDEX idx_chat_messages_created_at ON chat_messages(created_at);
|
||||
CREATE INDEX idx_chat_messages_session_order ON chat_messages(session_id, message_order);
|
||||
```
|
||||
|
||||
## 🎯 Жизненный цикл Session
|
||||
|
||||
```
|
||||
1. Создание (GetOrCreate)
|
||||
↓
|
||||
2. Добавление сообщений (AddMessage)
|
||||
↓
|
||||
3. Проверка длины истории
|
||||
↓
|
||||
4. Компрессия (если нужно)
|
||||
↓
|
||||
5. Сохранение в БД (SaveSessionAsync)
|
||||
↓
|
||||
6. Обновление LastUpdatedAt
|
||||
```
|
||||
|
||||
## 📚 См. также
|
||||
|
||||
- [Архитектура слоев](./layers.md)
|
||||
- [База данных](./database.md)
|
||||
- [Сервисы](../development/services.md)
|
||||
351
docs/architecture/database.md
Normal file
351
docs/architecture/database.md
Normal file
@@ -0,0 +1,351 @@
|
||||
# 🗄️ База данных
|
||||
|
||||
Описание работы с PostgreSQL в ChatBot.
|
||||
|
||||
## 📊 Схема базы данных
|
||||
|
||||
### Таблицы
|
||||
|
||||
#### chat_sessions
|
||||
|
||||
Хранит информацию о сессиях чатов.
|
||||
|
||||
| Колонка | Тип | Constraints | Описание |
|
||||
|---------|-----|-------------|----------|
|
||||
| id | SERIAL | PRIMARY KEY | Auto-increment ID |
|
||||
| session_id | VARCHAR(50) | UNIQUE, NOT NULL | Уникальный идентификатор |
|
||||
| chat_id | BIGINT | NOT NULL, INDEXED | Telegram chat ID |
|
||||
| chat_type | VARCHAR(20) | NOT NULL | Тип чата |
|
||||
| chat_title | VARCHAR(200) | NULL | Название чата |
|
||||
| model | VARCHAR(100) | NULL | AI модель |
|
||||
| created_at | TIMESTAMP | NOT NULL | Дата создания |
|
||||
| last_updated_at | TIMESTAMP | NOT NULL | Последнее обновление |
|
||||
|
||||
**Индексы:**
|
||||
```sql
|
||||
CREATE UNIQUE INDEX idx_chat_sessions_session_id ON chat_sessions(session_id);
|
||||
CREATE INDEX idx_chat_sessions_chat_id ON chat_sessions(chat_id);
|
||||
```
|
||||
|
||||
#### chat_messages
|
||||
|
||||
Хранит историю сообщений.
|
||||
|
||||
| Колонка | Тип | Constraints | Описание |
|
||||
|---------|-----|-------------|----------|
|
||||
| id | SERIAL | PRIMARY KEY | Auto-increment ID |
|
||||
| session_id | INTEGER | FK, NOT NULL | Ссылка на сессию |
|
||||
| content | VARCHAR(10000) | NOT NULL | Текст сообщения |
|
||||
| role | VARCHAR(20) | NOT NULL | user/assistant/system |
|
||||
| message_order | INTEGER | NOT NULL | Порядок в диалоге |
|
||||
| created_at | TIMESTAMP | NOT NULL | Время создания |
|
||||
|
||||
**Foreign Keys:**
|
||||
```sql
|
||||
FOREIGN KEY (session_id) REFERENCES chat_sessions(id) ON DELETE CASCADE
|
||||
```
|
||||
|
||||
**Индексы:**
|
||||
```sql
|
||||
CREATE INDEX idx_chat_messages_session_id ON chat_messages(session_id);
|
||||
CREATE INDEX idx_chat_messages_created_at ON chat_messages(created_at);
|
||||
CREATE INDEX idx_chat_messages_session_order ON chat_messages(session_id, message_order);
|
||||
```
|
||||
|
||||
## 🔄 Entity Framework Core
|
||||
|
||||
### DbContext
|
||||
|
||||
```csharp
|
||||
public class ChatBotDbContext : DbContext
|
||||
{
|
||||
public DbSet<ChatSessionEntity> ChatSessions { get; set; }
|
||||
public DbSet<ChatMessageEntity> ChatMessages { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
### Конфигурация моделей
|
||||
|
||||
```csharp
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
// ChatSessionEntity
|
||||
modelBuilder.Entity<ChatSessionEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.SessionId).IsRequired().HasMaxLength(50);
|
||||
entity.HasIndex(e => e.SessionId).IsUnique();
|
||||
entity.HasIndex(e => e.ChatId);
|
||||
|
||||
entity.HasMany(e => e.Messages)
|
||||
.WithOne(e => e.Session)
|
||||
.HasForeignKey(e => e.SessionId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
// ChatMessageEntity
|
||||
modelBuilder.Entity<ChatMessageEntity>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.Content).IsRequired().HasMaxLength(10000);
|
||||
entity.HasIndex(e => e.SessionId);
|
||||
entity.HasIndex(e => new { e.SessionId, e.MessageOrder });
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Миграции
|
||||
|
||||
#### Создание миграции
|
||||
|
||||
```bash
|
||||
dotnet ef migrations add InitialCreate --project ChatBot
|
||||
```
|
||||
|
||||
#### Применение миграций
|
||||
|
||||
```bash
|
||||
# Вручную
|
||||
dotnet ef database update --project ChatBot
|
||||
|
||||
# Автоматически при запуске (DatabaseInitializationService)
|
||||
```
|
||||
|
||||
#### Откат миграции
|
||||
|
||||
```bash
|
||||
dotnet ef database update PreviousMigration --project ChatBot
|
||||
```
|
||||
|
||||
#### Удаление последней миграции
|
||||
|
||||
```bash
|
||||
dotnet ef migrations remove --project ChatBot
|
||||
```
|
||||
|
||||
## 🔌 Подключение к БД
|
||||
|
||||
### Connection String
|
||||
|
||||
```
|
||||
Host={host};Port={port};Database={name};Username={user};Password={password}
|
||||
```
|
||||
|
||||
**Пример:**
|
||||
```
|
||||
Host=localhost;Port=5432;Database=chatbot;Username=chatbot;Password=secret
|
||||
```
|
||||
|
||||
### Конфигурация в Program.cs
|
||||
|
||||
```csharp
|
||||
builder.Services.AddDbContext<ChatBotDbContext>(
|
||||
(serviceProvider, options) =>
|
||||
{
|
||||
var dbSettings = serviceProvider
|
||||
.GetRequiredService<IOptions<DatabaseSettings>>()
|
||||
.Value;
|
||||
|
||||
options.UseNpgsql(
|
||||
dbSettings.ConnectionString,
|
||||
npgsqlOptions =>
|
||||
{
|
||||
npgsqlOptions.CommandTimeout(dbSettings.CommandTimeout);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
### Connection Pooling
|
||||
|
||||
Npgsql автоматически использует connection pooling:
|
||||
|
||||
```
|
||||
Max Pool Size=100
|
||||
Min Pool Size=1
|
||||
Connection Lifetime=300
|
||||
Connection Idle Lifetime=300
|
||||
```
|
||||
|
||||
## 📝 Repository Pattern
|
||||
|
||||
### Interface
|
||||
|
||||
```csharp
|
||||
public interface IChatSessionRepository
|
||||
{
|
||||
Task<ChatSessionEntity?> GetByChatIdAsync(long chatId);
|
||||
Task<ChatSessionEntity> CreateAsync(ChatSessionEntity session);
|
||||
Task UpdateAsync(ChatSessionEntity session);
|
||||
Task DeleteAsync(int id);
|
||||
Task<List<ChatSessionEntity>> GetAllAsync();
|
||||
}
|
||||
```
|
||||
|
||||
### Implementation
|
||||
|
||||
```csharp
|
||||
public class ChatSessionRepository : IChatSessionRepository
|
||||
{
|
||||
private readonly ChatBotDbContext _context;
|
||||
|
||||
public async Task<ChatSessionEntity?> GetByChatIdAsync(long chatId)
|
||||
{
|
||||
return await _context.ChatSessions
|
||||
.Include(s => s.Messages)
|
||||
.FirstOrDefaultAsync(s => s.ChatId == chatId);
|
||||
}
|
||||
|
||||
public async Task<ChatSessionEntity> CreateAsync(ChatSessionEntity session)
|
||||
{
|
||||
_context.ChatSessions.Add(session);
|
||||
await _context.SaveChangesAsync();
|
||||
return session;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🚀 Оптимизация запросов
|
||||
|
||||
### Eager Loading
|
||||
|
||||
```csharp
|
||||
// Загрузка с сообщениями
|
||||
var session = await _context.ChatSessions
|
||||
.Include(s => s.Messages)
|
||||
.FirstOrDefaultAsync(s => s.ChatId == chatId);
|
||||
```
|
||||
|
||||
### Projections
|
||||
|
||||
```csharp
|
||||
// Только нужные поля
|
||||
var sessionInfo = await _context.ChatSessions
|
||||
.Where(s => s.ChatId == chatId)
|
||||
.Select(s => new { s.SessionId, s.Model })
|
||||
.FirstOrDefaultAsync();
|
||||
```
|
||||
|
||||
### AsNoTracking
|
||||
|
||||
```csharp
|
||||
// Read-only запросы
|
||||
var sessions = await _context.ChatSessions
|
||||
.AsNoTracking()
|
||||
.ToListAsync();
|
||||
```
|
||||
|
||||
## 🔧 Обслуживание БД
|
||||
|
||||
### Vacuum (очистка)
|
||||
|
||||
```sql
|
||||
VACUUM ANALYZE chat_sessions;
|
||||
VACUUM ANALYZE chat_messages;
|
||||
```
|
||||
|
||||
### Статистика
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
schemaname,
|
||||
tablename,
|
||||
n_live_tup,
|
||||
n_dead_tup
|
||||
FROM pg_stat_user_tables
|
||||
WHERE tablename IN ('chat_sessions', 'chat_messages');
|
||||
```
|
||||
|
||||
### Размер таблиц
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
tablename,
|
||||
pg_size_pretty(pg_total_relation_size(tablename::regclass)) as size
|
||||
FROM pg_tables
|
||||
WHERE schemaname = 'public';
|
||||
```
|
||||
|
||||
## 🛡️ Безопасность
|
||||
|
||||
### SQL Injection Prevention
|
||||
|
||||
Entity Framework Core автоматически параметризует запросы:
|
||||
|
||||
```csharp
|
||||
// ✅ Безопасно
|
||||
var session = await _context.ChatSessions
|
||||
.Where(s => s.ChatId == chatId)
|
||||
.FirstOrDefaultAsync();
|
||||
```
|
||||
|
||||
### Права пользователя БД
|
||||
|
||||
```sql
|
||||
-- Создание пользователя
|
||||
CREATE USER chatbot WITH PASSWORD 'secure_password';
|
||||
|
||||
-- Выдача прав
|
||||
GRANT CONNECT ON DATABASE chatbot TO chatbot;
|
||||
GRANT USAGE ON SCHEMA public TO chatbot;
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO chatbot;
|
||||
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO chatbot;
|
||||
```
|
||||
|
||||
## 📊 Мониторинг
|
||||
|
||||
### Active Connections
|
||||
|
||||
```sql
|
||||
SELECT count(*)
|
||||
FROM pg_stat_activity
|
||||
WHERE datname = 'chatbot';
|
||||
```
|
||||
|
||||
### Long Running Queries
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
pid,
|
||||
now() - pg_stat_activity.query_start AS duration,
|
||||
query
|
||||
FROM pg_stat_activity
|
||||
WHERE state = 'active'
|
||||
ORDER BY duration DESC;
|
||||
```
|
||||
|
||||
### Locks
|
||||
|
||||
```sql
|
||||
SELECT * FROM pg_locks
|
||||
WHERE NOT granted;
|
||||
```
|
||||
|
||||
## 🔄 Backup & Restore
|
||||
|
||||
### Backup
|
||||
|
||||
```bash
|
||||
# Полный backup
|
||||
pg_dump -U chatbot chatbot > backup.sql
|
||||
|
||||
# Только схема
|
||||
pg_dump -U chatbot --schema-only chatbot > schema.sql
|
||||
|
||||
# Только данные
|
||||
pg_dump -U chatbot --data-only chatbot > data.sql
|
||||
```
|
||||
|
||||
### Restore
|
||||
|
||||
```bash
|
||||
# Восстановление
|
||||
psql -U chatbot chatbot < backup.sql
|
||||
```
|
||||
|
||||
## 📚 См. также
|
||||
|
||||
- [Модели данных](./data-models.md)
|
||||
- [Конфигурация](../configuration.md)
|
||||
- [Установка](../installation.md)
|
||||
349
docs/architecture/layers.md
Normal file
349
docs/architecture/layers.md
Normal file
@@ -0,0 +1,349 @@
|
||||
# 🏛️ Слои приложения
|
||||
|
||||
Детальное описание каждого слоя архитектуры ChatBot.
|
||||
|
||||
## 1️⃣ Presentation Layer (Уровень представления)
|
||||
|
||||
### Telegram Bot Integration
|
||||
|
||||
Отвечает за взаимодействие с пользователями через Telegram.
|
||||
|
||||
#### Основные компоненты
|
||||
|
||||
**TelegramBotService**
|
||||
- Главный сервис, управляющий ботом
|
||||
- Запускается как `IHostedService`
|
||||
- Получает updates через Webhook или Long Polling
|
||||
- Координирует обработку сообщений
|
||||
|
||||
**TelegramMessageHandler**
|
||||
- Обработка входящих сообщений
|
||||
- Фильтрация по типу чата
|
||||
- Извлечение информации о пользователе
|
||||
- Передача в ChatService
|
||||
|
||||
**TelegramCommandProcessor**
|
||||
- Распознавание команд (`/start`, `/help`, и т.д.)
|
||||
- Routing к соответствующему обработчику
|
||||
- Валидация прав доступа
|
||||
|
||||
**Commands (Команды)**
|
||||
```
|
||||
StartCommand - /start
|
||||
HelpCommand - /help
|
||||
ClearCommand - /clear
|
||||
SettingsCommand - /settings
|
||||
StatusCommand - /status
|
||||
```
|
||||
|
||||
#### Паттерн Command
|
||||
|
||||
```csharp
|
||||
public interface ITelegramCommand
|
||||
{
|
||||
string Command { get; }
|
||||
string Description { get; }
|
||||
Task<ReplyInfo> ExecuteAsync(TelegramCommandContext context);
|
||||
}
|
||||
```
|
||||
|
||||
Каждая команда:
|
||||
- Изолирована
|
||||
- Легко тестируется
|
||||
- Независимо расширяема
|
||||
|
||||
## 2️⃣ Service Layer (Бизнес-логика)
|
||||
|
||||
### Core Services
|
||||
|
||||
#### ChatService
|
||||
|
||||
**Ответственность:**
|
||||
- Управление сессиями чатов
|
||||
- Координация между AI и storage
|
||||
- Обработка сообщений пользователей
|
||||
|
||||
**Методы:**
|
||||
```csharp
|
||||
GetOrCreateSession() // Получить/создать сессию
|
||||
ProcessMessageAsync() // Обработать сообщение
|
||||
ClearHistoryAsync() // Очистить историю
|
||||
UpdateSessionParameters() // Обновить параметры
|
||||
```
|
||||
|
||||
**Взаимодействия:**
|
||||
- IAIService → Генерация ответов
|
||||
- ISessionStorage → Хранение сессий
|
||||
- IHistoryCompressionService → Оптимизация истории
|
||||
|
||||
#### AIService
|
||||
|
||||
**Ответственность:**
|
||||
- Генерация ответов через Ollama
|
||||
- Управление retry логикой
|
||||
- Таймауты и error handling
|
||||
|
||||
**Методы:**
|
||||
```csharp
|
||||
GenerateChatCompletionAsync() // Базовая генерация
|
||||
GenerateChatCompletionWithCompressionAsync() // С сжатием
|
||||
```
|
||||
|
||||
**Особенности:**
|
||||
- Экспоненциальный backoff
|
||||
- Streaming responses
|
||||
- Timeout handling
|
||||
- System prompt injection
|
||||
|
||||
#### HistoryCompressionService
|
||||
|
||||
**Ответственность:**
|
||||
- Суммаризация длинной истории
|
||||
- Оптимизация контекста
|
||||
- Сохранение важной информации
|
||||
|
||||
**Алгоритм:**
|
||||
```
|
||||
1. Сохранить system prompt
|
||||
2. Сохранить последние N сообщений
|
||||
3. Суммаризировать старые сообщения
|
||||
4. Объединить результаты
|
||||
```
|
||||
|
||||
**Методы:**
|
||||
```csharp
|
||||
ShouldCompress() // Проверка необходимости
|
||||
CompressHistoryAsync() // Выполнить сжатие
|
||||
SummarizeMessageAsync() // Суммаризировать одно сообщение
|
||||
```
|
||||
|
||||
#### SystemPromptService
|
||||
|
||||
**Ответственность:**
|
||||
- Загрузка системного промпта
|
||||
- Кеширование промпта
|
||||
- Обработка ошибок чтения файла
|
||||
|
||||
#### ModelService
|
||||
|
||||
**Ответственность:**
|
||||
- Управление AI моделями
|
||||
- Получение списка доступных моделей
|
||||
- Переключение между моделями
|
||||
|
||||
### Storage Services
|
||||
|
||||
#### DatabaseSessionStorage
|
||||
|
||||
**Ответственность:**
|
||||
- Сохранение сессий в PostgreSQL
|
||||
- CRUD операции через репозиторий
|
||||
- Синхронизация с базой данных
|
||||
|
||||
**Методы:**
|
||||
```csharp
|
||||
GetOrCreate() // Получить или создать
|
||||
Get() // Получить по ID
|
||||
SaveSessionAsync() // Сохранить сессию
|
||||
Remove() // Удалить сессию
|
||||
CleanupOldSessions() // Очистка старых
|
||||
```
|
||||
|
||||
**Особенности:**
|
||||
- Автоматическая конвертация Entity ↔ Model
|
||||
- Lazy loading сессий
|
||||
- Кеширование в памяти
|
||||
|
||||
#### InMemorySessionStorage
|
||||
|
||||
**Ответственность:**
|
||||
- Хранение сессий в памяти
|
||||
- Быстрый доступ для тестов
|
||||
- Не требует БД
|
||||
|
||||
**Использование:**
|
||||
- Unit тесты
|
||||
- Development режим
|
||||
- Прототипирование
|
||||
|
||||
## 3️⃣ Data Access Layer (Доступ к данным)
|
||||
|
||||
### DbContext
|
||||
|
||||
**ChatBotDbContext**
|
||||
- Entity Framework Core контекст
|
||||
- Конфигурация таблиц
|
||||
- Отношения между сущностями
|
||||
|
||||
```csharp
|
||||
DbSet<ChatSessionEntity> ChatSessions
|
||||
DbSet<ChatMessageEntity> ChatMessages
|
||||
```
|
||||
|
||||
**Конфигурация:**
|
||||
- Индексы для оптимизации
|
||||
- Foreign Keys и Cascade Delete
|
||||
- Constraints и Validation
|
||||
|
||||
### Repositories
|
||||
|
||||
#### ChatSessionRepository
|
||||
|
||||
**Ответственность:**
|
||||
- Абстракция доступа к данным
|
||||
- CRUD операции с сессиями
|
||||
- Query оптимизация
|
||||
|
||||
**Методы:**
|
||||
```csharp
|
||||
GetByChatIdAsync() // По chat ID
|
||||
CreateAsync() // Создать
|
||||
UpdateAsync() // Обновить
|
||||
DeleteAsync() // Удалить
|
||||
GetAllAsync() // Все сессии
|
||||
```
|
||||
|
||||
**Преимущества паттерна Repository:**
|
||||
- Изоляция от EF Core
|
||||
- Легкое тестирование
|
||||
- Возможность смены ORM
|
||||
|
||||
### Entities (Сущности БД)
|
||||
|
||||
#### ChatSessionEntity
|
||||
|
||||
```csharp
|
||||
Id // PK
|
||||
SessionId // Unique identifier
|
||||
ChatId // Telegram chat ID
|
||||
ChatType // private/group/supergroup
|
||||
ChatTitle // Название чата
|
||||
Model // AI модель
|
||||
CreatedAt // Дата создания
|
||||
LastUpdatedAt // Последнее обновление
|
||||
Messages // Коллекция сообщений
|
||||
```
|
||||
|
||||
#### ChatMessageEntity
|
||||
|
||||
```csharp
|
||||
Id // PK
|
||||
SessionId // FK → ChatSessionEntity
|
||||
Content // Текст сообщения
|
||||
Role // user/assistant/system
|
||||
MessageOrder // Порядок в диалоге
|
||||
CreatedAt // Дата создания
|
||||
```
|
||||
|
||||
## 4️⃣ Infrastructure Layer (Инфраструктура)
|
||||
|
||||
### External Services
|
||||
|
||||
#### PostgreSQL
|
||||
|
||||
**Функции:**
|
||||
- Persistent storage сессий
|
||||
- Транзакционность
|
||||
- ACID гарантии
|
||||
|
||||
**Оптимизации:**
|
||||
- Индексы на ChatId, SessionId
|
||||
- Connection pooling
|
||||
- Query optimization
|
||||
|
||||
#### Ollama
|
||||
|
||||
**Функции:**
|
||||
- Локальные LLM модели
|
||||
- Streaming responses
|
||||
- Multiple models support
|
||||
|
||||
**Адаптер:**
|
||||
```csharp
|
||||
OllamaClientAdapter : IOllamaClient
|
||||
```
|
||||
|
||||
Абстрагирует от конкретной реализации OllamaSharp.
|
||||
|
||||
#### Telegram Bot API
|
||||
|
||||
**Функции:**
|
||||
- Получение updates
|
||||
- Отправка сообщений
|
||||
- Управление ботом
|
||||
|
||||
**Wrapper:**
|
||||
```csharp
|
||||
TelegramBotClientWrapper : ITelegramBotClientWrapper
|
||||
```
|
||||
|
||||
## 🔄 Взаимодействие слоев
|
||||
|
||||
### Правила взаимодействия
|
||||
|
||||
```
|
||||
Presentation → Service → Data → Infrastructure
|
||||
↓ ↓ ↓
|
||||
Interfaces Interfaces Repository
|
||||
```
|
||||
|
||||
**Принципы:**
|
||||
- Слои зависят только от интерфейсов
|
||||
- Вышестоящие слои не знают о нижестоящих
|
||||
- Dependency Injection связывает реализации
|
||||
|
||||
### Пример: Обработка сообщения
|
||||
|
||||
```
|
||||
1. TelegramBotService (Presentation)
|
||||
↓ вызывает
|
||||
2. TelegramMessageHandler (Presentation)
|
||||
↓ вызывает
|
||||
3. ChatService (Service)
|
||||
↓ использует
|
||||
4. ISessionStorage (Service Interface)
|
||||
↓ реализован как
|
||||
5. DatabaseSessionStorage (Service)
|
||||
↓ использует
|
||||
6. IChatSessionRepository (Data Interface)
|
||||
↓ реализован как
|
||||
7. ChatSessionRepository (Data)
|
||||
↓ использует
|
||||
8. ChatBotDbContext (Data)
|
||||
↓ обращается к
|
||||
9. PostgreSQL (Infrastructure)
|
||||
```
|
||||
|
||||
## 🎯 Разделение ответственности
|
||||
|
||||
### Presentation Layer
|
||||
- ✅ Обработка входящих запросов
|
||||
- ✅ Валидация команд
|
||||
- ✅ Форматирование ответов
|
||||
- ❌ Бизнес-логика
|
||||
- ❌ Доступ к данным
|
||||
|
||||
### Service Layer
|
||||
- ✅ Бизнес-логика
|
||||
- ✅ Координация сервисов
|
||||
- ✅ Валидация бизнес-правил
|
||||
- ❌ UI логика
|
||||
- ❌ SQL запросы
|
||||
|
||||
### Data Layer
|
||||
- ✅ CRUD операции
|
||||
- ✅ Query построение
|
||||
- ✅ Маппинг Entity ↔ Model
|
||||
- ❌ Бизнес-логика
|
||||
- ❌ UI логика
|
||||
|
||||
### Infrastructure Layer
|
||||
- ✅ Внешние интеграции
|
||||
- ✅ Конфигурация подключений
|
||||
- ❌ Бизнес-логика
|
||||
|
||||
## 📚 См. также
|
||||
|
||||
- [Архитектура - Обзор](./overview.md)
|
||||
- [Модели данных](./data-models.md)
|
||||
- [Структура проекта](../development/project-structure.md)
|
||||
210
docs/architecture/overview.md
Normal file
210
docs/architecture/overview.md
Normal file
@@ -0,0 +1,210 @@
|
||||
# 🏗️ Архитектура проекта
|
||||
|
||||
## 📐 Общая архитектура
|
||||
|
||||
ChatBot построен на принципах **Clean Architecture** с четким разделением ответственности.
|
||||
|
||||
## 🔄 Диаграмма слоев
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ Presentation Layer │
|
||||
│ (Telegram Bot, Commands, Handlers) │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ Service Layer │
|
||||
│ (ChatService, AIService, Compression) │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ Data Access Layer │
|
||||
│ (Repositories, DbContext, Entities) │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ Infrastructure Layer │
|
||||
│ (PostgreSQL, Ollama, Telegram) │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 🎯 Принципы проектирования
|
||||
|
||||
### SOLID
|
||||
|
||||
- **S**ingle Responsibility - Каждый класс имеет одну ответственность
|
||||
- **O**pen/Closed - Открыт для расширения, закрыт для модификации
|
||||
- **L**iskov Substitution - Интерфейсы взаимозаменяемы
|
||||
- **I**nterface Segregation - Мелкие специализированные интерфейсы
|
||||
- **D**ependency Inversion - Зависимость от абстракций
|
||||
|
||||
### Design Patterns
|
||||
|
||||
- **Repository Pattern** - `IChatSessionRepository`
|
||||
- **Dependency Injection** - Microsoft.Extensions.DependencyInjection
|
||||
- **Strategy Pattern** - `ISessionStorage` (In-Memory/Database)
|
||||
- **Command Pattern** - Telegram команды
|
||||
- **Adapter Pattern** - `OllamaClientAdapter`
|
||||
|
||||
## 📦 Компоненты системы
|
||||
|
||||
### 1. Presentation Layer
|
||||
|
||||
**Telegram Bot Integration:**
|
||||
- `TelegramBotService` - Основной сервис бота
|
||||
- `TelegramMessageHandler` - Обработка сообщений
|
||||
- `TelegramCommandProcessor` - Обработка команд
|
||||
- `TelegramErrorHandler` - Обработка ошибок
|
||||
- Commands: `StartCommand`, `HelpCommand`, `ClearCommand`, etc.
|
||||
|
||||
### 2. Service Layer
|
||||
|
||||
**Core Services:**
|
||||
- `ChatService` - Управление диалогами
|
||||
- `AIService` - Генерация ответов AI
|
||||
- `HistoryCompressionService` - Сжатие истории
|
||||
- `SystemPromptService` - Загрузка системного промпта
|
||||
- `ModelService` - Управление AI моделями
|
||||
|
||||
**Storage Services:**
|
||||
- `DatabaseSessionStorage` - Хранение в БД
|
||||
- `InMemorySessionStorage` - Хранение в памяти
|
||||
|
||||
### 3. Data Access Layer
|
||||
|
||||
**Repositories:**
|
||||
- `ChatSessionRepository` - Работа с сессиями
|
||||
- `ChatBotDbContext` - EF Core контекст
|
||||
|
||||
**Entities:**
|
||||
- `ChatSessionEntity` - Сессия чата
|
||||
- `ChatMessageEntity` - Сообщение чата
|
||||
|
||||
### 4. Infrastructure
|
||||
|
||||
**External Services:**
|
||||
- PostgreSQL - База данных
|
||||
- Ollama - AI модели
|
||||
- Telegram Bot API - Telegram интеграция
|
||||
|
||||
## 🔌 Dependency Injection
|
||||
|
||||
```csharp
|
||||
// Telegram Services
|
||||
services.AddSingleton<ITelegramBotClient>
|
||||
services.AddSingleton<ITelegramBotService>
|
||||
services.AddSingleton<ITelegramMessageHandler>
|
||||
|
||||
// Core Services
|
||||
services.AddSingleton<IAIService, AIService>
|
||||
services.AddScoped<ChatService>
|
||||
services.AddScoped<ISessionStorage, DatabaseSessionStorage>
|
||||
|
||||
// Data Access
|
||||
services.AddDbContext<ChatBotDbContext>
|
||||
services.AddScoped<IChatSessionRepository, ChatSessionRepository>
|
||||
```
|
||||
|
||||
## 🔄 Data Flow
|
||||
|
||||
### Обработка сообщения пользователя
|
||||
|
||||
```
|
||||
User Message
|
||||
↓
|
||||
TelegramBotService (получение update)
|
||||
↓
|
||||
TelegramMessageHandler (валидация)
|
||||
↓
|
||||
TelegramCommandProcessor (проверка команды)
|
||||
↓ (если не команда)
|
||||
ChatService (обработка сообщения)
|
||||
↓
|
||||
SessionStorage (получение/создание сессии)
|
||||
↓
|
||||
AIService (генерация ответа)
|
||||
↓
|
||||
OllamaClient (запрос к AI)
|
||||
↓
|
||||
AIService (получение ответа)
|
||||
↓
|
||||
ChatService (сохранение в историю)
|
||||
↓
|
||||
SessionStorage (сохранение сессии)
|
||||
↓
|
||||
TelegramMessageSender (отправка ответа)
|
||||
↓
|
||||
User receives response
|
||||
```
|
||||
|
||||
## 🗂️ Структура проекта
|
||||
|
||||
```
|
||||
ChatBot/
|
||||
├── Common/ # Общие константы
|
||||
│ └── Constants/
|
||||
├── Data/ # Слой доступа к данным
|
||||
│ ├── Interfaces/
|
||||
│ ├── Repositories/
|
||||
│ └── ChatBotDbContext.cs
|
||||
├── Models/ # Модели и конфигурация
|
||||
│ ├── Configuration/
|
||||
│ ├── Dto/
|
||||
│ ├── Entities/
|
||||
│ └── ChatSession.cs
|
||||
├── Services/ # Бизнес-логика
|
||||
│ ├── HealthChecks/
|
||||
│ ├── Interfaces/
|
||||
│ ├── Telegram/
|
||||
│ └── *.cs
|
||||
├── Migrations/ # EF Core миграции
|
||||
├── Prompts/ # AI промпты
|
||||
└── Program.cs # Точка входа
|
||||
```
|
||||
|
||||
## 📊 Диаграмма классов (упрощенная)
|
||||
|
||||
```
|
||||
┌─────────────────────┐
|
||||
│ ChatService │
|
||||
├─────────────────────┤
|
||||
│ + ProcessMessage() │
|
||||
│ + ClearHistory() │
|
||||
└──────────┬──────────┘
|
||||
│
|
||||
├──> IAIService
|
||||
├──> ISessionStorage
|
||||
└──> IHistoryCompressionService
|
||||
|
||||
┌─────────────────────┐
|
||||
│ AIService │
|
||||
├─────────────────────┤
|
||||
│ + GenerateChat() │
|
||||
└──────────┬──────────┘
|
||||
│
|
||||
└──> IOllamaClient
|
||||
```
|
||||
|
||||
## 🔐 Security Architecture
|
||||
|
||||
- Секреты в переменных окружения
|
||||
- Валидация входных данных
|
||||
- SQL инъекции предотвращены (EF Core)
|
||||
- Безопасное логирование (без секретов)
|
||||
|
||||
## 📈 Scalability
|
||||
|
||||
**Готовность к масштабированию:**
|
||||
- Stateless сервисы
|
||||
- Database session storage
|
||||
- Async/await везде
|
||||
- Connection pooling
|
||||
- Health checks
|
||||
|
||||
## 🎛️ Configuration Management
|
||||
|
||||
```
|
||||
Environment Variables → .env
|
||||
↓
|
||||
appsettings.json
|
||||
↓
|
||||
IOptions<T>
|
||||
↓
|
||||
Validation (FluentValidation)
|
||||
↓
|
||||
Services
|
||||
```
|
||||
449
docs/configuration.md
Normal file
449
docs/configuration.md
Normal file
@@ -0,0 +1,449 @@
|
||||
# ⚙️ Конфигурация
|
||||
|
||||
Полное руководство по настройке ChatBot.
|
||||
|
||||
## 📝 Иерархия конфигурации
|
||||
|
||||
Настройки загружаются в следующем порядке (последующие переопределяют предыдущие):
|
||||
|
||||
1. `appsettings.json` - Базовые настройки
|
||||
2. `appsettings.Development.json` - Настройки для разработки
|
||||
3. User Secrets - Секреты для разработки
|
||||
4. Переменные окружения - Production настройки
|
||||
5. `.env` файл - Локальные переменные
|
||||
|
||||
## 🔐 Переменные окружения
|
||||
|
||||
### Telegram Bot
|
||||
|
||||
```env
|
||||
# Обязательно
|
||||
TELEGRAM_BOT_TOKEN=123456789:ABCdefGHIjklMNOpqrsTUVwxyz
|
||||
```
|
||||
|
||||
### Ollama
|
||||
|
||||
```env
|
||||
# URL сервера Ollama
|
||||
OLLAMA_URL=http://localhost:11434
|
||||
|
||||
# Модель по умолчанию
|
||||
OLLAMA_DEFAULT_MODEL=gemma2:2b
|
||||
```
|
||||
|
||||
### База данных
|
||||
|
||||
```env
|
||||
# Подключение к PostgreSQL
|
||||
DB_HOST=localhost
|
||||
DB_PORT=5432
|
||||
DB_NAME=chatbot
|
||||
DB_USER=postgres
|
||||
DB_PASSWORD=your_secure_password
|
||||
```
|
||||
|
||||
## 📄 appsettings.json
|
||||
|
||||
### Полная структура
|
||||
|
||||
```json
|
||||
{
|
||||
"Serilog": {
|
||||
"MinimumLevel": {
|
||||
"Default": "Information",
|
||||
"Override": {
|
||||
"Microsoft": "Warning",
|
||||
"System": "Warning"
|
||||
}
|
||||
},
|
||||
"WriteTo": [
|
||||
{
|
||||
"Name": "Console",
|
||||
"Args": {
|
||||
"outputTemplate": "[{Timestamp:HH:mm:ss}] [{Level}] {Message}{NewLine}{Exception}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "File",
|
||||
"Args": {
|
||||
"path": "logs/telegram-bot-.log",
|
||||
"rollingInterval": "Day",
|
||||
"retainedFileCountLimit": 7
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"TelegramBot": {
|
||||
"BotToken": ""
|
||||
},
|
||||
"Ollama": {
|
||||
"Url": "",
|
||||
"DefaultModel": ""
|
||||
},
|
||||
"AI": {
|
||||
"Temperature": 0.9,
|
||||
"SystemPromptPath": "Prompts/system-prompt.txt",
|
||||
"MaxRetryAttempts": 3,
|
||||
"RetryDelayMs": 1000,
|
||||
"RequestTimeoutSeconds": 180,
|
||||
"EnableHistoryCompression": true,
|
||||
"CompressionThreshold": 20,
|
||||
"CompressionTarget": 10,
|
||||
"MinMessageLengthForSummarization": 50,
|
||||
"MaxSummarizedMessageLength": 200,
|
||||
"EnableExponentialBackoff": true,
|
||||
"MaxRetryDelayMs": 30000,
|
||||
"CompressionTimeoutSeconds": 30,
|
||||
"StatusCheckTimeoutSeconds": 10
|
||||
},
|
||||
"Database": {
|
||||
"ConnectionString": "",
|
||||
"EnableSensitiveDataLogging": false,
|
||||
"CommandTimeout": 30
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🎯 Секции конфигурации
|
||||
|
||||
### TelegramBot
|
||||
|
||||
| Параметр | Тип | Описание | По умолчанию |
|
||||
|----------|-----|----------|--------------|
|
||||
| `BotToken` | string | Токен бота от @BotFather | - |
|
||||
|
||||
**Валидация:**
|
||||
- Токен не может быть пустым
|
||||
- Минимальная длина: 10 символов
|
||||
|
||||
**Пример:**
|
||||
```json
|
||||
{
|
||||
"TelegramBot": {
|
||||
"BotToken": "123456789:ABCdefGHIjklMNOpqrsTUVwxyz"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Ollama
|
||||
|
||||
| Параметр | Тип | Описание | По умолчанию |
|
||||
|----------|-----|----------|--------------|
|
||||
| `Url` | string | URL Ollama сервера | http://localhost:11434 |
|
||||
| `DefaultModel` | string | Модель по умолчанию | gemma2:2b |
|
||||
|
||||
**Валидация:**
|
||||
- URL должен быть валидным HTTP/HTTPS адресом
|
||||
- Модель не может быть пустой
|
||||
|
||||
**Пример:**
|
||||
```json
|
||||
{
|
||||
"Ollama": {
|
||||
"Url": "http://localhost:11434",
|
||||
"DefaultModel": "gemma2:2b"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Доступные модели:**
|
||||
- `gemma2:2b` - Быстрая, легкая (2GB RAM)
|
||||
- `llama3.2` - Средняя (4GB RAM)
|
||||
- `mistral` - Продвинутая (8GB RAM)
|
||||
- `phi3` - Компактная (2.5GB RAM)
|
||||
|
||||
### AI
|
||||
|
||||
| Параметр | Тип | Описание | По умолчанию |
|
||||
|----------|-----|----------|--------------|
|
||||
| `Temperature` | double | Креативность ответов (0.0-2.0) | 0.9 |
|
||||
| `SystemPromptPath` | string | Путь к системному промпту | Prompts/system-prompt.txt |
|
||||
| `MaxRetryAttempts` | int | Макс. попыток повтора | 3 |
|
||||
| `RetryDelayMs` | int | Задержка между попытками (мс) | 1000 |
|
||||
| `RequestTimeoutSeconds` | int | Таймаут запроса (сек) | 180 |
|
||||
| `EnableHistoryCompression` | bool | Включить сжатие истории | true |
|
||||
| `CompressionThreshold` | int | Порог для сжатия (кол-во сообщений) | 20 |
|
||||
| `CompressionTarget` | int | Целевое кол-во после сжатия | 10 |
|
||||
| `MinMessageLengthForSummarization` | int | Мин. длина для суммаризации | 50 |
|
||||
| `MaxSummarizedMessageLength` | int | Макс. длина суммаризации | 200 |
|
||||
| `EnableExponentialBackoff` | bool | Экспоненциальный backoff | true |
|
||||
| `MaxRetryDelayMs` | int | Макс. задержка повтора (мс) | 30000 |
|
||||
| `CompressionTimeoutSeconds` | int | Таймаут сжатия (сек) | 30 |
|
||||
| `StatusCheckTimeoutSeconds` | int | Таймаут проверки статуса (сек) | 10 |
|
||||
|
||||
**Валидация:**
|
||||
- `Temperature`: 0.0 ≤ x ≤ 2.0
|
||||
- `MaxRetryAttempts`: 1 ≤ x ≤ 10
|
||||
- `RetryDelayMs`: 100 ≤ x ≤ 60000
|
||||
- `RequestTimeoutSeconds`: 10 ≤ x ≤ 600
|
||||
|
||||
**Пример:**
|
||||
```json
|
||||
{
|
||||
"AI": {
|
||||
"Temperature": 0.9,
|
||||
"MaxRetryAttempts": 3,
|
||||
"EnableHistoryCompression": true,
|
||||
"CompressionThreshold": 20
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Temperature (Температура)
|
||||
|
||||
Определяет "креативность" ответов AI:
|
||||
|
||||
- **0.0-0.3**: Детерминированные, предсказуемые ответы
|
||||
- **0.4-0.7**: Сбалансированные ответы
|
||||
- **0.8-1.2**: Креативные, разнообразные ответы (рекомендуется)
|
||||
- **1.3-2.0**: Очень креативные, иногда непредсказуемые
|
||||
|
||||
#### History Compression
|
||||
|
||||
Автоматическое сжатие истории диалога для оптимизации:
|
||||
|
||||
```
|
||||
История: 20+ сообщений
|
||||
↓ (сжатие)
|
||||
Результат: 10 сообщений (суммаризация старых)
|
||||
```
|
||||
|
||||
**Алгоритм:**
|
||||
1. Сохранить системный промпт
|
||||
2. Сохранить последние N сообщений
|
||||
3. Старые сообщения суммаризировать
|
||||
|
||||
### Database
|
||||
|
||||
| Параметр | Тип | Описание | По умолчанию |
|
||||
|----------|-----|----------|--------------|
|
||||
| `ConnectionString` | string | Строка подключения PostgreSQL | - |
|
||||
| `EnableSensitiveDataLogging` | bool | Логировать SQL запросы | false |
|
||||
| `CommandTimeout` | int | Таймаут команд (сек) | 30 |
|
||||
|
||||
**Валидация:**
|
||||
- Connection string не может быть пустой
|
||||
- `CommandTimeout`: 5 ≤ x ≤ 300
|
||||
|
||||
**Пример:**
|
||||
```json
|
||||
{
|
||||
"Database": {
|
||||
"ConnectionString": "Host=localhost;Port=5432;Database=chatbot;Username=chatbot;Password=password",
|
||||
"EnableSensitiveDataLogging": false,
|
||||
"CommandTimeout": 30
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Connection String формат:**
|
||||
```
|
||||
Host={host};Port={port};Database={name};Username={user};Password={password}
|
||||
```
|
||||
|
||||
### Serilog (Логирование)
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
|----------|-----|----------|
|
||||
| `MinimumLevel.Default` | string | Минимальный уровень логов |
|
||||
| `WriteTo` | array | Sink'и для записи |
|
||||
|
||||
**Уровни логирования:**
|
||||
- `Verbose` - Все детали (разработка)
|
||||
- `Debug` - Отладочная информация
|
||||
- `Information` - Общая информация (по умолчанию)
|
||||
- `Warning` - Предупреждения
|
||||
- `Error` - Ошибки
|
||||
- `Fatal` - Критические ошибки
|
||||
|
||||
**Пример:**
|
||||
```json
|
||||
{
|
||||
"Serilog": {
|
||||
"MinimumLevel": {
|
||||
"Default": "Information",
|
||||
"Override": {
|
||||
"Microsoft.EntityFrameworkCore": "Warning"
|
||||
}
|
||||
},
|
||||
"WriteTo": [
|
||||
{
|
||||
"Name": "Console"
|
||||
},
|
||||
{
|
||||
"Name": "File",
|
||||
"Args": {
|
||||
"path": "logs/app-.log",
|
||||
"rollingInterval": "Day"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 Настройка системного промпта
|
||||
|
||||
Файл: `ChatBot/Prompts/system-prompt.txt`
|
||||
|
||||
Этот файл определяет личность и стиль общения бота.
|
||||
|
||||
### Структура промпта
|
||||
|
||||
```
|
||||
[Персонаж]
|
||||
- Имя, возраст, локация
|
||||
- Интересы, хобби
|
||||
- Стиль общения
|
||||
|
||||
[Правила ответов]
|
||||
- Естественность
|
||||
- Обработка {empty}
|
||||
- Реакция на провокации
|
||||
|
||||
[Примеры]
|
||||
- Корректные ответы
|
||||
- Примеры {empty}
|
||||
```
|
||||
|
||||
### Специальные маркеры
|
||||
|
||||
**{empty}** - Бот игнорирует сообщение
|
||||
|
||||
Используется когда:
|
||||
- Сообщение адресовано другому человеку
|
||||
- Контекст не требует ответа
|
||||
- Провокационные вопросы о боте
|
||||
|
||||
### Кастомизация промпта
|
||||
|
||||
1. Откройте `Prompts/system-prompt.txt`
|
||||
2. Отредактируйте под свои нужды
|
||||
3. Сохраните файл
|
||||
4. Перезапустите бота
|
||||
|
||||
## 🔄 Переключение режимов
|
||||
|
||||
### In-Memory Storage (для тестов)
|
||||
|
||||
В `Program.cs`:
|
||||
```csharp
|
||||
// Заменить
|
||||
builder.Services.AddScoped<ISessionStorage, DatabaseSessionStorage>();
|
||||
|
||||
// На
|
||||
builder.Services.AddScoped<ISessionStorage, InMemorySessionStorage>();
|
||||
```
|
||||
|
||||
### Отключение сжатия истории
|
||||
|
||||
В `appsettings.json`:
|
||||
```json
|
||||
{
|
||||
"AI": {
|
||||
"EnableHistoryCompression": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Изменение уровня логирования
|
||||
|
||||
```json
|
||||
{
|
||||
"Serilog": {
|
||||
"MinimumLevel": {
|
||||
"Default": "Debug" // или Verbose
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 Примеры конфигураций
|
||||
|
||||
### Development (разработка)
|
||||
|
||||
```json
|
||||
{
|
||||
"AI": {
|
||||
"Temperature": 0.7,
|
||||
"EnableHistoryCompression": false,
|
||||
"MaxRetryAttempts": 2
|
||||
},
|
||||
"Database": {
|
||||
"EnableSensitiveDataLogging": true
|
||||
},
|
||||
"Serilog": {
|
||||
"MinimumLevel": {
|
||||
"Default": "Debug"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Production (production)
|
||||
|
||||
```json
|
||||
{
|
||||
"AI": {
|
||||
"Temperature": 0.9,
|
||||
"EnableHistoryCompression": true,
|
||||
"MaxRetryAttempts": 3
|
||||
},
|
||||
"Database": {
|
||||
"EnableSensitiveDataLogging": false
|
||||
},
|
||||
"Serilog": {
|
||||
"MinimumLevel": {
|
||||
"Default": "Information"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### High Performance (производительность)
|
||||
|
||||
```json
|
||||
{
|
||||
"AI": {
|
||||
"Temperature": 0.8,
|
||||
"RequestTimeoutSeconds": 120,
|
||||
"EnableHistoryCompression": true,
|
||||
"CompressionThreshold": 15,
|
||||
"CompressionTarget": 8
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔍 Проверка конфигурации
|
||||
|
||||
### Валидация при старте
|
||||
|
||||
Приложение автоматически валидирует конфигурацию при запуске.
|
||||
|
||||
**Ошибки валидации:**
|
||||
```
|
||||
Options validation failed for 'TelegramBotSettings' with errors:
|
||||
- BotToken cannot be empty
|
||||
```
|
||||
|
||||
### Просмотр текущей конфигурации
|
||||
|
||||
Используйте команду бота:
|
||||
```
|
||||
/settings
|
||||
```
|
||||
|
||||
Ответ:
|
||||
```
|
||||
⚙️ Текущие настройки:
|
||||
🤖 Модель: gemma2:2b
|
||||
🌡️ Temperature: 0.9
|
||||
📝 Сообщений в истории: 5/30
|
||||
🗜️ Сжатие истории: Включено
|
||||
```
|
||||
|
||||
## 📚 См. также
|
||||
|
||||
- [Установка](./installation.md)
|
||||
- [Быстрый старт](./quickstart.md)
|
||||
- [Development](./development/project-structure.md)
|
||||
344
docs/development/project-structure.md
Normal file
344
docs/development/project-structure.md
Normal file
@@ -0,0 +1,344 @@
|
||||
# 📁 Структура проекта
|
||||
|
||||
Подробное описание организации кода в ChatBot.
|
||||
|
||||
## 🌳 Дерево проекта
|
||||
|
||||
```
|
||||
ChatBot/
|
||||
├── .gitea/
|
||||
│ └── workflows/
|
||||
│ └── build.yml # CI/CD pipeline (SonarQube)
|
||||
├── ChatBot/ # Основной проект
|
||||
│ ├── Common/
|
||||
│ │ └── Constants/
|
||||
│ │ ├── AIResponseConstants.cs
|
||||
│ │ └── ChatTypes.cs
|
||||
│ ├── Data/
|
||||
│ │ ├── Interfaces/
|
||||
│ │ │ └── IChatSessionRepository.cs
|
||||
│ │ ├── Repositories/
|
||||
│ │ │ └── ChatSessionRepository.cs
|
||||
│ │ └── ChatBotDbContext.cs
|
||||
│ ├── Migrations/
|
||||
│ │ └── [EF Core миграции]
|
||||
│ ├── Models/
|
||||
│ │ ├── Configuration/
|
||||
│ │ │ ├── Validators/
|
||||
│ │ │ ├── AISettings.cs
|
||||
│ │ │ ├── DatabaseSettings.cs
|
||||
│ │ │ ├── OllamaSettings.cs
|
||||
│ │ │ └── TelegramBotSettings.cs
|
||||
│ │ ├── Dto/
|
||||
│ │ │ └── ChatMessage.cs
|
||||
│ │ ├── Entities/
|
||||
│ │ │ ├── ChatMessageEntity.cs
|
||||
│ │ │ └── ChatSessionEntity.cs
|
||||
│ │ └── ChatSession.cs
|
||||
│ ├── Prompts/
|
||||
│ │ └── system-prompt.txt # AI промпт
|
||||
│ ├── Properties/
|
||||
│ │ └── launchSettings.json
|
||||
│ ├── Services/
|
||||
│ │ ├── HealthChecks/
|
||||
│ │ │ ├── OllamaHealthCheck.cs
|
||||
│ │ │ └── TelegramBotHealthCheck.cs
|
||||
│ │ ├── Interfaces/
|
||||
│ │ │ ├── IAIService.cs
|
||||
│ │ │ ├── IHistoryCompressionService.cs
|
||||
│ │ │ ├── IOllamaClient.cs
|
||||
│ │ │ ├── ISessionStorage.cs
|
||||
│ │ │ └── ITelegramBotClientWrapper.cs
|
||||
│ │ ├── Telegram/
|
||||
│ │ │ ├── Commands/
|
||||
│ │ │ │ ├── ClearCommand.cs
|
||||
│ │ │ │ ├── CommandAttribute.cs
|
||||
│ │ │ │ ├── CommandRegistry.cs
|
||||
│ │ │ │ ├── HelpCommand.cs
|
||||
│ │ │ │ ├── ReplyInfo.cs
|
||||
│ │ │ │ ├── SettingsCommand.cs
|
||||
│ │ │ │ ├── StartCommand.cs
|
||||
│ │ │ │ ├── StatusCommand.cs
|
||||
│ │ │ │ ├── TelegramCommandBase.cs
|
||||
│ │ │ │ ├── TelegramCommandContext.cs
|
||||
│ │ │ │ └── TelegramCommandProcessor.cs
|
||||
│ │ │ ├── Interfaces/
|
||||
│ │ │ │ ├── ITelegramBotService.cs
|
||||
│ │ │ │ ├── ITelegramCommand.cs
|
||||
│ │ │ │ ├── ITelegramCommandProcessor.cs
|
||||
│ │ │ │ ├── ITelegramErrorHandler.cs
|
||||
│ │ │ │ └── ITelegramMessageHandler.cs
|
||||
│ │ │ └── Services/
|
||||
│ │ │ ├── BotInfoService.cs
|
||||
│ │ │ ├── TelegramBotService.cs
|
||||
│ │ │ ├── TelegramErrorHandler.cs
|
||||
│ │ │ ├── TelegramMessageHandler.cs
|
||||
│ │ │ └── TelegramMessageSender.cs
|
||||
│ │ ├── AIService.cs
|
||||
│ │ ├── ChatService.cs
|
||||
│ │ ├── DatabaseInitializationService.cs
|
||||
│ │ ├── DatabaseSessionStorage.cs
|
||||
│ │ ├── HistoryCompressionService.cs
|
||||
│ │ ├── InMemorySessionStorage.cs
|
||||
│ │ ├── ModelService.cs
|
||||
│ │ ├── OllamaClientAdapter.cs
|
||||
│ │ ├── SystemPromptService.cs
|
||||
│ │ └── TelegramBotClientWrapper.cs
|
||||
│ ├── appsettings.json
|
||||
│ ├── appsettings.Development.json
|
||||
│ ├── ChatBot.csproj
|
||||
│ └── Program.cs
|
||||
├── ChatBot.Tests/ # Тестовый проект
|
||||
│ ├── Common/
|
||||
│ ├── Configuration/
|
||||
│ ├── Data/
|
||||
│ ├── Integration/
|
||||
│ ├── Models/
|
||||
│ ├── Program/
|
||||
│ ├── Services/
|
||||
│ ├── Telegram/
|
||||
│ └── ChatBot.Tests.csproj
|
||||
├── docs/ # Документация
|
||||
├── .gitignore
|
||||
├── .gitattributes
|
||||
├── ChatBot.sln
|
||||
├── LICENSE.txt
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## 📂 Основные папки
|
||||
|
||||
### `/Common`
|
||||
|
||||
Общие константы и утилиты.
|
||||
|
||||
**Constants/**
|
||||
- `AIResponseConstants.cs` - Константы для AI ответов
|
||||
- `EmptyResponseMarker = "{empty}"`
|
||||
- `DefaultErrorMessage`
|
||||
- `ChatTypes.cs` - Типы чатов
|
||||
- `Private`, `Group`, `Supergroup`, `Channel`
|
||||
|
||||
### `/Data`
|
||||
|
||||
Слой доступа к данным.
|
||||
|
||||
**Interfaces/**
|
||||
- `IChatSessionRepository.cs` - Интерфейс репозитория
|
||||
|
||||
**Repositories/**
|
||||
- `ChatSessionRepository.cs` - Реализация репозитория
|
||||
|
||||
**Root:**
|
||||
- `ChatBotDbContext.cs` - EF Core контекст
|
||||
|
||||
### `/Models`
|
||||
|
||||
Модели данных и конфигурация.
|
||||
|
||||
**Configuration/**
|
||||
- Settings классы для конфигурации
|
||||
- **Validators/** - FluentValidation валидаторы
|
||||
|
||||
**Dto/**
|
||||
- `ChatMessage.cs` - DTO для сообщений
|
||||
|
||||
**Entities/**
|
||||
- `ChatSessionEntity.cs` - Сущность сессии
|
||||
- `ChatMessageEntity.cs` - Сущность сообщения
|
||||
|
||||
**Root:**
|
||||
- `ChatSession.cs` - Доменная модель сессии
|
||||
|
||||
### `/Services`
|
||||
|
||||
Бизнес-логика приложения.
|
||||
|
||||
**HealthChecks/**
|
||||
- `OllamaHealthCheck.cs` - Проверка Ollama
|
||||
- `TelegramBotHealthCheck.cs` - Проверка Telegram
|
||||
|
||||
**Interfaces/**
|
||||
- Интерфейсы всех сервисов
|
||||
|
||||
**Telegram/**
|
||||
- **Commands/** - Реализация команд бота
|
||||
- **Interfaces/** - Интерфейсы Telegram сервисов
|
||||
- **Services/** - Реализация Telegram сервисов
|
||||
|
||||
**Root Services:**
|
||||
- `AIService.cs` - Работа с AI
|
||||
- `ChatService.cs` - Управление чатами
|
||||
- `HistoryCompressionService.cs` - Сжатие истории
|
||||
- `DatabaseSessionStorage.cs` - Хранение в БД
|
||||
- `InMemorySessionStorage.cs` - Хранение в памяти
|
||||
- И другие...
|
||||
|
||||
### `/Migrations`
|
||||
|
||||
EF Core миграции базы данных.
|
||||
|
||||
### `/Prompts`
|
||||
|
||||
AI промпты.
|
||||
|
||||
- `system-prompt.txt` - Системный промпт для AI
|
||||
|
||||
## 🎯 Naming Conventions
|
||||
|
||||
### Файлы
|
||||
|
||||
- **Classes**: `PascalCase.cs` (например, `ChatService.cs`)
|
||||
- **Interfaces**: `IPascalCase.cs` (например, `IAIService.cs`)
|
||||
- **Tests**: `ClassNameTests.cs`
|
||||
|
||||
### Namespace
|
||||
|
||||
```csharp
|
||||
namespace ChatBot.Services
|
||||
namespace ChatBot.Models.Configuration
|
||||
namespace ChatBot.Data.Repositories
|
||||
```
|
||||
|
||||
Структура namespace соответствует структуре папок.
|
||||
|
||||
### Классы
|
||||
|
||||
```csharp
|
||||
public class ChatService // Service classes
|
||||
public interface IAIService // Interfaces (I prefix)
|
||||
public class ChatSession // Models
|
||||
public class ChatSessionEntity // Entities (Entity suffix)
|
||||
```
|
||||
|
||||
## 🔍 Зависимости между слоями
|
||||
|
||||
```
|
||||
Program.cs
|
||||
↓
|
||||
Services/
|
||||
↓
|
||||
Data/Repositories
|
||||
↓
|
||||
Data/ChatBotDbContext
|
||||
↓
|
||||
Models/Entities
|
||||
```
|
||||
|
||||
### Правила:
|
||||
- Services зависят от Interfaces
|
||||
- Repositories зависят от Entities
|
||||
- Models независимы
|
||||
- Presentation зависит от Services
|
||||
|
||||
## 📦 NuGet пакеты
|
||||
|
||||
### Основные
|
||||
|
||||
```xml
|
||||
<PackageReference Include="Telegram.Bot" Version="22.7.2" />
|
||||
<PackageReference Include="OllamaSharp" Version="5.4.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.10" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
|
||||
```
|
||||
|
||||
### Логирование
|
||||
|
||||
```xml
|
||||
<PackageReference Include="Serilog" Version="4.3.0" />
|
||||
<PackageReference Include="Serilog.Extensions.Hosting" Version="9.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||
```
|
||||
|
||||
### Validation
|
||||
|
||||
```xml
|
||||
<PackageReference Include="FluentValidation" Version="12.0.0" />
|
||||
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="12.0.0" />
|
||||
```
|
||||
|
||||
## 🧪 Тестовый проект
|
||||
|
||||
### Структура
|
||||
|
||||
```
|
||||
ChatBot.Tests/
|
||||
├── Common/ # Тесты констант
|
||||
├── Configuration/ # Тесты валидаторов
|
||||
├── Data/ # Тесты репозиториев и DbContext
|
||||
├── Integration/ # Интеграционные тесты
|
||||
├── Models/ # Тесты моделей
|
||||
├── Services/ # Тесты сервисов
|
||||
└── Telegram/ # Тесты Telegram функций
|
||||
```
|
||||
|
||||
### Naming Convention
|
||||
|
||||
```csharp
|
||||
public class ChatServiceTests
|
||||
{
|
||||
[Fact]
|
||||
public void ProcessMessage_ShouldReturnResponse()
|
||||
|
||||
[Theory]
|
||||
[InlineData(...)]
|
||||
public void Method_Scenario_ExpectedBehavior()
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 Configuration Files
|
||||
|
||||
### appsettings.json
|
||||
|
||||
Основная конфигурация приложения.
|
||||
|
||||
### appsettings.Development.json
|
||||
|
||||
Переопределения для Development режима.
|
||||
|
||||
### .env
|
||||
|
||||
Локальные переменные окружения (не в git).
|
||||
|
||||
### launchSettings.json
|
||||
|
||||
Настройки запуска для Visual Studio/Rider.
|
||||
|
||||
## 📝 Special Files
|
||||
|
||||
### Program.cs
|
||||
|
||||
Точка входа приложения:
|
||||
- Конфигурация DI
|
||||
- Регистрация сервисов
|
||||
- Инициализация логирования
|
||||
|
||||
### ChatBot.csproj
|
||||
|
||||
Project file:
|
||||
- Target Framework: net9.0
|
||||
- Package References
|
||||
- Build configurations
|
||||
|
||||
### ChatBot.sln
|
||||
|
||||
Solution file для Visual Studio.
|
||||
|
||||
## 🚀 Build Output
|
||||
|
||||
```
|
||||
bin/
|
||||
├── Debug/
|
||||
│ └── net9.0/
|
||||
├── Release/
|
||||
│ └── net9.0/
|
||||
obj/
|
||||
└── [Промежуточные файлы]
|
||||
```
|
||||
|
||||
## 📚 См. также
|
||||
|
||||
- [Сервисы](./services.md)
|
||||
- [Архитектура](../architecture/overview.md)
|
||||
- [Разработка команд](./telegram-integration.md)
|
||||
485
docs/installation.md
Normal file
485
docs/installation.md
Normal file
@@ -0,0 +1,485 @@
|
||||
# 🛠️ Установка и настройка
|
||||
|
||||
Подробное руководство по установке ChatBot со всеми опциями.
|
||||
|
||||
## 📋 Системные требования
|
||||
|
||||
### Минимальные требования
|
||||
- **OS**: Windows 10/11, Linux (Ubuntu 20.04+), macOS 12+
|
||||
- **RAM**: 4 GB (рекомендуется 8 GB+)
|
||||
- **CPU**: 2 cores (рекомендуется 4+ cores)
|
||||
- **Диск**: 10 GB свободного места
|
||||
- **Сеть**: Стабильное интернет-соединение
|
||||
|
||||
### Программное обеспечение
|
||||
- **.NET 9.0 SDK** - обязательно
|
||||
- **PostgreSQL 14+** - обязательно
|
||||
- **Ollama** - обязательно
|
||||
- **Git** - для клонирования
|
||||
- **Docker** (опционально) - для контейнеризации
|
||||
|
||||
## 📥 Установка зависимостей
|
||||
|
||||
### Windows
|
||||
|
||||
#### .NET 9.0 SDK
|
||||
```powershell
|
||||
# Скачайте с официального сайта
|
||||
# https://dotnet.microsoft.com/download/dotnet/9.0
|
||||
|
||||
# Или через winget
|
||||
winget install Microsoft.DotNet.SDK.9
|
||||
|
||||
# Проверка установки
|
||||
dotnet --version
|
||||
```
|
||||
|
||||
#### PostgreSQL
|
||||
```powershell
|
||||
# Скачайте с официального сайта
|
||||
# https://www.postgresql.org/download/windows/
|
||||
|
||||
# Или через chocolatey
|
||||
choco install postgresql
|
||||
|
||||
# Инициализация
|
||||
# Следуйте инструкциям установщика
|
||||
```
|
||||
|
||||
#### Ollama
|
||||
```powershell
|
||||
# Скачайте с официального сайта
|
||||
# https://ollama.ai/download
|
||||
|
||||
# Установка модели
|
||||
ollama pull gemma2:2b
|
||||
# или другую модель
|
||||
ollama pull llama3.2
|
||||
```
|
||||
|
||||
### Linux (Ubuntu/Debian)
|
||||
|
||||
#### .NET 9.0 SDK
|
||||
```bash
|
||||
# Добавление репозитория Microsoft
|
||||
wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
|
||||
sudo dpkg -i packages-microsoft-prod.deb
|
||||
rm packages-microsoft-prod.deb
|
||||
|
||||
# Установка SDK
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y dotnet-sdk-9.0
|
||||
|
||||
# Проверка
|
||||
dotnet --version
|
||||
```
|
||||
|
||||
#### PostgreSQL
|
||||
```bash
|
||||
# Установка
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y postgresql postgresql-contrib
|
||||
|
||||
# Запуск
|
||||
sudo systemctl start postgresql
|
||||
sudo systemctl enable postgresql
|
||||
|
||||
# Создание пользователя и БД
|
||||
sudo -u postgres psql
|
||||
CREATE USER chatbot WITH PASSWORD 'your_password';
|
||||
CREATE DATABASE chatbot OWNER chatbot;
|
||||
GRANT ALL PRIVILEGES ON DATABASE chatbot TO chatbot;
|
||||
\q
|
||||
```
|
||||
|
||||
#### Ollama
|
||||
```bash
|
||||
# Установка
|
||||
curl -fsSL https://ollama.ai/install.sh | sh
|
||||
|
||||
# Запуск сервиса
|
||||
sudo systemctl start ollama
|
||||
sudo systemctl enable ollama
|
||||
|
||||
# Установка модели
|
||||
ollama pull gemma2:2b
|
||||
```
|
||||
|
||||
### macOS
|
||||
|
||||
#### .NET 9.0 SDK
|
||||
```bash
|
||||
# Через Homebrew
|
||||
brew install --cask dotnet-sdk
|
||||
|
||||
# Проверка
|
||||
dotnet --version
|
||||
```
|
||||
|
||||
#### PostgreSQL
|
||||
```bash
|
||||
# Через Homebrew
|
||||
brew install postgresql@14
|
||||
|
||||
# Запуск
|
||||
brew services start postgresql@14
|
||||
|
||||
# Создание БД
|
||||
createdb chatbot
|
||||
```
|
||||
|
||||
#### Ollama
|
||||
```bash
|
||||
# Скачайте с официального сайта
|
||||
# https://ollama.ai/download
|
||||
|
||||
# Или через Homebrew
|
||||
brew install ollama
|
||||
|
||||
# Установка модели
|
||||
ollama pull gemma2:2b
|
||||
```
|
||||
|
||||
## 🔧 Настройка проекта
|
||||
|
||||
### 1. Клонирование репозитория
|
||||
|
||||
```bash
|
||||
git clone https://github.com/mrleo1nid/ChatBot.git
|
||||
cd ChatBot
|
||||
```
|
||||
|
||||
### 2. Настройка базы данных
|
||||
|
||||
#### Создание базы данных
|
||||
|
||||
**PostgreSQL:**
|
||||
```sql
|
||||
-- Подключение к PostgreSQL
|
||||
psql -U postgres
|
||||
|
||||
-- Создание пользователя
|
||||
CREATE USER chatbot WITH PASSWORD 'secure_password';
|
||||
|
||||
-- Создание базы данных
|
||||
CREATE DATABASE chatbot OWNER chatbot;
|
||||
|
||||
-- Выдача прав
|
||||
GRANT ALL PRIVILEGES ON DATABASE chatbot TO chatbot;
|
||||
|
||||
-- Выход
|
||||
\q
|
||||
```
|
||||
|
||||
#### Проверка подключения
|
||||
```bash
|
||||
psql -U chatbot -d chatbot -h localhost
|
||||
```
|
||||
|
||||
### 3. Конфигурация приложения
|
||||
|
||||
#### Создание .env файла
|
||||
|
||||
Создайте файл `ChatBot/.env`:
|
||||
|
||||
```env
|
||||
# Database Configuration
|
||||
DB_HOST=localhost
|
||||
DB_PORT=5432
|
||||
DB_NAME=chatbot
|
||||
DB_USER=chatbot
|
||||
DB_PASSWORD=your_secure_password
|
||||
|
||||
# Telegram Bot Configuration
|
||||
TELEGRAM_BOT_TOKEN=123456789:ABCdefGHIjklMNOpqrsTUVwxyz
|
||||
|
||||
# Ollama Configuration
|
||||
OLLAMA_URL=http://localhost:11434
|
||||
OLLAMA_DEFAULT_MODEL=gemma2:2b
|
||||
```
|
||||
|
||||
#### Настройка appsettings.json
|
||||
|
||||
Файл `ChatBot/appsettings.json` уже содержит настройки по умолчанию. Переменные окружения имеют приоритет.
|
||||
|
||||
#### User Secrets (для разработки)
|
||||
|
||||
```bash
|
||||
cd ChatBot
|
||||
|
||||
# Инициализация secrets
|
||||
dotnet user-secrets init
|
||||
|
||||
# Добавление секретов
|
||||
dotnet user-secrets set "TelegramBot:BotToken" "your_token_here"
|
||||
dotnet user-secrets set "Database:ConnectionString" "Host=localhost;Database=chatbot;Username=chatbot;Password=your_password"
|
||||
```
|
||||
|
||||
### 4. Настройка Telegram бота
|
||||
|
||||
#### Создание бота через BotFather
|
||||
|
||||
1. Откройте Telegram и найдите [@BotFather](https://t.me/botfather)
|
||||
2. Отправьте `/newbot`
|
||||
3. Следуйте инструкциям:
|
||||
- Введите имя бота (например: "My AI ChatBot")
|
||||
- Введите username (например: "my_ai_chatbot")
|
||||
4. Скопируйте токен и добавьте в `.env`
|
||||
|
||||
#### Настройка команд бота (опционально)
|
||||
|
||||
```
|
||||
/setcommands
|
||||
|
||||
start - Начать работу с ботом
|
||||
help - Показать справку
|
||||
clear - Очистить историю диалога
|
||||
settings - Показать текущие настройки
|
||||
status - Проверить статус бота
|
||||
```
|
||||
|
||||
### 5. Установка AI модели
|
||||
|
||||
```bash
|
||||
# Просмотр доступных моделей
|
||||
ollama list
|
||||
|
||||
# Установка модели
|
||||
ollama pull gemma2:2b
|
||||
|
||||
# Или другие модели:
|
||||
ollama pull llama3.2
|
||||
ollama pull mistral
|
||||
ollama pull phi3
|
||||
|
||||
# Проверка
|
||||
ollama list
|
||||
```
|
||||
|
||||
### 6. Применение миграций
|
||||
|
||||
```bash
|
||||
cd ChatBot
|
||||
|
||||
# Автоматически применяются при первом запуске
|
||||
# Или вручную:
|
||||
dotnet ef database update
|
||||
|
||||
# Проверка миграций
|
||||
dotnet ef migrations list
|
||||
```
|
||||
|
||||
### 7. Сборка проекта
|
||||
|
||||
```bash
|
||||
# Восстановление зависимостей
|
||||
dotnet restore
|
||||
|
||||
# Сборка
|
||||
dotnet build
|
||||
|
||||
# Проверка на ошибки
|
||||
dotnet build --configuration Release
|
||||
```
|
||||
|
||||
## 🚀 Запуск приложения
|
||||
|
||||
### Режим разработки
|
||||
|
||||
```bash
|
||||
cd ChatBot
|
||||
dotnet run
|
||||
```
|
||||
|
||||
### Режим production
|
||||
|
||||
```bash
|
||||
# Сборка релиза
|
||||
dotnet publish -c Release -o ./publish
|
||||
|
||||
# Запуск
|
||||
cd publish
|
||||
dotnet ChatBot.dll
|
||||
```
|
||||
|
||||
### Запуск как служба (Windows)
|
||||
|
||||
```powershell
|
||||
# Создание службы
|
||||
sc.exe create ChatBot binPath="C:\path\to\publish\ChatBot.exe"
|
||||
|
||||
# Запуск
|
||||
sc.exe start ChatBot
|
||||
|
||||
# Остановка
|
||||
sc.exe stop ChatBot
|
||||
|
||||
# Удаление
|
||||
sc.exe delete ChatBot
|
||||
```
|
||||
|
||||
### Запуск как службы (Linux)
|
||||
|
||||
Создайте файл `/etc/systemd/system/chatbot.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=ChatBot Telegram Bot
|
||||
After=network.target postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
WorkingDirectory=/opt/chatbot
|
||||
ExecStart=/usr/bin/dotnet /opt/chatbot/ChatBot.dll
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
User=chatbot
|
||||
Environment=DOTNET_ENVIRONMENT=Production
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Запуск:
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable chatbot
|
||||
sudo systemctl start chatbot
|
||||
sudo systemctl status chatbot
|
||||
```
|
||||
|
||||
## 🐳 Docker установка
|
||||
|
||||
### Создание Dockerfile
|
||||
|
||||
Файл уже включен в проект. Для сборки:
|
||||
|
||||
```bash
|
||||
# Сборка образа
|
||||
docker build -t chatbot:latest .
|
||||
|
||||
# Запуск контейнера
|
||||
docker run -d \
|
||||
--name chatbot \
|
||||
--env-file .env \
|
||||
-v $(pwd)/logs:/app/logs \
|
||||
chatbot:latest
|
||||
```
|
||||
|
||||
### Docker Compose
|
||||
|
||||
Создайте `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:14-alpine
|
||||
environment:
|
||||
POSTGRES_DB: chatbot
|
||||
POSTGRES_USER: chatbot
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
ports:
|
||||
- "5432:5432"
|
||||
|
||||
chatbot:
|
||||
build: .
|
||||
depends_on:
|
||||
- postgres
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- ./logs:/app/logs
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
```
|
||||
|
||||
Запуск:
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
## ✅ Проверка установки
|
||||
|
||||
### 1. Проверка компонентов
|
||||
|
||||
```bash
|
||||
# .NET
|
||||
dotnet --version
|
||||
|
||||
# PostgreSQL
|
||||
psql --version
|
||||
pg_isready
|
||||
|
||||
# Ollama
|
||||
curl http://localhost:11434/api/tags
|
||||
```
|
||||
|
||||
### 2. Проверка подключений
|
||||
|
||||
```bash
|
||||
# PostgreSQL
|
||||
psql -U chatbot -d chatbot -h localhost -c "SELECT version();"
|
||||
|
||||
# Ollama
|
||||
ollama list
|
||||
```
|
||||
|
||||
### 3. Проверка логов
|
||||
|
||||
```bash
|
||||
# Логи приложения
|
||||
tail -f ChatBot/logs/telegram-bot-*.log
|
||||
|
||||
# Docker логи
|
||||
docker logs -f chatbot
|
||||
```
|
||||
|
||||
### 4. Тестирование бота
|
||||
|
||||
1. Откройте Telegram
|
||||
2. Найдите вашего бота
|
||||
3. Отправьте `/start`
|
||||
4. Отправьте любое сообщение
|
||||
|
||||
## 🔍 Troubleshooting
|
||||
|
||||
### Ошибка "Unable to connect to PostgreSQL"
|
||||
|
||||
```bash
|
||||
# Проверка статуса
|
||||
sudo systemctl status postgresql
|
||||
|
||||
# Проверка порта
|
||||
netstat -tulpn | grep 5432
|
||||
|
||||
# Проверка настроек pg_hba.conf
|
||||
sudo nano /etc/postgresql/14/main/pg_hba.conf
|
||||
```
|
||||
|
||||
### Ошибка "Ollama connection failed"
|
||||
|
||||
```bash
|
||||
# Запуск Ollama
|
||||
ollama serve
|
||||
|
||||
# Проверка доступности
|
||||
curl http://localhost:11434/api/tags
|
||||
```
|
||||
|
||||
### Ошибка "Invalid bot token"
|
||||
|
||||
- Проверьте правильность токена в `.env`
|
||||
- Убедитесь, что токен активен через @BotFather
|
||||
- Перезапустите приложение
|
||||
|
||||
## 📚 Следующие шаги
|
||||
|
||||
- [Конфигурация](./configuration.md) - Детальная настройка параметров
|
||||
- [Разработка](./development/project-structure.md) - Структура проекта
|
||||
- [Deployment](./deployment/docker.md) - Production развертывание
|
||||
144
docs/overview.md
Normal file
144
docs/overview.md
Normal file
@@ -0,0 +1,144 @@
|
||||
# 📋 Обзор проекта ChatBot
|
||||
|
||||
## 🎯 Что такое ChatBot?
|
||||
|
||||
**ChatBot** — это интеллектуальный Telegram-бот, использующий локальные AI модели через Ollama для создания естественных диалогов. Бот имитирует общение реального человека с индивидуальным характером и стилем общения.
|
||||
|
||||
## ✨ Основные возможности
|
||||
|
||||
### 🤖 AI-функциональность
|
||||
- **Интеграция с Ollama** - Использование локальных LLM моделей
|
||||
- **Контекстное общение** - Бот помнит историю диалога
|
||||
- **Сжатие истории** - Автоматическая оптимизация длинных диалогов
|
||||
- **Настраиваемый промпт** - Гибкая настройка личности бота
|
||||
- **Множественные модели** - Поддержка различных AI моделей
|
||||
|
||||
### 💬 Telegram функции
|
||||
- **Команды бота** - `/start`, `/help`, `/clear`, `/settings`, `/status`
|
||||
- **Групповые чаты** - Работа в приватных чатах и группах
|
||||
- **Обработка ошибок** - Устойчивость к сбоям
|
||||
- **Retry механизм** - Автоматические повторные попытки
|
||||
- **Health checks** - Мониторинг состояния сервисов
|
||||
|
||||
### 💾 Управление данными
|
||||
- **PostgreSQL** - Хранение сессий и истории
|
||||
- **Entity Framework Core** - ORM для работы с БД
|
||||
- **Миграции** - Автоматическое обновление схемы БД
|
||||
- **In-Memory опция** - Альтернативное хранилище для тестов
|
||||
|
||||
### 🛠️ Технические особенности
|
||||
- **.NET 9.0** - Современная платформа
|
||||
- **Dependency Injection** - Управление зависимостями
|
||||
- **Serilog** - Структурированное логирование
|
||||
- **FluentValidation** - Валидация конфигурации
|
||||
- **Health Checks** - Проверка работоспособности
|
||||
|
||||
## 🏗️ Архитектура
|
||||
|
||||
Проект построен на принципах:
|
||||
- **Clean Architecture** - Разделение на слои
|
||||
- **SOLID принципы** - Качественный дизайн кода
|
||||
- **Dependency Inversion** - Зависимость от абстракций
|
||||
- **Repository Pattern** - Абстракция доступа к данным
|
||||
- **Service Layer** - Бизнес-логика в сервисах
|
||||
|
||||
### Основные слои:
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Telegram Bot Layer │
|
||||
│ (TelegramBotService, Commands) │
|
||||
├─────────────────────────────────────┤
|
||||
│ Service Layer │
|
||||
│ (ChatService, AIService, etc.) │
|
||||
├─────────────────────────────────────┤
|
||||
│ Data Access Layer │
|
||||
│ (Repositories, DbContext) │
|
||||
├─────────────────────────────────────┤
|
||||
│ Infrastructure │
|
||||
│ (PostgreSQL, Ollama) │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 🔧 Технологический стек
|
||||
|
||||
### Backend
|
||||
- **Runtime**: .NET 9.0
|
||||
- **Language**: C# 13
|
||||
- **Архитектура**: Worker Service
|
||||
|
||||
### Библиотеки
|
||||
- **Telegram.Bot** 22.7.2 - Telegram Bot API
|
||||
- **OllamaSharp** 5.4.7 - Ollama клиент
|
||||
- **Entity Framework Core** 9.0.10 - ORM
|
||||
- **Npgsql** 9.0.4 - PostgreSQL провайдер
|
||||
- **Serilog** 4.3.0 - Логирование
|
||||
- **FluentValidation** 12.0.0 - Валидация
|
||||
|
||||
### База данных
|
||||
- **PostgreSQL** - Основное хранилище
|
||||
- **In-Memory** - Опция для разработки
|
||||
|
||||
### Тестирование
|
||||
- **xUnit** 2.9.3 - Тестовый фреймворк
|
||||
- **Moq** 4.20.72 - Моки
|
||||
- **FluentAssertions** 8.7.1 - Assertions
|
||||
- **Coverlet** 6.0.4 - Code coverage
|
||||
|
||||
### DevOps
|
||||
- **Docker** - Контейнеризация
|
||||
- **Gitea Actions** - CI/CD
|
||||
- **SonarQube** - Анализ кода
|
||||
|
||||
## 📊 Статистика проекта
|
||||
|
||||
- **Языки**: C#
|
||||
- **Файлов кода**: ~100+
|
||||
- **Тестов**: 50+ test classes
|
||||
- **Покрытие кода**: ~80%+
|
||||
- **Target Framework**: .NET 9.0
|
||||
|
||||
## 🎭 Особенности реализации
|
||||
|
||||
### Умная обработка сообщений
|
||||
Бот использует специальные маркеры в ответах AI:
|
||||
- `{empty}` - Игнорировать сообщение (не для него)
|
||||
- Контекстная обработка групповых чатов
|
||||
- Распознавание обращений по имени
|
||||
|
||||
### Оптимизация памяти
|
||||
- Автоматическое сжатие длинной истории
|
||||
- Сохранение системного промпта
|
||||
- Настраиваемые лимиты сообщений
|
||||
|
||||
### Отказоустойчивость
|
||||
- Retry механизм с экспоненциальным backoff
|
||||
- Обработка таймаутов
|
||||
- Health checks для мониторинга
|
||||
|
||||
## 🔐 Безопасность
|
||||
|
||||
- Переменные окружения для секретов
|
||||
- User Secrets для разработки
|
||||
- Валидация конфигурации при старте
|
||||
- Безопасное хранение токенов
|
||||
|
||||
## 🌟 Преимущества
|
||||
|
||||
1. **Модульность** - Легко расширяемая архитектура
|
||||
2. **Тестируемость** - Высокое покрытие тестами
|
||||
3. **Производительность** - Асинхронная обработка
|
||||
4. **Надежность** - Retry механизмы и обработка ошибок
|
||||
5. **Масштабируемость** - Готовность к росту нагрузки
|
||||
|
||||
## 📈 Планы развития
|
||||
|
||||
- [ ] Поддержка мультимодальных моделей
|
||||
- [ ] Веб-интерфейс для управления
|
||||
- [ ] Метрики и аналитика
|
||||
- [ ] Kubernetes deployment
|
||||
- [ ] Дополнительные команды
|
||||
- [ ] Плагинная система
|
||||
|
||||
## 🤝 Вклад в проект
|
||||
|
||||
Проект открыт для contributions! См. [Contributing Guide](./contributing.md) для деталей.
|
||||
148
docs/quickstart.md
Normal file
148
docs/quickstart.md
Normal file
@@ -0,0 +1,148 @@
|
||||
# 🚀 Быстрый старт
|
||||
|
||||
Запустите ChatBot за 5 минут!
|
||||
|
||||
## ⚡ Минимальные требования
|
||||
|
||||
- **.NET 9.0 SDK** ([скачать](https://dotnet.microsoft.com/download/dotnet/9.0))
|
||||
- **PostgreSQL 14+** ([скачать](https://www.postgresql.org/download/))
|
||||
- **Ollama** с установленной моделью ([установить](https://ollama.ai/))
|
||||
- **Telegram Bot Token** ([создать через @BotFather](https://t.me/botfather))
|
||||
|
||||
## 📋 Шаги установки
|
||||
|
||||
### 1️⃣ Клонирование репозитория
|
||||
|
||||
```bash
|
||||
git clone https://github.com/mrleo1nid/ChatBot.git
|
||||
cd ChatBot
|
||||
```
|
||||
|
||||
### 2️⃣ Установка Ollama и модели
|
||||
|
||||
```bash
|
||||
# Установите Ollama с официального сайта
|
||||
# https://ollama.ai/
|
||||
|
||||
# Загрузите модель (например, gemma2)
|
||||
ollama pull gemma2:2b
|
||||
```
|
||||
|
||||
### 3️⃣ Настройка PostgreSQL
|
||||
|
||||
```bash
|
||||
# Создайте базу данных
|
||||
psql -U postgres
|
||||
CREATE DATABASE chatbot;
|
||||
\q
|
||||
```
|
||||
|
||||
### 4️⃣ Создание .env файла
|
||||
|
||||
Создайте файл `.env` в папке `ChatBot/`:
|
||||
|
||||
```env
|
||||
# Database Configuration
|
||||
DB_HOST=localhost
|
||||
DB_PORT=5432
|
||||
DB_NAME=chatbot
|
||||
DB_USER=postgres
|
||||
DB_PASSWORD=your_password
|
||||
|
||||
# Telegram Bot Configuration
|
||||
TELEGRAM_BOT_TOKEN=your_bot_token_here
|
||||
|
||||
# Ollama Configuration
|
||||
OLLAMA_URL=http://localhost:11434
|
||||
OLLAMA_DEFAULT_MODEL=gemma2:2b
|
||||
```
|
||||
|
||||
### 5️⃣ Запуск приложения
|
||||
|
||||
```bash
|
||||
# Восстановление зависимостей
|
||||
dotnet restore
|
||||
|
||||
# Применение миграций (автоматически при первом запуске)
|
||||
# или вручную:
|
||||
dotnet ef database update --project ChatBot
|
||||
|
||||
# Запуск
|
||||
dotnet run --project ChatBot
|
||||
```
|
||||
|
||||
## 🎉 Готово!
|
||||
|
||||
Теперь откройте Telegram и найдите вашего бота. Отправьте `/start` для начала общения.
|
||||
|
||||
## 📱 Первые команды
|
||||
|
||||
```
|
||||
/start - Начать работу с ботом
|
||||
/help - Показать все команды
|
||||
/clear - Очистить историю диалога
|
||||
/settings - Текущие настройки
|
||||
/status - Статус бота
|
||||
```
|
||||
|
||||
## 🐳 Альтернатива: Docker
|
||||
|
||||
```bash
|
||||
# Сборка образа
|
||||
docker build -t chatbot .
|
||||
|
||||
# Запуск с docker-compose
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
## 🔧 Проверка работы
|
||||
|
||||
### Проверка Ollama
|
||||
```bash
|
||||
curl http://localhost:11434/api/tags
|
||||
```
|
||||
|
||||
### Проверка PostgreSQL
|
||||
```bash
|
||||
psql -U postgres -d chatbot -c "SELECT * FROM chat_sessions;"
|
||||
```
|
||||
|
||||
### Просмотр логов
|
||||
Логи находятся в папке `ChatBot/logs/`:
|
||||
```bash
|
||||
tail -f ChatBot/logs/telegram-bot-*.log
|
||||
```
|
||||
|
||||
## ❓ Проблемы?
|
||||
|
||||
### Ollama недоступен
|
||||
```bash
|
||||
# Проверьте статус
|
||||
systemctl status ollama # Linux
|
||||
# или запустите вручную
|
||||
ollama serve
|
||||
```
|
||||
|
||||
### Ошибка подключения к БД
|
||||
```bash
|
||||
# Проверьте PostgreSQL
|
||||
pg_isready -h localhost -p 5432
|
||||
```
|
||||
|
||||
### Неверный токен бота
|
||||
- Получите новый токен через [@BotFather](https://t.me/botfather)
|
||||
- Обновите `TELEGRAM_BOT_TOKEN` в `.env`
|
||||
|
||||
## 📚 Следующие шаги
|
||||
|
||||
- [Полная установка и настройка](./installation.md)
|
||||
- [Конфигурация](./configuration.md)
|
||||
- [Архитектура проекта](./architecture/overview.md)
|
||||
- [Разработка](./development/project-structure.md)
|
||||
|
||||
## 💡 Полезные ссылки
|
||||
|
||||
- [Ollama Models](https://ollama.ai/library)
|
||||
- [Telegram Bot API](https://core.telegram.org/bots/api)
|
||||
- [PostgreSQL Documentation](https://www.postgresql.org/docs/)
|
||||
- [.NET Documentation](https://docs.microsoft.com/dotnet/)
|
||||
Reference in New Issue
Block a user