3.8 KiB
Purpose
Классификация писем локальной LLM: после скачивания письма модель определяет тип письма (информационное, требует срочного ответа, содержит задачу, содержит встречу) и записывает тег + обоснование в frontmatter файла email.md. Обработка приватна — модель Qwen3:8b запущена локально через Ollama, текст письма не покидает хост.
ADDED Requirements
Requirement: Классификация каждого нового письма
Каждое письмо, заархивированное mail_archive.py, MUST быть классифицировано
локальной моделью не позднее одного прохода классификатора после архивации.
Scenario: Новое письмо после архивации
- WHEN
mail_archive.pyсохранил новое письмо в/opt/hermes/email/**/email.mdбез поляclassification - THEN
email_classifier.pyобработает его и запишет в frontmatter полеclassificationс одним из значений:info,urgent,task,meeting(или комбинацию через запятую)
Requirement: Приватность обработки
Классификация MUST выполняться локальной моделью (Qwen3:8b через Ollama на localhost:11434) и MUST NOT отправлять текст письма в облачные API.
Scenario: Локальная модель доступна
- WHEN классификатор запущен
- THEN запросы к LLM идут только на
http://localhost:11434(Ollama), никаких внешних HTTP-вызовов с телом письма
Requirement: Обоснование классификации
Классификатор MUST записывать краткое обоснование решения в frontmatter
(поле classification_reason), чтобы пользователь видел, почему письмо помечено
именно так.
Scenario: Обоснование для письма
- WHEN
email_classifier.pyклассифицировал письмо - THEN в frontmatter записано
classification_reasonс 1-2 предложениями на русском
Requirement: Идемпотентность
Письмо MUST обрабатываться классификатором только один раз; повторный запуск MUST NOT переклассифицировать уже обработанные письма (если не задан флаг принудительной переклассификации).
Scenario: Повторный запуск классификатора
- WHEN
email_classifier.pyзапущен повторно на уже обработанном письме (естьclassification) - THEN письмо пропускается без повторного вызова LLM
Requirement: Обработка ошибок классификатора
Если LLM не ответила или вернула невалидный JSON, классификатор MUST пометить
письмо как unclassified и продолжить со следующим письмом, не прерывая весь
проход.
Scenario: LLM вернула невалидный ответ
- WHEN модель не ответила или вернула не-JSON
- THEN письмо получает
classification: unclassified, а проход продолжается