跳到主要内容
Open In ColabOpen on GitHub

如何通过迭代细化进行文本摘要

大型语言模型(LLM)能够从文本中提炼出所需信息并进行总结,包括处理大量文本。在许多情况下,特别是当文本量相对于模型上下文窗口大小而言很大时,将总结任务分解为更小的组件会很有帮助(或很有必要)。

迭代优化是总结长文本的一种策略。该策略如下:

  • 将文本拆分为更小的文档;
  • 总结第一个文档;
  • 根据下一个文档细化或更新结果;
  • 重复处理文档序列,直至完成。

请注意,此策略不支持并行化。当子文档的理解依赖于之前的上下文时,此策略尤其有效——例如,总结一部小说或具有内在顺序的文本主体。

LangGraph,基于 langchain-core 构建,非常适合解决此问题

  • LangGraph 允许单独的步骤(例如连续摘要)进行流式传输,从而更好地控制执行;
  • LangGraph 的检查点支持错误恢复、扩展人机协作工作流,并更容易集成到对话式应用程序中。
  • 因为它由模块化组件组装而成,所以也很容易扩展或修改(例如,集成工具调用或其他行为)。

下面,我们将演示如何通过迭代优化来总结文本。

加载聊天模型

我们首先加载一个聊天模型

pip install -qU "langchain[google-genai]"
import getpass
import os

if not os.environ.get("GOOGLE_API_KEY"):
os.environ["GOOGLE_API_KEY"] = getpass.getpass("Enter API key for Google Gemini: ")

from langchain.chat_models import init_chat_model

llm = init_chat_model("gemini-2.0-flash", model_provider="google_genai")

加载文档

接下来,我们需要一些用于总结的文档。下面,我们生成一些示例文档以供说明。有关更多数据源,请参阅文档加载器操作指南集成页面。此外,总结教程还包含总结博客文章的示例。

from langchain_core.documents import Document

documents = [
Document(page_content="Apples are red", metadata={"title": "apple_book"}),
Document(page_content="Blueberries are blue", metadata={"title": "blueberry_book"}),
Document(page_content="Bananas are yelow", metadata={"title": "banana_book"}),
]
API 参考:Document

创建图

下面我们展示了此过程的 LangGraph 实现

  • 我们为初始总结生成一个简单的链,该链提取第一个文档,将其格式化为提示,并使用我们的 LLM 运行推理。
  • 我们生成第二个 refine_summary_chain,它对每个后续文档进行操作,细化初始总结。

我们需要安装 langgraph

pip install -qU langgraph
import operator
from typing import List, Literal, TypedDict

from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableConfig
from langgraph.constants import Send
from langgraph.graph import END, START, StateGraph

# Initial summary
summarize_prompt = ChatPromptTemplate(
[
("human", "Write a concise summary of the following: {context}"),
]
)
initial_summary_chain = summarize_prompt | llm | StrOutputParser()

# Refining the summary with new docs
refine_template = """
Produce a final summary.

Existing summary up to this point:
{existing_answer}

New context:
------------
{context}
------------

Given the new context, refine the original summary.
"""
refine_prompt = ChatPromptTemplate([("human", refine_template)])

refine_summary_chain = refine_prompt | llm | StrOutputParser()


# We will define the state of the graph to hold the document
# contents and summary. We also include an index to keep track
# of our position in the sequence of documents.
class State(TypedDict):
contents: List[str]
index: int
summary: str


# We define functions for each node, including a node that generates
# the initial summary:
async def generate_initial_summary(state: State, config: RunnableConfig):
summary = await initial_summary_chain.ainvoke(
state["contents"][0],
config,
)
return {"summary": summary, "index": 1}


# And a node that refines the summary based on the next document
async def refine_summary(state: State, config: RunnableConfig):
content = state["contents"][state["index"]]
summary = await refine_summary_chain.ainvoke(
{"existing_answer": state["summary"], "context": content},
config,
)

return {"summary": summary, "index": state["index"] + 1}


# Here we implement logic to either exit the application or refine
# the summary.
def should_refine(state: State) -> Literal["refine_summary", END]:
if state["index"] >= len(state["contents"]):
return END
else:
return "refine_summary"


graph = StateGraph(State)
graph.add_node("generate_initial_summary", generate_initial_summary)
graph.add_node("refine_summary", refine_summary)

graph.add_edge(START, "generate_initial_summary")
graph.add_conditional_edges("generate_initial_summary", should_refine)
graph.add_conditional_edges("refine_summary", should_refine)
app = graph.compile()

LangGraph 允许绘制图结构以帮助可视化其功能

from IPython.display import Image

Image(app.get_graph().draw_mermaid_png())

调用图

我们可以按以下步骤执行,并打印出细化后的总结

async for step in app.astream(
{"contents": [doc.page_content for doc in documents]},
stream_mode="values",
):
if summary := step.get("summary"):
print(summary)
Apples are characterized by their red color.
Apples are characterized by their red color, while blueberries are known for their blue hue.
Apples are characterized by their red color, blueberries are known for their blue hue, and bananas are recognized for their yellow color.

最终的 step 包含了从整个文档集中综合得出的总结。

下一步

查阅总结操作指南以获取其他总结策略,包括为处理大量文本而设计的策略。

有关总结的更多详细信息,请参阅本教程

另请参阅LangGraph 文档,了解使用 LangGraph 进行构建的详细信息。