Day 6・AIをフロントから呼ぶ(この教材の看板)
ストリーミングの考え方(応答を逐次表示する)
全部そろうまで待たず、届いた分から少しずつ表示するストリーミングの考え方をつかむ。
「全部待つ」か「届いた分から出す」か
ChatGPTのように、AIの返事が1文字ずつ流れて出てくるのを見たことがあると思います。あれが「ストリーミング」です。普通のやり方は答えが全部そろってからまとめて表示しますが、ストリーミングは届いた文字から順に表示していきます。体感の待ち時間が大きく変わるので、AIプロダクトではよく使われます。
非ストリーミング: 全部そろうまで無言
LLMが1000文字ぶんの返事を作り終えるまで、画面には何も出ない。ユーザーは「固まった?」と不安になる。
ストリーミング: 届いた分から表示
最初の数文字が来た瞬間から表示が始まる。全体の完成は同じでも、待っている感覚がぐっと減る。
なぜストリーミングにするのか
LLMは長い文章ほど生成に時間がかかります。完成を待つと数秒〜十数秒の無言時間が生まれます。ストリーミングなら最初の一片が来た瞬間に表示が始まるので、同じ生成時間でも「速い」と感じてもらえます。UX(使い心地)を上げる定番の手法です。
考え方: 川の水のように「少しずつ流れてくる」
非ストリーミングでは「返事(1つの文字列)」を丸ごと受け取ります。ストリーミングでは、返事が小さなかたまり(チャンク)に分かれて、時間差で次々と届きます。プログラム側は「かたまりが届くたびに、画面に追記する」というループを回すだけです。
// LLMがストリーミング対応で返してくると、res.body は
// 「少しずつ読める入れ物」になっている
export async function POST(req: Request): Promise<Response> {
const { prompt } = (await req.json()) as { prompt: string };
const llmRes = await fetch("https://api.example-llm.com/v1/messages", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + process.env.LLM_API_KEY
},
body: JSON.stringify({ prompt, stream: true }) // 流して返してと頼む
});
// 届いた流れ(body)をそのまま画面へ受け渡す
return new Response(llmRes.body, {
headers: { "Content-Type": "text/plain; charset=utf-8" }
});
}画面側は、届いたチャンクを読みながら で管理している文字列にどんどん足していきます。すると、足すたびに再描画されて、1文字ずつ増えていくように見えます。
"use client";
import { useState } from "react";
export function Chat() {
const [answer, setAnswer] = useState<string>("");
async function send(prompt: string) {
setAnswer("");
const res = await fetch("/api/chat", {
method: "POST",
body: JSON.stringify({ prompt })
});
// res.body から少しずつ読み、届いた分を足していく
const reader = res.body!.getReader();
const decoder = new TextDecoder();
while (true) {
const { value, done } = await reader.read();
if (done) break; // もう届かない
setAnswer((prev) => prev + decoder.decode(value));
}
}
return <p>{answer}</p>;
}AIにはこう聞く
「Next.jsのroute.tsで、LLMのストリーミング応答をそのままクライアントに中継したい。サーバー側とクライアント側(useStateで逐次追記)の最小サンプルをTypeScriptで」と頼むと、この形のたたき台が得られます。まず非ストリーミングで動かしてから、ストリーミングに差し替えると理解しやすいです。
最初は無理にストリーミングしない
ストリーミングは体感を良くしますが、実装は少し複雑です。学習段階ではまず非ストリーミング(全部そろってから表示)で正しく動くことを確認し、その後で置き換えるのが安全です。動く土台があると、AIに差分だけ頼めます。
読んでも腑に落ちない所は、AIに噛み砕いてもらいましょう。
理解度チェック
答えられれば、面接で説明できる状態に一歩近づきます。
ストリーミングで応答を表示する主な利点はどれ?
画面側でストリーミングされた文字を表示するとき、届いたチャンクをどう扱うのが典型的?
ストリーミングとは何か、非ストリーミングとの違いと、学習段階での進め方を含めて説明してください。
記述式です。まず自分の言葉で答えを考えてから、模範解答を開いて自己採点してください。