488 lines
24 KiB
Markdown
488 lines
24 KiB
Markdown
# SYSTEM AUDIT: LawBot
|
||
|
||
## 1. Что это за проект
|
||
|
||
`LawBot` — это Telegram-бот, который:
|
||
|
||
1. принимает вопрос пользователя;
|
||
2. ищет подходящие нормы закона РФ;
|
||
3. достает текст из своей базы;
|
||
4. передает найденные фрагменты в LLM;
|
||
5. возвращает пользователю ответ простыми словами.
|
||
|
||
Проект состоит из 4 основных частей:
|
||
|
||
| Часть | Папка | Что делает |
|
||
|---|---|---|
|
||
| Telegram-бот | `bot/` | Общается с пользователем в Telegram |
|
||
| API для RAG | `api/` | Делает поиск по законам и генерацию ответа |
|
||
| Парсер законов | `parser/` | Скачивает и нормализует документы |
|
||
| Общий слой БД | `shared/` | Хранит модели БД и методы работы с БД |
|
||
|
||
---
|
||
|
||
## 2. Архитектура проекта
|
||
|
||
### 2.1. Общая схема
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
User["Пользователь Telegram"]
|
||
Bot["bot/\nAiogram bot"]
|
||
Api["api/\nFastAPI RAG API"]
|
||
Parser["parser/\nCLI parser"]
|
||
Shared["shared/\nDB layer"]
|
||
Pg["PostgreSQL"]
|
||
Redis["Redis"]
|
||
Chroma["ChromaDB"]
|
||
LLM["OpenRouter LLM"]
|
||
Embed["Local embedding model"]
|
||
Consultant["consultant.ru"]
|
||
|
||
User --> Bot
|
||
Bot --> Api
|
||
Bot --> Shared
|
||
Bot --> Redis
|
||
|
||
Api --> Shared
|
||
Api --> Chroma
|
||
Api --> LLM
|
||
Api --> Embed
|
||
|
||
Shared --> Pg
|
||
|
||
Parser --> Consultant
|
||
Parser --> Shared
|
||
Parser --> Pg
|
||
```
|
||
|
||
### 2.2. Что запускается в Docker Compose
|
||
|
||
Файл: [compose.yml](/home/ruby/Desktop/DockerProjects/LawBot/compose.yml:1)
|
||
|
||
| Сервис | Образ / Dockerfile | Назначение | Порт |
|
||
|---|---|---|---|
|
||
| `tgbot` | `bot/Dockerfile` | Telegram-бот | нет внешнего порта |
|
||
| `api` | `api/Dockerfile` | FastAPI RAG API | `8080` |
|
||
| `postgredb` | `postgres:16-alpine` | Основная БД | нет внешнего порта |
|
||
| `redisdb` | `redis:6-alpine` | FSM/storage для aiogram | нет внешнего порта |
|
||
| `chromadb` | `chromadb/chroma:1.0.12` | Векторный поиск | `8000` |
|
||
|
||
Важно: отдельного контейнера для `parser/` нет. Парсер запускается командой внутри контейнера `tgbot`.
|
||
|
||
---
|
||
|
||
## 3. Структура директорий
|
||
|
||
### 3.1. Корень проекта
|
||
|
||
| Путь | Назначение |
|
||
|---|---|
|
||
| `compose.yml` | Запуск всех сервисов |
|
||
| `README.md` | Краткая инструкция по запуску |
|
||
| `mvp.md` | Текстовое описание MVP |
|
||
| `postgres.env` | Настройки подключения к PostgreSQL |
|
||
| `postgres.env.example` | Пример env для PostgreSQL |
|
||
| `SYSTEM_AUDIT.md` | Этот аудит |
|
||
| `volumes/` | Постоянные данные контейнеров |
|
||
| `protocol/` | Документы для курсовой |
|
||
|
||
### 3.2. Папка `api/`
|
||
|
||
| Путь | Назначение |
|
||
|---|---|
|
||
| `api/main.py` | Точка входа FastAPI |
|
||
| `api/config.py` | Чтение env-переменных API |
|
||
| `api/deps.py` | Создание singleton-зависимостей |
|
||
| `api/schemas.py` | Pydantic-схемы API |
|
||
| `api/logging.py` | Настройка логов API |
|
||
| `api/routers/` | HTTP-роуты (`health`, `indexing`, `rag`) |
|
||
| `api/services/` | Основная логика: embeddings, retrieval, indexing, LLM |
|
||
| `api/clients/` | Клиенты для OpenRouter и Chroma |
|
||
| `api/prompts/` | Промпты для классификации и ответа |
|
||
| `api/requirements.txt` | Зависимости API |
|
||
| `api/Dockerfile` | Сборка контейнера API |
|
||
|
||
### 3.3. Папка `bot/`
|
||
|
||
| Путь | Назначение |
|
||
|---|---|
|
||
| `bot/aiogram_run.py` | Точка входа Telegram-бота |
|
||
| `bot/create_bot.py` | Создание Bot / Dispatcher / Redis / ORM |
|
||
| `bot/handlers/` | Обработчики команд, кнопок и сценариев |
|
||
| `bot/keyboards/` | Reply и inline клавиатуры |
|
||
| `bot/middlewares/` | Антифлуд, blacklist, album middleware |
|
||
| `bot/states/` | FSM состояния aiogram |
|
||
| `bot/utils/rag_api.py` | HTTP-клиент бота для вызова `api` |
|
||
| `bot/utils/text_tools.py` | Форматирование и нарезка текста для Telegram |
|
||
| `bot/templates/` | Шаблоны файлов (`users.xlsx`) |
|
||
| `bot/requirements.txt` | Зависимости бота |
|
||
| `bot/Dockerfile` | Сборка контейнера бота |
|
||
| `bot/webhooks.py` | Отдельный тестовый FastAPI webhook, не подключен к `compose.yml` |
|
||
|
||
### 3.4. Папка `parser/`
|
||
|
||
| Путь | Назначение |
|
||
|---|---|
|
||
| `parser/__main__.py` | Позволяет запускать `python -m parser` |
|
||
| `parser/cli.py` | CLI-команды `discover/fetch/normalize/ingest/run` |
|
||
| `parser/config.py` | Список целевых документов и пути сохранения |
|
||
| `parser/discovery.py` | Проверка категорий на `consultant.ru/popular/` |
|
||
| `parser/fetcher.py` | Скачивание root HTML и страниц статей |
|
||
| `parser/normalizer.py` | Разбор HTML и сборка нормализованного JSON |
|
||
| `parser/ingest.py` | Запись документов и чанков в PostgreSQL |
|
||
| `parser/utils.py` | Общие функции парсера |
|
||
|
||
### 3.5. Папка `shared/`
|
||
|
||
| Путь | Назначение |
|
||
|---|---|
|
||
| `shared/models.py` | SQLAlchemy-модели |
|
||
| `shared/repositories.py` | Класс `ORM` и методы работы с БД |
|
||
| `shared/engine.py` | Создание async engine и sessionmaker |
|
||
| `shared/types.py` | Вспомогательные типы |
|
||
| `shared/__init__.py` | Единая точка импорта DB-слоя |
|
||
|
||
### 3.6. Папка `protocol/`
|
||
|
||
| Путь | Назначение |
|
||
|---|---|
|
||
| `protocol/generate_protocol_docx.py` | Генератор `.docx` протокола курсовой |
|
||
| `protocol/Протокол_курсовой_работы_LawBot.docx` | Готовый документ |
|
||
| `protocol/task/` | Входные материалы задания |
|
||
|
||
### 3.7. Папка `volumes/`
|
||
|
||
| Путь | Назначение |
|
||
|---|---|
|
||
| `volumes/postgres/` | Данные PostgreSQL |
|
||
| `volumes/chroma/` | Данные ChromaDB |
|
||
| `volumes/huggingface/` | Кеш embedding-модели |
|
||
| `volumes/parser/` | Артефакты парсера: raw, normalized, state |
|
||
|
||
---
|
||
|
||
## 4. Ключевые сервисы, модули и точки входа
|
||
|
||
### 4.1. Точки входа
|
||
|
||
| Компонент | Точка входа | Что происходит |
|
||
|---|---|---|
|
||
| Telegram-бот | [bot/aiogram_run.py](/home/ruby/Desktop/DockerProjects/LawBot/bot/aiogram_run.py:1) | Поднимает bot, middleware, routers и polling |
|
||
| FastAPI API | [api/main.py](/home/ruby/Desktop/DockerProjects/LawBot/api/main.py:1) | Поднимает API, проверяет БД, запускает автоиндексацию |
|
||
| Парсер | [parser/__main__.py](/home/ruby/Desktop/DockerProjects/LawBot/parser/__main__.py:1) -> [parser/cli.py](/home/ruby/Desktop/DockerProjects/LawBot/parser/cli.py:1) | Запускает CLI пайплайн |
|
||
|
||
### 4.2. Основные модули API
|
||
|
||
| Модуль | Файл | Роль |
|
||
|---|---|---|
|
||
| Конфиг | `api/config.py` | Читает env и хранит настройки |
|
||
| Роуты | `api/routers/rag.py` | `/search` и `/answer` |
|
||
| Индексация | `api/routers/indexing.py` | `/api/v1/index/rebuild` |
|
||
| Retrieval | `api/services/retrieval.py` | Гибридный поиск: Postgres FTS + Chroma |
|
||
| Индексация | `api/services/indexing.py` | Перенос чанков из Postgres в Chroma |
|
||
| Embeddings | `api/services/local_embeddings.py` | Локальные эмбеддинги через `sentence-transformers` |
|
||
| LLM-логика | `api/services/legal_ai.py` | Классификация, генерация ответа, заголовка консультации |
|
||
| Векторное хранилище | `api/clients/chroma_store.py` | Работа с Chroma |
|
||
| LLM-клиент | `api/clients/openrouter_client.py` | AsyncOpenAI-клиент для OpenRouter |
|
||
|
||
### 4.3. Основные модули бота
|
||
|
||
| Модуль | Файл | Роль |
|
||
|---|---|---|
|
||
| Создание бота | `bot/create_bot.py` | Bot, Dispatcher, RedisStorage, ORM, timezone |
|
||
| Главный запуск | `bot/aiogram_run.py` | Сборка всех роутеров |
|
||
| Пользовательский сценарий | `bot/handlers/client/main.py` | Вопрос -> регион -> ответ -> история |
|
||
| Админка | `bot/handlers/admin/*.py` | Статистика, blacklist, рассылка, настройки |
|
||
| HTTP-клиент к API | `bot/utils/rag_api.py` | Отправляет запросы в FastAPI |
|
||
| Форматирование | `bot/utils/text_tools.py` | Подготовка текста под Telegram HTML |
|
||
|
||
### 4.4. Основные модули парсера
|
||
|
||
| Модуль | Файл | Роль |
|
||
|---|---|---|
|
||
| Discovery | `parser/discovery.py` | Собирает manifest целевых документов |
|
||
| Fetch | `parser/fetcher.py` | Скачивает страницы документов |
|
||
| Normalize | `parser/normalizer.py` | Превращает HTML в нормализованный JSON |
|
||
| Ingest | `parser/ingest.py` | Пишет `law_sources` и `law_chunks` в БД |
|
||
|
||
### 4.5. Основной DB-слой
|
||
|
||
| Модуль | Файл | Роль |
|
||
|---|---|---|
|
||
| ORM | `shared/repositories.py` | Все операции с PostgreSQL |
|
||
| Модели | `shared/models.py` | Таблицы пользователей, консультаций, законов, чанков |
|
||
|
||
---
|
||
|
||
## 5. Кто за что отвечает
|
||
|
||
| Сервис / модуль | Отвечает за |
|
||
|---|---|
|
||
| `tgbot` | UI для пользователя и администратора |
|
||
| `api` | Поиск по законам и генерацию ответа |
|
||
| `parser` | Наполнение базы законами |
|
||
| `shared` | Единый доступ к PostgreSQL |
|
||
| `postgredb` | Хранение пользователей, консультаций, законов и чанков |
|
||
| `redisdb` | Хранение FSM-состояний aiogram |
|
||
| `chromadb` | Векторный индекс чанков |
|
||
| `OpenRouter` | LLM для классификации и ответа |
|
||
| Локальная embedding-модель | Преобразование текста в векторы |
|
||
|
||
---
|
||
|
||
## 6. Переменные окружения
|
||
|
||
### 6.1. `bot/.env`
|
||
|
||
Источник: [bot/.env.example](/home/ruby/Desktop/DockerProjects/LawBot/bot/.env.example:1)
|
||
|
||
| Переменная | Назначение |
|
||
|---|---|
|
||
| `TOKEN` | Telegram bot token |
|
||
| `TELEGRAM_BOT_PROXY` | Прокси для Telegram Bot API |
|
||
| `BASE_ADMIN` | Telegram ID администратора |
|
||
| `RAG_API_URL` | URL FastAPI сервиса |
|
||
| `REDIS_URL` | Подключение к Redis |
|
||
| `POSTGRES_DB` | Имя БД |
|
||
| `POSTGRES_USER` | Логин БД |
|
||
| `POSTGRES_PASSWORD` | Пароль БД |
|
||
| `POSTGRES_HOST` | Хост PostgreSQL |
|
||
| `POSTGRES_PORT` | Порт PostgreSQL |
|
||
| `TIMEZONE` | Часовой пояс для отображения дат |
|
||
|
||
### 6.2. `api/.env`
|
||
|
||
Источник: [api/.env.example](/home/ruby/Desktop/DockerProjects/LawBot/api/.env.example:1)
|
||
|
||
| Переменная | Назначение |
|
||
|---|---|
|
||
| `OPENAI_BASE_URL` | Базовый URL OpenRouter |
|
||
| `OPENAI_API_KEY` | Ключ доступа к OpenRouter |
|
||
| `LLM_MODEL` | Модель LLM для классификации и ответа |
|
||
| `EMBEDDING_MODEL` | Локальная embedding-модель |
|
||
| `EMBEDDING_DEVICE` | Устройство (`cpu`) |
|
||
| `CHROMA_HOST` | Хост ChromaDB |
|
||
| `CHROMA_PORT` | Порт ChromaDB |
|
||
| `CHROMA_COLLECTION` | Название коллекции Chroma |
|
||
| `CHROMA_SSL` | Использовать ли SSL |
|
||
| `RAG_TOP_K` | Дефолтное число результатов RAG |
|
||
| `FTS_TOP_K` | Сколько брать из full-text поиска |
|
||
| `VECTOR_TOP_K` | Сколько брать из vector search |
|
||
| `INDEX_BATCH_SIZE` | Размер батча для индексации и embeddings |
|
||
| `LLM_TIMEOUT_SECONDS` | Таймаут LLM-запросов |
|
||
| `API_HOST` | Хост FastAPI |
|
||
| `API_PORT` | Порт FastAPI |
|
||
| `LOG_LEVEL` | Уровень логов |
|
||
| `AUTO_INDEX_ON_STARTUP` | Запускать ли автоиндексацию при старте API |
|
||
| `AUTO_INDEX_ONLY_IF_EMPTY` | Индексировать только если Chroma пустая/не синхронизирована |
|
||
| `AUTO_INDEX_RESET_COLLECTION` | Сбрасывать ли коллекцию при автоиндексации |
|
||
| `AUTO_INDEX_RETRY_DELAY_SECONDS` | Пауза между попытками автоиндексации |
|
||
| `AUTO_INDEX_MAX_ATTEMPTS` | Максимум попыток автоиндексации |
|
||
|
||
### 6.3. `postgres.env`
|
||
|
||
Источник: [postgres.env.example](/home/ruby/Desktop/DockerProjects/LawBot/postgres.env.example:1)
|
||
|
||
| Переменная | Назначение |
|
||
|---|---|
|
||
| `POSTGRES_DB` | Имя БД PostgreSQL |
|
||
| `POSTGRES_USER` | Пользователь БД |
|
||
| `POSTGRES_PASSWORD` | Пароль БД |
|
||
| `POSTGRES_HOST` | Хост БД |
|
||
| `POSTGRES_PORT` | Порт БД |
|
||
|
||
---
|
||
|
||
## 7. Основные таблицы данных
|
||
|
||
Источник: [shared/models.py](/home/ruby/Desktop/DockerProjects/LawBot/shared/models.py:1)
|
||
|
||
| Таблица | Назначение |
|
||
|---|---|
|
||
| `users` | Пользователи Telegram |
|
||
| `admins` | Администраторы |
|
||
| `blacklist` | Заблокированные пользователи |
|
||
| `settings` | Настройки бота |
|
||
| `consultations` | Диалоги пользователя с ботом |
|
||
| `messages` | Сообщения внутри консультаций |
|
||
| `rag_queries` | История поисковых запросов и найденных чанков |
|
||
| `law_sources` | Документы законов |
|
||
| `law_chunks` | Чанки статей законов |
|
||
|
||
---
|
||
|
||
## 8. Потоки данных
|
||
|
||
### 8.1. Поток ответа пользователю
|
||
|
||
1. Пользователь пишет в Telegram.
|
||
2. `bot/handlers/client/main.py` принимает сообщение.
|
||
3. Бот вызывает `bot/utils/rag_api.py`.
|
||
4. HTTP-запрос уходит в `POST /api/v1/rag/answer`.
|
||
5. `api/services/legal_ai.py` классифицирует вопрос.
|
||
6. `api/services/retrieval.py` ищет чанки:
|
||
- через PostgreSQL full-text search;
|
||
- через Chroma vector search.
|
||
7. `api/services/legal_ai.py` генерирует ответ через OpenRouter.
|
||
8. Если `save_history=true`, API сохраняет:
|
||
- консультацию;
|
||
- сообщения;
|
||
- rag-запрос.
|
||
9. Бот получает ответ, форматирует его и отправляет в Telegram.
|
||
|
||
### 8.2. Поток загрузки законов
|
||
|
||
1. Команда `python -m parser run`.
|
||
2. `parser/discovery.py` собирает manifest.
|
||
3. `parser/fetcher.py` скачивает root HTML и статьи.
|
||
4. `parser/normalizer.py` делает нормализованный JSON.
|
||
5. `parser/ingest.py` записывает документы и чанки в PostgreSQL.
|
||
6. `api/services/indexing.py` переносит чанки в Chroma.
|
||
|
||
### 8.3. Схема зависимости модулей
|
||
|
||
```text
|
||
bot/handlers/client/main.py
|
||
-> bot/utils/rag_api.py
|
||
-> api/routers/rag.py
|
||
-> api/services/legal_ai.py
|
||
-> api/services/retrieval.py
|
||
-> shared/repositories.py
|
||
-> PostgreSQL / ChromaDB / OpenRouter
|
||
|
||
parser/cli.py
|
||
-> parser/discovery.py
|
||
-> parser/fetcher.py
|
||
-> parser/normalizer.py
|
||
-> parser/ingest.py
|
||
-> shared/repositories.py
|
||
-> PostgreSQL
|
||
```
|
||
|
||
---
|
||
|
||
## 9. Используемые технологии и зависимости
|
||
|
||
### 9.1. По сервисам
|
||
|
||
| Область | Технологии |
|
||
|---|---|
|
||
| Bot | `aiogram`, `aiohttp`, `httpx`, `redis`, `uvloop` |
|
||
| API | `FastAPI`, `uvicorn`, `openai`, `chromadb`, `sentence-transformers`, `SQLAlchemy`, `asyncpg` |
|
||
| Parser | `requests`, `beautifulsoup4` |
|
||
| DB | `PostgreSQL`, `SQLAlchemy`, `asyncpg` |
|
||
| Vector search | `ChromaDB` |
|
||
| LLM | `OpenRouter` через `AsyncOpenAI` |
|
||
| Embeddings | `sentence-transformers` + локальная модель |
|
||
|
||
### 9.2. Замеченные версии
|
||
|
||
Источники:
|
||
- [api/requirements.txt](/home/ruby/Desktop/DockerProjects/LawBot/api/requirements.txt:1)
|
||
- [bot/requirements.txt](/home/ruby/Desktop/DockerProjects/LawBot/bot/requirements.txt:1)
|
||
|
||
| Пакет | Версия |
|
||
|---|---|
|
||
| `fastapi` | `0.115.9` |
|
||
| `uvicorn` | `0.34.2` |
|
||
| `openai` | `1.82.0` |
|
||
| `chromadb` | `1.0.12` |
|
||
| `SQLAlchemy` | `2.0.38` |
|
||
| `asyncpg` | `0.30.0` |
|
||
| `sentence-transformers` | `5.1.2` |
|
||
| `aiogram` | `3.17.0` |
|
||
| `httpx` | `0.28.1` |
|
||
| `redis` | `5.2.1` |
|
||
| `beautifulsoup4` | `4.13.4` |
|
||
|
||
---
|
||
|
||
## 10. Что выглядит слабо или странно
|
||
|
||
Ниже только то, что видно по текущему коду.
|
||
|
||
| Проблема | Где видно | Почему это слабое место |
|
||
|---|---|---|
|
||
| Нет отдельного сервиса `parser` | `compose.yml` | Парсер живет внутри контейнера бота. Это смешивает роли и зависимости. |
|
||
| Нет миграций БД | `shared/repositories.py:97` | Схема создается через `create_all()` и `ALTER TABLE`, что плохо масштабируется. |
|
||
| Один большой репозиторий БД | `shared/repositories.py` | Класс `ORM` содержит слишком много обязанностей: users, laws, consultations, search. |
|
||
| Один большой сервис LLM | `api/services/legal_ai.py` | В одном файле смешаны классификация, ответ, fallback, sanitizing и генерация заголовка. |
|
||
| `bot/requirements.txt` содержит лишнее | `bot/requirements.txt` | Там есть `fastapi`, `uvicorn`, parser-зависимости. Контейнер бота тяжелее, чем должен быть. |
|
||
| `cfg_loader.py` выглядит мертвым кодом | `bot/utils/cfg_loader.py` | Ищет `cfg/config.json`, но такой папки в проекте нет и импортов почти нет. |
|
||
| `bot/webhooks.py` не подключен | `bot/webhooks.py`, `compose.yml` | В проекте есть отдельный FastAPI webhook-файл, но он не участвует в основном запуске. |
|
||
| Нет тестов | по структуре файлов | В проекте не найдено папки `tests/` или явных unit/integration тестов. |
|
||
| Парсер завязан на HTML-структуру сайта | `parser/fetcher.py`, `parser/normalizer.py` | Любое изменение верстки `consultant.ru` может сломать парсинг. |
|
||
| Full-text поиск только на русском tsvector | `shared/repositories.py` | Это нормально для РФ, но поиск по сложным формулировкам может быть нестабилен без доп. нормализации. |
|
||
| В `api` автоиндексация идет при старте | `api/main.py` | Удобно для MVP, но на большом объеме это может тормозить старт сервиса. |
|
||
| В репозитории есть `.venv/` | структура проекта | Локальное окружение лежит внутри проекта. Это легко случайно потащить в архив или deploy-контекст. |
|
||
|
||
### 10.1. Неясные или частично подтвержденные зоны
|
||
|
||
| Наблюдение | Что именно неясно |
|
||
|---|---|
|
||
| Админская часть | Полный функционал не анализировался построчно во всех admin handlers |
|
||
| `protocol/` | Это не runtime-часть приложения, а документы для курсовой |
|
||
| `bot/keyboards/inline_keyboards.py` | Файл существует, но по структуре почти пустой и не играет заметной роли |
|
||
|
||
---
|
||
|
||
## 11. Рекомендации по улучшению структуры
|
||
|
||
### 11.1. Что стоит сделать в первую очередь
|
||
|
||
| Рекомендация | Зачем |
|
||
|---|---|
|
||
| Выделить `parser` в отдельный контейнер | Чтобы бот не таскал лишние parser-зависимости |
|
||
| Ввести миграции (`alembic`) | Чтобы схема БД менялась предсказуемо |
|
||
| Разбить `shared/repositories.py` на несколько репозиториев | Например: `users`, `consultations`, `laws`, `rag` |
|
||
| Разбить `api/services/legal_ai.py` | Отдельно: classifier, answer renderer, title generator, fallback |
|
||
| Добавить `tests/` | Минимум smoke-тесты для `api`, `parser`, `shared` |
|
||
| Вынести parser-зависимости из `bot/requirements.txt` | Уменьшить размер и сложность контейнера бота |
|
||
|
||
### 11.2. Что улучшит понятность проекта
|
||
|
||
| Рекомендация | Зачем |
|
||
|---|---|
|
||
| Добавить `docs/architecture.md` | Новичку будет проще понять проект |
|
||
| Сделать единый `settings`-слой и для `bot`, и для `parser` | Сейчас конфигурация читается разными способами |
|
||
| Удалить или подключить мертвые файлы | Например `bot/webhooks.py`, `bot/utils/cfg_loader.py` |
|
||
| Добавить схему “как идет запрос” в README | Снизит порог входа |
|
||
|
||
### 11.3. Что важно для production
|
||
|
||
| Рекомендация | Зачем |
|
||
|---|---|
|
||
| Ограничить и логировать ошибки внешних API | OpenRouter и Consultant могут вести себя нестабильно |
|
||
| Добавить rate limiting и retry policy на уровне API-клиентов | Улучшит устойчивость |
|
||
| Отдельно мониторить время поиска и генерации | Позволит понять, где тормозит система |
|
||
| Добавить backup-стратегию для `volumes/postgres` и `volumes/chroma` | Сейчас данные локально персистентны, но не защищены от потери |
|
||
|
||
---
|
||
|
||
## 12. Краткий вывод
|
||
|
||
Проект уже собран как рабочий MVP:
|
||
|
||
- есть Telegram-бот;
|
||
- есть FastAPI-сервис для RAG;
|
||
- есть парсер законов;
|
||
- есть PostgreSQL и ChromaDB;
|
||
- есть единый DB-слой.
|
||
|
||
Главная архитектурная идея понятная:
|
||
|
||
1. `parser` наполняет PostgreSQL законами;
|
||
2. `api` строит векторный индекс и отвечает на вопросы;
|
||
3. `bot` общается с пользователем;
|
||
4. `shared` соединяет все это с БД.
|
||
|
||
Главные слабые места сейчас:
|
||
|
||
- смешение ролей `bot` и `parser`;
|
||
- отсутствие миграций;
|
||
- слишком крупные файлы `shared/repositories.py` и `api/services/legal_ai.py`;
|
||
- отсутствие автоматических тестов.
|
||
|
||
Для новичка проект уже читаемый, но поддерживать его дальше будет проще после разделения больших модулей на более мелкие.
|