Sentio · 感识
Feel the human, not the data.
感知人,而非数据。
Sentio(拉丁语 sentīre,「我感知、我感受」;中文对译感识——感知 + 意识)是一个区别于传统埋点分析(神策 / GrowingIO)的用户行为意图感知平台。
传统平台记录「用户点了什么」,Sentio 捕捉点击之前的整个过程——悬停时长、指针微抖动、点击前的微停顿、滚动折返与阅读节奏——并用规则引擎(后续接入 LLM)实时推理用户当下的状态:困惑、犹豫、惊喜、被劝退。
核心立场:数据单位不是「事件 + 标签」,而是「意图片段 + 状态流 + 体验旅程」;异常不是流失,而是沟通机会。
功能一览
- 实时行为感知 —— IntentSensor 监听带
data-intent-*标注的元素/区域,采集 11 种信号(悬停、微抖动、停留、点击、滚动折返、阅读节奏、可见性等),全程端侧完成。 - 意图状态推断 —— 规则引擎按时间窗统计,实时推断 8 种意图状态(安静浏览 / 产生兴趣 / 犹豫纠结 / 困惑卡住 / 深度阅读 / 被劝退 / 果断行动 / 顺畅完成),输出强度、置信度与人话依据。
- LLM 第二意见 ——
/api/interpret可选 AI 解读(命中带「AI 解读」徽标);未配置密钥或限流时静默降级为规则引擎。 - 实时看板 —— 状态卡(含判定依据)、实时意图概率光谱、意图波形、状态迁移流、会话统计读数。
- 意图片段 —— 会话切分为「意图片段」(时长 × 主导状态),导出与叙事的核心数据单元。
- 注意力热力图 —— canvas 覆盖层,轨迹 × 停留加权,只罩标本区并标出注意力焦点。
- 第一人称回放 —— 以用户视角重放历史信号(暂停 / 拖拽 / 倍速),播放头处实时重算意图状态,不写入当前会话。
- 用户修正(数据主权) —— 「对 / 不太准」一键纠正平台判断,可改状态 + 写理由;修正落库并在片段与故事线打 ✎。
- 体验数据导出 / 导入 —— 导出
sentio.experience v1JSON 包;支持 MeLog 文件导入(与/api/sync共用校验规则)。 - 本地持久化 —— SQLite(better-sqlite3 + WAL,预编译语句 + 参数绑定)经
/api/ingest、/api/feedback、/api/sync、/api/export存会话与反馈。 - 隐私透明 —— 「数据透明」弹层说明端侧处理与收集清单;会话级数据,不采集 PII。
- 两个页面 ——
/理念页、/demo实时工作台。
品牌
| 维度 | 定案 |
|---|---|
| 名称 | Sentio(拉丁语,「我感知」),中文对译感识 |
| 核心隐喻 | 不是「分析你」,是「感受到你」 |
| 调性 | 克制、人文、有技术深度但不冰冷 |
| 主色 | 熔金 oklch(76% 0.17 50) —— 暖金 #FDCB6E 的直系后代:人的温度、顿悟时刻 |
| 副色 | 珊瑚 oklch(68% 0.16 18) —— 风险与拒绝、感知层开启、用户修正 |
| 画布 / 文字 | 冷紫近黑 oklch(13% 0.014 265) / oklch(96% 0.006 262) · oklch(70% 0.012 264) |
| 字体 | Instrument Serif(英文标题)· Geist + 苹方/思源黑体(正文)· JetBrains Mono(数据) |
| Logo | 涟漪:中心小圆点是一次微小交互(如悬停),向外扩散出不完美的波纹——意图被感知;波纹圆心略有偏移,因为人不是标准数据 |
完整设计系统(token / 字阶 / 动效 / CTA 语态 / 页面家族)见 design.md,可移植版本为 tokens.css。
意图状态色与信号色由 lib/intent/palette.ts 唯一管理(八状态 / 十一信号):犹豫 = 黄铜、深度阅读与流动 = 青绿(已从品牌色降级为功能数据色)、兴趣 = 浅紫、被劝退 = 珊瑚……
快速开始
npm install
npm run dev # http://localhost:3000
npm test # 单元测试(vitest,28 条)
/—— 理念落地页/demo—— 实时演示:左侧是带data-intent-*标注的模拟商品页,右侧是实时意图看板- 把鼠标放到「立即购买」上停 2 秒 → 触发「犹豫纠结」+ Sentio Agent 机会发现建议
- 快速扫过按钮又移开 → 触发「被劝退」
- 在产品详情里上下反复滚动 → 触发「困惑卡住」
- 静止在一段文字上 → 触发「深度阅读」
- 左上角热力图 → 注意力热力(轨迹 × 停留加权),并标出注意力焦点区域
- 左上角回放 → 第一人称回放:ghost 光标重走路径,播放头处实时重算当时的意图状态
- 右侧「Sentio 理解得对吗?」→ 用户修正:纠正平台的判断("我不是犹豫,我只是在找眼镜"),落库到
/api/feedback - 右侧意图片段卡:会话被切分为带证据链的片段(时间带宽度 = 持续时长,✎ = 被修正过)
- 顶栏数据透明 → 查看收集清单;导出 → 下载
sentio.experience v1完整体验数据
目录结构
app/
page.tsx # 落地页
demo/page.tsx # 实时演示看板
api/ingest/route.ts # 信号批量上报端点
api/interpret/route.ts # LLM 第二意见(MiniMax,未配置密钥时 503 静默降级)
api/export/route.ts # 服务端 sentio.experience v1 导出(重建 fragments)
api/feedback/route.ts # 用户修正落库
api/sync/route.ts # 外部数据包导入(MeLog → Sentio)
components/
logo.tsx # 涟漪标识
ui/ # shadcn/UI 基础组件
demo/ # 看板组件:状态卡/波形图/状态流/故事线/Agent 建议
lib/
sdk/intent-sensor.ts # 核心:Web 传感器 SDK(可独立复用)
intent/interpreter.ts # 意图解释器(规则引擎,实时兜底)
intent/online-scorer.ts# 端侧八状态概率光谱
intent/replay.ts # 会话重放:由事件流重建状态流(服务端复用同一解释器)
intent/store.ts # Zustand 状态中心
intent/use-intent-sensor.ts
ai/minimax.ts # LLM 客户端(输出白名单校验)
standard/ # 开放标准:导出/校验/片段聚合/MeLog 适配
db/schema.sql # 体验数据标准 Schema(意图片段/用户修正)
db/sqlite.ts # 本地持久化(better-sqlite3 + WAL,数据文件 .data/)
db/event-store.ts # 事件存储(生产替换点:Supabase)
types/intent.ts # 领域类型:IntentEvent / IntentState
信号类型(Experience 数据标准 v0.1)
| 信号 | 语义 | 判定逻辑(原型) |
|---|---|---|
dwell |
犹豫级停留 | 悬停超过 1200ms 仍不离开 |
tremor |
微抖动(焦虑) | 短窗口内路径长、净位移 <12px、方向翻转 ≥3 次 |
rapid_leave |
拒绝 / 误触 | 停留 <400ms 且离开速度 >1.1 px/ms |
pre_click_pause |
下决心的过程 | 点击时刻 − 最后一次显著移动 ≥350ms |
scroll(折返) |
困惑 / 反复对比 | 5 秒内滚动方向翻转 ≥2 次 |
reading |
深度阅读 | 页面可见且指针/滚动静止 >900ms |
每种信号都携带 confidenceScore(0~1),并汇入解释器生成 IntentState——每个状态都附带 evidence(判定依据) 与 suggestion(此刻更有用的动作),这是「透明化理解」与「机会发现」的落点。
业务侧接入只需两行标注:
<button data-intent-target data-intent-label="立即购买">立即购买</button>
<div data-intent-region data-intent-label="产品详情">…长文本…</div>
开放标准:sentio.experience v1
数据可携带性是数据主权的一半。看板右上角的「导出」会下载本次会话的完整体验数据(lib/standard/):
{
"format": "sentio.experience",
"version": 1,
"sessionId": "…",
"privacy": { "localOnly": true, "note": "本文件由用户浏览器本地导出…用户有权查看、携带与删除它。" },
"signals": [{ "type": "dwell", "count": 3 }], // 收集了什么,一目了然
"fragments": [{ // 意图片段:核心数据单元
"dominantState": "hesitating",
"startedAt": 0, "endedAt": 4200,
"intensityAvg": 0.71,
"focusLabel": "立即购买",
"evidence": ["在「立即购买」上停留了 2.4s"],
"correction": null // 若被用户修正则携带修正内容
}],
"events": [ /* 原始体验信号(证据原料) */ ],
"corrections": [ /* 用户修正(user_interpretations) */ ]
}
设计原则:自描述(不解释也能读懂)、可携带(用户一键导出)、可重建(fragments 可由 events + 判定器重算,lib/standard/fragmenter.ts 是参考实现)。"可重建"不是口号而是已验证的性质:服务端 /api/export?sessionId=… 只从持久化的原始信号出发,经 lib/intent/replay.ts 重放状态流、再交给同一个片段聚合器,产出与客户端完全同构的数据包——包括用户修正的归属。
MeLog 双向同步(原型):出方向由 lib/standard/melog.ts 把意图片段映射为 MeLog 时间线条目(含用户修正);入方向通过 /api/sync 接收外部数据包(入站校验与容量上限见 lib/standard/validate.ts,客户端"从 MeLog 导入"按钮共用同一套规则)。TODO(MeLog):与 MeLog 真实 Schema 对齐字段映射。
端侧实时意图概率(on-device)
规则引擎给出离散判定,lib/intent/online-scorer.ts 输出八状态连续概率光谱:证据按"半衰期 3.5s × 置信度"加权(滚动折返计为困惑的附加证据),softmax 归一后画进看板「实时意图概率」卡。它与 LLM"第二意见"构成三层理解:
- 端侧概率(每 260ms,零成本)→ 光谱全景;
- 规则引擎(每 260ms)→ 离散判定 + 证据链;
- LLM 增强(状态切换时 ≤8s 一次)→ 语义第二意见。
TODO(ONNX):用 WebGPU/ONNX 序列模型替换 online-scorer 的手工权重表,输入输出接口不变。
数据模型与持久化
见 lib/db/schema.sql(PostgreSQL/Supabase 生产目标)。与传统 events 表的三个根本差异:
- 一等公民是会话上下文 + 意图片段(intent_fragments),孤立事件只是证据原料;
- 每个意图判定必须携带 evidence——理解必须可解释;
- 用户可以修正平台的理解(user_interpretations)——"我不是犹豫,我只是在找眼镜"。
本地开发已接通 SQLite 持久化(lib/db/sqlite.ts,better-sqlite3 + WAL):DDL 与 schema.sql 字段一一对应,所有查询使用预编译语句 + 参数绑定,数据文件在 .data/sentio.db(已 gitignore),重启不丢。生产迁移 Supabase 时按 schema.sql 建表、复用同一套 store 接口。
测试
npm test # vitest,28 条断言
纯函数(解释器 / 片段聚合器 / 会话重放 / 概率模型 / 数据包校验器 / MeLog 适配器)全部有单元测试——它们是产品理念的直接编码,测试即理念回归。IntentSensor 依赖真实 DOM 事件流,由 /demo 的端到端验证覆盖。
说明:
lib/db/sqlite.ts中的 DDL 为字面量常量逐条执行(无插值、无用户输入、不经过 shell),安全扫描工具对该模式的"命令注入"启发式告警属误报,依据如上。
AI 接入:MiniMax 意图理解(已接通)
复制 .env.example 为 .env.local 并填入密钥(.env.local 已被 gitignore,密钥只存在服务端):
MINIMAX_API_KEY=你的密钥
MINIMAX_BASE_URL=https://api.minimaxi.com/v1
MINIMAX_MODEL=MiniMax-Text-01
工作方式(双层架构):
- 规则引擎(
lib/intent/interpreter.ts)实时兜底——每个信号到达 260ms 内给出判定,零成本; - LLM 增强(
/api/interpret→lib/ai/minimax.ts)——状态切换到"值得理解"的状态时(客户端 ≤8s 一次),把最近 40 条压缩信号交给 MiniMax 做"第二意见",返回同构的 IntentState 并合并进看板,带 AI 解读 徽标。
降级策略:未配置密钥(503)/ 限流(429)/ 超时或输出不合法(502)→ 全部静默回退规则结果,演示体验不受影响。模型输出经白名单校验(kind 枚举、数值钳制、长度截断)后才回传。
AI 接入点(部分已接通)
- [x]
lib/intent/interpreter.ts+/api/interpret:MiniMax LLM "第二意见"(规则引擎保留为实时兜底) - [x]
lib/intent/online-scorer.ts:端侧实时概率光谱(原型权重表;ONNX/WebGPU 序列模型替换点) - [x]
components/demo/agent-suggestion.tsx:建议文案 = 规则库兜底 + LLM 第二意见(命中时带 "AI 解读" 徽标)
Roadmap
- [x] 注意力热力图:鼠标轨迹 × 停留加权(
/demo工具条开启) - [x] 会话回放:第一人称 ghost 光标 + 时间轴 + 播放头状态重算
- [x] 用户修正面板:把「被理解的结果」还给用户(
/api/feedback) - [x] 开放标准:sentio.experience v1 导出格式 + 意图片段聚合器(
lib/standard/) - [x] 服务端可重建导出:
/api/export由事件流重放状态流并重建片段(lib/intent/replay.ts) - [x] 端侧实时意图概率光谱(
lib/intent/online-scorer.ts,ONNX 模型替换点已留) - [x] MeLog 双向同步原型:条目适配器 +
/api/sync+ 文件导入 - [x] 区域注意力分布(热力图图例:兴趣分布Top2)
- [ ] MeLog 真实 Schema 对齐(现为原型字段映射,待 MeLog 侧确认字段;
lib/standard/melog.ts适配层已隔离变化) - [ ] 端侧 ONNX 模型训练(需要真实标注数据;替换点
lib/intent/online-scorer.ts接口已固定) - [ ] 摄像头授权方案(视觉注意力升级)——需要产品决策:授权流程与模型选型(WebGazer / MediaPipe)
- [ ] 部署(Vercel / 私有化;
.data/卷需要持久化挂载)
演示数据不出本机:浏览器端信号写入本地 SQLite(.data/sentio.db,已 gitignore),不外发任何第三方;用户可随时导出完整理解、或直接修正它。我们展示「理解」,而非「监控」。