langchain源码剖析 Chains系列(二)

StuffDocumentsChain

快速开始

python 复制代码
from langchain.chains import StuffDocumentsChain, LLMChain
from langchain.prompts import PromptTemplate
from langchain.chat_models import ChatOpenAI
from langchain.schema import Document


document_prompt = PromptTemplate(
    input_variables=["page_content"],
     template="{page_content}"
)
document_variable_name = "context"
llm = ChatOpenAI()

prompt = PromptTemplate.from_template(
    "Summarize this content: {context} in Chinese"
)
llm_chain = LLMChain(llm=llm, prompt=prompt)
chain = StuffDocumentsChain(
    llm_chain=llm_chain,
    document_prompt=document_prompt,
    document_variable_name=document_variable_name,
    verbose=True,
)
# {'input_documents': [Document(page_content='5.2.6新员工转为正式员工后由人事行政部以邮件形式发出《转正通知单》的形式以通知转正人员相关\n事宜。6.转正类别转正可分为提前转正、按期转正、终止试用四个类别。\n6.1提前转正:新员工入职三个月以后,确因工作态度、工作绩效、团队融合表现突出者,部门负责人\n可为员工申请提前转正。并依据本办法5.2试用期满评估程序实施转正。\n6.2按期转正:依据本办法5.2试用期满评估程序实施转正。\n6.3终止试用\n6.3.1试用期员工在试用期如不能认同企业文化,感到公司状况与个人预期差距较大或者其它原因决定\n离开公司的,可提出辞职,但应提前3日以书面形式提交辞职报告。\n6.3.2试用期员工在试用期间如不能达到公司岗位任职要求,公司可随时停止试用,予以辞退。\n6.3.3试用期员工在试用期间有严重违反公司规章制度行为并造成不良影响的,公司可随时停止试用,\n予以辞退。\n6.3.4终止试用的员工,至人事行政部办理离职手续。7.转正日期新员工如果提前转正,则转正日期以最终审批的提前转正日期为准;如果按期转正,新员工的转正日期\n为试用期满之日。8.其他及附件8.1本办法自发布之日起生效。\n8.2附件\n《月度工作计划表》\n《试用期转正述职报告》\n《转正述职与答辩评分表》\n《试用期转正评估表》\n《员工转正通知书》\n二○一九年八月[COMPANY_NAME_CN]', metadata={'source': '试用期评估及转正管理办法.pdf', 'page': 1}), Document(page_content='试用期评估及转正管理办法\n1目的\n为帮助员工发展、统一员工在试用期内评估及转正要求与流程,明确各相关部门的工作职责,特制定本\n办法。\n2适用范围\n本办法适用于公司所有新进员工。\n3定义\n3.1试用期:指劳动合同期限内公司与员工为相互了解对方而约定的考察期间。\n3.2试用期期限根据相关劳动法律法规及工作岗位性质确定。\n3.3转正:指新员工试用期满,达到岗位任职资格,并按规定办完相应手续后,成为公司的正式员工。\n4各方权责\n4.1试用期员工的权责\n主动了解自己的工作职责与工作内容、工作目标、公司文化等各项规章制度;\n接受人力部门的入职培训与相关评估;\n4.2试用期各部门负责人的权责\n在工作中引导新员工领悟并融入公司的文化、督促并指导其执行公司各项任务、工作须知及管理制度;\n帮助新员工,使其了解并掌握所任职岗位的岗位职责、内容、目标与岗位应知应会;\n4.3人事行政部的权责\n培训新员工有关公司的组织、文化、发展、管理制度及日常办公工作须知等;\n负责试用期员工的评估执行。\n5试用期评估\n试用期员工的评估分为两种形式:中间评估与期满综合评估。中间评估自入职之日起试用期内分阶段(每\n阶段按月或者按照季度设定)进行,期满综合评估在试用期结束时进行。\n5.1中间评估程序\n5.1.1部门负责人必须在入职第一个月内与新员工确定阶段性(月度或者季度)工作目标。\n5.1.2在阶段结束时,部门负责人与新员工对本阶段学习任务与工作目标达成情况以及下阶段工作计划\n与目标进行沟通,对新员工遇到的疑问进行合理解答,对新员工遇到的困难进行及时解决。\n5.1.3中间评估完成后由部门负责人批准将表格原件备案至人事行政部,人事行政部对月度评估表的合\n理性进行评估确认。\n5.2试用期满综合评估\n5.2.1试用期期满前10天,人事行政部将试用期《试用期转正述职报告模板》发给新员工,抄送部门\n负责人;将《试用期转正评估表》发给部门负责人;\n5.2.2新员工填写《试用期转正述职报告模板》,对试用期间的学习与工作心得进行总结,于转正期满\n前一周完成并交部门负责人审核,交人事行政部备案;\n5.2.3部门负责人初步考核通过后,人事行政部安排新员工转正述职,邀请关联团队经理、部门负责人、\n公司负责人、HR作为评审人员参与转正述职评审;\n5.2.4评审人员根据新员工现场述职、述职材料、既往的中间评估给予综合评分,最终评分≥3.5分方\n为通过转正述职评估;\n5.2.5部门负责人需于新员工试用期满前3天完成《试用期转正评估表》;', metadata={'source': '试用期评估及转正管理办法.pdf', 'page': 0})], 'output_text': '根据该内容,公司在员工试用期结束后,人事行政部会通过邮件形式发送转正通知单来通知员工转正的相关事宜。转正的类别可分为提前转正、按期转正和终止试用三个类别。提前转正是指在员工入职三个月后,如果工作态度、工作绩效和团队融合表现突出,部门负责人可以为员工申请提前转正。按期转正是根据试用期满后的评估程序来进行转正。终止试用是指在试用期内,员工不能认同公司文化、感到公司状况与个人预期差距大,或者有其他原因决定离开公司时,可以提出辞职。试用期员工还有严重违反公司规章制度行为并造成不良影响时,公司也可以停止试用并辞退员工。转正日期根据最终审批的提前转正日期或试用期满的日期来确定。此外,还有一些附件文件,包括月度工作计划表、试用期转正述职报告、转正述职与答辩评分表、试用期转正评估表和员工转正通知书。该办法适用于公司所有新进员工,旨在帮助员工发展并明确各部门的工作职责。员工在试用期需要了解自己的工作职责和公司规章制度,接受入职培训和评估。试用期中,部门负责人需要引导新员工融入公司文化,指导其执行任务和管理制度。人事行政部负责培训新员工并进行试用期员工的评估执行。评估分为中间评估和期满综合评估两种形式。中间评估在试用期内分阶段进行,而期满综合评估在试用期结束时进行。'}
print(chain([Document(page_content='5.2.6新员工转为正式员工后由人事行政部以邮件形式发出《转正通知单》的形式以通知转正人员相关\n事宜。6.转正类别转正可分为提前转正、按期转正、终止试用四个类别。\n6.1提前转正:新员工入职三个月以后,确因工作态度、工作绩效、团队融合表现突出者,部门负责人\n可为员工申请提前转正。并依据本办法5.2试用期满评估程序实施转正。\n6.2按期转正:依据本办法5.2试用期满评估程序实施转正。\n6.3终止试用\n6.3.1试用期员工在试用期如不能认同企业文化,感到公司状况与个人预期差距较大或者其它原因决定\n离开公司的,可提出辞职,但应提前3日以书面形式提交辞职报告。\n6.3.2试用期员工在试用期间如不能达到公司岗位任职要求,公司可随时停止试用,予以辞退。\n6.3.3试用期员工在试用期间有严重违反公司规章制度行为并造成不良影响的,公司可随时停止试用,\n予以辞退。\n6.3.4终止试用的员工,至人事行政部办理离职手续。7.转正日期新员工如果提前转正,则转正日期以最终审批的提前转正日期为准;如果按期转正,新员工的转正日期\n为试用期满之日。8.其他及附件8.1本办法自发布之日起生效。\n8.2附件\n《月度工作计划表》\n《试用期转正述职报告》\n《转正述职与答辩评分表》\n《试用期转正评估表》\n《员工转正通知书》\n二○一九年八月[COMPANY_NAME_CN]', metadata={'source': '试用期评估及转正管理办法.pdf', 'page': 1}), Document(page_content='试用期评估及转正管理办法\n1目的\n为帮助员工发展、统一员工在试用期内评估及转正要求与流程,明确各相关部门的工作职责,特制定本\n办法。\n2适用范围\n本办法适用于公司所有新进员工。\n3定义\n3.1试用期:指劳动合同期限内公司与员工为相互了解对方而约定的考察期间。\n3.2试用期期限根据相关劳动法律法规及工作岗位性质确定。\n3.3转正:指新员工试用期满,达到岗位任职资格,并按规定办完相应手续后,成为公司的正式员工。\n4各方权责\n4.1试用期员工的权责\n主动了解自己的工作职责与工作内容、工作目标、公司文化等各项规章制度;\n接受人力部门的入职培训与相关评估;\n4.2试用期各部门负责人的权责\n在工作中引导新员工领悟并融入公司的文化、督促并指导其执行公司各项任务、工作须知及管理制度;\n帮助新员工,使其了解并掌握所任职岗位的岗位职责、内容、目标与岗位应知应会;\n4.3人事行政部的权责\n培训新员工有关公司的组织、文化、发展、管理制度及日常办公工作须知等;\n负责试用期员工的评估执行。\n5试用期评估\n试用期员工的评估分为两种形式:中间评估与期满综合评估。中间评估自入职之日起试用期内分阶段(每\n阶段按月或者按照季度设定)进行,期满综合评估在试用期结束时进行。\n5.1中间评估程序\n5.1.1部门负责人必须在入职第一个月内与新员工确定阶段性(月度或者季度)工作目标。\n5.1.2在阶段结束时,部门负责人与新员工对本阶段学习任务与工作目标达成情况以及下阶段工作计划\n与目标进行沟通,对新员工遇到的疑问进行合理解答,对新员工遇到的困难进行及时解决。\n5.1.3中间评估完成后由部门负责人批准将表格原件备案至人事行政部,人事行政部对月度评估表的合\n理性进行评估确认。\n5.2试用期满综合评估\n5.2.1试用期期满前10天,人事行政部将试用期《试用期转正述职报告模板》发给新员工,抄送部门\n负责人;将《试用期转正评估表》发给部门负责人;\n5.2.2新员工填写《试用期转正述职报告模板》,对试用期间的学习与工作心得进行总结,于转正期满\n前一周完成并交部门负责人审核,交人事行政部备案;\n5.2.3部门负责人初步考核通过后,人事行政部安排新员工转正述职,邀请关联团队经理、部门负责人、\n公司负责人、HR作为评审人员参与转正述职评审;\n5.2.4评审人员根据新员工现场述职、述职材料、既往的中间评估给予综合评分,最终评分≥3.5分方\n为通过转正述职评估;\n5.2.5部门负责人需于新员工试用期满前3天完成《试用期转正评估表》;', metadata={'source': '试用期评估及转正管理办法.pdf', 'page': 0})]))

StuffChain首先接收一个文档列表作为输入。每个文档都被格式化成一个字符串,这是通过document_prompt实现的。然后,这些字符串用document_separator连接成一个大的字符串,这可以是你选择的任何字符或短语。这个大的字符串被添加到inputs中,并以document_variable_name设置的变量名命名。最后,inputs(现在含有你的合并文档字符串)被传递到llm_chain进行进一步的处理。 这个过程基本上是将多个文档压缩成一个单一的字符串,使得语言模型可以将它们视为一个实体进行处理。

自定义prompt

python 复制代码
from langchain.chains import StuffDocumentsChain, LLMChain
from langchain.prompts import PromptTemplate
from langchain.chat_models import ChatOpenAI
from langchain.schema import Document


document_prompt = PromptTemplate(
    input_variables=["page_content"],
    template="{page_content}"
)
document_variable_name = "context"
llm = ChatOpenAI()

prompt = PromptTemplate.from_template(
    """Use the following pieces of context to answer the question at the end: {context},
    question: {question}"""
)
llm_chain = LLMChain(llm=llm, prompt=prompt)
chain = StuffDocumentsChain(
    llm_chain=llm_chain,
    document_prompt=document_prompt,
    document_variable_name=document_variable_name,
    verbose=True,
)
input = {'input_documents': [Document(page_content='5.2.6新员工转为正式员工后由人事行政部以邮件形式发出《转正通知单》的形式以通知转正人员相关\n事宜。6.转正类别转正可分为提前转正、按期转正、终止试用四个类别。\n6.1提前转正:新员工入职三个月以后,确因工作态度、工作绩效、团队融合表现突出者,部门负责人\n可为员工申请提前转正。并依据本办法5.2试用期满评估程序实施转正。\n6.2按期转正:依据本办法5.2试用期满评估程序实施转正。\n6.3终止试用\n6.3.1试用期员工在试用期如不能认同企业文化,感到公司状况与个人预期差距较大或者其它原因决定\n离开公司的,可提出辞职,但应提前3日以书面形式提交辞职报告。\n6.3.2试用期员工在试用期间如不能达到公司岗位任职要求,公司可随时停止试用,予以辞退。\n6.3.3试用期员工在试用期间有严重违反公司规章制度行为并造成不良影响的,公司可随时停止试用,\n予以辞退。\n6.3.4终止试用的员工,至人事行政部办理离职手续。7.转正日期新员工如果提前转正,则转正日期以最终审批的提前转正日期为准;如果按期转正,新员工的转正日期\n为试用期满之日。8.其他及附件8.1本办法自发布之日起生效。\n8.2附件\n《月度工作计划表》\n《试用期转正述职报告》\n《转正述职与答辩评分表》\n《试用期转正评估表》\n《员工转正通知书》\n二○一九年八月[COMPANY_NAME_CN]', metadata={'source': '试用期评估及转正管理办法.pdf', 'page': 1}), Document(page_content='试用期评估及转正管理办法\n1目的\n为帮助员工发展、统一员工在试用期内评估及转正要求与流程,明确各相关部门的工作职责,特制定本\n办法。\n2适用范围\n本办法适用于公司所有新进员工。\n3定义\n3.1试用期:指劳动合同期限内公司与员工为相互了解对方而约定的考察期间。\n3.2试用期期限根据相关劳动法律法规及工作岗位性质确定。\n3.3转正:指新员工试用期满,达到岗位任职资格,并按规定办完相应手续后,成为公司的正式员工。\n4各方权责\n4.1试用期员工的权责\n主动了解自己的工作职责与工作内容、工作目标、公司文化等各项规章制度;\n接受人力部门的入职培训与相关评估;\n4.2试用期各部门负责人的权责\n在工作中引导新员工领悟并融入公司的文化、督促并指导其执行公司各项任务、工作须知及管理制度;\n帮助新员工,使其了解并掌握所任职岗位的岗位职责、内容、目标与岗位应知应会;\n4.3人事行政部的权责\n培训新员工有关公司的组织、文化、发展、管理制度及日常办公工作须知等;\n负责试用期员工的评估执行。\n5试用期评估\n试用期员工的评估分为两种形式:中间评估与期满综合评估。中间评估自入职之日起试用期内分阶段(每\n阶段按月或者按照季度设定)进行,期满综合评估在试用期结束时进行。\n5.1中间评估程序\n5.1.1部门负责人必须在入职第一个月内与新员工确定阶段性(月度或者季度)工作目标。\n5.1.2在阶段结束时,部门负责人与新员工对本阶段学习任务与工作目标达成情况以及下阶段工作计划\n与目标进行沟通,对新员工遇到的疑问进行合理解答,对新员工遇到的困难进行及时解决。\n5.1.3中间评估完成后由部门负责人批准将表格原件备案至人事行政部,人事行政部对月度评估表的合\n理性进行评估确认。\n5.2试用期满综合评估\n5.2.1试用期期满前10天,人事行政部将试用期《试用期转正述职报告模板》发给新员工,抄送部门\n负责人;将《试用期转正评估表》发给部门负责人;\n5.2.2新员工填写《试用期转正述职报告模板》,对试用期间的学习与工作心得进行总结,于转正期满\n前一周完成并交部门负责人审核,交人事行政部备案;\n5.2.3部门负责人初步考核通过后,人事行政部安排新员工转正述职,邀请关联团队经理、部门负责人、\n公司负责人、HR作为评审人员参与转正述职评审;\n5.2.4评审人员根据新员工现场述职、述职材料、既往的中间评估给予综合评分,最终评分≥3.5分方\n为通过转正述职评估;\n5.2.5部门负责人需于新员工试用期满前3天完成《试用期转正评估表》;', metadata={'source': '试用期评估及转正管理办法.pdf', 'page': 0})]}
input["question"] = "新员工怎么转正"
result = chain(input)
print(result.keys())  # dict_keys(['input_documents', 'question', 'output_text'])
print(result["output_text"])  # 新员工可以通过提前转正或按期转正的方式转正。对于提前转正,新员工需在入职三个月后,凭借出色的工作态度、工作绩效和团队融合表现,由部门负责人申请提前转正,并按照试用期满评估程序实施转正。对于按期转正,新员工需在试用期满后,按照试用期满评估程序实施转正。具体的转正日期根据最终审批的提前转正日期或试用期满之日确定。

StuffDocumentsChain类扮演这样一个角色------处理、组合和准备相关文档,以便进一步处理和回答问题。当需要处理的提示(prompt)同时需要上下文(context)和问题(question)时,我们的输入是一个字典。这个字典包含两个键值对:'input_documents'和'question',其中'input_documents'是BaseCombineDocumentsChain关注的主要部分。BaseCombineDocumentsChain的input_key属性的默认值就是'input_documents'。这意味着当我们实例化这个类并调用它的方法时,它会根据input_key从输入字典中获取相应的文档。

一旦获取了输入文档,BaseCombineDocumentsChain会执行其_combine_docs方法。这个方法将所有相关的文档合并成一个单一的字符串。这个字符串通常包含所有文档的核心内容,是我们后续进行语言模型处理的基础。

输出准备 生成这个合并后的字符串之后,BaseCombineDocumentsChain会将其放入输入字典中,并且使用document_variable_name作为新的键。在许多情况下,我们选择"context"作为这个键,因为这个字符串实际上就是我们希望模型处理的上下文信息。所以,在执行完BaseCombineDocumentsChain的操作后,输入字典会新增一个条目:'context'。其值就是由_combine_docs方法得到的字符串。

进一步使用 完成上述操作后,新的输入字典就可以作为语言模型链(LLM Chain)的输入了。LLM Chain将使用这个"context"(即合并后的文档字符串),并加上"question"(即用户问题),进一步利用这些数据生成答案。

源码分析

BaseCombineDocumentsChain是一个抽象基类,它定义了一种处理文档组合的通用接口。这个基类的主要目的是为了实现各种子类链处理逻辑的统一性。特别地,每个子类都需要通过定义一个与待处理文档相关的输入键(默认为 input_documents)来实现这个接口,并需要公开一个计算给定文档的提示长度的方法。这个方法允许外部调用者预先判断将一系列文档传递给此链是否安全,或者是否可能超过上下文长度限制。

StuffDocumentChainBaseCombineDocumentsChain 的一个具体子类,它采用一种特定的方式来组合文档。需要注意的是,BaseCombineDocumentsChain 类中的 _call 方法有效地实现了模板方法设计模式:它定义了操作文档的基本步骤或"骨架",而具体的 combine_docs 步骤则由子类进行实现。

下面是StuffDocumentChain和BaseCombineDocumentsChain的UML类图:

BaseCombineDocumentsChain

python 复制代码
class BaseCombineDocumentsChain(Chain, ABC):
    """Base interface for chains combining documents."""

    input_key: str = "input_documents"  
    output_key: str = "output_text"  

    @property
    def input_keys(self) -> List[str]:
        return [self.input_key]

    @property
    def output_keys(self) -> List[str]:
        return [self.output_key]

    def prompt_length(self, docs: List[Document], **kwargs: Any) -> Optional[int]:
        return None
		

    @abstractmethod
    def combine_docs(self, docs: List[Document], **kwargs: Any) -> Tuple[str, dict]:


    def _call(
        self,
        inputs: Dict[str, List[Document]],
        run_manager: Optional[CallbackManagerForChainRun] = None,
    ) -> Dict[str, str]:
        """Prepare inputs, call combine docs, prepare outputs."""
        _run_manager = run_manager or CallbackManagerForChainRun.get_noop_manager()
        docs = inputs[self.input_key]
        # Other keys are assumed to be needed for LLM prediction
        other_keys = {k: v for k, v in inputs.items() if k != self.input_key}
        output, extra_return_dict = self.combine_docs(
            docs, callbacks=_run_manager.get_child(), **other_keys
        )
        extra_return_dict[self.output_key] = output
        return extra_return_dict

属性:

  • input_key:输入键,该属性确定从哪个键名中提取文档,默认值为 "input_documents"。
  • output_key:输出键,该属性确定将最终结果保存在哪个键名下,默认值为 "output_text"。

方法:

  • input_keys(辅助方法):返回一个列表,其中包含所有的输入键名。
  • output_keys(辅助方法):返回一个列表,其中包含所有的输出键名。
  • prompt_length:给定一系列文档,此方法计算提示长度。这是为了让调用者能够判断是否有超过某个长度限制。如果不需要考虑提示长度,则返回 None;否则返回提示的token数。
  • combine_docs(抽象方法):将多个文档合并成一个字符串。这是需要由子类实现的方法。第一个返回值是输出的单一字符串,第二个返回值是一个字典,其中包含了其他需要返回的键和对应的值。
  • _call:此方法用于准备输入,调用combine_docs,并准备输出。它首先从输入中提取文档,然后假定除输入键以外的其他所有键都是语言模型预测所必需的信息。接着调用combine_docs方法,并将结果与额外的返回字典一起作为输出返回。
python 复制代码
def _call(
        self,
        inputs: Dict[str, List[Document]],  # A dictionary where each key is a string and each value is a list of Document objects
        run_manager: Optional[CallbackManagerForChainRun] = None,  # An optional argument for managing the running callback
    ) -> Dict[str, str]:  # Returned dictionary where each key is a string and its corresponding value is also a string
        """Prepare inputs, call combine_docs, prepare outputs."""
        
        # Assign a non-operational callback manager if not explicitly provided
        _run_manager = run_manager or CallbackManagerForChainRun.get_noop_manager()
        
        # Extract documents from the input dictionary
        docs = inputs[self.input_key]
        
        # Assume other keys, apart from input_key, are necessary for language model (LLM) prediction
        other_keys = {k: v for k, v in inputs.items() if k != self.input_key}
        
        # Call the combine_docs method with docs and other_keys as arguments
        output, extra_return_dict = self.combine_docs(
            docs, callbacks=_run_manager.get_child(), **other_keys
        )
        
        # Add output to the dictionary under the specified output_key
        extra_return_dict[self.output_key] = output

        # Return the dictionary containing all returned values including the generated output
        return extra_return_dict

总的来说,这个类定义了如何接收和处理文档列表,如何计算提示长度,以及如何将多个文档合并成一个字符串,但具体的合并流程需要由其子类来实现。

StuffDocumentsChain

python 复制代码
class StuffDocumentsChain(BaseCombineDocumentsChain):
    """Chain that combines documents by stuffing into context."""

    llm_chain: LLMChain
    """LLM chain which is called with the formatted document string,
    along with any other inputs."""
    document_prompt: BasePromptTemplate = Field(
        default_factory=_get_default_document_prompt
    )
    """Prompt to use to format each document, gets passed to `format_document`."""
    document_variable_name: str
    """The variable name in the llm_chain to put the documents in.
    If only one variable in the llm_chain, this need not be provided."""
    document_separator: str = "\n\n"
    """The string with which to join the formatted documents"""

    def _get_inputs(self, docs: List[Document], **kwargs: Any) -> dict:
        # Format each document according to the prompt
        doc_strings = [format_document(doc, self.document_prompt) for doc in docs]
        # Join the documents together to put them in the prompt.
        inputs = {
            k: v
            for k, v in kwargs.items()
            if k in self.llm_chain.prompt.input_variables
        }
        inputs[self.document_variable_name] = self.document_separator.join(doc_strings)
        return inputs

    def prompt_length(self, docs: List[Document], **kwargs: Any) -> Optional[int]:
        inputs = self._get_inputs(docs, **kwargs)
        prompt = self.llm_chain.prompt.format(**inputs)
        return self.llm_chain.llm.get_num_tokens(prompt)

    def combine_docs(
        self, docs: List[Document], callbacks: Callbacks = None, **kwargs: Any
    ) -> Tuple[str, dict]:
        """Stuff all documents into one prompt and pass to LLM."""
        inputs = self._get_inputs(docs, **kwargs)
        # Call predict on the LLM.
        return self.llm_chain.predict(callbacks=callbacks, **inputs), {}


    @property
    def _chain_type(self) -> str:
        return "stuff_documents_chain"

核心方法combine_docs内部是准备了输入,然后调用下一级的chain: llm_chain, _get_inputs就是组合了文档成一个字符串,然后用document_variable_name这个key来保持,最后得到一个dict作为下一级chain的输入, document_variable_name 必须是llm_chain中prompt的变量。

检索问答RetrievalQA

快速开始

python 复制代码
from langchain.chains import RetrievalQA
from langchain.document_loaders import PyPDFLoader
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.text_splitter import CharacterTextSplitter
from langchain.chat_models import ChatOpenAI

loader = PyPDFLoader("试用期评估及转正管理办法.pdf")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents=documents)

embeddings = OpenAIEmbeddings()
docsearch = Chroma.from_documents(texts, embeddings)

qa = RetrievalQA.from_chain_type(llm=ChatOpenAI(), chain_type="stuff", retriever=docsearch.as_retriever())
query = "转正的流程是什么?"
"""
转正的流程如下:
1. 试用期评估:在入职后的试用期内,会进行中间评估和期满综合评估。中间评估是在试用期内的一定阶段进行,部门负责人与新员工沟通工作目标和计划,解答问题和解决困难。期满综合评估是试用期结束时进行,新员工需要填写《试用期转正述职报告》,并经部门负责人审核后进行转正述职评审。

2. 转正申请:根据公司的规定,可以分为提前转正、按期转正和终止试用三种情况。员工在试用期结束前10天,人事行政部会发出《试用期转正述职报告模板》和《试用期转正评估表》给新员工和部门负责人。

3. 转正述职评审:新员工填写《试用期转正述职报告模板》,总结试用期的学习和工作心得,由部门负责人审核后交给人事行政部备案。然后,人事行政部会安排新员工进行转正述职,邀请相关人员参与评审,根据现场述职、述职材料和中间评估结果给予综合评分。

4. 转正决定:根据评审人员的综合评分,如果评分达到3.5分及以上,即通过转正述职评估。

5. 转正通知:人事行政部会以邮件形式发出《转正通知单》通知转正人员相关事宜。

请注意,具体的转正流程可能会因公司而异,以上是一般的转正流程。
"""
print(qa.run(query))

自定义提示

python 复制代码
from langchain.chains import RetrievalQA
from langchain.document_loaders import PyPDFLoader
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.text_splitter import CharacterTextSplitter
from langchain.chat_models import ChatOpenAI
from langchain.prompts import PromptTemplate


loader = PyPDFLoader("试用期评估及转正管理办法.pdf")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents=documents)

embeddings = OpenAIEmbeddings()
docsearch = Chroma.from_documents(texts, embeddings)

prompt_template = """Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.

{context}

Question: {question}
Answer in English:"""
PROMPT = PromptTemplate(
    template=prompt_template, input_variables=["context", "question"]
)
chain_type_kwargs = {"prompt": PROMPT}
qa = RetrievalQA.from_chain_type(
    llm=ChatOpenAI(),
    chain_type="stuff",
    retriever=docsearch.as_retriever(),
    chain_type_kwargs=chain_type_kwargs
)
query = "转正的流程是什么?"
"""
The process for conversion to regular employment includes the following steps:
1. The human resources administration department sends out a "Confirmation Notice" via email to inform the employee of their conversion to regular status.
2. There are four categories for conversion: early conversion, conversion on schedule, termination of probation, and probation termination for serious misconduct.
3. Early conversion can be requested by the department head for employees who have been with the company for three months or more and have demonstrated outstanding work attitude, performance, and team integration.
4. On-schedule conversion is implemented based on the evaluation process at the end of the probation period.
5. Termination of probation can occur if the probationary employee does not identify with the company culture, feels a significant gap between company conditions and personal expectations, or for other reasons. The employee must submit a written resignation report three days in advance.
6. Probationary employees who fail to meet job requirements during the probation period may be terminated at any time.
7. Probationary employees who engage in serious violations of company rules and regulations that have a negative impact may be terminated at any time.
8. Employees whose probation is terminated must go through the departure procedures in the human resources administration department.
9. The conversion date for new employees is determined based on whether it is an early conversion or an on-schedule conversion. The early conversion date is determined by the final approval, while the on-schedule conversion date is the end of the probation period.
10. The probation evaluation and conversion management measures come into effect upon publication, and additional attachments include the Monthly Work Plan, Probationary Conversion Job Performance Report, Probationary Conversion Job Performance and Defense Evaluation Form, Probationary Conversion Evaluation Form, and Employee Confirmation Notice.
"""
print(qa.run(query))

返回源文档

python 复制代码
from langchain.chains import RetrievalQA
from langchain.document_loaders import PyPDFLoader
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.text_splitter import CharacterTextSplitter
from langchain.chat_models import ChatOpenAI
from langchain.prompts import PromptTemplate


loader = PyPDFLoader("试用期评估及转正管理办法.pdf")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents=documents)

embeddings = OpenAIEmbeddings()
docsearch = Chroma.from_documents(texts, embeddings)

prompt_template = """Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.

{context}

Question: {question}
Answer in English:"""
PROMPT = PromptTemplate(
    template=prompt_template, input_variables=["context", "question"]
)
chain_type_kwargs = {"prompt": PROMPT}
qa = RetrievalQA.from_chain_type(
    llm=ChatOpenAI(),
    chain_type="stuff",
    retriever=docsearch.as_retriever(),
    chain_type_kwargs=chain_type_kwargs,
    return_source_documents=True,
)
query = "转正的流程是什么?"
"""
{'query': '转正的流程是什么?', 'result': 'The process of becoming a regular employee includes the following steps:\n1. The Human Resources Administration Department sends a "Confirmation Notice" to the employee via email after they have been converted to a regular employee.\n2. There are four categories for conversion: early conversion, on-time conversion, and termination of probation.\n3. Early conversion is possible for employees who have been with the company for more than three months and have demonstrated outstanding work attitude, performance, and team integration. The department manager can apply for early conversion based on the evaluation process outlined in Section 5.2.\n4. On-time conversion is based on the evaluation process outlined in Section 5.2.\n5. Termination of probation can occur if the probationary employee does not identify with the company culture, feels a significant difference between the company's situation and personal expectations, or for other reasons. The employee can submit a resignation letter in writing three days in advance.\n6. The company can terminate the probationary period at any time if the probationary employee does not meet the job requirements or violates company rules and regulations, causing adverse effects.\n7. Employees who have their probation terminated must complete the departure procedures at the Human Resources Administration Department.\n8. The conversion date depends on whether the employee is early or on-time. If the employee is early, the conversion date is based on the approved early conversion date. If the employee is on-time, the conversion date is the last day of the probationary period.', 'source_documents': [Document(page_content='5.2.6新员工转为正式员工后由人事行政部以邮件形式发出《转正通知单》的形式以通知转正人员相关\n事宜。6.转正类别转正可分为提前转正、按期转正、终止试用四个类别。\n6.1提前转正:新员工入职三个月以后,确因工作态度、工作绩效、 团队融合表现突出者,部门负责人\n可为员工申请提前转正。并依据本办法5.2试用期满评估程序实施转正。\n6.2按期转正:依据本办法5.2试用期满评估程序实施转正。\n6.3终止试用\n6.3.1试用期员工在试用期如不能认同企业文化,感到公司状况与个人预期差距较大或者其 它原因决定\n离开公司的,可提出辞职,但应提前3日以书面形式提交辞职报告。\n6.3.2试用期员工在试用期间如不能达到公司岗位任职要求,公司可随时停止试用,予以辞退。\n6.3.3试用期员工在试用期间有严重违反公司规章制度行为并造成不良影响的,公司可随时停止试 用,\n予以辞退。\n6.3.4终止试用的员工,至人事行政部办理离职手续。7.转正日期新员工如果提前转正,则转正日期以最终审批的提前 转正日期为准;如果按期转正,新员工的转正日期\n为试用期满之日。8.其他及附件8.1本办法自发布之日起生效。\n8.2附件\n《月度工作计划表》\n《试用期转正述职报告》\n《转正述职与答辩评分表》\n《试用期转正评估表》\n《员工转正通知书》\n二○一九年八月[COMPANY_NAME_CN]', metadata={'source': '试用期评估及转正管理办法.pdf', 'page': 1}), Document(page_content='试用期评估及转正管理 办法\n1目的\n为帮助员工发展、统一员工在试用期内评估及转正要求与流程,明确各相关部门的工作职责,特制定本\n办法。\n2适用范围\n本办法适用于公司所有新进员工。\n3定义\n3.1试用期:指劳动合同期限内公司与员工为相互了解对方而约定的考察期间。\n3.2试用期 期限根据相关劳动法律法规及工作岗位性质确定。\n3.3转正:指新员工试用期满,达到岗位任职资格,并按规定办完相应手续后,成为公 司的正式员工。\n4各方权责\n4.1试用期员工的权责\n主动了解自己的工作职责与工作内容、工作目标、公司文化等各项规章制度;\n接受人力部门的入职培训与相关评估;\n4.2试用期各部门负责人的权责\n在工作中引导新员工领悟并融入公司的文化、督促并指导其执行公司 各项任务、工作须知及管理制度;\n帮助新员工,使其了解并掌握所任职岗位的岗位职责、内容、目标与岗位应知应会;\n4.3人事行政部 的权责\n培训新员工有关公司的组织、文化、发展、管理制度及日常办公工作须知等;\n负责试用期员工的评估执行。\n5试用期评估\n试 用期员工的评估分为两种形式:中间评估与期满综合评估。中间评估自入职之日起试用期内分阶段(每\n阶段按月或者按照季度设定)进行,期满综合评估在试用期结束时进行。\n5.1中间评估程序\n5.1.1部门负责人必须在入职第一个月内与新员工确定阶段性(月度或者季度)工作目标。\n5.1.2在阶段结束时,部门负责人与新员工对本阶段学习任务与工作目标达成情况以及下阶段工作计划\n与目标进行沟通,对 新员工遇到的疑问进行合理解答,对新员工遇到的困难进行及时解决。\n5.1.3中间评估完成后由部门负责人批准将表格原件备案至人事行 政部,人事行政部对月度评估表的合\n理性进行评估确认。\n5.2试用期满综合评估\n5.2.1试用期期满前10天,人事行政部将试用期《试用期转正述职报告模板》发给新员工,抄送部门\n负责人;将《试用期转正评估表》发给部门负责人;\n5.2.2新员工填写《试用期转正述职 报告模板》,对试用期间的学习与工作心得进行总结,于转正期满\n前一周完成并交部门负责人审核,交人事行政部备案;\n5.2.3部门负 责人初步考核通过后,人事行政部安排新员工转正述职,邀请关联团队经理、部门负责人、\n公司负责人、HR作为评审人员参与转正述职评审;\n5.2.4评审人员根据新员工现场述职、述职材料、既往的中间评估给予综合评分,最终评分
"""
print(qa(query))

源码分析

BaseRetrievalQA

BaseRetrievalQA是我们问答(QA)系统的重要组成部分,其主要功能是根据特定的查询找到相关的文档,并基于这些文档生成答案。该类与BaseCombineDocumentsChain紧密关联,后者负责处理一组文档。因此,为了给BaseCombineDocumentsChain提供输入,BaseRetrievalQA需要通过retriever负责构建所需的文档。

属性

  1. combine_documents_chain:用来组合文档的类实例。
  2. input_key:输入键,默认为 "query"。
  3. output_key:输出键,默认为 "result"。
  4. return_source_documents:标识是否返回源文档,默认为 False。

方法

抽象方法
  1. _get_docs:这是一个抽象方法,所有继承自BaseRetrievalQA的子类必须实现它。该方法负责返回与查询相关的Document对象集合。
工厂方法
  1. from_llm:利用预先存在的语言模型(llm)及可选的提示(prompt)来创建并初始化BaseRetrievalQA类的实例。
  2. from_chain_type:根据给定的链类型来创建并初始化BaseRetrievalQA类的实例。
from_llm
python 复制代码
@classmethod
    def from_llm(
        cls,
        llm: BaseLanguageModel,
        prompt: Optional[PromptTemplate] = None,
        **kwargs: Any,
    ) -> BaseRetrievalQA:
        """Initialize from LLM."""
        _prompt = prompt or PROMPT_SELECTOR.get_prompt(llm)
        llm_chain = LLMChain(llm=llm, prompt=_prompt)
        document_prompt = PromptTemplate(
            input_variables=["page_content"], template="Context:\n{page_content}"
        )
        combine_documents_chain = StuffDocumentsChain(
            llm_chain=llm_chain,
            document_variable_name="context",
            document_prompt=document_prompt,
        )

        return cls(combine_documents_chain=combine_documents_chain, **kwargs)
核心方法

_call:这个方法处理输入的查询,通过调用_get_docs方法获取相关文档,然后借助combine_document_chain(一个负责将多个文档内容合并的工具)将得到的文档内容融合,并输出结果。如果设定return_source_documents为True,则同时返回为生成结果所使用的原始文档。

python 复制代码
def _call(
        self,
        inputs: Dict[str, Any],
        run_manager: Optional[CallbackManagerForChainRun] = None,
    ) -> Dict[str, Any]:
        """Run get_relevant_text and llm on input query.

        If chain has 'return_source_documents' as 'True', returns
        the retrieved documents as well under the key 'source_documents'.

        Example:
        .. code-block:: python

        res = indexqa({'query': 'This is my query'})
        answer, docs = res['result'], res['source_documents']
        """
        _run_manager = run_manager or CallbackManagerForChainRun.get_noop_manager()
        question = inputs[self.input_key]
        accepts_run_manager = (
            "run_manager" in inspect.signature(self._get_docs).parameters
        )
        if accepts_run_manager:
            docs = self._get_docs(question, run_manager=_run_manager)
        else:
            docs = self._get_docs(question)  # type: ignore[call-arg]
        answer = self.combine_documents_chain.run(
            input_documents=docs, question=question, callbacks=_run_manager.get_child()
        )

        if self.return_source_documents:
            return {self.output_key: answer, "source_documents": docs}
        else:
            return {self.output_key: answer}

此方法接收两个参数:一个名为inputs的输入字典,其中包含问题文本等信息;以及一个可选的run_manager,它用于控制和监视整个运行过程。

以下是_call方法执行的主要步骤:

  1. 如果没有特别提供run_manager,则会赋值为一个无操作(noop)管理器,这样不会影响到程序的运行,但同时也不会提供任何额外功能。
  2. 从输入字典inputs中提取出问题文本。
  3. 检查抽象方法_get_docs是否接受run_manager作为参数。这一步是为了确认当前的BaseRetrievalQA子类是否需要run_manager来获取文档。
  4. 如果_get_docs可以接受run_manager,那么就把run_manager传递给它以获取相关文档;否则,直接调用_get_docs获取文档。
  5. 通过调用combine_documents_chain(一个合并多个文档内容的工具)使用提取的问题和获取的文档生成答案。
  6. 根据return_source_documents的值决定是否返回源文档。如果其值为True,返回的结果将包括生成答案所依据的原始文档及答案本身;否则,只返回答案。

重要的是要理解,_call方法不直接执行文档检索和问答任务,而是通过协调其他组件(例如文档检索器和语言模型)完成这些任务。

属性方法
  1. input_keys:返回一个包含所有输入键名的列表。这是一个属性方法,可以直接通过访问类实例的.input_keys属性进行调用。
  2. output_keys:返回一个包含所有输出键名的列表。这是一个属性方法,可以直接通过访问类实例的.output_keys属性进行调用。

虽然这个类定义了整个过程的协调流程,但它本身并不直接执行文档的检索或生成答案。这些任务是由其他组件(如文档检索器和语言模型)来完成的。

相关推荐
潇雷1 小时前
Netty(3)进阶篇|半包粘包、编解码器
java·后端·netty
捂月1 小时前
Spring Boot 携手 Deeplearning4j:构建高效的企业知识图谱系统
spring boot·后端·知识图谱
奔跑的废柴1 小时前
Spring Boot 自动装配原理
java·spring boot·后端
于顾而言2 小时前
代理模式下获取客户真实IP
后端·网络协议
郝同学的测开笔记2 小时前
云原生探索系列(十二):Go 语言接口详解
后端·云原生·go
wclass-zhengge2 小时前
SpringCloud篇(注册中心 - Nacos)
后端·spring·spring cloud
2401_857439692 小时前
Spring Boot编程训练系统:深入设计与实现
java·spring boot·后端
2401_857636393 小时前
电商系统设计与实现:Spring Boot框架
数据库·spring boot·后端
码蜂窝编程官方3 小时前
【含开题报告+文档+PPT+源码】基于Spring Boot智能综合交通出行管理平台的设计与实现
java·vue.js·spring boot·后端·spring
晚睡早起₍˄·͈༝·͈˄*₎◞ ̑̑3 小时前
SpringBoot(三)
java·spring boot·后端