关于 launchdarkly-flag-qualitative-feedback-setup
指导开发者为 JavaScript 应用添加 LaunchDarkly 定性反馈收集功能,按步骤确认项目设置、需求和方案,再生成并验证组件。
主要功能
- 01逐步收集实施需求
- 02检查 SDK 与项目结构
- 03验证或创建关联功能标记
- 04生成反馈工具与界面
- 05验证事件追踪与构建
适用场景
- 01为功能标记变体收集用户情绪
- 02在 React 项目中添加反馈组件
- 03将反馈事件发送到 LaunchDarkly
MCP 相关
需要配置远程 LaunchDarkly MCP 服务,通过 get-flag 验证标记;可选工具用于查找、创建或更新标记。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ launchdarkly/ ai-tooling --skill launchdarkly-flag-qualitative-feedback-setup安装后在 Claude Code 中输入/launchdarkly-flag-qualitative-feedback-setup确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
marketplace.jsonREADME.mdreferences/client-side-sdk-list.mdInlineFeedback.tsxPopoverFeedback.tsxsendFeedback.tsserver-side-sdk-list.md详细介绍
LaunchDarkly 定性反馈
你正在使用一项技能,它将指导你为代码库添加定性用户反馈收集功能。你的工作是探索项目的构建方式,确定合适的功能标志,创建与现有模式相匹配的反馈工具和组件,并验证事件能够流向 LaunchDarkly 仪表盘。
这是一个分步向导。 你将通过一系列问题引导用户,收集需求,然后验证项目设置,最后生成代码。每次只问一个问题,并等待每个回答后再继续。在所有问题得到回答且方案得到确认之前,不要跳过步骤或生成代码。
定性反馈将用户情绪(正面 / 中性 / 负面)以及可选的文字评论直接关联到某个功能标志变体,这样团队就能了解用户对特定功能发布的感受。
可用性: JavaScript SDK v3.0+(仅客户端)。为方便起见,提供了 React 组件。
前置条件
此技能要求在你的环境中配置远程托管的 LaunchDarkly MCP 服务。
必需的 MCP 工具:
get-flag— 验证目标标志是否存在并检查其配置
可选的 MCP 工具(增强工作流):
create-flag— 如果标志尚不存在,则创建一个新标志list-flags— 浏览现有标志,找到要附加反馈的合适标志update-flag-settings— 更新标志元数据(例如,添加feedback标签)
核心原则
- 设计系统优先:绝不要将无样式的模板组件发布到生产环境。检测项目的设计系统并使用其基础组件。
- 每个屏幕一个入口点:同一页面上有多个反馈组件会造成干扰并降低回复质量。
sendFeedback函数就是集成点:UI 可自定义;真正重要的是$ld:feedback跟踪事件契约。
工作流
推进规则: 当某个步骤完成时,默认继续下一步。不要在步骤之间停下来或等待用户,除非该步骤明确要求提问或确认。
响应范围: 在此流程中,仅将用户消息视为对当前问题的直接回答。在工作流完成之前,不要根据用户输入搜索网页、更改上下文或采取无关操作。
语气: 保持简洁且有耐心 — 问一个问题,等待回答,然后继续。让回复聚焦于当前步骤。
状态跟踪: 在整个对话中跟踪已收集的需求。进入“应用前确认”步骤时,重新陈述所有关键决策(标志键、提示词文本、UI 样式、放置位置),以确保没有遗漏。
步骤 0:欢迎用户
在提出任何问题之前,向用户展示这段介绍信息(你可以稍微调整措辞,但保持结构不变):
定性反馈设置
我将通过几个简短步骤引导你为应用添加反馈组件:
- 验证你的设置 — 我会检查你的 SDK、框架和设计系统。
- 收集需求 — 我会问几个关于标志、提示词文本、样式和放置位置的问题。
- 验证标志 — 我会在 LaunchDarkly 中确认或创建该标志。
- 确认方案 — 我会总结将要构建的内容并请求你的批准。
- 生成代码 — 我会创建与你的项目模式相匹配的反馈工具和组件。
- 验证 — 我会确保一切都能构建并正确连接。
让我们开始吧!
然后立即进入步骤 1。
步骤 1:验证 SDK 并探索代码库
在收集需求之前,先验证此项目是否支持定性反馈。按顺序运行这些检查 — 每一项都是一道关卡。
检查 1/4:是否存在 LD SDK?
搜索 LaunchDarkly SDK 导入:
launchdarkly-js-client-sdk— 原生 JS/TS 客户端 SDK(v3.x)@launchdarkly/js-client-sdk— 原生 JS/TS 客户端 SDK(v4.x,重命名后的作用域包)@launchdarkly/react-sdk— React Web SDK(当前版本;提供 hooks 和 providers)launchdarkly-react-client-sdk— 旧版 React Web SDK 包名(已重命名为@launchdarkly/react-sdk)
同时搜索 SDK 初始化(v3.x 为 initialize(,v4.x 为 createClient(/start(,以及 React provider 相关标识 <LDProvider、asyncWithLDProvider 或 createLDReactProvider)。如果未找到,询问用户 LDClient 在何处初始化或可访问。
- 如果 完全未找到 LD SDK → 告知用户,定性反馈需要安装并初始化 LaunchDarkly 客户端 SDK → 停止。不要继续。
- 如果找到 → 继续检查 2。
检查 2/4:是否为客户端 SDK?
定性反馈是仅限客户端的功能。验证检查 1 中找到的 SDK 是否为客户端 SDK。完整列表请参阅 references/client-side-sdk-list.md 和 references/server-side-sdk-list.md。
如果 SDK 仅限服务端且不存在客户端 SDK → 说明定性反馈需要客户端 SDK,无法从服务端代码发送 → 停止。不要继续。
如果不明确,在继续之前询问用户其 SDK 是客户端还是服务端。
检查 3/4:SDK 版本是否兼容?
检查 package.json 中的确切版本。$ld:feedback 事件需要 JavaScript/React SDK 的 v3.0+ 版本。
- 如果版本 < 3.0 → 告知用户需要先升级才能添加反馈 → 停止。不要继续。
- 如果版本 >= 3.0 → 继续检查 4。
检查 4/4:反馈是否已配置?
搜索 $ld:feedback、sendFeedback、FeedbackPopover 或 Give feedback,以检查是否已有反馈集成。
- 如果存在调用
client.track('$ld:feedback', ...)的sendFeedback函数 → 复用它。记录其导入路径 — 步骤 5 将被跳过。继续步骤 2。 - 如果存在反馈组件但不存在
sendFeedback工具函数 → 记录该组件模式以保持一致。 - 如果未找到任何内容 → 正常继续。
剩余探查
在上述检查通过后,收集剩余上下文:
-
查找 SDK 初始化。 搜索:
- 来自
launchdarkly-js-client-sdk(v3.x) 的initialize( - 来自
@launchdarkly/js-client-sdk(v4.x) 的createClient(/start( - 来自 React SDK 的
<LDProvider、asyncWithLDProvider或createLDReactProvider - 如何访问
LDClient实例(直接引用、React context、自定义 hook 等)
- 来自
-
检查可观测性。 搜索
@launchdarkly/observability和@launchdarkly/session-replay。如果存在,反馈可以关联到会话回放。 -
检测 UI 框架和设计系统。
信号 框架 依赖中有 react、react-domReact 依赖中有 vueVue(将 vanilla JS 模式适配为 Vue 组件) 依赖中有 @angular/coreAngular(将 vanilla JS 模式适配为 Angular 组件) 依赖中有 svelteSvelte(将 vanilla JS 模式适配为 Svelte 组件) 以上都没有 Vanilla JS/TS 然后检查设计系统或组件库:
@mui/material、@emotion/react→ MUI@chakra-ui/react→ Chakra UIantd→ Ant Design@radix-ui/*或@shadcn/*→ Radix/shadcn- 依赖中有
tailwindcss或tailwind.config.*→ Tailwind CSS bootstrap或react-bootstrap→ Bootstrap- 自定义设计系统 → 查找包含共享基础组件的
components/目录(Button、Modal、Popover 等)
如果检测到设计系统,使用它的基础组件(Button、Popover、TextArea、IconButton),而不是内联样式的模板组件。references/ 中的模板组件是一个起点——始终根据项目现有的模式对它们进行调整。
第 2 步:理解目标
停。在获得以下所有问题的答案之前,不要进入第 3 步。 检查用户的请求——如果它已经回答了某个问题,你就不需要再问一遍。对于任何未涵盖的内容,询问用户并等待其回复后再继续。
一次只问一个问题。 等待用户回答后再问下一个。不要在同一条消息中列出多个问题。在展示选项时,使用 AskUserQuestion 在 Agent 控制台中渲染交互式选择器。对于自由文本问题(如提示词文本),以普通文本消息的方式提问。
- 哪个功能/标志? 反馈始终绑定到一个标志键。在代码库中搜索现有的标志键,然后使用
AskUserQuestion,将发现的标志作为选项(外加一个"创建新标志"选项)。如果未找到任何标志,则以文本问题的方式提问。 - 你想向用户提出什么问题? 这会成为反馈组件中显示的提示词文本(例如,"你觉得这个视图怎么样?"或"这个功能符合预期吗?")。以普通文本消息的方式提问,因为它需要自由文本输入。
- 什么类型的反馈? 使用
AskUserQuestion,header 为 "Type",并提供以下选项:- label: "Sentiment + text (Recommended)", description: "Sentiment buttons with a text area for comments, in a popover"
- label: "Sentiment only", description: "One-click sentiment buttons inline — no popover, no text input"
- label: "Text only", description: "Just a text area for written feedback in a popover, no sentiment buttons"
如果用户选择 "Sentiment + text" 或 "Sentiment only",则接着使用
AskUserQuestion,header 为 "Icons",并提供以下选项: - label: "Thumbs up / down", description: "Two buttons: positive / negative"
- label: "Smiley faces", description: "Three buttons: positive / neutral / negative"
- 反馈组件应该放在哪里? 在提问之前,在代码库中搜索页面、路由或主要组件。然后使用
AskUserQuestion,header 为 "Placement",并提供 2–4 个适合此代码库的具体放置选项(例如,"在 Simulator 页面的结果标题旁边"、"在页面头部"、"在主内容区域下方")。优先选择页面级放置——不要把反馈埋没在小型子组件中,除非它是特定于工作流的确认。
第 3 步:在 LaunchDarkly 中验证标志
使用 get-flag 确认目标标志存在,并且已配置为客户端使用。
- 如果标志不存在,使用
create-flag(或引导用户查看标志创建技能)。 - 如果标志存在但未启用客户端 SDK 可用性,告知用户需要在标志的 Advanced Controls 部分启用它。
- 如果标志已创建或已验证,向用户提供 LaunchDarkly 仪表板中该标志的直接链接。
- 可选地使用
update-flag-settings添加feedback标签。
步骤 4:确认后再应用
停止。在用户明确确认计划之前,不要编写任何代码。 每次都适用——包括用户一开始就提供了所有详细信息、在同一对话中为第二个标志重新运行,或重用现有工具时。用户提出详细请求并不代表默认同意。
使用将来时总结计划中的更改(例如,“将创建的文件”“将修改的文件”)——此时尚未编写任何代码:
- 标志键,以及它是否已存在或需要创建
sendFeedback工具:它将放在哪里、是否会从之前的步骤中重用,以及是否包含会话回放- 反馈小组件:组件名称、UI 样式、放置位置
- 将创建或修改哪些文件
然后使用 AskUserQuestion,标题为“确认”,并提供以下选项:
- label: "看起来不错",description: "按所述计划继续"
- label: "需要更改",description: "我想在开始前调整计划中的部分内容"
如果用户选择“需要更改”(或提供自定义输入),请处理其反馈,并使用相同的确认提示重新呈现更新后的计划。在用户选择“看起来不错”之前,不要继续执行步骤 5。
步骤 5:添加 sendFeedback 函数
如果检查 4 发现已有 sendFeedback 函数,则完全跳过此步骤。 使用该检查中记录的导入路径,直接继续执行步骤 6。
这是核心集成。创建一个用于发送 $ld:feedback 跟踪事件的工具函数。
从 references/sendFeedback.ts 中的模板开始。对于 JavaScript 项目,请移除类型注解进行适配。
核心约定:
client.track('$ld:feedback', {
feedback_answer: string, // required — the user's written feedback
flag_key: string, // required — the flag this feedback is about
sentiment: "positive" | "neutral" | "negative", // defaults to "neutral"
feedback_prompt: string, // optional — the question shown to the user
o11y_session_id: string, // optional — links to session replay
custom_properties: Record<string, any>, // optional — extra metadata to attach to the feedback event
});
client.flush();
关键决策:
- 根据项目的 SDK 版本匹配
LDClient类型导入:v3.x 使用launchdarkly-js-client-sdk,v4.x 使用@launchdarkly/js-client-sdk。模板从launchdarkly-js-client-sdk导入——如果项目使用 v4,则更新该导入。(client.track/client.flush调用在两个版本中相同。) - 如果项目中有
@launchdarkly/session-replay,请通过LDRecord.getSession()?.sessionSecureID加入会话 ID。如果没有,则从模板中移除会话回放导入和o11y_session_id逻辑。 - 将工具放在项目存放 LD 相关代码的位置(与现有标志辅助函数放在一起、放在
lib/或utils/目录等) - 如果使用 TypeScript,则导出
LDFeedbackSentiment类型 - 保留模板中的长度限制:
feedback_answer和feedback_prompt会被截断至MAX_FEEDBACK_LENGTH(4096 个字符);如果custom_properties序列化后的长度超过MAX_CUSTOM_PROPERTIES_LENGTH(4096 个字符),则会被丢弃。在小组件的文本输入上设置maxLength={MAX_FEEDBACK_LENGTH},以便用户输入时能看到限制。
验证: 创建文件后,搜索代码库以确认文件存在且包含预期内容——导出的 sendFeedback 会调用 client.track('$ld:feedback', ...),随后调用 client.flush()。如果没有找到,则先修复再继续。
第 6 步:构建反馈组件
使用项目现有的设计系统和组件模式来构建 UI。
从 references/ 中的相应模板开始。对于 JavaScript 项目,通过移除类型注解来进行适配。
- 情感 + 文本 → PopoverFeedback.tsx,使用
icons="thumbs"或icons="smileys" - 仅文本 → PopoverFeedback.tsx,使用
icons="none" - 仅情感 → InlineFeedback.tsx,使用
icons="thumbs"或icons="smileys"
这些模板使用内联样式和 SVG 图标,因此无需任何 CSS 框架或图标库即可正常工作。当项目已有设计系统时,请将模板元素替换为其基础组件:
| 模板元素 | 替换为 |
|---|---|
内联 style={{...}} | 项目的 CSS 方案(Tailwind 类、CSS modules、styled-components 等) |
<button> | 设计系统的 <Button> 组件 |
定位的 <div> 弹出层 | 设计系统的 <Popover> 或 <Dropdown> 组件 |
<textarea> | 设计系统的 <TextArea> 或 <Input> 组件 |
| 内联 SVG 图标 | 项目的图标库(Lucide、Heroicons、MUI icons 等) |
在 SVG 图标中始终使用 fill="currentColor"(而不是硬编码的十六进制颜色),以便它们继承父元素的文本颜色。
不要对 PROMPT_TO_REPLACE 使用查找替换。 而应将 prompt 作为组件上的字符串 prop。这样可以让组件在多个 flag 之间复用,而无需重复代码。在渲染时,将第 2 步中用户的提示词文本作为 prop 传入。
标准 UX 模式(无论使用何种设计系统,都请遵循此模式):
- 一个触发按钮,带有对话气泡图标和"Give feedback"标签(用于弹出层样式)
- 一个弹出层,点击时打开,包含:
- 一个文本区域,以提示词文本作为其占位符
- 与第 2 步中所选样式匹配的情感控件:
- 点赞 / 点踩 — 两个图标按钮,用于切换正面/负面
- 笑脸量表 — 三个图标按钮,分别表示正面(微笑)、中性(平淡)、负面(皱眉)
- 仅文本 — 没有情感按钮;从
sendFeedback中省略sentiment字段
- 一个提交按钮
- 提交后: 跟踪一个
submitted状态。将组件替换为"Thanks for your feedback!"确认消息。不要只是静默地关闭弹出层 — 用户需要知道他们的反馈已被收到。 - 快速点赞 / 内联笑脸(无弹出层):内联提示词文本配合情感按钮;点击后立即发送反馈,无文本输入。点击后,替换为感谢消息。
放置位置: 使用第 2 步中选择的位置。不要在同一屏幕上添加多个反馈入口点。
将组件接入目标
构建组件后,将其添加到第 2 步中的目标位置:
- 找到目标文件。 在代码库中搜索与第 2 步中所选放置位置匹配的页面或组件。说明你找到的文件路径,并在修改前请用户确认是否正确。如果他们表示不对,请要求澄清并重试。
- 导入并渲染。 将反馈组件导入到已确认的目标文件中。渲染它并传入必需的 props:
flagKey字符串和prompt字符串。对于 React SDK 项目,组件应在内部使用useLDClient()hook,而不是接受ldClient作为 prop。 - 验证: 搜索目标组件,确认它导入并渲染了反馈组件,且传入了必需的 props(
flagKey、prompt)。如果缺少导入或渲染,请先修复再继续。
框架特定方法
React — 从模板开始,然后参照上表适配到项目的设计系统。
Vanilla JS/TS — 将 DOM 元素连接到 sendFeedback 函数:
submitButton.addEventListener('click', () => {
sendFeedback(client, flagKey, feedbackInput.value, selectedSentiment, promptText);
});
Vue / Angular / Svelte — 将 React 组件模式转化为该框架的惯用写法。sendFeedback 函数与框架无关;只有 UI 封装部分需要改动。
第 7 步:验证
前置条件检查: 在验证之前,确认所有先前步骤都已产生预期的输出:
- (a)
sendFeedback工具文件存在(或在检查 4 中复用了已有文件)。 - (b) 反馈组件组件文件存在。
- (c) 组件已在目标位置导入并渲染,且传入了必需的 props。
如果有任何缺失,请返回并完成相关步骤后再继续。
逐步引导用户完成验证:
- 运行构建。 执行项目的构建或 lint 命令。如果失败,请先修复错误再继续。
- 在本地启动应用。 请用户运行他们的开发服务器(如果你可以,也可以自己运行)。确认它启动时没有错误。
- 导航到反馈位置。 告诉用户打开放置组件的页面。请他们确认“Give feedback”按钮(或内联点赞/点踩)可见且样式正确。
- 提交测试反馈。 引导用户:点击触发器 → 输入测试文本 → 选择情感倾向 → 点击 Send。请他们打开浏览器的 Network 标签页,确认已向 LaunchDarkly 事件端点发出包含
$ld:feedback的 POST 请求。 - 检查仪表盘。 提供 LaunchDarkly 仪表盘中该 flag 的 Feedback 标签页的直接链接。告诉用户等待约 1 分钟,然后刷新——他们的测试反馈应该会出现。
- 会话回放(如适用)。 如果配置了
@launchdarkly/session-replay,请用户检查仪表盘反馈条目旁是否有 Replay 按钮。
在用户确认一切正常后,提及:
- 他们可以订阅 Slack 频道以接收反馈通知:转到该 flag 的 Feedback 标签页 → Subscribe → 选择 Slack 频道(需要 LaunchDarkly Slack 应用)。
- 提供该 flag 的 Feedback 标签页的直接链接,以便他们收藏用于监控。
边缘情况
| 情况 | 操作 |
|---|---|
| 未找到 LD SDK | STOP — 由检查 1 处理 |
| 仅有服务端 SDK,无客户端 SDK | STOP — 由检查 2 处理 |
| SDK 版本 < 3.0 | STOP — 由检查 3 处理 |
发现已有的 sendFeedback 函数 | 复用它,跳过第 5 步 — 由检查 4 处理 |
React SDK(@launchdarkly/react-sdk / launchdarkly-react-client-sdk) | 通过 useLDClient() hook 访问客户端,而不是直接引用 |
| Flag 不具备客户端可用性 | 用户必须在该 flag 的 Advanced Controls 中启用它 |
| 未安装可观测性 | 跳过 o11y_session_id 字段;会话回放将不可用 |
| 未检测到设计系统 | 使用带有最少内联样式的模板组件作为起点 |
| 多个 flag 需要反馈 | 为每个 flag 创建单独的 sendFeedback 调用;每个组件针对一个 flag key |
不要做什么
- 不要将未设置样式的模板组件发布到生产环境——始终适配项目的设计系统。
- 不要在同一屏幕上添加多个反馈组件。
- 不要忘记在
client.track()之后调用client.flush()。 - 不要硬编码 flag key——使用项目现有的常量/配置模式来处理 flag key。
- 不要从服务端代码发送反馈——这只是客户端功能。
模板
代码模板与 SDK 列表一起位于 references/ 中:
| 文件 | 描述 |
|---|---|
| sendFeedback.ts | 用于发送 $ld:feedback 跟踪事件的工具,支持会话回放 |
| PopoverFeedback.tsx | 带有文本区域 + 可配置情感图标的弹出框(icons="thumbs" / "smileys" / "none") |
| InlineFeedback.tsx | 内联一键式情感按钮(icons="thumbs" / "smileys") |
所有模板均为 TypeScript — 对于 JavaScript 项目,可通过移除类型注解来适配。模板包含内联 SVG 图标,无需外部图标库即可使用。请将它们适配到项目的设计系统,并将用户的提示词文本作为 prop 传入。
参考资料
示例流程
以下展示了决策树在常见场景中的执行过程。
顺利路径 — React + TypeScript、新标志、thumbs 弹出框:
步骤 0 → 欢迎。步骤 1 → 找到 @launchdarkly/react-sdk、React + Tailwind,无现有反馈。步骤 2 → 用户选择新标志 checkout-redesign,提示词为“How do you feel about the new checkout?”,thumbs 样式,放置在订单摘要下方。步骤 3 → 通过 create-flag 创建标志。步骤 4 → 用户批准。步骤 5 → 在 lib/ld/ 中创建 sendFeedback.ts。步骤 6 → 创建适配 Tailwind 的 FeedbackPopover.tsx,并通过 useLDClient() 将其接入 CheckoutPage.tsx。步骤 7 → 构建通过,事件触发。
已有 sendFeedback — 复用并跳过:
步骤 1 → 检查 4 发现 src/utils/sendFeedback.ts 已在调用 client.track('$ld:feedback', ...)。记录导入路径。步骤 2 → 照常收集需求。步骤 3–4 → 照常。步骤 5 → 跳过(复用现有函数)。步骤 6 → 构建组件,从现有路径导入 sendFeedback。步骤 7 → 构建通过,事件触发。
服务端 SDK — 提前 STOP:
步骤 1 → 检查 1 发现 @launchdarkly/node-server-sdk。检查 2 → 它位于 server-side-sdk-list.md 中,不存在客户端 SDK。→ 告知用户定性反馈需要客户端 SDK。STOP。
无设计系统 — 极简样式:
步骤 1 → 找到 launchdarkly-js-client-sdk v3.2,无 React、无 Tailwind、无组件库。步骤 6 → 使用带有内联样式的模板作为基线,适配项目的原生 JS 模式和现有 CSS 约定。