取り組みの背景:AI × EC の可能性
オンラインショップの成長を左右する最大の課題は何でしょうか?それはスケールです。
商品が10個なら、商品説明の執筆も手作業で十分かもしれません。しかし100個、1000個となると、物理的に不可能です。さらにグローバル展開となれば、日本語・英語・中国語・スペイン語…と多言語対応も必須。加えて、SEO最適化、顧客レビュー分析、在庫管理との連携など、やることが無限に増えていきます。
ここで活躍するのが Gemini API です。
Gemini APIの最新モデル(gemini-2.0-flash など)は、以下の能力を備えています:
- マルチモーダル処理: 商品画像から詳細な商品説明を自動生成
- 構造化出力: JSON形式で必要なメタデータを確実に取り出す
- 大量処理: Batch API で数千件の商品を低コストで処理
- 多言語対応: 同じプロンプトで複数言語の自然な説明文を生成
このガイドでは、実在するEC運営の課題を、Gemini APIでいかに解決するかを、ステップバイステップで解説します。Shopify、BASE、自社ECなど、どのプラットフォームでも応用可能な実装パターンです。
商品画像 → 商品説明 自動生成パイプライン
Vision API と構造化出力の組み合わせ
ECサイトで最も時間がかかるのが、商品ページの作成です。特に商品説明文は、営業視点・SEO視点の両立が難しく、外注するにもコストがかかります。
Gemini APIの Vision 能力と構造化出力を組み合わせれば、画像1枚から以下を一度に生成できます:
- 商品名(原文から抽出もしくは提案)
- SEO最適化された説明文(150文字・300文字・500文字の複数バージョン)
- 主要キーワード
- 商品カテゴリ
- 価格帯の提案
- ターゲット顧客層
具体的な実装例を見てみましょう。
import Anthropic from "@anthropic-ai/sdk";
import * as fs from "fs";
const client = new Anthropic();
interface ProductMetadata {
productName: string;
shortDescription: string; // 150文字
mediumDescription: string; // 300文字
longDescription: string; // 500文字
primaryKeywords: string[];
secondaryKeywords: string[];
category: string;
targetAudience: string;
priceRange: {
minJPY: number;
maxJPY: number;
};
highlights: string[];
}
async function generateProductContent(
imagePath: string
): Promise<ProductMetadata> {
const imageData = fs.readFileSync(imagePath);
const base64Image = imageData.toString("base64");
const imageExtension = imagePath.split(".").pop()?.toLowerCase() || "jpeg";
const mediaType =
imageExtension === "png" ? "image/png" : "image/jpeg";
const response = await client.messages.create({
model: "gemini-2.0-flash",
max_tokens: 1024,
messages: [
{
role: "user",
content: [
{
type: "image",
source: {
type: "base64",
media_type: mediaType,
data: base64Image,
},
},
{
type: "text",
text: `This image shows a product. Analyze it carefully and provide structured product metadata in JSON format.
Requirements:
1. productName: Extract or infer the product name from the image
2. shortDescription: 150文字以内の説明(ECサイトのサムネイル下に表示される想定)
3. mediumDescription: 300文字以内の説明(商品一覧ページ用)
4. longDescription: 500文字以内の説明(商品詳細ページの冒頭)
5. primaryKeywords: 商品の主要キーワード(5個)
6. secondaryKeywords: 関連キーワード(5個)
7. category: カテゴリ(e.g., "ファッション", "家電", "食品")
8. targetAudience: ターゲット顧客層の説明
9. priceRange: 日本円での想定価格帯(minJPY, maxJPY)
10. highlights: 商品の主要な特徴・メリット(3〜5個)
Respond ONLY with valid JSON, no other text.`,
},
],
},
],
});
const content = response.content[0];
if (content.type !== "text") {
throw new Error("Unexpected response type");
}
const metadata = JSON.parse(content.text) as ProductMetadata;
return metadata;
}
// 使用例
(async () => {
const metadata = await generateProductContent("./product-image.jpg");
console.log(JSON.stringify(metadata, null, 2));
})();このコードの重要なポイント:
- Base64エンコード: Vision APIに画像を送信する際は、ファイルをBase64に変換
- 構造化出力:
JSON.parse()で直接オブジェクトに変換可能(JSONスキーマ互換形式を指定) - 複数バージョン生成: 150・300・500文字の説明を一度に生成し、ECプラットフォームの異なる表示場所に使い分け
大量商品処理への拡張
1000件の商品がある場合、上記のコードを単純にループするとAPI料金が高くなります。ここで Batch API を活用します。
interface BatchProductJob {
product_id: string;
image_url: string;
}
async function createBatchProductProcessing(
products: BatchProductJob[]
): Promise<string> {
const requests = products.map((product, index) => ({
custom_id: `product-${product.product_id}`,
params: {
model: "gemini-2.0-flash",
max_tokens: 1024,
messages: [
{
role: "user",
content: [
{
type: "image",
source: {
type: "url",
url: product.image_url,
},
},
{
type: "text",
text: "Generate product metadata (JSON format)...", // 前述のプロンプト
},
],
},
],
},
}));
// Batch APIで送信(詳細は後述)
console.log(`Created batch job for ${products.length} products`);
return "batch-job-id";
}SEO最適化された商品ページ自動生成
メタデータとキーワード最適化
商品説明が生成できても、検索エンジンに最適化されていなければ意味がありません。Gemini APIを使って、以下も自動化できます:
- メタディスクリプション: 160文字以内で、キーワードを自然に盛り込む
- OG画像用テキスト: SNSシェア時に表示される説明
- 構造化データ(Schema.org): Google検索で商品の価格・在庫が表示される
- 内部リンク提案: 関連商品へのリンク
interface SEOOptimizedProduct {
metaTitle: string; // 60文字以内
metaDescription: string; // 160文字以内
ogDescription: string; // 120文字以内
schemaData: {
"@context": string;
"@type": string;
name: string;
description: string;
image: string;
brand: string;
offers: {
"@type": string;
price: number;
priceCurrency: string;
availability: string;
};
};
relatedProductSlugs: string[]; // 関連商品のスラッグ
internalLinks: Array<{
text: string;
slug: string;
}>;
}
async function generateSEOOptimizedProduct(
productName: string,
description: string,
category: string,
keywords: string[]
): Promise<SEOOptimizedProduct> {
const response = await client.messages.create({
model: "gemini-2.0-flash",
max_tokens: 1024,
messages: [
{
role: "user",
content: `Product information:
- Name: ${productName}
- Category: ${category}
- Description: ${description}
- Keywords: ${keywords.join(", ")}
Generate SEO-optimized metadata in JSON format:
1. metaTitle (60 chars max): Include primary keyword naturally
2. metaDescription (160 chars max): Include secondary keywords, CTAを含める
3. ogDescription (120 chars max): Optimized for social sharing
4. schemaData: JSON-LD format for Google Rich Results
5. relatedProductSlugs: 関連商品のスラッグ(3〜5個の例示)
6. internalLinks: 内部リンク提案(テキストとスラッグのペア)
Respond ONLY with valid JSON.`,
},
],
});
const content = response.content[0];
if (content.type !== "text") {
throw new Error("Unexpected response type");
}
return JSON.parse(content.text) as SEOOptimizedProduct;
}このアプローチにより、検索エンジン + ユーザー両面での最適化が一度に実現します。
顧客レビュー AI分析
レビューテキストから購買インサイトを抽出
ECサイトに蓄積される顧客レビューは、商品改善の宝庫です。しかし、数百件のレビューを手動で読むことは現実的ではありません。
Gemini APIを使えば、以下を自動抽出できます:
- 感情スコア: ポジティブ/ネガティブ/ニュートラル
- 頻出テーマ: 「配送が遅かった」「サイズが小さい」など
- 改善提案: レビューから導き出される商品改善ポイント
- 顧客セグメント: どの層の顧客が何を評価しているか
interface ReviewAnalysis {
sentiment: "positive" | "neutral" | "negative";
sentimentScore: number; // 0.0 ~ 1.0
mainThemes: Array<{
theme: string;
frequency: number;
examples: string[];
}>;
improvementSuggestions: string[];
customerSegment: string;
repurchaseLikelihood: number; // 0.0 ~ 1.0
}
async function analyzeProductReview(review: string): Promise<ReviewAnalysis> {
const response = await client.messages.create({
model: "gemini-2.0-flash",
max_tokens: 1024,
messages: [
{
role: "user",
content: `Analyze this customer review in detail:
"${review}"
Provide structured analysis in JSON format:
1. sentiment: positive / neutral / negative
2. sentimentScore: 0.0 (very negative) to 1.0 (very positive)
3. mainThemes: Array of {theme, frequency (how many times mentioned), examples}
4. improvementSuggestions: What could the product/service improve based on this review?
5. customerSegment: What type of customer is this (age, profession, use case)?
6. repurchaseLikelihood: Probability they will buy again (0.0 ~ 1.0)
Respond ONLY with valid JSON.`,
},
],
});
const content = response.content[0];
if (content.type !== "text") {
throw new Error("Unexpected response type");
}
return JSON.parse(content.text) as ReviewAnalysis;
}
// 複数レビューの一括分析とサマリー生成
async function generateReviewSummary(reviews: string[]): Promise<{
overallSentiment: number;
topThemes: string[];
criticalIssues: string[];
recommendedActions: string[];
}> {
const analyses = await Promise.all(reviews.map(analyzeProductReview));
const response = await client.messages.create({
model: "gemini-2.0-flash",
max_tokens: 1024,
messages: [
{
role: "user",
content: `Based on these ${analyses.length} review analyses:
${JSON.stringify(analyses, null, 2)}
Generate a summary JSON with:
1. overallSentiment: Average sentiment score across all reviews
2. topThemes: Top 3-5 recurring themes
3. criticalIssues: Issues that urgently need fixing
4. recommendedActions: Prioritized action items for the business
Respond ONLY with valid JSON.`,
},
],
});
const content = response.content[0];
if (content.type !== "text") {
throw new Error("Unexpected response type");
}
return JSON.parse(content.text);
}このレビュー分析は、商品開発チーム と マーケティングチーム の両方に価値をもたらします。開発チームは改善ポイントを、マーケティングチームは販促メッセージの改善案を得られるのです。
多言語商品カタログ一括生成
ローカライズ+文化的適応
グローバル展開は、単なる翻訳ではなく ローカライゼーション が必須です。日本で「プレミアム」と書いても、アメリカ人には響きません。
Gemini APIはマルチモーダル + マルチ言語なので、以下が可能です:
- 日本語商品説明 → 英語・中国語・スペイン語に「翻訳」ではなく「文化的に適応」
- 各言語で異なるターゲット顧客を想定した説明の生成
- 現地の法規制に合わせた表現の調整
interface LocalizedProduct {
locale: string;
title: string;
description: string;
keywords: string[];
culturalAdaptations: string[];
localRegulations: string[];
}
async function generateLocalizedProduct(
originalJaProduct: {
title: string;
description: string;
keywords: string[];
},
targetLocales: string[] // e.g., ["en-US", "zh-CN", "es-MX"]
): Promise<LocalizedProduct[]> {
const results: LocalizedProduct[] = [];
for (const locale of targetLocales) {
const response = await client.messages.create({
model: "gemini-2.0-flash",
max_tokens: 1024,
messages: [
{
role: "user",
content: `Original Japanese product:
- Title: ${originalJaProduct.title}
- Description: ${originalJaProduct.description}
- Keywords: ${originalJaProduct.keywords.join(", ")}
Localize this product for ${locale} market. Respond in JSON:
1. locale: "${locale}"
2. title: Localized title (natural for ${locale} readers, not just translation)
3. description: Localized description (consider local preferences, lifestyle, values)
4. keywords: Keywords relevant for ${locale} search engines
5. culturalAdaptations: What cultural aspects were changed from original?
6. localRegulations: Any legal/regulatory considerations for ${locale}?
Respond ONLY with valid JSON.`,
},
],
});
const content = response.content[0];
if (content.type !== "text") {
throw new Error("Unexpected response type");
}
results.push(JSON.parse(content.text));
}
return results;
}実例を挙げると:
| 観点 | 日本語版 | 英語版(US) | 中国語版(CN) |
|---|---|---|---|
| 説明の重点 | 品質・ブランド価値 | 機能・実用性 | 価格・性価比(コスパ) |
| トーン | 丁寧・謙虚 | フレンドリー・力強い | ダイレクト・説得的 |
| キーワード例 | 「上質」「職人」「和」 | 「innovative」「premium」「advanced」 | 「超值」「品质」「经久耐用」 |
ECプラットフォーム連携
Shopify、BASE との実装パターン
商品コンテンツを自動生成しても、ECプラットフォームに自動登録できなければ意味がありません。主要プラットフォームとの連携パターンを紹介します。
Shopify Admin API との連携
import fetch from "node-fetch";
interface ShopifyProduct {
title: string;
body_html: string;
vendor: string;
product_type: string;
images: Array<{ src: string }>;
variants: Array<{
title: string;
price: string;
sku: string;
}>;
metafields: Array<{
namespace: string;
key: string;
value: string;
type: string;
}>;
}
async function createShopifyProduct(
shop: string,
accessToken: string,
product: ShopifyProduct
): Promise<void> {
const response = await fetch(
`https://${shop}.myshopify.com/admin/api/2024-01/products.json`,
{
method: "POST",
headers: {
"X-Shopify-Access-Token": accessToken,
"Content-Type": "application/json",
},
body: JSON.stringify({ product }),
}
);
if (!response.ok) {
throw new Error(`Shopify API error: ${response.statusText}`);
}
console.log("Product created successfully");
}
// Gemini生成コンテンツからShopify形式への変換
async function convertToShopifyFormat(
generatedProduct: ProductMetadata
): Promise<ShopifyProduct> {
return {
title: generatedProduct.productName,
body_html: generatedProduct.longDescription, // HTMLエスケープ処理省略
vendor: "自社",
product_type: generatedProduct.category,
images: [],
variants: [
{
title: "Default",
price: String(generatedProduct.priceRange.minJPY),
sku: `SKU-${Date.now()}`,
},
],
metafields: [
{
namespace: "ai_generated",
key: "keywords",
value: generatedProduct.primaryKeywords.join(","),
type: "single_line_text_field",
},
{
namespace: "seo",
key: "meta_description",
value: generatedProduct.shortDescription,
type: "single_line_text_field",
},
],
};
}BASE との API 連携
BASEはShopifyよりも API制限がありますが、基本的なパターンは同じです:
async function createBASEProduct(
apiKey: string,
product: {
title: string;
description: string;
category: string;
price: number;
}
): Promise<void> {
const response = await fetch("https://api.thebase.in/api/v1/items/search", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
title: product.title,
description: product.description,
category: product.category,
price: product.price,
}),
});
if (!response.ok) {
throw new Error(`BASE API error: ${response.statusText}`);
}
}実際の運用では、Shopify・BASEの仕様に合わせたメタデータ変換層を用意する点が肝心です。
大量商品の一括処理
Batch API でコスト最適化
1000件以上の商品を処理する場合、リアルタイムAPI呼び出しは非効率です。ここで Batch API を活用します。
interface BatchRequest {
custom_id: string;
params: {
model: string;
max_tokens: number;
messages: Array<{
role: "user" | "assistant";
content: string | Array<object>;
}>;
};
}
async function submitBatchJob(requests: BatchRequest[]): Promise<string> {
const response = await client.messages.create({
model: "gemini-2.0-flash",
max_tokens: 1024,
messages: [
{
role: "user",
content: `You are a batch processor. Process the following requests.`,
},
],
});
// Batch API の詳細なエンドポイント仕様は、APIドキュメント参照
console.log("Batch job submitted");
return "batch-job-id";
}
async function monitorBatchJob(jobId: string): Promise<object[]> {
// ジョブの完了をポーリング
let attempts = 0;
while (attempts < 120) {
// 最大2時間待機
await new Promise((resolve) => setTimeout(resolve, 60000)); // 60秒待機
// Batch APIからの結果取得
console.log(`Checking batch job status: ${jobId}`);
attempts++;
}
return [];
}Batch API の利点:
- 料金が50%割引 通常のAPI呼び出しと比較
- スケジューリング可能 ピーク時間外での処理が可能
- 非同期処理 大量データでもタイムアウトなし
実際の流れ:
ステップ1: 商品リスト → JSON形式のBatch要求に変換
ステップ2: Batch APIに送信 → job IDを取得
ステップ3: 定期的にステータスをチェック
ステップ4: 完了後、結果を取得 → DB登録
品質管理とヒューマンインザループ
AI生成の品質チェック
Gemini APIは強力ですが、完全に自動化するのは危険です。例えば:
- 価格提案が実感と合わない
- SEOキーワードが競合と被りすぎている
- 翻訳の自然さが低い
こうしたリスクを軽減するため、以下のアプローチを推奨します:
1. 自動チェック層
interface QualityCheckResult {
isValid: boolean;
issues: string[];
confidence: number;
}
async function qualityCheckProduct(
product: ProductMetadata
): Promise<QualityCheckResult> {
const checks = [
// キーワード数チェック
product.primaryKeywords.length >= 5 ? null : "主要キーワードが5個未満",
// 説明文の長さチェック
product.longDescription.length < 300 ? "説明文が短すぎる" : null,
// キーワード密度チェック(SEO観点)
// "AI" が説明に3回以上含まれているか等の自動チェック
];
const issues = checks.filter((c) => c !== null) as string[];
return {
isValid: issues.length === 0,
issues,
confidence:
issues.length === 0 ? 1.0 : Math.max(0.5, 1.0 - issues.length * 0.1),
};
}2. ヒューマンレビューの自動ルーティング
async function routeForReview(
product: ProductMetadata,
qualityScore: number
): Promise<{
requiresReview: boolean;
reviewTier: "auto-approve" | "standard" | "priority";
}> {
let reviewTier: "auto-approve" | "standard" | "priority";
if (qualityScore > 0.9) {
reviewTier = "auto-approve";
} else if (qualityScore > 0.7) {
reviewTier = "standard";
} else {
reviewTier = "priority";
}
return {
requiresReview: qualityScore < 0.9,
reviewTier,
};
}3. レビュー画面の実装例(概念)
レビュー担当者向けダッシュボード:
- 差分表示: 元の商品情報 vs. AI生成コンテンツを横並び表示
- クイックエディット: 修正が必要な場合、その場で編集可能
- 承認フロー: 修正後、ワンクリックで本番DBに登録
まとめ
Gemini APIを使ったEC自動化は、スケール と 品質 の両立を実現します。
もう一度、このガイドで紹介した手法を整理します:
短期(1〜2ヶ月): 既存商品の説明文自動再生成と SEO最適化。ROI が最も高い。
中期(3〜6ヶ月): 顧客レビュー分析、自動改善提案の導入。商品開発との連携を強化。
長期(6〜12ヶ月): 多言語展開、Shopify/BASE連携の自動化。グローバルECへの足がかり。
最後に、最も大切なポイント: AI は道具です。生成したコンテンツが本当に顧客の心に響くか、売上につながるかは、最終的には ヒューマンレビューと実験検証 が決めます。
「100%自動化」を目指すのではなく、「AI + 人間の協働」で、スケーラビリティと真正性の両立 を目指してください。
参考資料
実装をサポートする資料として、以下が参考になります: