Soulwise's core challenge is fusing three things into one meaningful daily insight: the user's natal chart, today's sky and the user's current mood. Astrology is not deterministic — yet Soulwise's output must be consistent, personal and actionable every day.
Neither pure LLM nor pure ephemeris
A pure LLM solution looks tempting at first: ask GPT "give me a daily reading for my sign", done. In practice two problems: (1) hallucination risks date-specific astrological claims that disagree with reality ("Mars is in Leo today" when it isn't); (2) you cannot build a consistent personalisation layer — the model has no idea what is personal to whom.
A pure ephemeris solution: use Swiss Ephemeris, compute every planet, generate readings from deterministic rules. That falls into a different trap — the output is dry and mechanical, and loses the "this is talking to me" feel.
A three-layer engine
Soulwise's content engine has three layers:
1. Ephemeris layer (deterministic)
We use Swiss Ephemeris for source-of-truth accuracy. Every day at 00:00 UTC a scheduled job computes major planetary positions, house cusps and the principal aspects (conjunction, opposition, square, trine, sextile). A sky_state row is written to the database. The computation is sub-second, deterministic and cacheable.
2. Rules engine (interpretive vocabulary)
The classical interpretive vocabulary is encoded as rules:
- Transit rule: "If Saturn squares the Sun in your natal chart, expect heightened responsibility" — the engine checks whether that transit is active for the user.
- Lunar cycle: new-moon / full-moon / waning phases drive intention-setting / release prompts.
- Sign affinity: the user's rising / moon / sun combination shapes which days they are more sensitive to.
This layer is plain TypeScript: testable, predictable, identical for every user. Output is structured: { slot: "energy", level: 0.85, hints: ["mars-trine-sun", "moon-cancer"] }
3. LLM composition layer
The structured output is composed into a warm, natural daily insight by an LLM. The key constraint: the LLM does not invent astrological knowledge. It only narrates the structured hints from the rules engine. The system prompt is explicit: "Make no astrological claims beyond the hintsyou are given. Stay compassionate but never diagnostic."
Hallucination control
Every LLM output is post-processed: planet + sign + house combinations in the text are validated against the day's sky_state from the ephemeris layer. Any mismatch rejects the output and triggers a retry. After three failed attempts the user sees a plain rules-engine fallback — drier but factually correct.
The mood input
Third variable: the user's answer to "how do you feel today?" — bucketed into open / cautious / sad. That state shapes the LLM composition layer's tone: the same astrological hints get expressed more gently for a "cautious" user, more boldly for an "open" one.
Performance
The ephemeris and rules layers run once a day per user (triggered at 00:00 in the user's local timezone, queued as a background job). LLM composition runs when the user opens the app or taps a notification. This hybrid keeps deterministic output cached and only spends LLM tokens on on-demand creative work.
Why isn't Soulwise a RAG system?
RAG (retrieval-augmented generation) might seem attractive here: index classical astrology texts in a vector DB, retrieve on query, ground the model. In practice the win is limited:
- Classical astrology texts are mostly general — they aren't tailored to a specific natal chart.
- Soulwise's personalisation requirement is solved better by a deterministic rules engine than by RAG retrieval.
- RAG-fetched classical text often clashes with modern voice; we always rewrite to a warm, contemporary tone in composition anyway.
Open questions
- The LLM-cost curve at scale — tuning the cache vs. deterministic-fallback ratio for sustainable margins.
- Tarot card draws: deterministic (e.g. user + date hash) or truly random? A philosophical decision.
- Time-zone edges: planetary positions are UTC; user experience is local. Making "tomorrow" mean the same thing in Türkiye and Hawaii.
We'll measure this engine against real usage data once Soulwise enters early release. Which layer earns the most trust, which rules resonate, where users push back — we'll share what we learn back here on the blog.