こんにちは!Futuristic Imagination LLC 代表の佐藤琢也です。
弊社では現在、Next.jsとGemini API、そしてVercel Cronを組み合わせ、AIオウンドメディアを18サイト、9言語展開で自動運用しています。おかげさまで年間6,570記事を自動生成しており、この圧倒的な物量の裏側には、Gemini 2.5 Flashを最大限に活用したプロンプト設計の知見が詰まっています。
「AIで記事生成って、品質どうなの?」と疑問に思う方もいるかもしれませんが、Gemini 2.5 Flashは高速かつ高精度で、適切なプロンプトを与えれば驚くほど自然でSEOにも強い日本語コンテンツを生成してくれます。
今回は、その"秘伝のタレ"とも言えるプロンプト設計パターンと、実際に僕がどう実装しているのかを、コードを交えながら徹底解説します。
この記事を読めば、AIによるコンテンツ生成で消耗している人、高品質な記事をスケーラブルに作りたいと思っている人の悩みを解決できるはずです。
この記事でわかること
- Gemini 2.5 Flashが日本語コンテンツ生成に最適な理由
- AI生成コンテンツの品質を最大化するプロンプト設計の基本原則
- 【実践!】具体的なプロンプトテンプレートとTypeScriptでの実装例
- タイトル・見出し・本文・結論を自動生成する一連のパイプライン構築のヒント
- Next.jsとGemini APIを組み合わせた自動運用戦略
1. なぜGemini 2.5 Flashなのか? 高速性と日本語の親和性
LLMを使ったコンテンツ生成において、モデル選びは非常に重要です。これまで様々なモデルを試してきましたが、Gemini 2.5 Flashは日本語コンテンツ生成において、現状で最もコストパフォーマンスに優れていると感じています。
高速レスポンスと高いスケーラビリティ
「Flash」の名前が示す通り、そのレスポンス速度は驚異的です。僕のように大量のコンテンツを生成するケースでは、この高速性は必須です。Vercel Cronで一日何百記事も生成するとなると、モデルの応答速度が少しでも遅いと、全体のスループットに大きく影響します。
日本語コンテンツ生成の品質
Gemini 2.5 Flashは、複雑な指示やニュアンスも比較的正確に理解し、自然な日本語を生成してくれます。特に、定型的な記事構成やSEOキーワードを盛り込む際も、不自然さが少なく、ユーザーが読んでも違和感のない文章を出力してくれるのが強みです。もちろん、完璧ではないので後述するプロンプト設計で補完していきます。
コスト効率
数多くの記事を生成する上で、コストは無視できません。Gemini 2.5 Flashは性能に対して非常に低コストで利用できるため、大量生産の基盤として最適な選択肢となります。
2. AI生成コンテンツの品質を最大化するプロンプト設計の基本原則
「プロンプトエンジニアリング」と聞くと難しそうに聞こえるかもしれませんが、僕が実践しているのは至ってシンプルです。重要なのは、AIに「何を、どのように、どこまで」やってほしいのかを明確に伝えることです。
原則1: 具体的な役割と目的を与える
AIに「あなたは専門家です」「最高の記事を作成してください」といった具体的な役割と目的を与えることで、AIの出力品質は格段に向上します。
原則2: 出力形式を明確にする
JSON形式、Markdown形式、特定のタグの使用など、AIが出力する形式を具体的に指示します。これにより、後続の処理(パースやデプロイ)が容易になります。
原則3: 制約とルールを設ける
文字数、キーワードの必須使用、避けるべき表現、著作権への配慮など、出力に関する制約やルールを明確に指示します。弊社では著作権、特にJASRAC管理楽曲の取り扱いなどには厳しく、プロンプトで回避策を指示しています。
原則4: 段階的な生成(チェインプロンプティング)
いきなり「記事全体を生成して!」と指示するのではなく、「まずタイトルを生成」「次に見出しを生成」「最後に本文を生成」といったように、タスクを分割して段階的に実行させます。これにより、各ステップで品質をチェックしやすく、問題発生時のデバッグも容易になります。僕が「なんかこれって〜じゃない?」「〜ないかな?」と常に探求しているのは、まさにこの段階的な改善点ですね。
原則5: 例示学習 (Few-shot Learning)
もし可能であれば、理想的な出力例をいくつかプロンプトに含めることで、AIはより期待に沿った出力を生成しやすくなります。
3. 【実践!】具体的なプロンプトテンプレートとTypeScriptでの実装例
それでは、実際に僕がNext.jsのバックエンド(Node.js/TypeScript)で使っているプロンプトと、それを呼び出すコードを紹介します。今回は記事のタイトル、見出し構成、そして本文を段階的に生成する例です。
3.1. 記事タイトル生成プロンプト
まずは、ユーザーが興味を持つような、SEOに強く、かつクリックしたくなるタイトルを生成します。
// src/lib/prompts/titleGeneratorPrompt.ts
export const createTitleGeneratorPrompt = (
topic: string,
keywords: string[]
) => {
return `
あなたはSEOの専門家であり、ユーザーの検索意図を深く理解したコンテンツプランナーです。
以下の指示に従い、指定されたトピックとキーワードに基づいて、魅力的な記事タイトルを3つ提案してください。
## 指示:
- 提案するタイトルは、読者の興味を引きつけ、クリックを促すものであること。
- SEOキーワードを自然に含め、検索エンジンでの視認性を高めること。
- 各タイトルは40文字以内とすること。
- 日本語で出力すること。
## トピック:
${topic}
## キーワード:
${keywords.join(", ")}
## 出力形式:
以下のようなJSON配列形式でタイトルを提案してください。
\`\`\`json
[
{ "title": "提案1のタイトル" },
{ "title": "提案2のタイトル" },
{ "title": "提案3のタイトル" }
]
\`\`\`
`;
};
実装例(Next.js API Route)
// src/app/api/generate-title/route.ts
import { NextResponse } from 'next/server';
import { GoogleGenerativeAI } from '@google/generative-ai';
import { createTitleGeneratorPrompt } from '@/lib/prompts/titleGeneratorPrompt';
const API_KEY = process.env.GEMINI_API_KEY!;
const genAI = new GoogleGenerativeAI(API_KEY);
export async function POST(req: Request) {
try {
const { topic, keywords } = await req.json();
if (!topic || !keywords || !Array.isArray(keywords)) {
return NextResponse.json({ error: 'Missing topic or keywords' }, { status: 400 });
}
const model = genAI.getGenerativeModel({ model: "gemini-2.5-flash" });
const prompt = createTitleGeneratorPrompt(topic, keywords);
const result = await model.generateContent(prompt);
const response = result.response;
const text = response.text();
// JSONパースの堅牢性を高める
const titles = JSON.parse(text.replace(/```json\n|\n```/g, '')) as { title: string }[];
return NextResponse.json({ titles });
} catch (error) {
console.error('Error generating title:', error);
return NextResponse.json({ error: 'Failed to generate title' }, { status: 500 });
}
}
これで、トピックとキーワードから適切な記事タイトルを自動生成できます。僕のAIオウンドメディアでは、ここで生成されたタイトルの中から、過去のパフォーマンスデータ(CTRなど)に基づいて最適なものを選択するロジックを組み込んでいます。
3.2. 見出し構成生成プロンプト
次に、選ばれたタイトルとキーワードに基づいて、記事全体の構造となる見出し構成を生成します。
// src/lib/prompts/headingGeneratorPrompt.ts
export const createHeadingGeneratorPrompt = (
title: string,
keywords: string[]
) => {
return `
あなたはSEOコンテンツプランナーであり、読者の検索意図とニーズを満たす記事構成のエキスパートです。
以下の記事タイトルとキーワードに基づいて、効果的なH2、H3見出しの構成案を提案してください。
## 指示:
- 記事タイトルとキーワードを最大限に活用し、網羅性の高い見出し構成を作成すること。
- 各H2見出しの下に、関連性の高いH3見出しを2〜4つ含めること。
- 読者が理解しやすい論理的な流れとなるように構成すること。
- 見出しの数は、H2が3〜5個、H3が各H2の下に2〜4個程度を目安とすること。
- 見出しには必ず日本語を使用すること。
## 記事タイトル:
${title}
## キーワード:
${keywords.join(", ")}
## 出力形式:
以下のようなJSON配列形式でH2見出しとその子要素H3見出しを提案してください。
\`\`\`json
[
{
"h2": "H2見出し1",
"h3": [
"H3見出し1-1",
"H3見出し1-2",
"H3見出し1-3"
]
},
{
"h2": "H2見出し2",
"h3": [
"H3見出し2-1",
"H3見出し2-2"
]
}
]
\`\`\`
`;
};
実装例(Next.js API Route)
これはgenerate-titleと同様の構造になります。titleとkeywordsをPOSTリクエストで受け取り、Gemini 2.5 Flashで処理します。
// src/app/api/generate-headings/route.ts
import { NextResponse } from 'next/server';
import { GoogleGenerativeAI } from '@google/generative-ai';
import { createHeadingGeneratorPrompt } from '@/lib/prompts/headingGeneratorPrompt';
const API_KEY = process.env.GEMINI_API_KEY!;
const genAI = new GoogleGenerativeAI(API_KEY);
export async function POST(req: Request) {
try {
const { title, keywords } = await req.json();
if (!title || !keywords || !Array.isArray(keywords)) {
return NextResponse.json({ error: 'Missing title or keywords' }, { status: 400 });
}
const model = genAI.getGenerativeModel({ model: "gemini-2.5-flash" });
const prompt = createHeadingGeneratorPrompt(title, keywords);
const result = await model.generateContent(prompt);
const response = result.response;
const text = response.text();
const headings = JSON.parse(text.replace(/```json\n|\n```/g, '')) as { h2: string; h3: string[] }[];
return NextResponse.json({ headings });
} catch (error) {
console.error('Error generating headings:', error);
return NextResponse.json({ error: 'Failed to generate headings' }, { status: 500 });
}
}
3.3. 本文生成プロンプト(セクションごと)
いよいよ本文です。ここが最も重要で、僕の「自社実証ファースト」の考え方が活きる部分です。いきなり記事全体を生成させると、一貫性が失われたり、冗長になったりしがちです。そこで、各H3見出しごとに本文を生成するアプローチを採用します。
これにより、各セクションの品質管理がしやすくなり、必要に応じて再生成したり、特定の情報を追加したりといった柔軟な対応が可能になります。
// src/lib/prompts/contentGeneratorPrompt.ts
export const createContentGeneratorPrompt = (
title: string,
h2Heading: string,
h3Heading: string,
keywords: string[],
context: string = "" // 記事全体の流れを考慮するための追加情報
) => {
return `
あなたは読者に価値を提供する優秀なコンテンツライターです。
以下の記事タイトル、H2見出し、H3見出し、そして関連キーワードを参考に、
ユーザーの疑問を解決する、具体的で分かりやすいコンテンツを作成してください。
## 指示:
- このセクションの目的は、与えられたH3見出しの内容を深く掘り下げ、読者に実用的な情報を提供することです。
- 文字数は400〜600文字程度とすること。
- 必要に応じて箇条書きや具体的な例を交えることで、読みやすさを向上させること。
- SEOキーワードを自然に含め、読みやすく、理解しやすい日本語で記述すること。
- 他のサイトからのコピペは絶対にしないこと。独自の視点と表現で記述すること。
- ${context ? `以下の記事の文脈を考慮して記述してください。\n文脈: ${context}` : ''}
## 記事タイトル:
${title}
## 現在のH2見出し:
${h2Heading}
## 現在のH3見出し (このセクションで書く内容):
${h3Heading}
## キーワード:
${keywords.join(", ")}
## 出力形式:
マークダウン形式のプレーンテキストで、H3見出しの内容を記述してください。
H3見出し自体は出力に含めないでください。
`;
};
実装例(Next.js API Route)
このエンドポイントは、各H3見出しごとに呼び出されます。
// src/app/api/generate-content-section/route.ts
import { NextResponse } from 'next/server';
import { GoogleGenerativeAI } from '@google/generativeAI';
import { createContentGeneratorPrompt } from '@/lib/prompts/contentGeneratorPrompt';
const API_KEY = process.env.GEMINI_API_KEY!;
const genAI = new GoogleGenerativeAI(API_KEY);
export async function POST(req: Request) {
try {
const { title, h2Heading, h3Heading, keywords, context } = await req.json();
if (!title || !h2Heading || !h3Heading || !keywords || !Array.isArray(keywords)) {
return NextResponse.json({ error: 'Missing required parameters' }, { status: 400 });
}
const model = genAI.getGenerativeModel({ model: "gemini-2.5-flash" });
const prompt = createContentGeneratorPrompt(title, h2Heading, h3Heading, keywords, context);
const result = await model.generateContent(prompt);
const response = result.response;
const text = response.text();
return NextResponse.json({ content: text });
} catch (error) {
console.error('Error generating content section:', error);
return NextResponse.json({ error: 'Failed to generate content section' }, { status: 500 });
}
}
3.4. 全体を統合するパイプライン
これらのAPIを呼び出し、記事全体を構成するパイプラインは以下のようになります。
-
トピックとキーワードからタイトルを生成 (
generate-titleを呼び出し) -
選定したタイトルとキーワードから見出し構成を生成 (
generate-headingsを呼び出し) -
生成された見出し構成をループし、各H3セクションの本文を生成 (
generate-content-sectionをH3の数だけ呼び出し)- この際、
context引数を使って、既に生成済みのセクション内容を渡すことで、記事全体の一貫性を保ちやすくします。
- この際、
- 序文と結論を生成 (これは別のプロンプトで、生成済みのタイトルと見出し、本文の概要を参考に生成します)
- 生成されたすべてのコンテンツを結合し、最終的なMarkdown形式の記事を作成
- Next.jsのISR(Incremental Static Regeneration)やVercel Deploy Hookを使ってデプロイ
僕のシステムでは、これをVercel Cronで定期的に実行し、毎日新しい記事が自動生成・公開される仕組みを構築しています。「なんかこれって〜じゃない?」「〜ないかな?」と常に新しい技術や効率化の余地を探しているので、このパイプラインも日々改善を加えています。例えば、自動クイズ生成や、Google Search Console APIと連携した自動リライトパイプラインも構築しており、低順位の記事はGemini 2.5 Flashで自動的にリライトされて再インデックス送信まで完結します。
まとめ
Gemini 2.5 Flashは、その高速性と日本語生成能力の高さから、AIを活用したコンテンツ自動生成において非常に強力なツールとなります。重要なのは、AIの特性を理解し、今回紹介したような段階的かつ明確なプロンプト設計を行うことです。
僕が目指しているのは「極限まで自動化された高生産性エコシステムの構築」であり、その最前線でNext.jsとGemini APIを駆使して日々進化させています。この技術スタックとプロンプト設計のノウハウを組み合わせることで、少人数(あるいは僕一人)でも圧倒的な量の高品質コンテンツを生成し、事業をスケールさせることが可能です。
「弊社自身がヘビーユーザーとして使いこなしている状態を作らないと、顧客に刺さらない」という哲学のもと、これからも最新のAI技術とWeb開発を融合させ、未来を切り開いていきます。
今回紹介したようなシステムの構築代行も行っていますので、ご興味があればぜひお問い合わせください。
→ https://www.futuristicimagination.co.jp/service/
また、AIとキャリア、副業に関するShorts動画を毎日配信中です。ぜひご覧ください!
→ https://www.youtube.com/channel/UCFobIbWz1KDKaIdDqXpTPAA