RORK LABEN
TOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しましたTOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しました
記事一覧/開発ツール
開発ツール/2026-04-13上級

Rork アプリで LLM ストリーミングを実装する — ChatGPT 風リアルタイム AI 応答 UI を Expo × SSE で本番構築する

React Native / Expo で LLM ストリーミング(SSE)を本番実装する完全ガイド。Anthropic・OpenAI の streaming API 接続から AbortController・エラーリトライ・Cloudflare Workers プロキシ・マルチプロバイダー抽象化まで動作済みコード付きで解説。

streamingSSELLM3AI31Anthropic4OpenAI5React Native209Expo149Cloudflare Workers24Rork515

プレミアム記事

AI チャット機能を Rork アプリに実装するとき、最初に躓くのはレスポンスが一括で返ってくるからです。ユーザーが「送信」ボタンを押してから 10 秒間ローディングスピナーが回り、突然全文が表示される—これでは ChatGPT の体験とは程遠い。

LLM ストリーミング(SSE: Server-Sent Events)は、この問題を根本から解決します。トークンが生成されるたびにリアルタイムでテキストが流れてくる体験を、ユーザーは「生きている AI」として感じる。React Native でこれを実装しようとすると、ブラウザとは異なる壁にすぐ直面します。EventSource は動かありません。fetch() のストリーム読み取りは特殊な API が必要です。AbortController との組み合わせも癖があります。

ここで扱うのはRork で AI チャットアプリを作る開発者が実際に詰まるポイントを全て潰し、本番で動く実装コードを提供します。

なぜ LLM ストリーミングが UX の分水嶺になるのか

LLM API には 2 つの呼び出し方があります。一括レスポンス(blocking)ストリーミング(streaming) です。

一括レスポンスは単純です。リクエストを投げ、モデルが全文生成を終えてから JSON が返ってくる。実装は簡単だが、Claude Sonnet のような大型モデルは長い回答を生成するとき 15〜20 秒かかることもあります。この待ち時間にユーザーの 40% 以上が離脱するというデータがある(個人開発でのチャーン計測では特に顕著)。

ストリーミングは、LLM がトークンを生成するたびにその断片を逐次送信します。ユーザーには数百ミリ秒後から文字が流れ始め、全体の生成時間が同じでも「速い」と感じる。これは単なる体感の話ではなく、エンゲージメント指標に直結します。

React Native でのもう一つの利点はコスト可視化です。ストリーミングを途中でキャンセルすれば、生成済みトークン分しか課金されない(Anthropic、OpenAI ともに途中キャンセル対応)。長い回答が不要なケースで「停止」ボタンを提供することで、API コストを 30〜50% 削減できる実績があります。

React Native で SSE を扱う際の根本的な違い

Web ブラウザでは EventSource API を使って SSE を受信できます。しかし React Native では EventSource は存在しない。これを知らずに new EventSource(url) を書いてビルドが通り、実機で真っ白になるパターンは定番の落とし穴です。

React Native でストリーミングを実現する正しいアプローチは fetch() API の ReadableStream インターフェースを使うことです。Expo SDK 49 以降、React Native の fetchresponse.body から ReadableStream を取得できるようになっています。

// ❌ ブラウザでは動くが RN では動かない
const es = new EventSource('https://api.anthropic.com/v1/messages');
 
// ✅ RN / Expo で正しいアプローチ
const response = await fetch('https://api.anthropic.com/v1/messages', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'anthropic-version': '2023-06-01',
    'x-api-key': 'YOUR_ANTHROPIC_API_KEY', // 本番ではプロキシ経由で渡す(後述)
  },
  body: JSON.stringify({ stream: true, ...params }),
});
 
// response.body は ReadableStream
const reader = response.body?.getReader();
const decoder = new TextDecoder();
 
while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  const chunk = decoder.decode(value, { stream: true });
  // chunk を解析して UI を更新
}

Expo SDK 48 以前のプロジェクトでは response.bodynull になります。その場合は react-native-fetch-api ライブラリか、Expo SDK のアップグレードが必要です。Rork が生成するプロジェクトは基本的に最新 Expo SDK を使うので、この問題は新規プロジェクトでは発生しません。

SSE フォーマットの解析

Anthropic の streaming API は以下の形式でチャンクを送信します。

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"こんにちは"}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"、今日は"}}

一つの read() 呼び出しで複数の SSE イベントが含まれることがあります。また、一つのイベントが複数の read() に跨がって届くこともあります。これを正しく処理しないと、JSON parse エラーが散発的に発生します。

OpenAI の streaming 形式は少し異なります。

data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","choices":[{"delta":{"content":"こんにちは"},"index":0}]}

data: [DONE]

それぞれのパーサーを個別に書くより、抽象化レイヤーを設けることを強く推奨する(後述)。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
SSE の fetch 実装で詰まっていた人が、React Native で LLM ストリーミング接続を今日から本番環境で動かせる
AbortController・エラーリトライ・コスト最適化の3セットが揃った、コピペで使える実装コードを手に入れられる
Anthropic/OpenAI/Gemini の3社 API に対応した抽象化レイヤーの設計パターンを習得し、プロバイダー切り替えをアプリ再起動なしで実現できる
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

開発ツール2026-07-15
「、」が行頭に落ちた — Rork が組んだ名言カードと日本語の禁則処理
React Native の Text は日本語の行頭禁則を保証しません。実測した違反率、WORD JOINER による事前結合の実装、onTextLayout での自動監査、Rork Max(SwiftUI)との挙動差までまとめました。
開発ツール2026-07-10
React Compiler を Expo に入れて、手書き memo を 41 箇所消しました
Rork が生成した React Native 画面に React Compiler を導入し、再レンダリング回数を Profiler で実測しました。手書き memo/useCallback の削除判断、効かない箇所の見分け方、CI での回帰検知までをまとめています。
開発ツール2026-07-07
アイコンのバッジが「3」のまま消えない — Expoアプリのバッジ数をSource of Truthで作り直す
Expoアプリのアイコンバッジが実際の未読と食い違い、消えなくなる原因を突き止め、バッジ数を状態から再計算して同期するSource of Truth設計を、動くコードと実運用の落とし穴つきで整理します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →