ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

LobeHub UX 审计实战:Memory 模块审计案例全解,并用当前源码逐条复核审计结论

LobeHub UX 审计实战:Memory 模块审计案例全解,并用当前源码逐条复核审计结论 LobeHub UX 审计实战Memory 模块审计案例全解并用当前源码逐条复核审计结论【免费下载链接】lobehub LobeHub is your Chief Agent Operator, organizing your agents into 7×24 operations by hiring, scheduling, and reporting on your entire AI team.项目地址: https://gitcode.com/GitHub_Trending/lo/lobehub本篇以 LobeHub 仓库中.agents技能目录下的 ux-audit 已归档审计案例Memory 模块2026-07工单 LOBE-11150为主体完整拆解一次“有标准、可重复、证据驱动”的 UX 审计是如何组织输出的面类surface class基准、L1 静态层审计、模式pattern盘点表、亮点与经验缺口的分级排序、以及审计结论“回灌”回ux检查清单的闭环机制。同时由于原文档自身明确声明“只作为输出形态模板不是当前状态真相引用前需重新核验”本文结合当前仓库源码对其中关键结论做了逐条复核展示哪些缺口已被修复、哪些仍然成立——这本身就是一次“静态层审计如何随代码演进而失效/再生效”的现场教学。1. 案例文档在 ux-audit 技能中的定位案例文档位于 .agents/skills/ux-audit/references/example/memory.md与 home.md、task-detail.md 等十余个案例并排存放。它是 ux-audit 技能“落地发现Land the findings”四步中的一步每次审计完成后把报告存为references/example/page.md让下一次审计有模板可依见 SKILL.md 的 “Land the findings” 一节。要读懂这份案例先理解技能的整体框架三层审计模型。审计不是单一活动结论只能来自“看得见它”的那一层见 SKILL.md 的三张表层做法能捕获什么成本L1 静态读代码layer-1-static.md缺失的空/错/重试分支、草稿未持久化、整类模式缺失、结构性问题低、离线每次审计必跑L2 视觉渲染截图核验真实视觉层级与主控件、间距/对比度/对齐、截断溢出、暗色模式、响应式中需要渲染L3 动态驱动真实用户旅程 性能插桩进行中/锁定态、强制错误/空态、焦点/键盘可达性、CLS / LCP / INP / long-task 数值高需要运行环境 鉴权覆盖矩阵的核心规则是“结论必须来自能看见它的层”视觉层级、空态“读起来”像不像一个真实页面、任何带数字的指标都不能从 L1 的variantprop 直接打勾。案例文档开头标注 “Layers run: L1 ✅. L2 / L3 ⏳ not run”正是在声明证据边界——整份报告的可信范围就是静态读码能覆盖的部分。两条与案例强相关的地基规则案例的缺口 C 直接由它们驱动对标“面类”而不只是自己的代码读码只能发现“已建功能”的缺陷对“整个能力从未建过”是结构性盲区的——因为完全缺失的能力没有file:line可 grep。审计前必须先给界面命名它的“类”写出成熟同类产品在该类界面上的能力清单再拿它逐项核。Memory 模块的面类是“个人 AI 记忆 / 个性化存储”基准是 ChatGPT 的 “Manage memories”、Gemini 个性化、Mem0、Personal.ai、CRM 的 “customer 360”。报告好的部分而不只报缺口亮点✅ 亮点与缺口同为一级发现——它们“教学”成为检查清单的 ✅ 例、“保护”告诉下次重构哪些行为是承重的、“校准严重度”缺口要放在基线上排序才有意义。2. 审计对象Memory 模块的面与数据底座案例审计的 Memory 模块个人 AI 记忆管理区由两部分构成案例文档把它们与代码位置的映射写得很清楚本文按当前仓库核验如下五个同构列表面 一个人设主页。路由位于src/routes/(main)/memory/下(home)/人设 dashboardPersona 角色/标签云、identities/、contexts/、preferences/、experiences/、activities/。每个列表 tab 具备FilterBar服务端搜索q、grid / timeline 双视图、右侧详情面板*RightPanel、以及“Analyze”流程——从聊天历史提取记忆。当前仓库目录结构与案例描述一致contexts/features/ContextRightPanel.tsx、features/MemoryAnalysis/等均存在。五个同构 store slice。状态层在src/store/userMemory/slices/{home,identity,context,preference,experience,activity,base}每个 slice 由action.tsinitialState.ts组成统一经由 SWR 拉取userMemoryService.queryMemories按LayersEnum区分层配合请求守卫 isMemoryListRequestCurrent.ts 丢弃过期响应。这一“slice 同构”结构正是案例能把“系统性根因”归纳成单条缺口 A 的前提——五个列表的错误行为由同一套模式复制而来。3. 模式盘点案例的模式表与当前代码对照案例的第一步输出是模式表对应 layer-1-static.md 的步骤 2逐族走 pattern-catalog.md每个模式评级 ✅ solid / ⚠️ partial-or-misused / — absent-but-expected。以下完整继承案例的模式表并补充当前仓库复核注记模式族位置案例评级注记Overview Detail导航home → 5 个列表 tab → 右侧详情面板✅干净的层层下钻侧边栏Nav.tsxEmpty-as-onboarding成长列表/home 空态 →MemoryEmptyMemoryAnalysisCTA⚠️activities 空态没有 CTA缺口 X1Loading Skeleton反馈列表Loading.tsx复用卡片外框DetailLoading✅外框复用式骨架屏home 用整页Failure Retry反馈全部 fetch5 列表 persona/tags 详情 加载更多— abs.系统性根因缺口 A审计时点Search / filter读每 tab 的FilterBarq → queryMemories服务端✅服务端搜索——未取回数据不会误判空Lists at scale读Virtuoso 的 grid timeline每页 12 条 load-more✅虚拟化 load-more spinnerSelection visibility读 §1.3卡片点击 →?xId 右侧面板— abs.无 scroll-into-view、无选中高亮缺口 DLive/polling读 §1.7分析任务轮询useTask.ts⚠️失败的轮询与运行中不可区分缺口 EEntity lifecycle — delete行动*Dropdown删除 →confirmModaldanger⚠️确认对话框合格无 undo、无失败 toastEntity lifecycle — edit行动/编辑EditableModal→EditorModal⚠️审计时点保存失败按钮永久转圈缺口 B草稿易失Entity lifecycle — correct / add—— abs.不能标记“记错了”也不能手动添加缺口 C、X3Wide-blast confirm行动 §3.7PurgeButton全量删除⚠️一键高危无 type-to-confirm缺口 CProvenance来源链接SourceLink.tsx→ 来源聊天话题✅该面类唯一交付的信任规范仅向后Data control导出/暂停—— abs.无导出、无 off 开关、无 undo缺口 CCross-tab consistency语义一致5 个列表 tab⚠️activities 偏离timeline 下排序消失当前代码复核上表多数位置在当前仓库中仍然成立MemoryEmpty、SourceLink、*Dropdown、PurgeButton、Loading.tsx均在src/routes/(main)/memory/下。唯一需要修正的是“Failure Retry 整列缺失”一行——见下文缺口 A 的复核当前代码中列表页已具备错误态与重试但 home 页 persona/tags 两条 fetch 仍是onSuccess-only。4. 亮点清单Strengths / good cases不要回退案例特别强调“读 happy-path 强、写侧只有一个写流程analysis强但错误处理与数据控制弱”并要求把亮点单列成一节。完整继承如下并给出当前源码佐证✅ 亮点 —DateRangeModal提交状态机。双重提交保护 try/catch/finally 成功 toast 关闭。当前源码 DateRangeModal.tsx L49-L67/memory/features/MemoryAnalysis/DateRangeModal.tsx#L49-L67) 与案例描述逐行对应setSubmitting(true)防重入try中调memoryExtractionService.requestFromChatTopics并await refresh()成功后toast.successclose()catch中toast.errorfinally中setSubmitting(false)。案例称之为“承重亮点”它正是缺口 B 反例的正面对照——每一个记忆写操作都应复制的模型busy 状态在finally复位、catch里出 toast。✅ 亮点 — 每 tab 服务端搜索。q直接传入queryMemories搜索查询的是全量数据而非已加载页因此不会出现客户端过滤造成的“假无结果”。当前 contexts/index.tsx L61-L66/memory/contexts/index.tsx#L61-L66) 仍把q透传给useFetchContexts并进入 SWR key其余 tab 同构。承重理由规模化下的搜索正确性。✅ 亮点 —SourceLink溯源。每个条目可回链到来源聊天话题渲染于每个*RightPanel。承重理由这是信任轴上该面类唯一交付的规范“它为什么知道这个”缺口 C 主张的正确动作是“保留并扩展”它从向后溯源到向前“在 N 次对话中被使用”而不是推倒。✅ — 虚拟化 grid timeline 配真实的 load-more spinner。Virtuoso 列表features/GridView、features/TimeLineView第 2 页请求未命中缓存时页脚显示骨架SWR key 未缓存 →isLoading。承重理由load-more 路径本身健全只有它的失败是静默的属缺口 A 的一部分。✅ — 外框复用式列表骨架Loading.tsx保留卡片容器/边框/圆角仅替换文本单条删除确认*Dropdown.tsxdangerconfirmModal分析运行/错误 AlertStatus.tsx。案例评级“扎实但不出彩——保留”。5. 经验缺口按严重度排序与当前源码逐条复核案例给出 AN 共 14 个缺口。本节完整继承案例结论并在每条后用当前仓库源码标注复核状态。这是本案例对读者最有价值的部分它演示了审计发现如何随代码演进被消化以及复核时应看哪些文件。 A —审计时点任何 fetch 都没有onError/ 错误态。案例归纳每个 slice 只在onSuccess里置xSearchLoadingfalse/xInittrue导致四类消费方挂死方式各异——列表页永久骨架、home 假空态加载失败读作“去分析一下开始使用”诱导重复分析、详情面板永久空白error 与 not-found 都渲染空面板体、load-more 静默无效失败的第 2 页什么都不追加spinner 消失读作“就这些了”。当前复核——部分成立且值得注意修复方式列表页已修复当前contextslice 的 internal_failContextsListL98-L122 通过 SWRresponse.error的useEffect把错误写入contextsSearchError并复位contextsSearchLoading错误是否上浮由 shouldSurfaceMemoryListError.ts L11-L15 决定——“仅当第 1 页且重置中或未初始化才用错误替换列表后台刷新与翻页失败必须保留已定型的可见内容”。路由层 contexts/index.tsx L112-L122/memory/contexts/index.tsx#L112-L122) 把error/isInitialized/isResetting交给MemoryListBoundarysrc/features/Memory/MemoryListBoundary.tsx并提供onRetry{() void mutate()}。“永久骨架无重试”已不成立。home 页仍成立home/action.ts L27-L68 中useFetchPersona/useFetchTags依旧是onSuccess回调置personaInit/tagsInit没有失败分支。案例中“home 假空态”这一半在当前代码中仍可复现。 B —审计时点编辑保存失败OK 按钮永久转圈无错误、无重试关闭即丢稿。案例指出EditorModal onOk是setConfirmLoading(true) → await onConfirm → setConfirmLoading(false)且无 try/catch/finally而updateMemory也没有.catch/ 失败 toast。当前复核——主体已修复EditorModal/index.tsx L24-L39 的handleConfirm现在是setConfirmLoading(true)后进入try { … await onConfirm?.(…); close(); } finally { setConfirmLoading(false); }——正是亮点一里DateRangeModal状态机下沉到公共组件的结果失败时按钮会停止转圈、模态保持打开。残留差异onConfirm的 rejection 没有catch分支接 toast错误反馈仍不如DateRangeModal完整。这个“案例 → 修复 → 公共组件沉淀”的链路恰好印证案例 §4 的回灌结论DateRangeModal已作为 ✅ 例落入 Feedback §4.2。 C — 面类信任修复与数据控制轴整体缺失这是“关于用户的数据”。对一个存放“AI 对你的信念”的存储面类契约是纠正错误信念、保留事实但不使用、把数据带走、撤销误操作。案例列出的四项缺失无“记错了”/上报——下拉只有编辑 删除编辑是单字段盲覆盖删掉的事实下次分析可被原样重新提取无“保留但不使用”——阻止 AI 使用某条事实的唯一方式是永久删除schema 有status列但 UI 无开关无全局“记忆关闭”、无逐条暂停/排除无导出/下载——CRUD 只暴露 get/update/delete/deleteAllUI 无导出无 undo/软删——删除与purgeAllMemories都是硬删Purge all 是一键危险确认无 type-to-confirm。当前复核——仍然成立PurgeButton.tsx L32-L58/memory/features/ActionBar/PurgeButton.tsx#L32-L58) 当前仍是confirmModal({ okButtonProps: { danger: true }, … })一键确认没有 type-to-confirm其onOk内部倒是做了try/catch/finally 成功/失败 toast删除动作本身的状态处理是合格的缺的是“宽杀伤确认”这一层。案例据此提出新规则 Act §3.7wide-blast与本条的新规则 Act §3.9并坦承“L1 对这些项是结构性盲的没有file:line可读”——这正是面类基准规则的用武之地。 X1 — activities 空态无 CTA工具栏也丢掉了 Analysis。activities的List渲染无子节点的MemoryEmpty兄弟 tab 传MemoryAnalysis/且ActionBar只有showPurge兄弟 tab 有showAnalysisActivities 没有任何进入分析的路径空 tab 是死胡同。→ Read §1.1“一致性是语义的”。对照当前 contexts/index.tsx L92/memory/contexts/index.tsx#L92) 的ActionBar showAnalysis showPurgeactivities 与兄弟 tab 的不对称仍可从源码读出。 D — 深链/恢复的选中项不滚动入视、卡片无选中高亮。案例在 memory 树内grep scrollIntoView|scrollToIndex得 0Virtuoso 从scrollTop0挂载卡片不接受activeprop。?contextId指向折叠线下方的条目 零列表反馈。→ Read §1.3无锚点情形。 E — 分析流程失败运行无重试失败轮询与运行中不可区分。Status.tsx展示错误 Alert 但无 RetryuseTask.ts轮询出错时保留 SWR 上一次的 data失败的刷新继续挂着过期的“运行中”帧。→ Act §3.1、Read §1.7。 F — 无跨层全局搜索。每个 tab 只搜自己service 层的searchMemory/retrieveMemory存在于services/userMemory/index.ts但未接入任何 UI“找所有关于 X 的东西”意味着在 5 个 tab 重复查询。→ Read §1.8面类规范。 G — 后端支持手动添加但 UI 无法“Add memory”。add*Memory/createIdentity在 service 层存在但没有按钮调用它们。→ Act §3.4生命周期创建入口。 H — 切到 timeline 时排序静默消失4 个 tab。排序Select只在 grid 模式渲染切换时所选排序被丢弃且无任何信号。当前代码可印证这一行为contexts/index.tsx L65 与 L107-L110/memory/contexts/index.tsx#L105-L111) 中sort: viewMode grid ? apiSort : undefined、sortOptions{viewMode grid ? sortOptions : undefined}——timeline 下排序选择器直接不渲染URL 里的sort参数值仍保留但不生效。→ “一致性是语义的”。 I — home 人设只读且是死胡同。人设编辑器与编辑触发被注释掉人设分区/角色标签不链接进详情 tab。→ Grow §5.3、Act §3.4。 J — 编辑草稿易失关闭静默丢弃。源是内存中的editingMemoryContentdestroyOnHiddenonCancelclearEditingMemory无 dirty-check 直接丢弃。→ Edit §2.1模态场景可放宽。 K — 分数/使用信号不一致。Confidence 仅对 experiences 显示scoreImpact/scoreUrgency/scorePriority与accessedCount/lastAccessedAt已存储但从未在 UI 呈现。→ 一致性面类规范新鲜度/使用信号。 L — 无批量选择只有“逐条”或“全部”。单条删除与 Purge-all 之间没有多选。→ Act §3.1批量 ⇄ 单条对等。 M — 无逐层解释/引导。五个 tab 只有泛化空态文案用户得不到 identities 与 contexts 等的定义。→ Grow §5.1。 N —DateRangeModal允许提交全空无界时间范围且无范围确认分析触发在任务进行中未硬锁定。→ 摩擦 / Act §3.1。6. 技能反馈回灌审计如何反哺检查清单案例的 §4 展示了 ux-audit 与ux技能之间的闭环——“审计是基准ux的度量者也是让它保持诚实的机制”。Memory 案例落地的反馈新规则 Act §3.9持有“关于用户的数据”的界面记忆/个性化/档案存储欠下信任修复 数据控制四项债务——correct-or-mark-wrong不只是删、retain-without-use暂停/排除、export、undo/软删。Memory 是该规则的 ❌ 范例。作为既有规则的 ❌ 例落地Feedback §4.2整个userMemorystore 的onSuccess-only / 无onError模式缺口 AEditorModal onOk无finally的写操作陷阱缺口 B、Read §1.1详情面板 error 与 not-found 同显空白 home 假空态缺口 A、Read §1.3列表无 scroll-into-view 无选中卡片高亮缺口 D、Act §3.7PurgeButton一键宽杀伤、无 type-to-confirm缺口 C。作为既有规则的 ✅ 例落地回灌的另一半Feedback §4.2 现引用DateRangeModal提交状态机作为仓库内 ✅ 例与缺口 B 的 ❌ 并排Read §1.2 引用 Memory 每 tab 服务端搜索与 Pages 客户端过滤 ❌ 对照。验证了既有规则§4.2 永久骨架、Read §1.1 空 vs 失败、Act §3.1 完成/错误、以及“一致性是语义的”缺口 X1/H。回灌的机制要求SKILL.md “Land the findings”每次运行必须把可泛化的缺口写回ux检查清单规则 ✅/❌ 例并镜像一行到 Quick review亮点则用来“磨规则文本”而不只是装饰——例如 Fleet 案例从 scroll-into-view 提炼出“重跑触发有两种味道”与“滚动轴跟随列表方向”两条子规则。若一次运行确实没有可泛化缺口也要在报告里明说——沉默不是可接受的收尾。7. 待办层L2 与 L3 验证计划案例末尾保留了 L2/L3 的待办清单这也示范了“层间交接”应写成什么样子L2— 永久骨架/空白/假空态实际渲染成什么样home 整页加载器的 CLSMemoryEmpty是否读起来像一个真实页面人设/标签云布局暗色模式。L3— 强制每条 fetch 失败在线验证缺口 A/B/E永久骨架/空白/转圈模态/过期轮询走一遍 analyze → 运行中 → 完成深链一个折叠线下的?xId验证缺口 D强制 delete/update 失败验证缺失的 toast。注意本案例 L1 运行于 2026-07本文复核时发现列表侧错误处理已重构MemoryListBoundaryinternal_failContextsList——若按上述 L3 计划重跑验证对象应从“是否永久骨架”更新为“shouldSurfaceMemoryListError的四象限首页失败/后台刷新失败/翻页失败/重置中失败行为是否符合注释声明”。这就是文档“re-verify before citing”提示的实操含义。8. 如何复用这份案例模板如果读者要在自己的界面上复刻这套流程案例文档给出的输出形态可以直接抄头部三行面类 基准产品跑了哪些层一句话 headline本案例“两条轴失败——读/写错误侧完全无处理数据控制轴缺失”Patterns in use 表模式 | 位置块文件| 评级 | 注记缺失的模式也要占一行标— abs.Strengths / good cases独立小节每个亮点给file:line “承重理由” 是否回灌为 ✅ 例Experience gaps排序列表每条 发现 违反的ux规则/目录模式 来源层与证据 一行补救方向Skill feedback新规则 / ❌ 例 / ✅ 例 / 仅验证既有规则四选一写清Pending L2/L3写不出结论的层要留下可执行的验证剧本。证据纪律贯穿始终layer-1-static.md 的 “What L1 can and cannot conclude”L1 能断“分支缺失、init 标志只挂在成功上、草稿无持久化”不能断“空态读起来像真页面”“主控件是主操作”更不能断“某类能力缺失”——后者要靠面类基准清单引入 L1 逐项核。本案例对缺口 C 的处理是范本它没有任何file:line却依然被排进 因为它的证据是面类契约而不是代码。最后引用本文路径时的提醒案例内所有file:line引用如context/action.ts:88锚定的是 2026-07 审计时的代码当前仓库中部分行号与行为已演进第 5 节的复核列即是权威对照引用该案例时请以当前仓库为准重新核验。【免费下载链接】lobehub LobeHub is your Chief Agent Operator, organizing your agents into 7×24 operations by hiring, scheduling, and reporting on your entire AI team.项目地址: https://gitcode.com/GitHub_Trending/lo/lobehub创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表