大模型:多种RAG组合优化(langchain实现)

大模型RAG优化:Adaptive RAG

这篇文档整合了多种rag优化策略,并且使用langchain实现。可以有效的解决幻觉的问题。

图片

概要

我们将把RAG论文中的想法整合到RAG代理中:

  • Routing: Adaptive RAG (paper). 将问题路由到不同的检索方法
  • Fallback: Corrective RAG (paper). 如果文档与查询不相关,则回退到网络搜索
  • Self-correction: Self-RAG (paper). 修正有幻觉的答案或不回答问题

具体的逻辑图如下:

大致意思为:

1、首先根据问题描述判断是从rag获取信息还是网络搜索

2、如果rag获取的信息中出现幻觉,则重新回到网络进行搜索

3、根据问题和信息生成答案,然后查看答案和问题的资料判断是否有幻觉。

4、最终生成问题的答案。

5、在生成答案的过程中发现内容信息不相关,则会loop回去网络搜索重新生成答案。

图片

embedding模型

名词嵌入对比训练
我们用nomic-bert-2048初始化nomic嵌入的训练。我们的对比数据集由约2.35亿个文本对组成。我们在收集Nomic Atlas的过程中广泛验证了其质量。你可以在nomic ai/constrastors代码库中找到数据集的详细信息,也可以在nomic Atlas中探索500万对子集。
在大规模文本嵌入基准测试(MTEB)中,nomic嵌入的性能优于Text-Embedding-ada-002和jina-embeddings-v2-base-en。

nomic和其他的embedding算法比较下来,效果更好。

NameSeqLenMTEBLoCoJina Long ContextOpen WeightsOpen Training CodeOpen Data
nomic-embed819262.3985.5354.16
jina-embeddings-v2-base-en819260.3985.4551.90
text-embedding-3-small819162.2682.4058.20
text-embedding-ada-002819160.9952.755.25

不过我们要使用qwen-max对应的embedding


业务分析

我们根据上面的摘要,拆分成多个模块。一步步的实现。增加rag搜索的能力。总体的业务流程如下:

图片下载

1、在start后面隐藏了一个条件边(route结点)【决定将问题路由到不同的检索方法】

2、retrieve结点【返回知识库获取的数据信息】

3、grade_documents结点【确定检索到的文档是否与问题相关如果任何文档不相关,我们将设置一个标志来运行网络搜索】

4、web_search【网络搜索:根据问题在网上寻找答案】

5、generate【根据文档的内容生成答案】

6、增加条件边grade_generation_v_documents_and_question【确定生成是否基于文档并回答问题、是否产生幻觉】

1、route模块

可以将问题路由到不同的检索方法。我们通过agent来决定路由到哪个方向。

# Prompt
router_prompt = """You are an expert at routing a user question to a vectorstore or web search.

The vectorstore contains documents related to agents, prompt engineering, and adversarial attacks.

Use the vectorstore for questions on these topics. For all else, and especially for current events, use web-search.

Return JSON with single key, datasource, that is 'websearch' or 'vectorstore' depending on the question.
Here is the user question: \n\n {question}. 
"""

router_prompt = ChatPromptTemplate.from_template(router_prompt)
#json格式输出
class router_out(BaseModel):
    datasource: str = Field(description="选择'websearch' or 'vectorstore'")
    res :str = Field(description="结果")

router_llm  = router_prompt | model.with_structured_output(router_out)

1、我们建立一个prompt。

您是将用户问题路由到向量库或网络搜索的专家。
向量库包含与agents, prompt engineering, and adversarial attacks相关的文档。【可以根据知识库内容修改,也可以再增加一个agent总结知识库的内容】
使用向量库回答有关这些主题的问题。对于所有其他内容,尤其是时事,请使用网络搜索。
根据问题的不同,返回带有单键数据源的JSON,即“websearch”或“vectorstore”。
这是用户的问题:\n\n{question}

2、将结果格式化输出:

输出作为一个BaseModel的类,里面有两个对象datasource和res

class router_out(BaseModel):
    datasource: str = Field(description="选择'websearch' or 'vectorstore'")
    res :str = Field(description="结果")

2、retrieve

定义知识库返回的节点

def retrieve(state):
    """
    Retrieve documents from vectorstore
    Args:
        state (dict): The current graph state
    Returns:
        state (dict): New key added to state, documents, that contains retrieved documents
    """
    print("---RETRIEVE---")
    question = state["question"]

    # Write retrieved documents to documents key in state
    documents = retriever.invoke(question)
    return {"documents": documents}

3、generate(基于rag回答问题)

def generate(state):
    """
    Generate answer using RAG on retrieved documents
    Args:
        state (dict): The current graph state

    Returns:
        state (dict): New key added to state, generation, that contains LLM generation
    """
    print("---GENERATE---")
    question = state["question"]
    documents = state["documents"]
    loop_step = state.get("loop_step", 0)

    # RAG generation
    docs_txt = format_docs(documents)

    rag_prompt_formatted = rag_prompt.format(context=docs_txt, question=question)
    generation = model.invoke([HumanMessage(content=rag_prompt_formatted)])
    return {"generation": generation.content, "loop_step": loop_step + 1}

4、grade_documents

def grade_documents(state):
    """
    Determines whether the retrieved documents are relevant to the question
    If any document is not relevant, we will set a flag to run web search

    Args:
        state (dict): The current graph state

    Returns:
        state (dict): Filtered out irrelevant documents and updated web_search state
    """

    print("---CHECK DOCUMENT RELEVANCE TO QUESTION---")
    question = state["question"]
    documents = state["documents"]

    # Score each doc
    filtered_docs = []
    web_search = "No"

    for d in documents:
        result = grader_llm.invoke(
            {"document": d, "question": question}
        )
        grade = result.binary_score
        # Document relevant
        if grade.lower() == "yes":
            print("---GRADE: DOCUMENT RELEVANT---")
            filtered_docs.append(d)
        # Document not relevant
        else:
            print("---GRADE: DOCUMENT NOT RELEVANT---")
            # We do not include the document in filtered_docs
            # We set a flag to indicate that we want to run web search
            web_search = "Yes"
            continue
    return {"documents": filtered_docs, "web_search": web_search}

1、遍历所有知识库返回的文档,只要有一个文档内容和问题无关。我们就需要通过网络搜索进行补充。

5、grade_generation_v_documents_and_question

def grade_generation_v_documents_and_question(state):
    print("---CHECK HALLUCINATIONS---")
    question = state["question"]
    documents = state["documents"]
    generation = state["generation"]
    max_retries = state.get("max_retries", 3)  # Default to 3 if not provided
    result = hallucination_llm.invoke(
        {"documents": format_docs(documents), "generation": generation}
    )
    grade =result.binary_score

    # Check hallucination
    if grade == "yes":
        print("---DECISION: GENERATION IS GROUNDED IN DOCUMENTS---")
        # Check question-answering
        print("---GRADE GENERATION vs QUESTION---")
        # Test using question and generation from above
        result = answer_llm.invoke({"question":question,"generation": generation})
        grade = result.binary_score
        if grade == "yes":
            print("---DECISION: GENERATION ADDRESSES QUESTION---")
            return "useful"
        elif state["loop_step"] <= max_retries:
            print("---DECISION: GENERATION DOES NOT ADDRESS QUESTION---")
            return "not useful"
        else:
            print("---DECISION: MAX RETRIES REACHED---")
            return "max retries"
    elif state["loop_step"] <= max_retries:
        print("---DECISION: GENERATION IS NOT GROUNDED IN DOCUMENTS, RE-TRY---")
        return "not supported"
    else:
        print("---DECISION: MAX RETRIES REACHED---")
        return "max retries"

1、确定生成是否基于文档并回答问题

如果不相关且循环次数<3,则输出不支持。重新返回generate结点

2、根据最终问题的回答判断是否相关

如果不相关且循环次数<3,则输出无用,则返回websearch结点。


监控与对比

查看langsmith的监控信息会看到我们的任务走向和实际消耗的时间。

1、先调用retrieve后进入grade_documents

2、需要web搜索,进入web_search

3、grade_generation_v_documents_and_question 输出结果

loop_step =1


对比情况

问题:什么是cot?

答案:思维链 (CoT) 是一种通过模拟人类推理过程来解决复杂问题的技术,它将任务分解为一系列逻辑步骤,逐步引导至最终答案。这种方法提高了模型的透明度和多步推理能力,适用于多种任务如算术推理、常识推理等。然而,它也存在对高质量提示的需求和计算成本增加等局限性。

直接用rag:

自一致性抽样#
自洽采样(Wang等人,2022a)是对温度>0的多个输出进行采样,然后从这些候选者中选择最佳的一个。
选择最佳候选人的标准可能因任务而异。一般的解决方案是选择多数票。对于易于验证的任务,例如使用单元测试的编程问题,我们可以简单地运行解释器并使用单元测试验证其正确性。
思维链(CoT)#
思维链(CoT)提示(Wei等人,2022)生成一系列短句,逐步描述推理逻辑,称为推理链或理由,最终得出最终答案。CoT的优势在复杂的推理任务中更为明显,同时使用大型模型(例如,参数超过50B)。简单的任务只会从CoT提示中略微受益。
CoT提示的类型#
CoT提示的两种主要类型:
很少拍摄CoT。它是通过一些演示来提示模型,每个演示都包含手动编写(或模型生成)的高质量推理链。

代码重点

ChatPromptTemplate

用途

ChatPromptTemplate为聊天式交互场景设计,用于构建多轮对话形式的提示信息。它可以处理不同角色(如人类、AI)的消息,并按照一定的格式组合这些消息。这更符合聊天机器人、对话式 AI 等应用的需求。ChatPromptTemplate能够处理不同角色,是与PromptTemplate最大的不同。
模板结构

ChatPromptTemplate由多个消息模板组成,每个消息模板对应一个特定的角色(如 HumanMessagePromptTemplateAIMessagePromptTemplate 等)。这些消息模板可以包含各自的占位符,用于填充动态内容。例如:

from langchain.prompts.chat import (
    ChatPromptTemplate,
    SystemMessagePromptTemplate,
    HumanMessagePromptTemplate
)

# 定义系统消息模板
system_template = "你是一个乐于助人的助手,总是用简洁的语言回答问题。"
system_message_prompt = SystemMessagePromptTemplate.from_template(system_template)

# 定义用户消息模板
human_template = "请提供关于{topic}的简要信息。"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)

# 组合成聊天提示模板
chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])

# 构建提示,填充占位符
prompt = chat_prompt.format_prompt(topic="LLM").to_messages()

print(prompt)

主要参数
messages:列表类型。定义聊天消息的结构。列表中的每个元素代表一条消息,消息通常由 BaseMessagePromptTemplate 类的实例组成,比如 SystemMessagePromptTemplate、HumanMessagePromptTemplate 等,分别对应系统消息、人类消息等不同角色的消息模板。通过 messages 参数可以构建出一个完整的聊天对话流程的提示模板。

例子如下:

[HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['topic'], input_types={}, partial_variables={}, template='请提供关于{topic}的简要信息。\n\n'), additional_kwargs={})]

input_variables:列表类型。模板字符串里所有占位符的名称。

LLM的角色
system“角色,通过分配特定行为给聊天助手来创建对话的上下文或范围。例如,如果您希望与ChatGPT在与体育相关的话题范围内进行对话,可以将”system"角色分配给聊天助手,并设置内容为"体育专家”。然后ChatGPT会表现得像体育专家一样回答您的问题。
"human"角色,代表实际的最终用户,他向ChatGPT发送提问。
"ai“角色,代表响应最终用户提示的实体。这个角色表示消息是助手(聊天模型)的响应。”ai"角色用于在当前请求中设置模型的先前响应,以保持对话的连贯性。

如何学习大模型 AI ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

在这里插入图片描述

第一阶段(10天):初阶应用

该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。

  • 大模型 AI 能干什么?
  • 大模型是怎样获得「智能」的?
  • 用好 AI 的核心心法
  • 大模型应用业务架构
  • 大模型应用技术架构
  • 代码示例:向 GPT-3.5 灌入新知识
  • 提示工程的意义和核心思想
  • Prompt 典型构成
  • 指令调优方法论
  • 思维链和思维树
  • Prompt 攻击和防范

第二阶段(30天):高阶应用

该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。

  • 为什么要做 RAG
  • 搭建一个简单的 ChatPDF
  • 检索的基础概念
  • 什么是向量表示(Embeddings)
  • 向量数据库与向量检索
  • 基于向量检索的 RAG
  • 搭建 RAG 系统的扩展知识
  • 混合检索与 RAG-Fusion 简介
  • 向量模型本地部署

第三阶段(30天):模型训练

恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。

到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?

  • 为什么要做 RAG
  • 什么是模型
  • 什么是模型训练
  • 求解器 & 损失函数简介
  • 小实验2:手写一个简单的神经网络并训练它
  • 什么是训练/预训练/微调/轻量化微调
  • Transformer结构简介
  • 轻量化微调
  • 实验数据集的构建

第四阶段(20天):商业闭环

对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。

  • 硬件选型
  • 带你了解全球大模型
  • 使用国产大模型服务
  • 搭建 OpenAI 代理
  • 热身:基于阿里云 PAI 部署 Stable Diffusion
  • 在本地计算机运行大模型
  • 大模型的私有化部署
  • 基于 vLLM 部署大模型
  • 案例:如何优雅地在阿里云私有部署开源大模型
  • 部署一套开源 LLM 项目
  • 内容安全
  • 互联网信息服务算法备案

学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。

如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值