基于langchain的长文本多迭代总结

此笔记由idea插件辅助生成

idea插件推荐 AnNote - IntelliJ IDEs Plugin | Marketplace 75 折折扣:
MGRYF-TJW4N-WZMSJ-MZDLD-LVGJH
BTKQ8-XZLPH-L3QH3-MPKBH-BP9RR
之前我们讲到langchain的rag问答,有兴趣的同学可以做下回顾

langchain基于混元大模型的实时内容的RAG问答


今天我们来了解下如何基于前文的方案实现长文本总结

为什么需要文本总结

通常会议内容是冗长的,如果能够提取关键信息的话,能够帮我们节省大量的时间

模型不能总结吗,为什么单独提出来长文本这个概念

大部分模型都会限制输入长度,如果会议长度超出了模型的限制则无法进行总结

方案

langchain提供了多种方案供我们选择,https://python.langchain.com/v0.1/docs/use_cases/summarization/

  1. stuff:全文本总结,将整个文本全部投入模型;这样仍然可能会超出模型
  2. MapReduce:将文本拆成n个小段,每个小段分别总结,然后再将最终的内容一起总结;这样虽然能解决问题,但是可能会破坏文本的上下文导致最终的结果不理想
  3. refine:和MapReduce相似的是将文本拆成n个小段,但是会以循环的方式先总结第一段,然后将第一段的总结结果和第二段再总结以此类推,此方法能够更好的保留原文的语义

难点

  1. 代码实现
  2. 流式返回
  3. 如何确定是最后一轮的返回(在流式响应的情况下,每轮都会返回总结结果,那么入会确定是最后一轮并返回个前端)

实现

由于langchain的部分实现比较紧凑,导致做二次开发不是很方便,所以可能有部分修改源码的地方

  1. 创建文本加载工具,用于加载文本
    AttachCode
from typing import Dict, Optional

from langchain.chains.combine_documents.base import AnalyzeDocumentChain
from langchain_community.document_loaders import WebBaseLoader
from langchain_core.callbacks import CallbackManagerForChainRun

from modules.BasinessException import BusinessException
from modules.resultCodeEnum import ResultCodeEnum
from service.SubtitleService import SubtitleService
from utils import constants
from utils.logger import logger

class download_summarize_chain(AnalyzeDocumentChain):
    def _call(
            self,
            inputs: Dict[str, str],
            run_manager: Optional[CallbackManagerForChainRun] = None,
    ) -> dict[str, str]:

        docs = self.get_docs(inputs, run_manager)

        # Other keys are assumed to be needed for LLM prediction
        other_keys: Dict = {k: v for k, v in inputs.items() if k != self.input_key}
        other_keys[self.combine_docs_chain.input_key] = docs

        _run_manager = run_manager or CallbackManagerForChainRun.get_noop_manager()
        return self.combine_docs_chain(
            other_keys, return_only_outputs=True, callbacks=_run_manager.get_child()
        )

    def get_docs(self, inputs, run_manager):

        file_download_url = str(inputs[constants.TRANSCRIPTION_FILE_URL])
        if file_download_url is not None and file_download_url.startswith("http"):
            # 通过下载地址下载文件
            loader = WebBaseLoader(file_download_url, None, False)
            """Split document into chunks and pass to CombineDocumentsChain."""
            document = loader.load()[0].page_content
            if len(document) <= 0:
                logger.error(f"file not exists:{file_download_url}")
                raise BusinessException.new_instance_with_rce(400, ResultCodeEnum.EMPTY_CONTENT)
        else:
            # 通过企业id和会议id获取字幕
            enterprise_id: str = run_manager.metadata.get(constants.ENTERPRISE_ID)
            meeting_id: str = run_manager.metadata.get(constants.MEETING_ID)
            logger.info(f"process task with llm:{enterprise_id}-{meeting_id}")
            document = SubtitleService().fetch_subtitles(enterprise_id=enterprise_id, meeting_id=meeting_id)

        docs = self.text_splitter.create_documents([document])
        logger.info("number of splitting doc parts:{}", len(docs))
        return docs
  1. 创建重写chain,实现迭代次数的记录
    AttachCode
"""Load summarizing chains."""

from typing import Any, Mapping, Optional, Protocol

from langchain.chains.combine_documents.base import BaseCombineDocumentsChain
from langchain.chains.combine_documents.map_reduce import MapReduceDocumentsChain
from langchain.chains.combine_documents.reduce import ReduceDocumentsChain
from langchain.chains.combine_documents.stuff import StuffDocumentsChain
from langchain.chains.llm import LLMChain
from langchain.chains.summarize import map_reduce_prompt, refine_prompts, stuff_prompt
from langchain_core.callbacks import Callbacks
from langchain_core.language_models import BaseLanguageModel
from langchain_core.prompts import BasePromptTemplate

from adapters.langchain.chains.refine import RefineDocumentsChain


clas
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值