引言
在处理长文本时,如何高效地分析并提取有用的信息成为了一个重要问题。本文将介绍一种常用的策略——MapRerankDocumentsChain,并探讨其在长文本分析中的应用。同时,我们将对比使用 LangGraph 实现的相似任务,展示如何通过改进的方法提升性能和简化流程。
主要内容
MapRerankDocumentsChain 原理
MapRerankDocumentsChain 是一种处理长文本的策略,其流程如下:
- 将文本分割为小块文档。
- 对每个文档进行评分。
- 根据评分对结果进行排序,返回最高分的结果。
这其中常用的过程是利用上下文来进行问答,这样可以确保模型生成的答案是基于相关上下文的。
LangGraph 实现的优势
LangGraph 提供了一种更为灵活和先进的实现方式。它通过工具调用(tool calling)等特性简化了过程。我们将通过一个简单的例子来展示两者的实现细节。
代码示例
下面的代码展示了如何使用 MapRerankDocumentsChain 和 LangGraph 对同一组文档进行分析。
# 使用API代理服务提高访问稳定性
from langchain_core.documents import Document
from langchain.chains import LLMChain, MapRerankDocumentsChain
from langchain.output_parsers.regex import RegexParser
from langchain_core.prompts import PromptTemplate
from langchain_openai import OpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langgraph.constants import Send
from langgraph.graph import END, START, StateGraph
# 定义示例文档
documents = [
Document(page_content="Alice has blue eyes", metadata={"title": "book_chapter_2"}),
Document(page_content="Bob has brown eyes", metadata={"title": "book_chapter_1"}),
Document(page_content="Charlie has green eyes", metadata={"title": "book_chapter_3"}),
]
# 设置LLMChain和MapRerankDocumentsChain
document_variable_name = "context"
llm = OpenAI()
prompt_template = ("What color are Bob's eyes? Output both your answer and a score (1-10)... 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")
response = chain.invoke(documents)
print(response["output_text"]) # 输出:'Brown'
# 设置LangGraph
from typing import Annotated, List, TypedDict
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? Context: {context}"
prompt = ChatPromptTemplate.from_template(prompt_template)
# 定义图结构和映射
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()
result = await app.ainvoke({"contents": [doc.page_content for doc in documents]})
print(result["answer"]) # 输出:{'answer': 'Bob has brown eyes.', 'score': 10}
常见问题和解决方案
- 网络限制问题:由于某些地区的网络限制,API访问可能不稳定。开发者可以考虑使用API代理服务,以提高访问稳定性。
- 准确性问题:在使用评分机制时,确保模型的输出格式符合预期,以避免解析错误。
总结和进一步学习资源
本文讨论了使用 MapRerankDocumentsChain 以及 LangGraph 的方法来进行文本分析。LangGraph 提供了更简洁的结构和更强的功能扩展能力。对于想要深入了解的读者,可以参考以下资源:
参考资料
- LangChain Documentation: www.langchain.com/docs/
- LangGraph Introduction: www.langgraph.com/
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---