はじめに
長文を読むのが苦手なユーザーに、どうやって情報を届けるか?
私が自治会 DX(自治会業務デジタル化アプリ)を開発していたとき、この課題に直面しました。回覧板の内容は、時に数百文字、数千文字に及びます。特にシニア層のユーザーにとって、長文を最後まで読むのは負担が大きい。
そこで Claude Code に依頼して実装したのが、AI による自動要約機能です。
2026年1月27日の開発日記にはこう書いています:
AI 要約: 長文の回覧板をシニアが読みやすいように3行以内で要約
この記事では、Vercel AI SDK と Google Gemini を使って日本語要約 API を実装した経験を共有します。
なぜ Google Gemini を選んだのか
AI モデルの選定は、コスト、性能、使いやすさのバランスで決まります。
開発日記には、比較検討の結果をこう記録しています:
Google Gemini vs OpenAI:
- Gemini 2.0 Flash を採用
- 理由: 無料枠が大きい、日本語性能が良い、レスポンスが速い
Gemini 2.0 Flash の特徴
| 特徴 | 内容 |
|---|---|
| 無料枠 | 1日15リクエスト(開発には十分) |
| 日本語性能 | 自然な日本語を生成 |
| レスポンス速度 | Flash モデルは高速 |
| コスト | 有料枠でも比較的安価 |
個人開発やスタートアップのプロダクトには、この無料枠の大きさは魅力的です。OpenAI の GPT-4 も高性能ですが、コストを考えると Gemini は良い選択肢でした。
Vercel AI SDK とは
Vercel AI SDK は、AI モデルとのやり取りを簡単に実装できるライブラリです。特に以下の点が便利です:
- 統一されたインターフェース: OpenAI、Anthropic、Google など複数のプロバイダーに対応
- ストリーミングサポート: レスポンスをリアルタイムで表示
- Next.js との統合: App Router と相性が良い
開発日記にはこう書いています:
Vercel AI SDK の
streamTextを使うとストリーミングレスポンスが簡単に実装できる
実装の全体像
自治会 DX での要約機能は、以下のような構成になっています:
ユーザー
↓ 要約リクエスト
Next.js API Route (/api/summarize)
↓ Vercel AI SDK
Google Gemini API
↓ ストリーミングレスポンス
ユーザー(リアルタイム表示)
API Route の実装
Next.js App Router で API Route を作成します。
// app/api/summarize/route.ts
import { streamText } from "ai";
import { google } from "@ai-sdk/google";
export async function POST(request: Request) {
const { content } = await request.json();
const result = await streamText({
model: google("gemini-2.0-flash-exp"),
system: `あなたは日本語の文章を要約するアシスタントです。
以下のルールに従って要約してください:
- 3行以内で要約する
- 重要なポイントを漏らさない
- シニア層が読みやすい平易な表現を使う
- 敬語は使わず、「です・ます」調で書く`,
prompt: `以下の文章を要約してください:
${content}`,
});
return result.toDataStreamResponse();
}
ポイント: システムプロンプトの設計
要約の品質は、システムプロンプトの設計で大きく変わります。自治会 DX では、以下の要件を明示しました:
- 3行以内: 長すぎると読まれない
- 重要なポイント: 日時、場所、締切などを漏らさない
- 平易な表現: シニア層がターゲット
- です・ます調: 親しみやすさ
クライアント側の実装
Vercel AI SDK には、React 用のフックも用意されています。
// components/SummaryButton.tsx
"use client";
import { useCompletion } from "ai/react";
export function SummaryButton({ content }: { content: string }) {
const { completion, complete, isLoading } = useCompletion({
api: "/api/summarize",
});
const handleClick = async () => {
await complete(content);
};
return (
<div>
<button onClick={handleClick} disabled={isLoading}>
{isLoading ? "要約中..." : "AI で要約"}
</button>
{completion && (
<div className="mt-4 p-4 bg-gray-100 rounded">
<h3>要約</h3>
<p>{completion}</p>
</div>
)}
</div>
);
}
ポイント: ストリーミング表示
useCompletion フックを使うと、レスポンスがストリーミングで返ってくるたびに completion が更新されます。ユーザーは、AI が文字を「打っている」ように見え、待ち時間のストレスが軽減されます。
環境変数の設定
Google Gemini API を使うには、API キーが必要です。
# .env.local
GOOGLE_GENERATIVE_AI_API_KEY=your-api-key-here
API キーは Google AI Studio で無料で取得できます。
シニア向け UI への組み込み
自治会 DX はシニア層がメインターゲットです。要約機能も、シニアに使いやすい形で組み込む必要がありました。
開発日記から:
シニア向け UI 設計:
- タップターゲット最小48px(WAI推奨44px以上)
- フォントサイズ本文18px以上
- 高コントラスト配色
要約ボタンのデザイン
<button
onClick={handleSummarize}
className="
w-full py-4 px-6
text-lg font-medium
bg-blue-600 text-white
rounded-lg
active:bg-blue-700
"
>
AI で要約する
</button>
- w-full: 画面幅いっぱいに広げる
- py-4: 十分な高さを確保
- text-lg: 読みやすいフォントサイズ
要約結果の表示
{summary && (
<div className="mt-4 p-6 bg-yellow-50 border-2 border-yellow-200 rounded-lg">
<h3 className="text-lg font-bold mb-2">📝 かんたんまとめ</h3>
<p className="text-lg leading-relaxed">{summary}</p>
</div>
)}
- bg-yellow-50: 目立つ背景色
- border-2: はっきりした境界線
- text-lg leading-relaxed: 読みやすい文字サイズと行間
実装時に悩んだこと
要約の一貫性
同じ文章を要約しても、AI の出力は毎回少し異なります。これは LLM の特性上避けられませんが、ユーザーによっては混乱の原因になりえます。
対策として、以下を検討しました:
- temperature を下げる: 出力のランダム性を抑える
- キャッシュ: 同じ入力に対しては同じ結果を返す
const result = await streamText({
model: google("gemini-2.0-flash-exp"),
// temperature: 0.3, // 低めに設定すると一貫性が上がる
// ...
});
レート制限
開発中は無料枠で十分でしたが、本番運用ではレート制限を考慮する必要があります。
- クライアント側でのデバウンス: 連打を防止
- サーバー側でのレート制限: IP ベースでリクエスト数を制限
- キャッシュ活用: 同じ文章の再要約を防止
プロンプトエンジニアリングの試行錯誤
要約の品質を上げるために、プロンプトを何度も調整しました。
初期のプロンプト(NG)
以下の文章を要約してください:
このシンプルなプロンプトでは、要約が長くなったり、重要な情報が抜けたりしました。
改善後のプロンプト(OK)
あなたは日本語の文章を要約するアシスタントです。
以下のルールに従って要約してください:
- 3行以内で要約する
- 重要なポイント(日時、場所、締切、金額)を必ず含める
- シニア層が読みやすい平易な表現を使う
- 「です・ます」調で書く
- 専門用語は避け、平易な言葉に言い換える
具体的なルールを列挙することで、出力の品質が安定しました。
回覧板特有のルール
回覧板には「日時」「場所」「締切」など、絶対に漏らしてはいけない情報があります。これをプロンプトに明示することで、重要情報の抜け落ちを防ぎました。
まとめ
Vercel AI SDK と Google Gemini を使えば、日本語要約 API を簡単に実装できます。
ポイントをまとめると:
- モデル選定: Gemini 2.0 Flash は無料枠が大きく、日本語性能も良い
- Vercel AI SDK:
streamTextでストリーミングレスポンスが簡単 - プロンプト設計: 具体的なルールを明示すると品質が安定する
- シニア向け UI: 大きなボタン、読みやすいフォント、目立つ表示
開発日記から引用します:
Vercel AI SDK の
streamTextを使うとストリーミングレスポンスが簡単に実装できる
実際、Claude Code で API Route を実装したところ、数十行で済みました。AI の力を借りることで、ユーザー体験を大きく向上させられます。
長文を要約する機能が必要な場面は、自治会アプリに限らず多いはずです。ニュースアプリ、ドキュメント管理、メール要約... この記事が、皆さんのプロダクトに AI 要約機能を実装するきっかけになれば幸いです。
Zeronova(ゼロノバ)
Product Manager / AI-Native Builder
Web/IT業界19年以上・20以上のWebサービスを担当したPdM。東証プライム上場企業の子会社代表として事業経営を経験。現在はAIを駆使して企画から実装まで完結させる個人開発を実践中。