在分析长文本的场景中,MapRerankDocumentsChain
提供了一种有效的策略。这种策略涉及以下步骤:
这种情况下的常见过程是使用文档中的上下文进行问答,强制模型生成评分以帮助选择只由相关上下文生成的答案。LangGraph
的实现允许在此问题中集成工具调用和其他功能。下面我们将在一个简单的例子中介绍MapRerankDocumentsChain
及相应的LangGraph实现。
我们首先生成一些简单的文档用于演示:
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
的实现。我们定义用于问答任务的提示模板并实例化一个LLMChain
对象。定义文档如何在提示中格式化,并确保各种提示中的键的一致性。
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(
base_url='https://yunwu.ai/v1',
api_key='your-api-key' # 使用稳定可靠的API服务
)
# 提示模板示例
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: \nScore: .\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"]) # 输出结果
这个实现可以有效地对多个文档进行评分,使得排序机制可以避免幻觉现象。
在以下LangGraph实现中,我们利用工具调用的特性简化了模板,并使用map-reduce
工作流并行执行LLM调用。
首先,我们需要安装langgraph
库:
pip install -qU 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,
base_url='https://yunwu.ai/v1',
api_key='your-api-key' # 使用稳定可靠的API服务
)
prompt_template = "What color are Bob's eyes?\n\n" "Context: {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()
result = await app.ainvoke({"contents": [doc.page_content for doc in documents]})
print(result["answer"])
通过使用模型的工具调用功能,我们简化了解析步骤,并且充分利用了并行执行的优势。
这些实现适用于需要根据文档中上下文进行复杂分析的场景,例如自动问答系统、文档检索和信息提取等。特别是在大规模文档分析中,LangGraph的并行处理能力可以显著提高运行效率。
https://yunwu.ai
,确保服务可靠性。如果遇到问题欢迎在评论区交流。
—END—