ARTICLE DETAIL

资讯详情

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

RunAnywhere Web SDK 最小示例应用:从零构建一个浏览器端本地 AI 流式生成应用

RunAnywhere Web SDK 最小示例应用:从零构建一个浏览器端本地 AI 流式生成应用 AI模型推理服务推理引擎本地部署多模态【免费下载链接】runanywhere-sdksProduction ready toolkit to run AI locally项目地址https://gitcode.com/gh_mirrors/ru/runanywhere-sdks点击查看免费下载本指南以 bindings/web/example 仓库中的最小示例应用为骨架完整讲解 RunAnywhere Web SDK 在浏览器中的真实启动流程、模型注册与流式生成调用链以及跨源隔离、WASM 构建等关键工程细节。读完本指南你将掌握如何在纯 DOM Vite 项目中正确初始化 SDK 双阶段启动、注册 llama.cpp 后端、让模型按需下载加载并通过generateStream消费流式事件同时理解该应用作为仓库内贡献者验证环境contributor harness与 Playwright 浏览器测试默认目标的设计原理。一、这个最小示例是什么bindings/web/example是整个仓库中最小的、能证明 Web SDK 可用的应用一个输入框、一个 Generate 按钮、一段流式输出的回答。它不依赖任何前端框架直接使用原生 DOM 操作全部逻辑集中在 src/main.ts 与一个 index.html 中。它在项目里扮演两个角色仓库内贡献者验证环境contributor harness默认构建时通过 Vite 别名alias与tsconfig.json的 paths 映射把runanywhere/web、runanywhere/web-llamacpp和runanywhere/proto-ts直接指向仓库源码目录。这意味着修改 SDK 源码后无需发布即可在此应用里立即看到效果。浏览器测试默认目标bindings/web/tests/browser/*下的 Playwright 测试默认驱动该应用RA_E2E_APP_DIR环境变量可以将同一批测试指向其他应用如发布验收用的 release harness。从源码结构看整个应用刻意保持零框架、单屏index.html里只有一个status段落、一个prompt文本域、一个generate按钮和一个output预格式化块。这是为了让任何人人类或自动化测试都能在 10 秒内看懂它做了什么。二、运行与构建命令在bindings/web/example目录下核心命令如下npm install npm run typecheck # 类型检查 npm run build # 生产构建产物输出到 dist/ npm run preview # 预览 dist/地址 http://localhost:3000 npm run dev # 开发服务器地址 http://localhost:3000这些脚本定义在 package.json 中dev/previewvite --host localhost --port 3000 --strictPort端口固定 3000端口被占用会直接报错而非换端口。typechecktsc --noEmit基于 tsconfig.json。typecheck:installedtsc --noEmit -p tsconfig.installed-sdk.json用于针对已安装的 SDK 包做类型检查见下文 RAC_USE_INSTALLED_SDK。构建前置条件四个 canonical WASM 对必须存在。npm run build依赖四个标准 Emscripten 运行时产物对每个包含.js与.wasm两个文件baseName所属包作用racommonscoreSDK 核心 commons WASMracommons-llamacppllamacppllama.cpp CPU 后端racommons-llamacpp-webgpullamacppllama.cpp WebGPU 后端racommons-onnx-sherpaonnxONNX / sherpa 语音后端这四个对分别位于bindings/web/packages/*/wasm目录。构建前需先在bindings/web/下执行npm run build:wasm:all生成它们。Vite 插件vite.config.ts 中的copyWasmPlugin会在buildStart阶段检查这些文件是否存在且非空缺失时会直接让构建失败并列出缺失文件名而不是产出一个只在浏览器里才报错的残缺 bundle——这是刻意的 fail-fast 设计。切换到已安装的 SDK发布消费方验证模式设置环境变量RAC_USE_INSTALLED_SDK1后模块解析与 WASM 源目录都会切换到node_modules中已安装的runanywhere/*包。这是发布消费方门禁release consumer gate使用的模式安装发布候选 tarball 后验证真实发布包而不是仓库源码。RAC_USE_INSTALLED_SDK1 npm run build RAC_USE_INSTALLED_SDK1 npm run typecheck:installedtypecheck:installed会清空 tsconfig 中的本地源码 paths 映射见 tsconfig.installed-sdk.json确保类型检查针对的是真正安装进node_modules的包而非源码路径。三、应用到底做了什么双阶段启动与流式生成整个应用逻辑就在 src/main.ts。启动顺序至关重要——它精确镜像了 SDK 文档化的双阶段初始化流程await RunAnywhere.initialize({ environment: development }); // 阶段一加载 racommons.wasm await LlamaCPP.register({ acceleration: auto }); // 阶段二加载 racommons-llamacpp[-webgpu].wasm await RunAnywhere.completeServicesInitialization(); // 已废弃入口但此处并非无效 // initialize() 已在后台启动 Phase 2 // 此调用负责 join/await 它 RunAnywhere.models.register({ id: smollm2-360m-q8_0, ... }); // 目录catalog由应用持有之后是流式生成一次回答for await (const event of RunAnywhere.llm.generateStream(prompt, { model: MODEL_ID })) { // event.type: textDelta | reasoningDelta | completed | failed | cancelled }3.1 启动流程逐行拆解RunAnywhere.initialize({ environment: development })初始化 SDK 核心加载racommons.wasm。environment: development会启用开发模式日志与遥测。LlamaCPP.register({ acceleration: auto })注册 llama.cpp 后端加载racommons-llamacpp[-webgpu].wasm。acceleration: auto让 SDK 根据当前设备自动选择 CPU 或 WebGPU 路径。RunAnywhere.completeServicesInitialization()文档注释明确标注为 deprecated已废弃的转发入口。它保留在这里是为了兼容文档化的两阶段启动写法——实际上initialize()已经折叠了两个阶段这个调用只是在后台 join/await 已启动的 Phase 2。RunAnywhere.models.register(...)把模型元数据注册进 SDK 的模型注册表。main.ts 中注册的是smollm2-360m-q8_0RunAnywhere.models.register({ id: MODEL_ID, // smollm2-360m-q8_0 name: SmolLM2 360M Q8_0, category: ModelCategory.MODEL_CATEGORY_LANGUAGE, // 语言模型 framework: InferenceFramework.INFERENCE_FRAMEWORK_LLAMA_CPP, format: ModelFormat.MODEL_FORMAT_GGUF, // GGUF 格式 url: https://huggingface.co/HuggingFaceTB/SmolLM2-360M-Instruct-GGUF/resolve/main/smollm2-360m-instruct-q8_0.gguf, sizeBytes: 386_404_992, // 约 386 MB memoryRequiredBytes: 500_000_000, // 建议内存 500 MB contextLength: 2048, });为什么应用必须在启动时调用一次models.register因为浏览器版 SDK不内置模型目录catalog——generateStream只能解析注册表里已有的 id。模型下载与加载则由 SDK 负责在生成请求中命名options.model即可首次使用时 SDK 会自动下载并加载模型应用自身从不编排下载/加载流程。3.2 流式事件消费generate()函数main.ts 第 78 行起调用generateStream并逐个处理事件textDelta增量文本累加后写入output元素实现打字机效果reasoningDelta推理过程的增量文本如思维链completed生成完成从event.result读取最终文本、outputTokens输出 token 数与tokensPerSecond生成速度状态栏显示Done — N tokens at X.X tok/s.failed生成失败读取event.error.messagecancelled生成被取消。generateStream的第二个参数还演示了maxOutputTokens: 256的用法用于限制最大输出 token 数。四、浏览器环境要求跨源隔离与 WASM 产物拷贝4.1 COOP/COEP 跨源隔离SharedArrayBuffer——以及依赖它的 pthread CPU WASM 构建——要求页面处于跨源隔离cross-origin isolation状态。因此 vite.config.ts 对 dev 服务器和 preview 服务器都设置了响应头const isolationHeaders { Cross-Origin-Opener-Policy: same-origin, Cross-Origin-Embedder-Policy: credentialless, } as const;同时生产构建目标被固定为chrome86Web SDK 文档化的最低浏览器版本防止未来 Vite 主版本通过其动态的baseline-widely-available默认值静默抬高浏览器要求。4.2 为什么 WASM 必须以原始文件名拷贝构建过程会把四个 canonical Emscripten.js/.wasm对以原始文件名拷贝到dist/assets/copyWasmPlugin的writeBundle钩子Emscripten glue 通过new URL(x.wasm, import.meta.url)解析自己的二进制文件每个启用 pthread 的模块还会按精确文件名生成 worker——如果只有 Vite 加了 hash 的副本worker 握手会失败CPU 构建会永远卡在等待 pthread 池上。这正是 vite 配置中assetsInclude: [**/*.wasm]与copyWasmPlugin存在的意义。构建日志会逐对打印拷贝结果例如✓ Copied racommons-llamacpp-webgpu.wasm (XX.X MB)。4.3 开发体验细节vite.config.ts还做了两件事来保证开发体验optimizeDeps.exclude: [runanywhere/web, runanywhere/web-llamacpp]排除这两个包进入 Vite 依赖预构建避免重复打包出两个 SDK 单例所有别名必须指向同一份源码模块——如果某个别名解析到了dist/就会创建第二个 SDK 单例duplicate SDK singleton这是配置注释中特别强调的坑。五、浏览器测试就绪契约Readiness Contractbindings/web/tests/browser/*下的 Playwright 测试不依赖 DOM 布局来判定应用状态而是读取 src/readiness.ts 发布的两个全局变量。这保证了即使应用被重写测试门禁依然有效全局变量承载内容window.__RUNANYWHERE_AI_READY__启动进度快照state、backend、step、reason、shellReadywindow.__RUNANYWHERE_SDK__导入的 SDK 单例供公共 API 面探测此外根html元素会把后端状态镜像为data-runanywhere-ai-backend属性Playwright 无需轮询脚本状态即可等待该属性。ReadinessSnapshot的类型定义readiness.ts第 28 行起包含ready应用是否可接受提示词statebooting | initializing-sdk | interactive | errorbackendpending | registered | unavailablestep细化到booting | initializing-sdk | registering-llamacpp | registering-catalog | interactive | errorshellReady单屏 shell 是否可用smoke 测试读取它reason当前状态的人类可读说明错误时附加error字段。publishReadiness()每次合并快照补丁并同步更新 DOM 属性publishSDK()把 SDK 单例挂到window.__RUNANYWHERE_SDK__。main.ts 中的boot()在不同阶段调用publishReadiness({...})把启动进度逐步上报——从initializing-sdkLoading the commons WASM.到registering-llamacpp再到registering-catalog最终ready: true进入interactive状态。运行浏览器测试从bindings/web/执行npm run test:browser:smoke # playwright test tests/browser/backend-readiness.spec.ts tests/browser/hybrid-stt.spec.ts npm run test:browser # 完整默认套件 npm run test:browser:release # RA_RUN_FULL_E2E1 playwright test tests/browser/release-app.e2e.spec.ts根据 playwright.config.ts 第 59 行默认appDir process.env.RA_E2E_APP_DIR ?? resolve(__dirname, example)——即默认驱动本示例应用发布验收测试可把RA_E2E_APP_DIR指向外部 checkout 的 release harness。六、验证什么才算真的跑通了构建和类型检查只是冒烟检查。真正的验证是一次完整的浏览器启动模型下载 → 模型加载 → 流式回答。文档记录的最后一次验证是针对npm run preview完成的COOP/COEP 响应头已生效跨源隔离开启四个 canonical WASM 对都以 JavaScript /application/wasmMIME 类型正常提供smollm2-360m-q8_0在 WebGPU llama.cpp 路径上完成下载、加载并成功生成。这也给出了一个可复现的验收清单启动npm run preview打开http://localhost:3000输入提示词点击 Generate观察状态栏从 Generating with smollm2-360m-q8_0 (first run downloads the model)… 推进到 Done — N tokens at X.X tok/s.——如果模型首次运行会自动下载说明按需下载/加载链路是通的。七、总结bindings/web/example以不到百行代码演示了 RunAnywhere Web SDK 在浏览器端最核心的完整链路双阶段启动initialize()→LlamaCPP.register()→completeServicesInitialization()应用持有目录通过models.register注册模型元数据模型下载/加载交给 SDK 按需完成流式生成generateStream的五类事件textDelta/reasoningDelta/completed/failed/cancelled驱动 UI 更新工程基建COOP/COEP 跨源隔离、WASM 原始文件名拷贝、构建失败前置检查、就绪契约全局变量。对于想要在自己项目中集成 RunAnywhere Web SDK 的开发者这个示例是最好的起点复制 index.html 与 src/main.ts 的骨架替换模型 id 与 UI 元素即可快速跑通首个浏览器端本地 AI 应用。赞分享AI模型推理服务推理引擎本地部署多模态【免费下载链接】runanywhere-sdksProduction ready toolkit to run AI locally项目地址https://gitcode.com/gh_mirrors/ru/runanywhere-sdks点击查看免费下载相关推荐RunAnywhere Web SDK 最小示例应用全解析浏览器端本地 AI 推理的完整落地路径RunAnywhere Web SDK 最小示例应用全解析浏览器端本地 AI 推理的完整落地路径 本篇文章以 bindings/web/example/REAAI模型推理服务推理引擎本地部署多模态jcode 性能优化技能实战指南从指标定义到瓶颈归因的完整工作流jcode 性能优化技能实战指南从指标定义到瓶颈归因的完整工作流 导读 本篇指南围绕 jcode 仓库内置的 optimization 技能 .jcode/AI模型推理服务推理引擎本地部署多模态RxDB Quickstart从零构建一个浏览器端的实时本地优先应用RxDB Quickstart从零构建一个浏览器端的实时本地优先应用 导读 本文是 RxDBlocal first 数据库运行于所有 JavaScript数据库NoSQL嵌入式数据库实时数据库上一篇OpenSign开源电子签名平台10分钟快速部署与专业配置指南下一篇终极指南如何用tokenizers CTC解码器解决语音识别中的重复令牌问题创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表