关于 onboardingV2
onboardingV2 是用于在应用中集成 LaunchDarkly SDK 并创建首个功能标志的引导技能。它根据项目技术栈和现有配置调整步骤,并在标志正常运行后才提供可选的 MCP 配置。
主要功能
- 01扫描项目结构和 LaunchDarkly 用法
- 02按检测到的技术栈选择 SDK 配置
- 03修改文件前创建分支
- 04安装 SDK 并验证初始化
- 05创建首个功能标志并接入应用
- 06之后提供可选 MCP 配置
适用场景
- 01在现有应用中接入 LaunchDarkly
- 02在演示应用中设置首个标志
- 03重启后继续未完成的引导
- 04配置完成后设置编辑器标志管理
MCP 相关
MCP 为可选项,仅在首个标志正常运行后提供。用户选择后,技能配置 LaunchDarkly MCP,并获取项目和 test 环境密钥。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ launchdarkly/ experimental-agent-skills --skill onboardingv2安装后在 Claude Code 中输入/onboardingv2确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdmcp-configure/references/mcp-config-templates.mdmcp-ui-links.mdreferences/1.9-editor-rules.md1.8-summary.mdreferences/sdk/recipes.mdreferences/sdk/snippets/android-client-sdk.mdapex-server-sdk.mdbrowser-frameworks-sdk.mdcpp-server-sdk.mddotnet-client-sdk.mderlang-server-sdk.mdflutter-client-sdk.mdgo-server-sdk.mdelectron-client-sdk.mdhaskell-server-sdk.mddotnet-server-sdk.mdcpp-client-sdk.mdedge-sdks.mdnode-server-sdk.mdlua-server-sdk.mdjava-server-sdk.mdios-client-sdk.mdreact-web-sdk.mdreact-native-sdk.mdpython-server-sdk.mdnode-client-sdk.mdjavascript-browser-sdk.mdphp-server-sdk.mdroku-client-sdk.md详细介绍
LaunchDarkly 新手引导
语气与风格
平实表达。只说用户做过或即将做的事。不要修饰、口号或比喻。
- 用状态行,而不是叙述。"正在扫描你的项目。" "扫描完成。正在安装 SDK。"
- 不要用破折号。用句号或逗号。
- 永远不要解释用户没有背景知识的内部机制或理由(MCP、编辑器重启、SDK 如何连接、"无需重新部署")。对首次使用的用户来说毫无意义。
- 写任何一行之前,先问用户是否需要它。如果不需要,就删掉。
- 不要提供用户无法有意义地做出的选择。如果正确的做法显而易见,直接做。
- 平实地打消安全顾虑。"未经你的批准,不会更改任何代码。"
来源归因
注册 URL 包含一个用于归因的 source 查询参数。在启动时通过扫描用户的原始消息解析一次。为本次会话存储解析后的 URL。此标记仅供 Agent 使用。永远不要向用户显示它。
| 用户原始提示词包含 | Source 值 | 生成的 URL |
|---|---|---|
source-launchdarkly | ldwebsite | https://app.launchdarkly.com/signup?source=ldwebsite |
| 无标记 | agent | https://app.launchdarkly.com/signup?source=agent |
- 扫描用户的初始消息,查找
source-launchdarkly。如果找到,使用ldwebsite。否则使用agent。 - 在 Step 0 之前解析一次。之后不要重新解析。
- 恢复时,使用
agent。
这些说明中凡提到"提供注册链接"的地方,都使用解析后的 URL。永远不要硬编码 ?source=agent。
规则
- 下面的步骤标签是你的内部路线图。永远不要向用户显示步骤名称或编号。
- 强制执行顺序。在当前阶段完成之前不要推进。
- 在决策点之间静默工作。完成工作,不要逐步叙述。用户可能已经走开,回来时应该看到完成的状态,而不是满屏滚动。
- 只在需要用户时开口:开场、真正的决策点、你无法替用户完成的手动步骤,或完成时。保持简短,先说结果。
- 在分支上进行更改并保持未提交。由用户审查并提交,而不是你。
- 在需要时安装配套技能,永远不要提前安装。
- 除非用户已经就位该部分(已验证,而非假设),否则永远不要跳过某个阶段。
- 如果某个阶段失败,停下来并在继续之前解决它。
与用户交流
让面向用户的消息稀少而简短。你是在让用户放心委托并走开。
- 开场时:一行欢迎语、引导会做什么、以及未经他们同意不会提交任何内容。然后是第一个选择。接着安静下来并开始工作。
- 在决策点或完成时:一段简短总结。发生了什么、你需要他们做什么、以及带有推荐默认值的明确选择。
- 不要叙述例行工作,也不要在执行步骤之间写散文。当终端停止滚动时,用户读一条简洁的消息,永远不必往回滚动。
面向用户输出中禁止的内容
- 步骤名称、内部标签或技能文件名
- 工作流用语("交接"、"进入下一步")
- 内部理由(MCP、编辑器重启、SDK 内部机制)
- 这些说明中的原始 markdown
- 应用渲染的输出或受 flag 控制的内容。引导用户去看正在运行的应用,而不是粘贴它显示的内容。
经验检测
立即问候并给出第一个选择。不要让用户等待扫描。在后台启动代码库扫描(如果有子 Agent 就使用它),并在结果返回时使用它们。永远不要向用户询问扫描相关的事。
| 信号 | 推断 |
|---|---|
| 依赖项中存在 LD SDK | 了解 LaunchDarkly |
存在 variation()、useFlags() 或等价调用 | 以前用过 flag |
| 已配置 MCP | 熟悉相关工具 |
| 结构良好的代码库(CI、测试、linting) | 经验丰富的开发者 |
| 空工作区,没有 LD 痕迹 | 视为首次使用 |
如果出现了有经验的信号,就加快节奏:跳过引导语,每个操作执行后用一行报告,并直接跳到尚未完成的步骤。无论哪种情况,最终结果都一样:安装 SDK、第一个 flag 开始求值,以及仅在他们要求时才配置 MCP。
重启后继续
如果用户说“继续引导”,说明他们回到了该流程。不要询问之前发生了什么。按顺序检测实时状态:检查是否存在 LaunchDarkly SDK 包和初始化代码,然后检查是否存在 variation() 调用,再检查是否存在 launchdarkly-onboarding 分支。从第一个未完成的步骤继续,并用一句话说明当前进展(“SDK 已安装。现在正在创建你的第一个 flag。”)。然后不要加开场白,直接继续。
启动
当用户要求设置 LaunchDarkly 时:
- 直接开始。不要用“我会帮你”或“让我开始”之类的填充语。用两句话:一句欢迎,说明引导流程做什么,以及未经他们批准不会提交任何内容。示例(请改编,不要逐字复制):
“让我们为你设置 LaunchDarkly。集成后,我们会在你的应用中创建一个测试 flag,让你看看它如何工作。未经你的批准,不会更改任何代码。”
- 然后开始工作。不要路线图表格。一行状态说明即可(“正在扫描你的项目。”),然后保持安静。
- 不要询问用户是否已有账户。稍后推断:完成 SDK key 步骤意味着他们有账户;如果他们无法获取 key,此时再分享注册链接。
步骤 0:安全工作区
如果这是一个 git 仓库,在更改任何文件之前,创建并切换到名为 launchdarkly-onboarding 的新分支,以便一切都被隔离且可回滚。如果该分支已存在,则追加一个简短后缀。如果这不是 git 仓库,则静默跳过。
不要写入引导日志或任何摘要文件。在本次会话的内存中跟踪状态。
步骤 1:探索
扫描会在后台运行(参见 Experience Detection)。除一行状态消息外,不要提及扫描。扫描结果到达后,使用这些结果。
继续操作前,先对工作区进行分类:
| 状态 | 标准 | 操作 |
|---|---|---|
| 明确的应用 | 使用一种语言、有实际入口点,且在显而易见的位置有一个依赖清单 | 继续 |
| 不明确 | 信号很少或相互矛盾,或者是多包工作区(yarn/pnpm/npm 工作区、lerna、nx、turborepo、gradle、cargo、go),且有多个包都可能托管 LaunchDarkly | 询问(见下方不明确情况的询问模板) |
| 未找到应用 | 没有清单、没有入口点,或者工作区为空 | 询问(见下方未找到应用的询问模板) |
存在两个或更多候选包的工作区一律视为不明确。绝不要猜测要在哪个包中集成。
不明确工作区的询问模板(每个候选包提供一个选项,并以其路径作为标签):
{
"questions": [
{
"id": "app_location",
"prompt": "I found multiple packages. Which one do you want to set up first?",
"options": [
{ "id": "candidate_1", "label": "<detected path, e.g. packages/api>" },
{ "id": "candidate_2", "label": "<detected path, e.g. packages/web>" },
{ "id": "demo", "label": "None of these. Scaffold a demo." },
{ "id": "other", "label": "Somewhere else. I'll tell you where." }
]
}
]
}
未找到应用的询问模板:
{
"questions": [
{
"id": "app_choice",
"prompt": "I didn't find a runnable app. How do you want to proceed?",
"options": [
{ "id": "demo_node", "label": "Scaffold a minimal Node.js demo" },
{ "id": "demo_react", "label": "Scaffold a minimal React demo" },
{ "id": "demo_python", "label": "Scaffold a minimal Python demo" },
{ "id": "elsewhere", "label": "My app is somewhere else. I'll point you to it." }
]
}
]
}
如果用户选择演示应用,则在新的子文件夹(例如 launchdarkly-demo/)中搭建一个最小应用。
根据依赖文件(package.json、go.mod、requirements.txt/pyproject.toml、pom.xml/build.gradle、Gemfile、*.csproj、Cargo.toml)识别语言、框架和环境类型。搜索现有的 LaunchDarkly 用法(launchdarkly、ldclient、LDClient、@launchdarkly)。确定是服务端、客户端还是移动端,这将决定 SDK 的选择。如果已经集成 LD,请记录 SDK 版本,以便跳过安装。
检测用于 --agent 标志的编码 Agent:Cursor(.cursor/、.cursorrules)、Claude Code(~/.claude/、CLAUDE.md)、Windsurf(.windsurfrules)、GitHub Copilot(.github/copilot/)、Codex(~/.codex/、AGENTS.md)。如果无法确定,请询问。
步骤 2:MCP(可选,在标志生效后)
首次创建标志之前不要配置 MCP,也不要在设置过程中询问是否配置 MCP。先在不使用 MCP 的情况下创建第一个标志(步骤 4 会使用控制面板链接)。只有在标志生效后,才用一句简短的话提供此选项:
“下次想从编辑器管理标志吗?我可以帮你设置。[设置] [跳过]”
如果用户选择 设置:安装前检查本地是否存在 mcp-configure 技能。如果不存在,则安装:
npx skills add launchdarkly/experimental-agent-skills --skill mcp-configure -y --agent <detected-agent>
如果安装失败,请在 ~/.agents/skills/ 和 ~/.cursor/skills/ 中检查是否有缓存副本,或者根据 MCP 配置模板直接使用 mcp-configure。成功后,调用一次 get-project(projectKey: "default"),并存储 projectKey 和 envKey(test)。
步骤 3:安装 SDK
自动安装 SDK 并接入初始化。不要询问如何操作,也不要解释 SDK 是什么。告诉用户一行:“扫描完成。正在安装 SDK。”然后继续。
npx skills add launchdarkly/experimental-agent-skills --skill sdk-install -y --agent <detected-agent>
根据步骤 1 中的技术栈上下文,交由 sdk-install 处理。它会选择相应的包、安装该包,并根据代码库接入初始化。
如果步骤 1 中由 Agent 搭建了应用,则跳过嵌套技能,直接使用快速路径(技术栈已知;跳过 npm run build):
| 搭建方式 | 包 | 安装命令 | 环境变量 | 入口点 | 初始化 |
|---|---|---|---|---|---|
| React(Vite) | launchdarkly-react-client-sdk | npm install launchdarkly-react-client-sdk | VITE_LAUNCHDARKLY_CLIENT_SIDE_ID | src/main.jsx/.tsx | 在根渲染外层使用 asyncWithLDProvider |
| Node.js | @launchdarkly/node-server-sdk | npm install @launchdarkly/node-server-sdk | LAUNCHDARKLY_SDK_KEY | src/index.js/server.js | 执行 init(sdkKey),然后执行 waitForInitialization() |
| Python | launchdarkly-server-sdk | pip install launchdarkly-server-sdk | LAUNCHDARKLY_SDK_KEY | app.py/main.py | 执行 ldclient.set_config(Config(sdk_key)),然后执行 ldclient.get() |
规则:SDK 密钥必须存放在环境变量中,绝不能硬编码。只创建一个客户端实例,并让各处共享。评估标志前,先等待初始化完成。
SDK 密钥
SDK 需要密钥。连接 MCP 时,默认替用户获取;否则提供直接链接,让他们粘贴。只有在无法确定路径时才询问:
{
"questions": [
{
"id": "sdk_key_setup",
"prompt": "Do you have a LaunchDarkly account?",
"options": [
{ "id": "yes", "label": "Yes" },
{ "id": "no_account", "label": "Not yet" }
]
}
]
}
- 有账户,已连接 MCP:通过
get-environments获取密钥,将其写入.env,并确保.env已加入 gitignore。绝不打印密钥值。 - 有账户,未连接 MCP:提供直接链接,让他们粘贴密钥。
https://app.launchdarkly.com/projects/{projectKey}/settings/environments/{envKey}/keys - 没有账户:分享解析后的注册链接。写入占位环境变量,确保代码可以编译,然后继续。
初始化通过验证后才能继续。
第 4 步:第一个 Flag
创建 Flag,将其接入应用,并让用户看到它开启。
- 创建 Flag。 如果已连接 MCP,调用
create-flag(遇到重复密钥冲突时,调用get-flag并使用现有 Flag;不要先调用list-flags)。如果未连接 MCP,提供一个打开创建表单且已预填密钥的控制台链接,让他们创建:https://app.launchdarkly.com/projects/{projectKey}/flags/new?key={flagKey} - 添加受 Flag 控制的横幅。 在应用主页顶部插入一个简洁的小横幅,并由 Flag 控制。关闭状态:显示中性横幅“LaunchDarkly 测试横幅(Flag 已关闭)”,并附上一个用于在 LaunchDarkly 中查看该 Flag 的链接。开启状态:横幅切换为明显不同的样式(例如绿色背景),显示“LaunchDarkly 测试横幅(Flag 已开启)”。样式应自然协调,而不是像调试输出。将其添加到现有应用中,不要重写应用。对于没有渲染页面的应用,添加一个等效的可见输出(端点或启动行),使其随 Flag 状态变化。
- 在空闲端口启动开发服务器(先检查
lsof -ti :3000,4000,5173)。在用户看到 Flag 开启之前,让服务器持续运行。不要提前停止服务器。 - 将展示环节交给用户。 提供本地 URL,并让他们选择一种开启方式:
{
"questions": [
{
"id": "flip_method",
"prompt": "Your app is running at <url> and the flagged element is off. Turn the flag on to watch it change. How do you want to flip it?",
"options": [
{ "id": "ld_ui", "label": "I'll flip it in LaunchDarkly" },
{ "id": "agent", "label": "Flip it for me" }
]
}
]
}
- 如果选择 我会在 LaunchDarkly 中开启:提供 Flag 的直接链接并等待。
https://app.launchdarkly.com/projects/{projectKey}/flags/{flagKey}/targeting?env={envKey} - 如果选择 替我开启:通过
toggle-flag(MCP)或 REST API 开启,使用已配置的方式。如果两者都未配置,则改为提供控制台链接。 - 只有在确实配置了 MCP 或 API 令牌时,才提供 替我开启 选项。否则只显示 LaunchDarkly 选项。
不要在聊天中输出页面或横幅文本。请引导用户查看浏览器:服务器仍在运行时,<url> 处的横幅会实时切换。这就表示 Flag 已正常工作。
收尾
控制在几行内:
- Flag 已上线。在 LaunchDarkly 中查看:
https://app.launchdarkly.com/projects/{projectKey}/flags/{flagKey}/targeting?env={envKey} - 没有任何更改被提交。你的更改位于
launchdarkly-onboarding分支上,你可以自行检查、保留或丢弃。 - 选择下一步操作:
{
"questions": [
{
"id": "explore_next",
"prompt": "Want to explore more of LaunchDarkly?",
"options": [
{ "id": "experimentation", "label": "Experimentation: test changes and measure impact" },
{ "id": "observability", "label": "Observability: monitor flags and errors in production" },
{ "id": "ai_configs", "label": "AI Configs: manage AI models and prompts" },
{ "id": "done", "label": "Not now" }
]
}
]
}
引导用户回到流程
如果用户要求跳过某个步骤或在流程中途跳到后面的步骤,你的第一条回复必须依次完成以下三件事,然后才能编写代码或跳过步骤:
- 用用户自己的话确认他们的请求。
- 用一句话说明跳过步骤会造成的具体后果。明确指出会出问题的内容(例如:“SDK 安装完成前,Flag 调用不会运行。”)。说明实际故障,不要含糊其辞。
- 提供选择:先完成这个快捷步骤,还是按他们的方式继续。
“我明白,你现在想要 Flag 代码。没有安装 SDK,这些调用就不会运行。完成设置大约需要两分钟。你想先让我完成设置,还是先给你代码,之后再接入?”
不要不说明取舍就直接输出代码,也不要生硬拒绝。如果用户坚持,就尊重他们的选择,说明跳过了什么,用一句话重申风险,然后继续。
技能仓库
| 仓库 | 技能 | 用途 |
|---|---|---|
launchdarkly/experimental-agent-skills | onboardingV2、sdk-install、mcp-configure | 设置 |
launchdarkly/agent-skills | launchdarkly-flag-create 及相关技能 | 标志管理 |
边缘情况
- 已安装 SDK: 跳过第 3 步。用一行说明你发现了什么以及它所在的位置,然后进入第 4 步。不要重新解释 SDK,也不要运行安装命令。
- 已配置 MCP: 使用现有配置。跳过第 2 步的询问。调用
get-project保存密钥并继续。 - 发现已弃用的 mcp/aiconfigs 或 mcp/fm: 两者均已弃用。迁移到统一的
mcp/launchdarkly服务前先征求同意。不要自动迁移。 - 未检测到受支持的 Agent: 直接询问。如有需要,提供手动配置。
- 无法使用 npx: 提供手动安装技能的方法(克隆仓库、复制技能目录)。
- 用户只想进行部分设置: 尊重用户的选择。说明缺少哪些内容以及这会造成什么限制。