ARTICLE DETAIL

资讯详情

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

ClawHub 特性开关实践:基于 Krill Switch 的首页文案试点与 SSR 评估契约

ClawHub 特性开关实践:基于 Krill Switch 的首页文案试点与 SSR 评估契约 后端前端AI 技能AI 插件搜索引擎【免费下载链接】clawhubSkill Plugin Registry for OpenClaw项目地址https://gitcode.com/gh_mirrors/mo/clawhub点击查看免费下载ClawHub 是 OpenClaw 的 Skill Plugin 注册中心。本站技术指南基于仓库规范文档 specs/feature-flags.md 展开讲解 ClawHub 如何通过 Krill Switch 实现一套“有界的、全局的、仅影响展示层”的首页文案试点服务端渲染时评估开关、浏览器端保持其新鲜度同时在无 key、超时或网络故障时安全回退到代码默认值。读完本篇你将理解该特性开关的完整运行时契约环境变量、200 ms SSR 预算、60 秒轮询与 ETag 缓存、它在首页路由中的具体接线方式以及“开关绝不作为安全边界”这一设计原则在代码层面是如何被固化的。特性开关在 ClawHub 中的定位specs/feature-flags.md 开篇就给出了两条基本约束评估时机ClawHub 在服务端渲染SSR阶段通过 Krill Switch 评估发布开关随后在浏览器端持续保鲜refresh。边界声明Flags 不是授权或安全边界。所有受保护操作仍必须在 Convex 函数与 HTTP 处理器中强制其自身规则。这一原则贯穿了后续所有实现ClawHub 当前唯一落地的是一个“首页副标题文案”开关它只改变展示文案不改变任何应用行为。运行时契约Runtime contract规范文档中 “Runtime contract” 一节定义了这套开关系统的完整行为契约逐条对照仓库源码可以全部验证契约条款源码依据首页路由 loader 调用POST https://flags.openclaw.ai/v1/eval使用VITE_KRILLSWITCH_EVAL_KEY中的公开环境评估 key并将评估结果序列化用于 hydration非首页路由不评估、不轮询src/routes/index.tsx、src/lib/featureFlags.functions.tsVITE_KRILLSWITCH_BASE_URL可在本地测试时覆盖评估源默认为生产评估主机src/lib/featureFlags.tsxVITE_KRILLSWITCH_EVAL_KEY缺失时首页直接使用代码默认值不接触 Krill Switchsrc/lib/featureFlags.tsx、src/lib/featureFlags.functions.ts配置缺失、网络错误、非法 payload、不兼容的远端值类型都保留代码持有的默认值服务端评估有 200 ms 预算不得因此阻塞渲染src/lib/featureFlags.functions.ts、src/lib/featureFlags.functions.ts服务端与浏览器均使用服务级clawhub-homepagecontext初始证明开关是全局开关——ClawHub 不创建也不传输任何按访问者的 rollout 标识符。引入按访问者定向或百分比灰度需要单独的隐私与产品决策src/lib/featureFlagManifest.ts首页路由挂载期间页面重新可见时每 60 秒刷新一次取值ETag 避免重复传输未变化的评估结果由openclaw/krillswitch-reactSDK 内部承担见下文规范同时划定了职责边界响应校验、带类型 manifest 合并、SSR 评估、hydration 引导、缓存与轮询全部由官方 SDKopenclaw/krillswitch-react承担依赖声明见 package.json 中的openclaw/krillswitch-react: 0.0.1ClawHub 自建的适配器必须保持克制只包含运行时配置与应用相关开关。这一点在代码中体现得非常干净——应用侧全部逻辑集中在四个文件里src/lib/featureFlagManifest.ts开关 manifest默认值、context key、类型src/lib/featureFlags.tsx浏览器端 Provider 适配器src/lib/featureFlags.functions.tsSSR 评估 server functionsrc/routes/index.tsx首页路由接线。环境变量配置两个环境变量在 specs/deploy.md 中作为部署变量列出变量作用缺省行为VITE_KRILLSWITCH_EVAL_KEY公开的 Krill Switch 环境评估 key同时是“启用开关系统”的总开关缺失时整条链路短路首页渲染代码默认值不发起任何网络请求VITE_KRILLSWITCH_BASE_URL覆盖评估源地址本地测试用默认https://flags.openclaw.ai环境读取本身还有一个值得注意的细节。适配器通过 src/lib/runtimeEnv.ts 的getRuntimeEnv读取变量浏览器端优先取打包进 bundle 的import.meta.env值服务端Node优先取process.env唯一的例外是当VITE_CLAWHUB_DEPLOY_ENV preview时即使是服务端也优先使用打包值。由于 key 是公开publickey打包进前端 bundle 是该试点的既定前提——它授权的是“读取一组展示开关”而不是任何特权操作。浏览器端适配器FeatureFlagProvider 与 useFeatureFlagsrc/lib/featureFlags.tsx 的核心逻辑只有 40 多行把“opt-in”语义写得非常直白const DEFAULT_KRILLSWITCH_BASE_URL https://flags.openclaw.ai; const krill createKrillswitch(FEATURE_FLAG_DEFAULTS); export const useFeatureFlag krill.useFeatureFlag; export function FeatureFlagProvider({ baseUrl, children, evalKey, initialValues, pollIntervalMs, }: { baseUrl?: string; children: ReactNode; evalKey?: string; initialValues?: PartialFeatureFlagValues | null; pollIntervalMs?: number; }) { const resolvedEvalKey evalKey ?? getRuntimeEnv(VITE_KRILLSWITCH_EVAL_KEY); if (!resolvedEvalKey) return children; return ( krill.FeatureFlagProvider baseUrl{ baseUrl ?? getRuntimeEnv(VITE_KRILLSWITCH_BASE_URL) ?? DEFAULT_KRILLSWITCH_BASE_URL } contextKey{FEATURE_FLAG_CONTEXT_KEY} evalKey{resolvedEvalKey} initialValues{initialValues} pollIntervalMs{pollIntervalMs} {children} /krill.FeatureFlagProvider ); }实现要点无 key 即透传evalKey解析不到时直接return childrenProvider 退化为一个无操作的包裹层保证“删除配置即可禁用无需代码回滚”production contract 的明确要求。baseUrl 三级回退props 显式传入 VITE_KRILLSWITCH_BASE_URL 生产默认https://flags.openclaw.ai。测试与本地环境可以精确注入地址。initialValues 直通服务端评估得到的值经 hydration 传入 SDK作为首屏取值避免“先渲染代码默认值、hydration 后跳变”。manifest 作为默认值源createKrillswitch(FEATURE_FLAG_DEFAULTS)中的FEATURE_FLAG_DEFAULTS来自 src/lib/featureFlagManifest.tsSDK 用它做带类型的响应校验与合并——远端返回非法或不兼容的值类型时manifest 里的代码默认值原样保留这正是契约中“invalid payloads preserve code-owned defaults”的落点。测试用例对契约的固化浏览器端行为由 src/lib/featureFlags.test.tsx 三条用例锁死hydrates from server values without rendering the code default first向 Provider 传入initialValues{{ homepageTestMessage: true }}后断言首次渲染观察到的值就是true而不是先闪一下代码默认值false——对应规范中“被 flag 控制的可见内容在 hydration 之前不得渲染出不同的代码默认值”。applies a successful browser refresh after hydrationhydration 后浏览器侧重新评估成功返回false时UI 随之切换用例同时断言了请求形态——POST https://flags.openclaw.ai/v1/evalbody 为{context:{key:clawhub-homepage}}证明服务端与浏览器共用同一个非标识 context。renders code defaults without contacting Krill when no evaluation key is configuredevalKey时渲染安全默认值且fetch从未被调用。SSR 评估200 ms 预算与 fail-soft 回退服务端评估封装在 src/lib/featureFlags.functions.ts 中这是一个 TanStack Start 的 server functionconst DEFAULT_KRILLSWITCH_BASE_URL https://flags.openclaw.ai; const SSR_EVALUATION_TIMEOUT_MS 200; const evaluateFlags createKrillswitchEvaluator(FEATURE_FLAG_DEFAULTS); export const loadInitialFeatureFlags createServerFn({ method: GET }).handler( async (): PromiseInitialFeatureFlags { const evalKey getRuntimeEnv(VITE_KRILLSWITCH_EVAL_KEY); if (!evalKey) return { values: null }; try { const values await evaluateInitialFeatureFlags({ baseUrl: getRuntimeEnv(VITE_KRILLSWITCH_BASE_URL) ?? DEFAULT_KRILLSWITCH_BASE_URL, evalKey, signal: AbortSignal.timeout(SSR_EVALUATION_TIMEOUT_MS), }); return { values }; } catch (error) { console.warn(Krill Switch SSR evaluation failed; using code defaults., error); return { values: null }; } }, );这段代码把契约中“服务端评估有 200 ms 预算、且不得阻塞渲染”落成了两个具体机制AbortSignal.timeout(200)评估请求硬性 200 ms 超时超时即中断fail-soft 的 catch 分支任何失败超时、网络错误、非法响应都只打一条console.warn并返回{ values: null }让 Provider 侧退回 manifest 代码默认值。“Krill 的可用性绝不允许拖垮首页可用性”不是口号而是被异常处理路径保证的。src/lib/featureFlags.server.test.ts 从服务端视角补齐了验证无 key 时loadInitialFeatureFlags()返回{ values: null }且不发起 fetch带 key 时评估 manifest 的请求是POST /v1/eval携带authorization: Bearer evalKey头与clawhub-homepagecontext。首页路由接线与初始证明开关首页路由 src/routes/index.tsx 是整个特性的唯一消费方export const Route createFileRoute(/)({ loader: loadHomeRoute, component: SkillsHome, }); async function loadHomeRoute(): PromiseHomeRouteLoaderData { const [initialFeatureFlags, initialListing] await Promise.all([ loadInitialFeatureFlags(), loadInitialHomeListing(), ]); return { initialFeatureFlags, initialListing }; } function SkillsHome() { const { initialFeatureFlags, initialListing } Route.useLoaderData(); return ( FeatureFlagProvider initialValues{initialFeatureFlags.values} SkillsHomeContent initialListing{initialListing} / /FeatureFlagProvider ); }两个工程细节值得注意并行加载flag 评估与首页列表数据loadInitialHomeListing通过Promise.all并行执行且列表数据加载失败被单独 try/catch 吞掉——两者互不拖垮共同体现“展示层组件失败不阻断首页”的思路。Provider 只包首页组件树FeatureFlagProvider没有出现在根布局中因此轮询只随首页路由挂载而存在严格满足“与首页无关的路由不评估、不轮询 Krill Switch”。而 flag 的消费点只有一个——hero 区副标题function SkillsHomeContent({ initialListing }: { initialListing: HomeListingInitialData | null }) { const showTestMessage useFeatureFlag(homepageTestMessage); return ( main classNamehome-v2-main oc-app-surface ... p classNamehome-v2-sub oc-hero-lede {showTestMessage ? Feature flag test is enabled. : Discover skills and plugins from top creators} /p ...这正是规范中 “Initial proof flag” 一节描述的内容homepageTestMessage是布尔开关默认false启用时 hero 副标题从 “Discover skills and plugins from top creators” 变为 “Feature flag test is enabled.”。规范特意说明这是一个“刻意显眼的、临时的、仅文案的证明开关”an obvious, temporary, copy-only proof——它的存在目的是验证整条链路SSR 评估 → hydration → 浏览器轮询 → 展示切换可用而无需改变任何应用行为。manifest 也印证了这一点src/lib/featureFlagManifest.ts 目前只声明了这一个开关export const FEATURE_FLAG_DEFAULTS: FeatureFlagValues { homepageTestMessage: false, }; export const FEATURE_FLAG_CONTEXT_KEY clawhub-homepage; export type FeatureFlagValues { homepageTestMessage: boolean; };首页试点决策Production contract规范文档 “Homepage pilot decision” 一节记录了采纳该方案的生产契约可视为这个试点的验收清单服务归属OpenClaw 拥有 Krill Switch 服务与公开发布的 SDK 包。opt-in 集成通过VITE_KRILLSWITCH_EVAL_KEY开启移除该配置即可禁用评估不需要代码回滚。这一点在 src/lib/featureFlags.tsx 的if (!resolvedEvalKey) return children;中得到实现闭环。200 ms 等待上限首页最多等 200 ms 服务端评估随后渲染代码默认值Krill 不可用不得导致首页不可用见AbortSignal.timeout与 fail-soft catch。单一非标识 context试点只使用一个不携带身份信息的clawhub-homepagecontext按访问者定向、属性定向或百分比灰度均在已批准范围之外——因为 ClawHub 不创建、也不传输任何按访问者的 rollout 标识符。要引入这类能力需要单独的隐私与产品决策。仅控制展示授权与安全决策继续由应用代码与后端代码强制执行flags 只做 presentation。SDK 升级管控openclaw/krillswitch-react的版本升级须经过常规的依赖审查、完整性校验与行为变化评审后才能用于生产当前锁定为 package.json 中的0.0.1。小结一份“克制”的开关系统从源码结构看ClawHub 的 feature flag 实现把规范文档里的每一条契约都收敛到了极小的代码面一个四行的 manifest、一个无 key 即短路的 Provider、一个 200 ms 超时 fail-soft 的 server function以及首页路由中唯一的一个消费点。它没有把开关系统做成通用基础设施而是刻意维持为“有界试点”全局开关、非标识 context、纯展示影响、删除一个环境变量即可整体下线。对需要在 SSR 应用中接入远程 feature flag 的团队而言这份实现提供了可直接参考的模式——用 manifest 默认值兜底所有失败路径、用并行 loader 隔离外部依赖的延迟、用测试用例src/lib/featureFlags.test.tsx、src/lib/featureFlags.server.test.ts把“无 key 不联网”“hydration 前不闪默认值”等安全属性固化为可回归断言。赞分享后端前端AI 技能AI 插件搜索引擎【免费下载链接】clawhubSkill Plugin Registry for OpenClaw项目地址https://gitcode.com/gh_mirrors/mo/clawhub点击查看免费下载相关推荐ClawHub 落地 OpenClaw 公开页面规范openclaw-marketing-pages 技能与 Carapace 设计契约ClawHub 落地 OpenClaw 公开页面规范openclaw marketing pages 技能与 Carapace 设计契约 本文围绕 ClawH后端前端AI 技能AI 插件搜索引擎Hermes Desktop 的 Agent 能力兼容层基于证据的特性开关、契约演进与降级策略Hermes Desktop 的 Agent 能力兼容层基于证据的特性开关、契约演进与降级策略 导读 Hermes Desktop 是 Hermes AgenAI 应用交互助手桌面应用Tyk 网关 OpenAPI 契约测试实战基于 Portman、Venom 与 Newman 的规范一致性验证Tyk 网关 OpenAPI 契约测试实战基于 Portman、Venom 与 Newman 的规范一致性验证 Tyk 网关对外暴露了大量 REST APIAPI网关后端云原生上一篇cann/asc-tools show_kernel_debug_data离线分析Kernel调试数据的完整指南下一篇htmx房地产房源搜索和虚拟看房功能创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表