Back to blog
    React Native中的AI:从云API到端侧模型
    React Nativecross-platformcloud APIon-device AIllama.cppsegment:mobile-builder

    React Native中的AI:从云API到端侧模型

    如何为React Native应用添加AI功能。使用fetch集成云API,使用llama.cpp绑定进行端侧推理,以及从一种方案迁移到另一种的实际路径。

    EErtas Team·

    React Native让你用一套代码库支持iOS和Android。添加AI功能应该遵循同样的原则。但在React Native中从"调用API"到"在设备上运行推理"的路径与原生Swift或Kotlin不同。JavaScript桥接、原生模块系统和跨平台模型分发都需要特定的模式。

    本指南涵盖两种方法以及它们之间的实际迁移。

    云API集成

    为React Native应用添加AI最快的方式是调用云API。React Native的fetch API可以直接与OpenAI、Anthropic、Google Gemini和其他供应商配合使用。

    基本模式

    async function generateResponse(prompt: string): Promise<string> {
      const response = await fetch("https://api.openai.com/v1/chat/completions", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${API_KEY}`,
        },
        body: JSON.stringify({
          model: "gpt-4o-mini",
          messages: [{ role: "user", content: prompt }],
        }),
      });
    
      const data = await response.json();
      return data.choices[0].message.content;
    }

    这在iOS和Android上都能工作,零平台特定代码。对于流式响应,使用EventSource模式或react-native-sse等库。

    聊天UI的流式传输

    import EventSource from "react-native-sse";
    
    function streamResponse(prompt: string, onToken: (token: string) => void) {
      const es = new EventSource("https://api.openai.com/v1/chat/completions", {
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${API_KEY}`,
        },
        method: "POST",
        body: JSON.stringify({
          model: "gpt-4o-mini",
          messages: [{ role: "user", content: prompt }],
          stream: true,
        }),
      });
    
      es.addEventListener("message", (event) => {
        if (event.data === "[DONE]") return es.close();
        const parsed = JSON.parse(event.data);
        const token = parsed.choices[0]?.delta?.content;
        if (token) onToken(token);
      });
    }

    云API的天花板

    云API在原型验证和低用量应用中效果很好。问题与原生应用相同,但在React Native中略有加剧:

    • 网络依赖: React Native应用通常面向跨平台市场,包括网络不稳定的市场
    • 延迟: JS桥接在500-3,000ms网络往返之上额外增加约5-10ms
    • 成本增长: 每个用户、每个请求、每个令牌都要花钱
    • 隐私: 每次API调用都将用户数据通过网络传输

    React Native中的端侧AI

    在React Native中本地运行模型意味着使用一个封装llama.cpp的原生模块。JavaScript端发送提示词并接收令牌。原生端在设备的CPU和GPU上处理实际推理。

    llama.rn

    llama.rn包为llama.cpp提供React Native绑定。它暴露了一个JavaScript API,可以加载GGUF模型并在iOS(Metal)和Android(CPU/Vulkan)上原生运行推理。

    import { initLlama } from "llama.rn";
    
    // 加载模型
    const context = await initLlama({
      model: modelPath, // 设备上.gguf文件的路径
      n_ctx: 2048,
      n_threads: 4,
      n_gpu_layers: 32,
    });
    
    // 生成响应
    const result = await context.completion({
      prompt: "Summarize this note: ...",
      n_predict: 256,
      temperature: 0.7,
    });
    
    console.log(result.text);

    流式令牌

    const result = await context.completion(
      {
        prompt: userPrompt,
        n_predict: 512,
      },
      (token) => {
        // 每生成一个令牌调用一次
        setResponseText((prev) => prev + token.token);
      }
    );

    这提供与云API相同的逐令牌流式体验,但首令牌时间为50-200ms,而非500-3,000ms。

    模型分发

    将GGUF模型文件送达设备是React Native中的主要工程挑战。

    随应用捆绑: 将模型包含在应用的资源中。对于iOS,添加到Xcode项目。对于Android,放在assets目录或使用Android Asset Delivery(超过150MB的文件)。React Native的资源系统可以在运行时引用文件路径。

    安装后下载: 首次启动时下载模型。使用react-native-blob-utilexpo-file-system进行带进度追踪的后台下载:

    import * as FileSystem from "expo-file-system";
    
    const modelUri = FileSystem.documentDirectory + "model.gguf";
    
    const download = FileSystem.createDownloadResumable(
      MODEL_CDN_URL,
      modelUri,
      {},
      (progress) => {
        const pct = progress.totalBytesWritten / progress.totalBytesExpectedToWrite;
        setDownloadProgress(pct);
      }
    );
    
    const result = await download.downloadAsync();

    性能预期

    React Native中的端侧性能与原生应用几乎相同。llama.cpp推理运行在原生代码中,不通过JS桥接。桥接仅用于发送提示词和接收令牌。

    设备1B模型(令牌/秒)3B模型(令牌/秒)
    iPhone 15 Pro (A17)35-4518-25
    iPhone 14 (A15)25-3512-18
    Galaxy S24 (SD 8 Gen 3)35-4518-25
    Pixel 8 (Tensor G3)25-3512-18
    中端Android (SD 7 Gen 3)18-258-12

    令牌传输的JS桥接开销可以忽略不计(每令牌不到1ms)。

    架构:抽象AI层

    最佳的React Native架构将AI提供者抽象在一个通用接口之后。这让你可以在云端和端侧之间切换而不改变UI代码。

    interface AiProvider {
      generate(prompt: string, onToken?: (token: string) => void): Promise<string>;
      isReady(): boolean;
    }
    
    class CloudProvider implements AiProvider {
      async generate(prompt: string, onToken?: (token: string) => void) {
        // 云API调用
      }
      isReady() { return true; } // 联网则始终就绪
    }
    
    class OnDeviceProvider implements AiProvider {
      async generate(prompt: string, onToken?: (token: string) => void) {
        // llama.rn推理
      }
      isReady() { return this.modelLoaded; }
    }

    这种模式支持渐进式迁移。先用CloudProvider验证。准备好后添加OnDeviceProvider。进行A/B测试。最终将端侧设为默认,云端作为后备。

    跨平台优势

    React Native的跨平台模型在端侧AI方面是你的优势。你微调一个模型,导出一个GGUF文件,部署到iOS和Android。推理库处理平台差异(iOS用Metal,Android用CPU/Vulkan)。

    对比云API,你在每个平台上都按令牌付费。端侧方案中,你只需一次性支付微调和模型分发费用。成本不会随平台数量倍增。

    迁移路径

    1. 从云API开始,通过fetch。验证功能,收集使用数据。
    2. 尽早添加抽象层(AiProvider接口)。这没有成本,以后会有回报。
    3. 从API日志收集训练数据。 每次云API调用都是一个潜在的训练样本。
    4. 在领域数据上微调小模型。 像Ertas这样的平台提供可视化流水线:上传数据,用LoRA训练,导出GGUF。
    5. 集成llama.rn,在同一接口后面添加端侧提供者。
    6. 对真实用户进行A/B测试,比较云端与端侧。
    7. 将端侧设为默认,云端作为不支持设备的后备。

    最终结果:一套代码库,两个平台,离线可用的AI,零推理成本。

    Ship AI that runs on your users' devices.

    Early bird pricing starts at $14.50/mo — locked in for life. Plans for builders and agencies.

    Keep reading