Alchemy v2.0.0-beta.55 实战解析:AI Gateway 账户级花费上限与 Fetcher 桥接工具
Alchemy v2.0.0-beta.55 实战解析AI Gateway 账户级花费上限与 Fetcher 桥接工具【免费下载链接】t3code项目地址: https://gitcode.com/GitHub_Trending/t3/t3code本指南基于仓库内 beta.55 发布说明 展开。v2.0.0-beta.55 为 Alchemy 的 Cloudflare 集成带来两个关键能力Cloudflare.AiGatewaySpendingLimit资源为账户内所有 AI Gateway 设置声明式的美元硬性花费上限防止失控循环演变成失控账单以及从alchemy/Cloudflare/Bridge入口重新导出的 Fetcher/Socket 互操作工具让 TanStack Start、Astro 等框架 Worker 能够把普通 service binding 包装成完全类型化的 EffectHttpClient。读完本文你将掌握花费上限的完整配置、一次性引导充值与自动充值机制以及四种框架侧调用 Effect 后端的方式。为什么 AI Gateway 需要花费上限AI Gateway 位于所有模型调用之前意味着它也同时位于失控循环与失控账单之间。一旦某个重试循环或异常调用风暴发生账单会以肉眼可见的速度增长。beta.55 把这个护栏放进了你的基础设施声明中Cloudflare.AiGatewaySpendingLimit为账户内所有gateway 的累计 AI Gateway 花费设置硬性美元上限并且像其他任何 Alchemy 资源一样被声明与调和reconcile——不是部署后的手动配置而是与你的栈一起版本化、可审计、可复现的声明式资源。从源码结构看它与 Gateway 资源、BYOK 网关供应商配置 同属alchemy/Cloudflare命名空间下的账户级 AI Gateway 资源族CHANGELOG 确认其在 beta.55 中随 PR #569作者 Matthew Aylward 与 Sam Goodwin加入。Cloudflare.AiGatewaySpendingLimit声明式账户级上限基本声明与单位约定金额单位是cents美分——这是 Cloudflare 的原生计费单位最小值为1_00即 $1.00。花费在一个daily、weekly或monthly的窗口内累计窗口策略支持fixed在窗口边界重置或sliding滚动窗口import * as Cloudflare from alchemy/Cloudflare; // Cloudflare 要求必须先手动充值一次信用额度才能设置花费上限。 // topUp 调和了这一要求provider 观察计费状态 // 仅当账户从未充值过时才会向账户的默认支付方式发起一次性扣款。 const cap yield* Cloudflare.AiGatewaySpendingLimit(ai-spend-cap, { amount: 250_00, // cents - $250.00最小 1_00 $1.00 duration: monthly, topUp: { amount: 10_00 }, // cents - $10.00Cloudflare 最小充值额 });配置项取值说明amount整数单位 cents最小1_00$1.00账户级 AI Gateway 花费的硬性上限durationdaily/weekly/monthly花费累计的时间窗口窗口策略fixed窗口边界重置/sliding滚动窗口决定窗口如何滚动见发布说明描述topUp.amount整数单位 centsCloudflare 最小充值额 $10.00一次性引导充值的金额topUp.threshold整数单位 cents触发自动充值的余额阈值topUp.autoRecharge布尔默认true关闭后仅做一次性引导充值topUp与 Cloudflare 的引导要求topUp属性处理的是 Cloudflare 的引导bootstrap要求一个账户在通过至少一次手动充值加载 Unified Billing 信用额度之前无法设置花费上限对应错误码NO_MANUAL_TOPUP。Alchemy 的 provider 会观察实时计费 API 上的first_topup_success字段仅当账户从未充值过时才执行那一次性扣款一旦账户完成引导topUp属性即变为惰性inert永远不会再次扣款。如果支付需要交互式确认如 3-D Secure 验证资源会以类型化的AiGatewaySpendingLimitTopupRequired错误失败此时必须到 Cloudflare 控制台完成充值。自动充值默认开启自动充值默认开启——当信用余额低于threshold时Cloudflare 自动按amount充值const cap yield* Cloudflare.AiGatewaySpendingLimit(ai-spend-cap, { amount: 250_00, duration: monthly, topUp: { amount: 20_00, threshold: 10_00 }, // 余额低于 $10 时自动充值 $20 });如果需要仅一次性引导、不再自动充值则显式关闭const cap yield* Cloudflare.AiGatewaySpendingLimit(ai-spend-cap, { amount: 250_00, duration: monthly, topUp: { amount: 10_00, autoRecharge: false }, });一个重要的使用注意点一个值得反复强调的约束Cloudflare 在每个账户只存储一个花费上限因此该资源是一个每账户单例per-account singleton——在栈中恰好声明一个即可声明多个会破坏该约束。这与同账户下可以声明多个 AI Gateway 资源每个 gateway 拥有自己的cacheTtl、collectLogs等配置形成对比gateway 可以有多条但账户级上限永远只有一条。Fetcher 工具把 service binding 变成类型化HttpClient从alchemy/Cloudflare/Bridge导出Fetcher/Socket 互操作辅助函数——fromCloudflareFetcher、toCloudflareFetcher、toHttpClient、fromCloudflareSocket——现已从alchemy/Cloudflare/Bridge入口导出PR #581。同时fromCloudflareFetcher与fromCloudflareSocket现在可以直接接受全局的Fetcher/Socket类型而不再局限于cloudflare/workers-types的命名空间类型。仓库中的 Bridge.ts 是这一入口的实现export * from ./Fetcher.ts; export * from ./Workers/InferEnv.ts; export * from ./Workers/Rpc.ts; export * from ./Workers/RpcAsync.ts;四个函数的具体定位依据 Fetcher.ts 源码函数方向作用fromCloudflareFetcherCloudflareFetcher→ AlchemyFetcher接受cf.Fetcher \| globalThis.Fetcher包装为支持 EffectHttpClientRequest/HttpServerRequest的适配器toCloudflareFetcherAlchemyFetcher→ CloudflareFetcher反向适配把 Effect 侧的 fetch 暴露成 workerd 可调用的cf.FetchertoHttpClientAlchemyFetcher→ EffectHttpClient把暴露 server 形态fetch的对象DO stub、service binding转换为 EffectHttpClientfromCloudflareSocketCloudflareSocket→ EffectSocket把全局/workers-types 的 Socket 归一化为 EffectSocket.Socket框架 Worker 中的典型场景这一组合在框架 WorkerTanStack Start、Astro 等中尤其重要你的 Effect 后端以普通 service binding的形式出现在env上而不是以 Effect 生态的类型出现。过去你可能需要各种 cast现在只需要两步调用即可把它转成完全类型化的 EffectHttpClient——零 castimport * as Cloudflare from alchemy/Cloudflare/Bridge; import * as Effect from effect/Effect; import * as HttpServerResponse from effect/unstable/http/HttpServerResponse; const client Cloudflare.toHttpClient( Cloudflare.fromCloudflareFetcher(env.BACKEND), ); const res await client .get(https://backend/?key${encodeURIComponent(key)}) .pipe(Effect.runPromise); return HttpServerResponse.toWeb( HttpServerResponse.fromClientResponse(res), );请求走的是账户内 service binding而不是公共网络——这意味着更低延迟、无公网暴露并且请求会经过 Cloudflare 的边界网络基础设施。一个 gateway 对象四种调用方式对照仓库中的cloudflare-website-tanstack-start示例的/api/hello路由 现在用四种方式并排提供同一个对象每种都有对应的集成测试覆盖原始 R2 binding 直调env.BUCKET.get(key)/env.BUCKET.put(...)——完全绕过 Effect直接操作异步 bindingservice binding 的fetchenv.BACKEND.fetch(https://backend/?key...)——workerd 原生形态无类型保障类型化 RPCCloudflare.toRpcAsyncBackend(env.BACKEND)之后调用backend.hello(key)——把 wire-shape binding 包装为 Promise 视图Effect.fail时抛错、自动解包 stream 信封且hello为只读 RPCPUT 不支持viarpcHttpClient形态Cloudflare.toHttpClient(Cloudflare.fromCloudflareFetcher(env.BACKEND))——完整获得 EffectHttpClient的请求构建、重试、错误处理能力。四种方式的 GET/PUT 差异见下表方式GETPUTbindingenv.BUCKET.get(key)env.BUCKET.put(key, body, { httpMetadata })fetchenv.BACKEND.fetch(url)env.BACKEND.fetch(url, { method: PUT, body, headers })rpcbackend.hello(key)只读 RPC不支持400http-clientclient.get(url)client.execute(HttpClientRequest.fromWeb(request))204 时不带 body 响应源码级原理HandlerNotReady重试机制fromCloudflareFetcher内部有一段值得注意的健壮性设计见 Fetcher.ts新部署的 Durable Object / service script 是最终一致的——部署后短时间内workerd 可能把.fetch()路由到仍没有 fetch handler 的旧脚本版本表现为Handler does not export a fetch() function错误通常数秒内随新版本传播而消失。Alchemy 的处理方式每次尝试前request.clone()保持原请求未被消费使重试可安全重放将底层 promise 的拒绝提升为类型化的HandlerNotReady错误按Schedule.exponential(100 millis)指数退避重试最多 8 次因为请求从未到达 handler无副作用已提交重试是安全的预算耗尽后重新抛出原始 defecttoHttpClient层面再把任何残存的HandlerNotReady及一切失败 cause转换为类型化的TransportErrorHttpClientError而不是再次重试。由于该窗口适配逻辑位于所有 binding 流经的底层适配器上RPCtoRpcAsync、HttpClient、client/server 重载等所有上层包装都自动获得了这一韧性且不影响 RPC/stream 解码响应及其流式 body 保持原样。本版本其他修复修复了阻止alchemy deploy/alchemy destroy退出的悬挂进程本地RpcProvider服务层providerServices/providerServicesEffect现在只在AlchemyContext.dev被设置时才构造因此一次性 CLI 运行不再启动本地 dev provider 机制PR #580。从 LocalRuntime.ts 可以看到RpcProvider.providerServicesEffect在本地运行时路径中的使用位置。扩展阅读完整的上线流程添加 AI Gateway 指南——声明Cloudflare.AI.Gateway资源、绑定进 Worker、构建LanguageModelLayer、实现/generate与/stream路由以及缓存/限流/DLP 调优前端框架集成——TanStack Start、Astro、Next.js 等框架 Worker 与 Effect 后端的组合方式本版本完整变更见仓库根目录 CHANGELOG.md。【免费下载链接】t3code项目地址: https://gitcode.com/GitHub_Trending/t3/t3code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考