examples(account-signal-scoring): turn account signals into one score with SIE ranking - #205
Conversation
… demo
Turn a pile of CRM account signals into one score a team can act on, with
SIE doing the ranking. Signals roll up into a deterministic 0-100 score and
band, then the account's context is embedded and reranked against a corpus of
past-outcome playbooks (extract + encode + score) to pick the recommended
play. An optional chat/completions call drafts the account brief, falling
back to a deterministic writer so the board is always populated.
Self-contained Docker Compose + Node UI, CPU-only by default. Contributed
from a {Tech: Europe} London AI Hackathon project by the Attio-integration
team.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
Thank you @richard7ao ! @fm1320 can you check? do we have some content about it? |
fm1320
left a comment
There was a problem hiding this comment.
Thanks for this @richard7ao, great to see the hackathon project land as a gallery example. The structure is exactly right (it mirrors stripe-link-fraud closely) and everything I could verify statically checks out: model IDs, SDK usage, compose setup, typecheck.
One thing to fix before this is ready for review: the "Specific things to try in the UI" table doesn't match what the scoring code produces. Running scoreSignals on the sample data:
- CloudScale Systems scores 27, which is amber, but the table promises red
- Global Peak Inc scores 12, also amber, but the table promises red on the expansion board
The structural issue behind the second one: opportunity signals max out at 10 + 5 + 2 = 17, while red needs > 40, so no expansion account can ever go red. Could you either recalibrate the weights/bands (per-direction thresholds would work) or update the table to match the real output? As written, someone following the README watches the demo contradict it.
Two small optional ones while you're in there:
generateBriefswallows all chat errors silently; aconsole.warnin the catch would save people debuggingSIE_CHAT_MODELsome pain- the published SDK is now 0.6.x and has
chatCompletions(), so the comment in brief.ts about 0.3.x lacking chat is stale (bumping the pin and using the SDK method would be even nicer)
Happy to re-review once updated.
Summary
Adds a new gallery example,
account-signal-scoring— turning a pile of CRM account signals into one score a team can act on, with SIE doing the ranking.This is a cleaned-up, self-contained slice of our
{Tech: Europe}London AI Hackathon project (codename "Rick", built on top of Attio + Stripe signals). Opening as a draft per Daniel's note — happy to iterate on scope, naming, and the writing style with the team.What it does
encoded (MiniLM), and ranked (cosine → cross-encoderscorewith BGE-reranker) against a corpus of past-outcome playbooks to pick the recommended play.extract(GLiNER) surfaces entities alongside.SIE_CHAT_MODELset, the OpenAI-compatible/v1/chat/completionsendpoint drafts the brief, grounded in the matched playbook; otherwise a deterministic brief keeps the board populated.SIE primitives
extract,encode,score, and (optional)chat/completions— one cluster, one round-trip.Shape
Follows the
stripe-link-fraudexample:compose.yml(CPU image, 3 models preloaded, ~440 MB), a tiny Node HTTP + SSE server, and a vanilla-JS UI (no build step). CPU-only by default; the LLM brief is opt-in. Also ships a headless CLI (npm run score) that ranks the whole book into risk/expansion boards. Added a row toexamples/README.md.Test plan
npm install+npm run typecheckclean/api/health,/api/accounts, static assets, and graceful SSE error when SIE is unreachable all verifieddocker compose upend-to-end run against a live SIE server (needs Docker; not run in this environment — would appreciate a CI/maintainer check)Generated with Devin