Как устроен
Хорар.
Расчётная основа, собственная логика приложения и генерация текста — отдельные части системы. Ниже описана текущая реализация.
Swiss Ephemeris и Python-обёртка.
Swiss Ephemeris от Astrodienst ↗ используется для расчёта положений и скоростей планет, асцендента и границ домов Regiomontanus. Приложение вызывает swe.calc_ut с флагами FLG_MOSEPH | FLG_SPEED и swe.houses(..., b'R'). Планетные расчёты выполняются встроенным алгоритмом Moshier, без внешних файлов эфемерид.
Установлен пакет pysweph 2.10.3.6 ↗, импортируемый как swisseph. Это Python-обёртка над Swiss Ephemeris и продолжение проекта pyswisseph. Названия связаны, но пакеты не следует считать полностью взаимозаменяемыми: в текущем коде учтён массив домов pysweph с неиспользуемым нулевым элементом.
Что делает собственный код
engine.py рассчитывает карту для семи традиционных планет, относит планеты к знакам и домам, определяет ретроградность по скорости, выбирает управителей первого и седьмого либо десятого домов. Аспекты определяются по угловому расстоянию: 0°, 60°, 90°, 120°, 180°, с единым орбисом отображения 6°. Функция wheel рисует SVG из тех же данных; PNG создаётся в браузере.
Где здесь Kerykeion?
Kerykeion ↗ — библиотека более высокого уровня для астрологических данных и визуализации карт. В этом проекте она не установлена и не используется. Формирование данных карты, аспектов и SVG выполняется нашим кодом поверх Swiss Ephemeris. Добавление библиотеки само по себе не решит задачу полного хорарного толкования.
От браузера до архива.
- Интерфейс: статические HTML, CSS и JavaScript. Форма, поиск города, карта, результат и личный архив.
- Сервер: FastAPI на Python 3.12, размещение на Vercel. Проверка входных данных, вычисления, вызов OpenAI и проверка ответа.
- Города: локальный справочник geonamescache 2.0.0 с данными GeoNames. Координаты определяются по выбранному city_id; время берётся на сервере в UTC.
- Хранение: PostgreSQL в Neon, доступ через psycopg. Таблицы reports, quota и throttle хранят результаты, месячные резервы и ограничения частоты.
Основные маршруты: GET /api/cities, GET /api/status, POST /api/readings, GET /api/archive. Просмотр и удаление приватного результата проверяют владельца. Создание и отзыв ссылки выполняются через /api/readings/{id}/share, чтение по токену — через POST /api/shared.
Владелец определяется по случайной HttpOnly cookie; в базе используется её SHA-256-хеш. В production cookie также имеет Secure и SameSite=Strict. Это доступ на основе браузера, без учётной записи и восстановления. Публичный токен передаётся во фрагменте ссылки #share=…, затем отправляется серверу в теле запроса. Для ограничения частоты используется HMAC от IP.
Текущая модель: GPT-4.1 mini.
gpt-4.1-mini-2025-04-14Документация и стоимость модели ↗Каталог моделей OpenAI ↗Модель получает вопрос, тему, готовые расчётные данные и ограниченный набор правил. Веб-поиск и архив предыдущих разборов к запросу не подключаются. Ответ запрашивается в JSON, с лимитом 1400 выходных токенов, temperature 0.3 и таймаутом 45 секунд. На одну попытку выполняется один вызов, автоматических повторов нет.
Проверяются завершённость ответа, статус, текстовые поля, количество факторов от одного до трёх, существование fact_id и принадлежность rule_id разрешённому набору. Это структурная проверка: она не подтверждает, что смысл текста действительно следует из указанного факта. Результат хранит модель, prompt_version и token usage; старые ответы при смене модели не пересчитываются.
Модель выбирает владелец через HORARY_AI_MODEL в Vercel, с повторным развёртыванием. Допустимые значения и ограничения входа описаны в README. Неизвестное значение блокирует новые разборы. Название модели на страницах описания берётся из серверной настройки.
Резервирование перед вызовом ИИ.
В одной транзакции PostgreSQL под advisory lock проверяются 10 попыток на владельца за скользящие 24 часа, одна попытка на IP в минуту и общий потолок 380 платных вызовов (разборы и распознавание речи вместе) за календарный месяц UTC. Каждая разрешённая попытка резервирует $0.05 без возврата при ошибке ИИ. Предел резервирования $19 оставляет $1 запаса в бюджете $20.
Размер входа ограничен отдельно для каждой разрешённой модели: 30 000 байт для mini и 12 000 для полной GPT-4.1. Это позволяет удерживать консервативную оценку стоимости ниже резерва при проверенных тарифах. При добавлении моделей или изменении тарифов расчёт нужно пересмотреть. Лимит приложения не является настройкой бюджета аккаунта OpenAI.
Расчёт карты не равен полному хорарному анализу.
Не вычисляются достоинства планет, рецепции, передача и собирание света, Луна без курса и полная проверка достижения точного аспекта до смены знака или разворота. Метка applying означает только уменьшение отклонения от точного аспекта через один час.
Орбис 6° — упрощение MVP. Широты с абсолютным значением от 66° отклоняются. Предупреждения о раннем или позднем асценденте, Сатурне в седьмом доме и совпадении управителей не дают автоматического вердикта.
Главные следующие задачи — расширение и согласование правил, эталонные примеры и экспертная проверка трактовок. Точные астрономические координаты сами по себе не доказывают предсказательную достоверность астрологии.
Из голоса в черновик вопроса.
MediaRecorder записывает до 30 секунд. Web Audio API показывает реальную громкость микрофона и преобразует запись в mono PCM WAV, 16 kHz. Сервер проверяет формат, фактический размер и длительность до платного вызова. OpenAI GPT-4o mini Transcribe распознаёт речь через /v1/audio/transcriptions. Аудио не записывается в базу Хорара. Текст можно исправить перед отправкой.
Голосовой ввод имеет отдельные 10 попыток за 24 часа и паузу в минуту на IP. Он использует общий месячный бюджет: каждый запрос также резервирует $0.05. Отмена уже отправленного запроса не возвращает резерв. Модель распознавания необходимо заменить до её отключения 26 февраля 2027 года.
Прошлые и будущие события
Swiss Ephemeris рассчитывает ближайший переход знака каждой из семи планет, ближайшие развороты R и D и ближайший основной аспект каждой пары в обе стороны от момента карты. Солнце и Луна не имеют разворотов R/D. Горизонт поиска — 1096 суток в каждую сторону; список не является полным календарём. Геоцентрические тропические долготы, Moshier, шаг поиска 6 часов, уточнение корня до интервала менее секунды. Численная точность поиска не означает субсекундную физическую точность эфемерид.
Время отображается в UTC, последний столбец — сутки относительно момента карты. Положение относится к первой планете в строке; для перехода указан новый знак. Выборка и время могут отличаться от Sotis из-за настроек и алгоритма отбора. События рассчитываются при отображении, в том числе для старых разборов, и не передаются в инструкции ИИ. Это не реализация рецепций, передачи света или Луны без курса.