AIテキスト要約

異なる大規模言語モデル(LLM)には、入力プロンプト単語の長さ制限が異なります。長文を要約する必要があるが、記事の長さがモデルの最大長制限を超える場合、すべての記事をAIモデルに直接フィードすることはできません。そのようなシナリオでは、LangChainはこれを処理するための戦略とカプセル化を提供します。この章では、LangChainがテキスト要約を解決する方法を主に紹介します。

データの前処理

まず、テストデータを準備します。この例では、長いドキュメントをロードし、ドキュメントを複数の小さなフラグメントに分割します。

  • 注意:ここでのローカルファイルデータの読み込みはイラストのためだけです。実際のビジネスシナリオでは、独自のデータベースからドキュメントデータを読み込むことがあります。
from langchain import OpenAI, PromptTemplate, LLMChain
from langchain.text_splitter import CharacterTextSplitter
from langchain.chains.mapreduce import MapReduceChain
from langchain.prompts import PromptTemplate

llm = OpenAI(temperature=0)

text_splitter = CharacterTextSplitter()
with open("../../state_of_the_union.txt") as f:
    state_of_the_union = f.read()
texts = text_splitter.split_text(state_of_the_union)
from langchain.docstore.document import Document

docs = [Document(page_content=t) for t in texts[:3]]

はじめに

長文を要約する最も簡単な方法は、LangChainが提供するload_summarize_chainタスクを使用してテキスト要約タスクを実行することです。

from langchain.chains.summarize import load_summarize_chain
chain = load_summarize_chain(llm, chain_type="map_reduce")
chain.run(docs)

LangChainが提供するカプセル化されたテキスト要約Chainを使用することは簡単です。ただし、いくつかのパラメータを微調整する必要がある場合は、以下の内容を参照してください。たとえば、上記の例では組み込みのプロンプトワードテンプレートが使用されており、これは中国語には適していないかもしれません。独自のプロンプトワードテンプレートに変更するなどができます。

chain_typeパラメータの説明

LangChainでは、ChainタスクのプロンプトワードがLLMのトークン長制限を超える場合の4つの処理方法を設計しています。

4つのchain_typeの種類は次のとおりです:

  • stuff
  • map_reduce
  • refine
  • map_rerank

stuffタイプ

これはLangChainのデフォルトタイプであり、すべてのドキュメントコンテンツを一度にLLMモデルに送信して要約します。そのため、stuffingモードと呼ばれます。ドキュメントコンテンツが長すぎると、間違いなくLLMのトークン制限を超えます。

map_reduceタイプ

この方法は、まず各ドキュメントフラグメントを個別にLLMモデルに送り、それらの要約を結合して最終的な要約をAIに提供します。これは、多くのプログラミング言語のmap-reduce関数ライブラリのコンセプトと似ています。

refineタイプ

この方法は要約の方法でテキスト要約を生成します。まず、最初のドキュメントの内容をLLMモデルに送って要約し、次に最初のドキュメントの要約内容と2番目のドキュメントの内容をLLMモデルに送り、長いテキストの最終的な要約を取得します。

map_rerankタイプ

これは質問回答タスクで使用されます。質問に関連性が高いドキュメントフラグメントを選択し、それらをLLMモデルに送って質問に答えます。

stuffタスクの例

以下は、stuffタイプを使用して記事を要約する例です。これはLLMのトークン長制限を超えない記事に適しています:

chain = load_summarize_chain(llm, chain_type="stuff")
chain.run(docs)

カスタムプロンプトワード

stuffタイプの場合、カスタムプロンプトワードの例は以下の通りです:

prompt_template = """以下の内容を要約してください:

{text}

要約:"""
PROMPT = PromptTemplate(template=prompt_template, input_variables=["text"])
chain = load_summarize_chain(llm, chain_type="stuff", prompt=PROMPT)
chain.run(docs)

map_reduceタスクの例

map_reduceは記事を要約します。もちろん、この方法では複数のAIモデルの呼び出しが行われます。

chain = load_summarize_chain(llm, chain_type="map_reduce")
chain.run(docs)

map_reduceタスクのカスタムプロンプトワード

prompt_template = """以下の内容を要約してください:

{text}

要約:"""
PROMPT = PromptTemplate(template=prompt_template, input_variables=["text"])
chain = load_summarize_chain(OpenAI(temperature=0), chain_type="map_reduce", return_intermediate_steps=True, map_prompt=PROMPT, combine_prompt=PROMPT)
chain({"input_documents": docs}, return_only_outputs=True)

refineタスクの例

chain_typeパラメーターをrefineに変更するだけです。

chain = load_summarize_chain(llm, chain_type="refine")
chain.run(docs)

refineタスクのカスタムプロンプトワードテンプレート

refineタスクのカスタムプロンプトワードの例を以下に示します。

prompt_template = """以下の内容を要約してください:

{text}

要約:"""

PROMPT = PromptTemplate(template=prompt_template, input_variables=["text"])

refine_template = (
    "最終的なテキスト要約を生成してください\n"
    "以下は既存の要約情報です: {existing_answer}\n"
    "新しいバックグラウンド情報に基づいて既存の要約を強化してください\n"
    "バックグラウンド情報は以下の通りです\n"
    "------------\n"
    "{text}\n"
    "------------\n"
    "バックグラウンド情報に基づいて既存の要約を強化してください\n"
    "バックグラウンド情報が役立たない場合は既存の要約情報を返してください。"
)
refine_prompt = PromptTemplate(
    input_variables=["existing_answer", "text"],
    template=refine_template,
)
chain = load_summarize_chain(OpenAI(temperature=0), chain_type="refine", return_intermediate_steps=True, question_prompt=PROMPT, refine_prompt=refine_prompt)
chain({"input_documents": docs}, return_only_outputs=True)