Refly v0.2.3 更新解析:产品引导向导、会话制计费与知识库体验升级的实现细节
【免费下载链接】reflyThe first open-source agent skills builder. Define skills by vibe workflow, run on Claude Code, Cursor, Codex & more. Build Clawdbot 🦞· APIs for Lovable · Bots for Slack & Lark/Feishu · Skills are infrastructure, not prompts.项目地址: https://gitcode.com/GitHub_Trending/re/refly
本文基于 Refly 仓库中的 v0.2.3 更新日志,系统梳理该版本的核心变更:全新产品初始化设置向导、由 Token/存储容量制转向“会话次数 + 文件数量”的计费方案、知识库文档与资源预览、节点级永久删除能力,以及五项核心问题修复。读完本文,你可以理解每一项功能在前端触发链与后端服务层的对应实现(引导表单如何被服务端 Schema 驱动、用户偏好如何回写、配额如何计量),并能通过环境变量ONBOARDING_ENABLED等开关了解自部署时的相关配置项。
一、v0.2.3 更新总览
根据 v0.2.3 更新日志,本版本的定位是“全面升级产品引导体验、优化付费方案设计,并提供更直观的知识库展示,同时修复多个核心使用问题”。变更分为四大块:
| 模块 | 变更类型 | 关键内容 |
|---|---|---|
| 产品引导 | 新功能 | 初始化设置向导、核心功能介绍、交互式使用指南、功能点悬浮视频教程 |
| 付费方案 | 全新优化 | 计费单位由 Token/存储容量改为会话次数与文件数量;新增用量统计展示与用量不足提醒 |
| 知识库 | 体验升级 | 新增文档和资源预览功能 |
| 资源管理 | 新功能 | 删除节点时可永久删除对应资源/文档;删除画布时可级联删除画布内全部资源 |
| 核心修复 | 缺陷修复 | 频繁退出登录、网页内容复制导出丢失、文档标题末字符无法删除、空图片地址报错、弱网下删除最后画布跳转异常 |
下面按模块展开,并结合仓库源码说明各功能的实际实现位置。
二、产品引导全面升级:从“设置向导”到“悬浮视频教程”
更新日志中引导模块包含四个具体能力:
- 产品初始化设置向导:配置界面语言(UI Locale)、AI 回答语言(Output Locale)以及操作模式(鼠标/触控板);
- 产品核心功能介绍:帮助新用户快速理解产品价值;
- 交互式使用指南:手把手引导体验 Refly 辅助内容创作全流程;
- 功能点悬浮视频教程:直观了解各功能的使用方法。
2.1 初始化设置向导的触发链
设置向导是否弹出,由登录后拉取的用户设置中的preferences.hasFilledForm字段决定。前端在 use-get-user-settings.ts 中完成这一判断:
// packages/ai-workspace-common/src/hooks/use-get-user-settings.ts const updateModalStatus = (preferences: UserPreferences) => { const hasBeenInvited = preferences.hasBeenInvited; userStore.setShowInvitationCodeModal(!preferences.hasBeenInvited); // Only check form filling status if user has been invited if (hasBeenInvited) { const hasFilledForm = preferences.hasFilledForm ?? false; userStore.setShowOnboardingFormModal(!hasFilledForm); } };即:仅当用户已被邀请(hasBeenInvited)且尚未填过引导表单(hasFilledForm === false)时,才会置位showOnboardingFormModal。后端在注册时将该字段初始化为false(见 auth.service.ts 中hasFilledForm: false的初始化),表单提交成功后再置为true。
2.2 服务端驱动的动态表单
引导表单本身并不是前端写死的组件,而是由服务端下发 JSON Schema、前端用 RJSF(react-jsonschema-form)动态渲染的。FormOnboardingModal 的核心流程:
- 通过
useGetFormDefinition请求表单定义(含schema与uiSchema); - 将服务端返回的 Schema 解析后合并
formId与当前用户uid,交给ReflyRjsfForm渲染; - 解析失败或请求出错时展示错误占位,避免白屏。
对应的后端实现位于 form.service.ts:
getFormDefinition:从数据库FormDefinition表中读取已发布的表单定义(formId、title、description、schema、uiSchema、status);submitForm:写入FormSubmission记录,并将用户preferences.hasFilledForm更新为true,同时从答案中提取role字段同步到遥测属性user_identity;hasFilledForm:对外暴露“是否已填写”的判断逻辑,供用户设置接口聚合返回。
这一设计意味着运营侧可以在不发布前端版本的情况下调整引导表单的字段与文案——表单结构完全由数据驱动。
2.3 引导开关:ONBOARDING_ENABLED
是否强制走引导流程是一个可配置项。app.config.ts 中定义了:
// apps/api/src/modules/config/app.config.ts onboarding: { enabled: process.env.ONBOARDING_ENABLED === 'true' || false, },FormService.hasFilledForm首先检查auth.onboarding.enabled:关闭时直接返回hasFilledForm: true,跳过表单要求。对于自部署场景,可以通过设置环境变量ONBOARDING_ENABLED=true来启用该引导链路(可参考 env.example 中的环境变量约定)。
2.4 界面语言、AI 回答语言与操作模式的落地
向导收集的三项配置最终会写入用户设置并驱动本地行为,同样在 use-get-user-settings.ts 中可见:
localSettings = { ...localSettings, uiLocale, // 界面语言 outputLocale, // AI 回答语言 isLocaleInitialized: true, canvasMode: settings?.preferences?.operationMode || 'mouse', // 操作模式:鼠标/触控板 disableHoverCard: settings?.preferences?.disableHoverCard || false, };其中有一个值得注意的“首次登录回写”逻辑:若服务端返回的uiLocale与outputLocale均为空(新注册用户),前端会用浏览器navigator.language映射出默认语言并立即回写updateSettings({ uiLocale, outputLocale }),保证下次加载时语言配置已固化到服务端。操作模式则通过preferences.operationMode持久化,缺省为mouse,供画布交互层读取以切换鼠标/触控板适配方案。
三、付费方案全新优化:从 Token/存储容量到会话次数与文件数量
更新日志明确说明计费方式的变更:“由 Token/存储容量改为会话次数和文件数量,更清晰直观”,并配套了定价说明优化、用量统计展示与用量不足提醒。
3.1 配额模型在源码中的体现
当前仓库的订阅计量实现与“会话/请求次数 + 文件数量”的双维度模型一致。subscription.service.ts 中可以看到两类用量表(usage meter):
- 请求计量:
t1CountQuota/t2CountQuota(按请求层级计次的配额),缺省回落到配置项quota.request.t1/quota.request.t2,另有creditQuota对应的积分额度; - 存储计量:
fileCountQuota,缺省回落到配置项quota.storage.file,用于约束用户上传/入库的文件数量。
// apps/api/src/modules/subscription/subscription.service.ts(节选) t1CountQuota: plan?.t1CountQuota ?? this.config.get('quota.request.t1'), t2CountQuota: plan?.t2CountQuota ?? this.config.get('quota.request.t2'), // ... fileCountQuota: plan?.fileCountQuota ?? this.config.get('quota.storage.file'),即套餐(plan)上可单独配置各维度的上限,未配置时使用全局默认值。这种“按次 + 按文件数”的配额结构,正是更新日志所说新计费方式在服务端的落点。
3.2 用量统计与不足提醒
用量展示与提醒在前端有对应组件:hint.tsx 负责订阅/用量相关的提示渲染,聊天输入区(如 chat-box.tsx)与文件导入流程(如 storageLimit.tsx)也会基于剩余配额给出拦截或引导。套餐价格常量目前收敛在 pricing.ts(plus / starter / maker 三档月付与年付价格,注释说明应与支付平台配置保持一致)。
3.3 与旧方案的对照
| 维度 | 旧方案(≤v0.2.2 时期) | v0.2.3 起 |
|---|---|---|
| 计费单位 | Token 消耗、存储容量 | 会话(请求)次数、文件数量 |
| 用户感知 | 需理解 Token 概念 | 次数直观,便于预估 |
| 配额来源 | — | 套餐级t1CountQuota/t2CountQuota/fileCountQuota,缺省回落到全局配置 |
| 配套能力 | — | 用量统计展示、用量不足提醒与补充指引 |
四、知识库体验升级:预览与永久删除
更新日志记录了知识库的两项变更:
- 文档和资源预览:新增文档和资源预览功能,界面更加直观美观;
- 永久删除资源或文档:
- 在节点删除时,可永久从知识库中删除该资源或文档;
- 在删除画布时,可删除画布中所有的资源或文档。
永久删除的价值在于:此前的删除多为画布层面的移除,底层知识库资源仍会持续占用存储配额(对应上一节提到的fileCountQuota维度);v0.2.3 之后,删除操作可以直接清理底层数据,让配额回收成为可能。该能力在更新日志中描述为可选行为(“可永久删除”),即删除时由用户决定是否彻底移除。
五、核心问题修复与源码印证
更新日志列出了五项核心修复,其中“频繁退出登录”一项与前端鉴权状态管理直接相关,源码中可以看到对应的防御性设计(见 use-get-user-settings.ts):
- 竞态请求防护:
activeRequestId递增 +isLatestRequest()判断,确保慢响应不会覆盖新请求写入的登录态; - 登出误判防护:鉴权失败或无凭据时调用
authChannel.updateCurrentUid(null),避免跨标签页的 uid 监听把“未登录”误判为“切换用户/被登出”; - 重定向环路短路:鉴权失败时仅在“非公开页且不在根路径 /login”的情况下才跳转登录页,并保留
returnUrl,避免登录态检查引发的循环跳转——这类异常跳转在弱网环境下会显著放大“频繁掉登录”的观感。
其余四项修复(网页内容复制到 AI 文档再导出的内容丢失、文档标题最后字符无法删除、文档编辑器空图片地址报错、弱网环境下删除最后画布的跳转异常)属于编辑器与画布交互层面的缺陷修复,以 更新日志 的条目描述为准。
六、小结:这一版本解决了什么问题
- 降低上手门槛:初始化向导 + 功能介绍 + 交互式指南 + 悬浮视频教程,构成完整的新用户引导链路;表单由服务端 Schema 驱动,可通过
ONBOARDING_ENABLED在自部署中开关; - 计费心智更清晰:以会话次数和文件数量替代 Token/存储容量,配额按套餐维度配置并回落到全局默认,配套用量统计与不足提醒;
- 资源生命周期闭环:知识库预览提升浏览体验,节点/画布级永久删除打通了配额回收;
- 稳定性:针对登录态竞态、弱网跳转等高频问题做了修复。
如果想进一步跟进相关实现,建议从 form.service.ts、use-get-user-settings.ts、subscription.service.ts 三个文件入手,分别对应引导表单、登录态与本地偏好、配额计量三条主线。
【免费下载链接】reflyThe first open-source agent skills builder. Define skills by vibe workflow, run on Claude Code, Cursor, Codex & more. Build Clawdbot 🦞· APIs for Lovable · Bots for Slack & Lark/Feishu · Skills are infrastructure, not prompts.项目地址: https://gitcode.com/GitHub_Trending/re/refly
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考