ChatGPTで重複しない記事を量産するPython実装【Embeddingで自動判定】

記事
IT・テクノロジー

はじめに:なぜ“重複排除”が必要なのか

生成AIで記事を量産すると、必ず発生するのが「意味的な重複」です。
タイトルや文章が異なっても、内容の本質が同じであればSEOや品質面で致命的になります。

この問題はプロンプトでは解決できません。
必要なのは、Embeddingを使った意味ベースの重複判定です。


全体アーキテクチャ

今回実装する流れはシンプルです:

1. タイトル生成(ChatGPT)
2. Embedding化(ベクトル変換)
3. 類似度計算(cosine similarity)
4. 重複排除
5. 目次・本文生成


必要環境

* Python 3.10以上
* OpenAI APIキー
* ライブラリ
pip install openai numpy scikit-learn

ステップ① タイトル生成

まずはタイトルを生成します。

from openai import OpenAI
client = OpenAI()

def generate_titles(category, n=30):
    prompt = f"""
    「{category}」カテゴリにおいて、
    検索意図が重複しないタイトルを{n}個生成してください。
    """
    res = client.chat.completions.create(
        model="gpt-4.1-mini",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.9
    )
    titles = res.choices[0].message.content.split("\n")
    return [t.strip() for t in titles if t.strip()]

ステップ② Embeddingでベクトル化

タイトルを数値ベクトルに変換します。
def get_embeddings(texts):
    res = client.embeddings.create(
        model="text-embedding-3-small",
        input=texts
    )
    return [d.embedding for d in res.data]

ステップ③ 類似度チェックと重複排除

ここが核心部分です。

from sklearn.metrics.pairwise import cosine_similarity

def deduplicate(texts, threshold=0.85):
    embeddings = get_embeddings(texts)
    unique_texts = []
    unique_vectors = []

    for text, vec in zip(texts, embeddings):
        if not unique_vectors:
            unique_texts.append(text)
            unique_vectors.append(vec)
            continue
        similarities = cosine_similarity([vec], unique_vectors)[0]
        if max(similarities) < threshold:
            unique_texts.append(text)
            unique_vectors.append(vec)

    return unique_texts

ステップ④ 実行

実際に回してみます。

category = "AIライティング"
titles = generate_titles(category, 30)

unique_titles = deduplicate(titles)

print("生成数:", len(titles))
print("重複除去後:", len(unique_titles))

for t in unique_titles:
    print("-", t)

ステップ⑤ 目次・本文生成(応用)

重複排除されたタイトルに対して、さらに展開します。

def generate_outline(title):
    prompt = f"""
    以下のタイトルに対して、重複のない目次を10個作成してください。
    タイトル: {title}
    """
    res = client.chat.completions.create(
        model="gpt-4.1-mini",
        messages=[{"role": "user", "content": prompt}]
    )
    return res.choices[0].message.content
よくある失敗

① 閾値が低すぎる

→ 似た記事が残る
対策:0.85〜0.9に調整

② 一括生成

→ 文脈崩壊
対策:分割生成

③ プロンプト依存

→ 再現性なし
対策:コード化


まとめ

生成AIで記事を量産する上で重要なのは、文章力ではありません。

「生成 → 判定 → 再生成」のループ設計

これを実装することで、

* 重複のない記事生成
* 品質の安定化
* スケーラブルな運用

が実現できます。


補足(実務視点)

この仕組みはブログだけでなく:

* SEOコンテンツ制作
* EC商品説明生成
* FAQ自動化

にも応用可能です。


■締め(そのまま使える)

AI記事生成の自動化や、業務への組み込みについて相談したい方は気軽にご連絡ください。
テンプレ化・カスタマイズにも対応しています。
サービス数40万件のスキルマーケット、あなたにぴったりのサービスを探す ココナラコンテンツマーケット ノウハウ記事・テンプレート・デザイン素材はこちら