Under the hood

How Spectare works

From the moment a visitor lands to the moment personalised content appears: intent classification, atom assembly, multi-tier caching, image selection, and a conversion feedback loop that improves with every session.

01Intent classification

Reading the visitor

spectare.js runs on every page load. It reads the referrer, UTM parameters, landing page URL, and any page visit history stored in localStorage from earlier in the session or from previous visits. These signals are sent to /api/qualify, where Claude classifies them into an audience, funnel stage, and confidence score. The result is a signed context token: not a user profile, not a cookie, not a segment.

referrerUTM paramslanding page URLvisit history (localStorage)

spectare.js

reads signals, builds context string

POST /api/qualify

sends context to the server

Claude: classify intent

audience · stage · confidence · search query

Signed context token

{audience, stage, confidence}. Valid for 1 hour.

spectare.js runs client-side on every page load

No training period

Claude is the model. Classification is accurate from visitor one without historical traffic data.

No cookies

Intent is classified fresh each session. The context token is never stored against a person.

Returning visitors

Visit history in localStorage means returning visitors are personalised even with no UTM params.

02Content assembly

Building the experience

The context token is passed to /api/assemble/components. Vector search and image selection run in parallel: the search finds candidate atoms semantically relevant to the intent; the image bandit picks the best-converting hero image for this audience and stage. The co-conversion graph then surfaces atoms that have historically converted alongside the top candidate. Claude picks components from a registry of 9 types and returns a ComponentAssembly array that ComponentRenderer renders in the browser.

Context token

audience · stage · confidence

Vector search

candidate atoms by semantic similarity

Image selection

MAB: best hero for audience + stage

Co-conversion graph

surfaces atoms that convert alongside the top candidate

Claude: assembleComponentPage

picks from a registry of 9 component types

HeroStatement

StatGrid

CtaStrip

ComponentRenderer

renders the component tree in the browser

For the script tag: /api/assemble streams SSE events that fill data-spectare-slot divs instead.

Runs on the server after qualify returns a token

03Delivery speed

Two-tier caching

Full Claude assembly only happens once per intent pattern. The result is stored in Redis keyed by intent type, audience, and stage with a 24-hour TTL. On a cache hit, the component list is returned with no Claude call. The image bandit still runs on every request even for cache hits, so image optimisation never stalls.

Cache hitfast path

Redis edge cache

A matching intent pattern (type + audience + stage) was assembled recently. The component list is served from Redis with no Claude call. The image bandit still runs to keep MAB learning; only the component layout is cached.

0 Claude calls~50ms
Cache missfull assembly

New intent pattern

A genuinely new combination of type, audience, and stage. Vector search and image selection run in parallel, then Claude assembles the component list. Result is written to Redis immediately so the next matching visitor hits the cache.

Claude + pgvector~400ms

Cache key: orgSlug · intent type · audience · stage. TTL: 24 hours.

04Image selection

The image bandit

Spectare selects a hero image for each assembled experience. It uses a multi-armed bandit: 90% of requests exploit the image with the highest observed conversion rate for the current audience and stage combination; 10% explore a random image to gather data on untested combinations. Every impression is recorded, and conversions update the conversion rate in real time. No manual A/B test setup required.

Visitor arrives

audience + stage known from qualify

Select image

exploit (90%) or explore (10%)

Record impression

image_events: image_id, audience, stage

Visitor converts?

Mark converted = true

on the impression row

Next visitor

image with highest conversion_rate for this audience + stage

10% of requests explore a random image. 90% exploit the best-converting image.

05Feedback loop

The co-conversion graph

Every conversion event records which atoms appeared together in that session. A directed graph tracks the edge weight between every pair of atoms that co-appear in converting sessions. When the assembly pipeline picks a primary atom, it reads the graph to choose supporting content from what has actually worked alongside that primary, not just what is semantically similar. The graph is rebuilt nightly from all conversion data.

Visitor converts

session contained atoms A, B, and C

atom_graph edges updated

A→B weight++ · A→C weight++ · B→C weight++

Next visitor: primary = A

assembly reads top co-converting edges for A

B

weight 12

C

weight 7

D

weight 2

Supporting slot picks B. Not just semantically similar. Actually converted together.

The graph is rebuilt nightly. Supporting atom selection reads live edge weights.

See it running on a real site

The demo page runs the full qualify and assemble pipeline live. Describe your site and watch intent classification and content assembly happen in real time.