langchain從入門到精通(二十六)——RAG優化策略(四)問題分解策略提升負責問題檢索準確率

1. LangChain 少量示例提示模板

在與 LLM 的對話中,提供少量的示例被稱為 少量示例,這是一種簡單但強大的指導生成的方式,在某些情況下可以顯著提高模型性能(與之對應的是零樣本),少量示例可以降低 Prompt 的復雜度,快速告知 LLM 生成內容的規范。
在 LangChain 中,針對少量示例也封裝對應的提示模板——FewShotPromptTemplate,這個提示模板只需要傳遞 示例列表 與 示例模板 即可快速構建 少量示例提示模板,使用示例如下:

import dotenv
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate, FewShotChatMessagePromptTemplate
from langchain_openai import ChatOpenAIdotenv.load_dotenv()# 1.構建示例模板與示例
examples = [{"question": "幫我計算下2+2等于多少?", "answer": "4"},{"question": "幫我計算下2+3等于多少?", "answer": "5"},{"question": "幫我計算下20*15等于多少?", "answer": "300"},
]
example_prompt = ChatPromptTemplate.from_messages([("human", "{question}"),("ai", "{answer}"),
])# 2.構建少量示例提示模板
few_shot_prompt = FewShotChatMessagePromptTemplate(example_prompt=example_prompt,examples=examples,
)
print("少量示例模板:", few_shot_prompt.format())# 3.構建最終提示模板
prompt = ChatPromptTemplate.from_messages([("system", "你是一個可以計算復雜數學問題的聊天機器人"),few_shot_prompt,("human", "{question}"),
])# 4.創建大語言模型與鏈
llm = ChatOpenAI(model="gpt-3.5-turbo-16k", temperature=0)
chain = prompt | llm | StrOutputParser()# 5.調用鏈獲取結果
print(chain.invoke("幫我計算下14*15等于多少"))

輸出內容:

少量示例模板: Human: 幫我計算下2+2等于多少?
AI: 4
Human: 幫我計算下2+3等于多少?
AI: 5
Human: 幫我計算下20*15等于多少?
AI: 300
210

少量示例提示模板 在底層會根據傳遞的 示例模板 與 示例 格式化對應的 消息列表 或者 字符串,從而將對應的示例參考字符串信息添加到完整的提示模板中,簡化了 Prompt 編寫的繁瑣程度。
對于聊天模型可以使用 FewShotChatMessagePromptTemplate,而文本補全基座模型可以使用FewShotPromptTemplate

2. Step-Back 回答回退策略的優點

對于一些復雜的問題,除了使用 問題分解 來得到子問題亦或者依賴問題,還可以為復雜問題生成一個前置問題,通過前置問題來執行相應的檢索,這就是 Setp-Back 回答回退策略(后退提示),這是一種用于增強語言模型的推理和問題解決能力的技巧,它鼓勵 LLM 從一個給定的問題或問題后退一步,提出一個更抽象、更高級的問題,涵蓋原始查詢的本質。
概念來源:https://arxiv.org/pdf/2310.06117.pdf
后退提示背后的概念是,許多復雜的問題或任務包含很多復雜的細節和約束,這使 LLM 難以直接檢索和應用相關信息。通過引入一個后退問題,這個問題通常更容易回答,并且圍繞一個更廣泛的概念或原則,讓 LLM 可以更有效地構建它們的推理。
Step-Back 回答回退策略的運行流程也非常簡單,構建一個 少量示例提示模板,讓 LLM 根據傳遞的問題生成一個后退問題,使用 后退問題 執行相應的檢索,利用檢索到的文檔+原始問題執行 RAG 索引增強生成,運行流程如下:
在這里插入圖片描述

在 LangChain 中并沒有封裝好的 回答回退策略檢索器,所以可以執行相應的封裝,實現一個自定義檢索器,實現代碼如下:

from typing import Listimport dotenv
import weaviate
from langchain_core.callbacks import CallbackManagerForRetrieverRun
from langchain_core.documents import Document
from langchain_core.language_models import BaseLanguageModel
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate, FewShotChatMessagePromptTemplate
from langchain_core.retrievers import BaseRetriever
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_weaviate import WeaviateVectorStore
from weaviate.auth import AuthApiKeydotenv.load_dotenv()class StepBackRetriever(BaseRetriever):"""回答回退檢索器"""retriever: BaseRetrieverllm: BaseLanguageModeldef _get_relevant_documents(self, query: str, *, run_manager: CallbackManagerForRetrieverRun) -> List[Document]:"""根據傳遞的query執行問題回退并檢索"""# 1.構建少量提示模板examples = [{"input": "慕課網上有關于AI應用開發的課程嗎?", "output": "慕課網上有哪些課程?"},{"input": "慕小課出生在哪個國家?", "output": "慕小課的個人經歷是怎樣的?"},{"input": "司機可以開快車嗎?", "output": "司機可以做什么?"},]example_prompt = ChatPromptTemplate.from_messages([("human", "{input}"),("ai", "{output}")])few_show_prompt = FewShotChatMessagePromptTemplate(examples=examples,example_prompt=example_prompt,)# 2.構建生成回退問題提示system_prompt = "你是一個世界知識的專家。你的任務是回退問題,將問題改述為更一般或者前置問題,這樣更容易回答,請參考示例來實現。"prompt = ChatPromptTemplate.from_messages([("system", system_prompt),few_show_prompt,("human", "{question}")])# 3.構建生成回退問題的鏈chain = ({"question": RunnablePassthrough()}| prompt| self.llm| StrOutputParser()| self.retriever)return chain.invoke(query)# 1.構建向量數據庫與檢索器
db = WeaviateVectorStore(client=weaviate.connect_to_wcs(cluster_url="https://mbakeruerziae6psyex7ng.c0.us-west3.gcp.weaviate.cloud",auth_credentials=AuthApiKey("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"),),index_name="DatasetDemo",text_key="text",embedding=OpenAIEmbeddings(model="text-embedding-3-small"),
)
retriever = db.as_retriever(search_type="mmr")# 2.創建回答回退檢索器
step_back_retriever = StepBackRetriever(retriever=retriever,llm=ChatOpenAI(model="gpt-3.5-turbo-16k", temperature=0),
)# 3.檢索文檔
documents = step_back_retriever.invoke("人工智能會讓世界發生翻天覆地的變化嗎?")
print(documents)
print(len(documents))

輸出內容:

[Document(metadata={'source': './項目API文檔.md', 'start_index': 5818.0}, page_content='json { "code": "success", "data": { "list": [ { "id": "1550b71a-1444-47ed-a59d-c2f080fbae94", "conversation_id": "2d7d3e3f-95c9-4d9d-ba9c-9daaf09cc8a8", "query": "能詳細講解下LLM是什么嗎?", "answer": "LLM 即 Large Language Model,大語言模型,是一種基于深度學習的自然語言處理模型,具有很高的語言理解和生成能力,能夠處理各式各樣的自然語言任務,例如文本生成、問答、翻譯、摘要等。它通過在大量的文本數據上進行訓練,學習到語言的模式、結構和語義知識'), Document(metadata={'source': './項目API文檔.md', 'start_index': 6359.0}, page_content='1.7 [todo]刪除特定的調試消息\n\n接口說明:用于刪除 AI 應用調試對話過程中指定的消息,該刪除會在后端執行軟刪除操作,并且只有當會話 id 和消息 id 都匹配上時,才會刪除對應的調試消息。\n\n接口信息:授權+POST:/apps/:app_id/messages/:message_id/delete\n\n接口參數:\n\n請求參數:\n\napp_id -> uuid:路由參數,需要刪除消息歸屬的應用 id,格式為 uuid。\n\nmessage_id -> uuid:路由參數,需要刪除的消息 id,格式為 uuid。\n\n請求示例:\n\njson { "app_id": "1550b71a-1444-47ed-a59d-c2f080fbae94", "message_id": "2d7d3e3f-95c9-4d9d-ba9c-9daaf09cc8a8" }\n\n響應示例:\n\njson { "code": "success", "data": {}, "message": "刪除調試信息成功" }'), Document(metadata={'source': './項目API文檔.md', 'start_index': 490.0}, page_content='帶有分頁數據的接口會在 data 內固定傳遞 list 和 paginator 字段,其中 list 代表分頁后的列表數據,paginator 代表分頁的數據。\n\npaginator 內存在 4 個字段:current_page(當前頁數) 、page_size(每頁數據條數)、total_page(總頁數)、total_record(總記錄條數),示例數據如下:'), Document(metadata={'source': './項目API文檔.md', 'start_index': 2042.0}, page_content='dialog_round -> int:攜帶上下文輪數,類型為非負整型。\n\nmemory_mode -> string:記憶類型,涵蓋長記憶 long_term_memory 和 none 代表無。\n\nstatus -> string:應用配置的狀態,drafted 代表草稿、published 代表已發布配置。\n\nupdated_at -> int:應用配置的更新時間。\n\ncreated_at -> int:應用配置的創建時間。\n\nupdated_at -> int:應用的更新時間。\n\ncreated_at -> int:應用的創建時間。\n\n響應示例:')]

對比 問題分解策略,回答回退策略 僅僅多調用一次 LLM,所以相應速度更快,性能更高,并且復雜度更低,對于一些參數量較小的模型,也可以實現不錯的效果,對于 問題分解策略-迭代式回答,在一些極端的情況下,模型輸出了有偏差的內容,每次都在有偏差的 問題+答案 生成新內容,很有可能會導致最后的輸出完全偏離開始的預設。
就像早些年很火的 谷歌翻譯將同一句話翻譯20次,輸出的內容就完全偏離了原來的預設。本質上就是因為無論是 谷歌翻譯 還是 LLM大語言模型,執行轉換操作時,信息產生了丟失,并且隨著迭代的增加,信息丟失得越來越多

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/912576.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/912576.shtml
英文地址,請注明出處:http://en.pswp.cn/news/912576.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Nuxt.js基礎(Tailwind基礎)

??1. 按鈕組件實現?? ??傳統 CSS <!-- HTML --> <button class"btn-primary">提交</button><!-- CSS --> <style>.btn-primary {background-color: #3490dc;padding: 0.5rem 1rem;border-radius: 0.25rem;color: white;transi…

[C語言]存儲結構詳解

C語言存儲結構總結 在C語言中&#xff0c;數據根據其類型和聲明方式被存儲在不同的內存區域。以下是各類數據存儲位置的詳細總結&#xff1a; 內存五大分區 存儲區存儲內容生命周期特點代碼區(.text)程序代碼(機器指令)整個程序運行期只讀常量區(.rodata)字符串常量、const全…

【實戰】 容器中Spring boot項目 Graphics2D 畫圖中文亂碼解決方案

場景 架構&#xff1a;spring boot 容器技術&#xff1a;docker 服務器&#xff1a;阿里云 開發環境&#xff1a;windows10 IDEA 一、問題 服務器中出現Graphics2D 畫圖中文亂碼 本地環境運行正常 二、原因 spring boot 容器中沒有安裝中文字體 三、解決方案 安裝字體即可 …

深入淺出:Vue2 數據劫持原理剖析

目錄 一、什么是數據劫持&#xff1f; 二、核心 API&#xff1a;Object.defineProperty 三、Vue2 中的數據劫持實現 1. 對象屬性的劫持 2. 嵌套對象的處理 3. 數組的特殊處理 四、結合依賴收集的完整流程 五、數據劫持的局限性 六、Vue3 的改進方案 總結 一、什么是數…

數據湖 vs 數據倉庫:數據界的“自來水廠”與“瓶裝水廠”?

數據湖 vs 數據倉庫&#xff1a;數據界的“自來水廠”與“瓶裝水廠”&#xff1f; 說起“數據湖”和“數據倉庫”&#xff0c;很多剛入行的朋友都會覺得&#xff1a; “聽起來好高大上啊&#xff01;但到底有啥區別啊&#xff1f;是湖更大還是倉庫更高端&#xff1f;” 我得說…

Node.js-path模塊

Path 模塊 path 模塊提供了 操作路徑 的功能&#xff0c;我們將介紹如下幾個較為常用的幾個 API ??path.resolve([…paths]) 將路徑片段??解析為絕對路徑??&#xff08;從右向左拼接&#xff0c;遇到絕對路徑停止&#xff09; // 若參數為空&#xff0c;返回當前工作目…

Java面試題029:一文深入了解MySQL(1)

歡迎大家關注我的專欄,該專欄會持續更新,從原理角度覆蓋Java知識體系的方方面面。 一文吃透JAVA知識體系(面試題)https://blog.csdn.net/wuxinyan123/category_7521898.html?fromshare=blogcolumn&sharetype=blogcolumn&sharerId=7521898&

vue3.0所采用得Composition Api與Vue2.XOtions Api有什么不同?

Vue 3.0 引入的 Composition API 相較于 Vue 2.x 的 Options API 有顯著的不同。下面從幾個方面對比這兩者的差異&#xff1a; ? 1. 代碼組織方式不同 Vue 2.x — Options API 使用 data、methods、computed、watch 等分散的選項組織邏輯。 每個功能點分散在不同的選項中&am…

【IP 潮玩行業深度研究與學習】

潮玩行業發展趨勢分析&#xff1a;全球市場格局與中國政策支持體系 潮玩產業正經歷從"小眾收藏"到"大眾情緒消費"的深刻轉型&#xff0c;2025年中國潮玩市場規模已達727億元&#xff0c;預計2026年將突破1100億元&#xff0c;年復合增長率高達26%。這一千…

進程通信-消息隊列

消息隊列允許一個進程將一個消息發送到一個隊列中&#xff0c;另一個進程從該隊列中接收這個消息。 使用流程&#xff1a; 寫端&#xff1a; 使用結構體 mq_attr 設置消息隊列屬性&#xff0c;有四個選項&#xff1a; long mq_flags; // 隊列屬性: 0 表示阻塞 long …

串行通信接口USART,printf重定向數據發送,輪詢和中斷實現串口數據接收

目錄 UART通信協議的介紹 實現串口數據發送 CubeMX配置 printf重定向代碼編寫 實現串口數據接收 輪詢方式實現串口數據接收 接收單個字符 接收不定長字符串&#xff08;接收的字符串以\n結尾&#xff09; 中斷方式實現串口數據接收 CubeMX配置 UART中斷方式接收數據…

Kafka 生產者和消費者高級用法

Kafka 生產者和消費者高級用法 1 生產者的事務支持 Kafka 從版本0.11開始引入了事務支持&#xff0c;使得生產者可以實現原子操作&#xff0c;確保消息的可靠性。 // 示例代碼&#xff1a;使用 Kafka 事務 producer.initTransactions(); try {producer.beginTransaction();pr…

k8s中crictl命令常報錯解決方法

解決使用crictl命令時報默認端點棄用的報錯 報錯核心原因 默認端點棄用&#xff1a; crictl 會默認嘗試多個容器運行時端點&#xff08;如 dockershim.sock、containerd.sock 等&#xff09;&#xff0c;但這種 “自動探測” 方式已被 Kubernetes 棄用&#xff08;官方要求手動…

回轉體水下航行器簡單運動控制的奧秘:PID 控制和水動力方程的運用

在水下航行器的控制領域中&#xff0c;回轉體水下航行器的運動控制是一個關鍵課題。 今天&#xff0c;就來深入探討一下其簡單運動控制中&#xff0c;PID 控制以及水動力方程的相關運用。 PID 控制的基本原理PID 控制&#xff08;比例 - 積分 - 微分控制&#xff09;是一種廣…

從入門到精通:npm、npx、nvm 包管理工具詳解及常用命令

目錄 1. 引言2. npm (Node Package Manager)2.1 定義與用途2.2 常見命令2.3 使用示例 3. npx (Node Package Execute)3.1 定義與用途3.2 常見命令3.3 使用示例3.4 npm 與 npx 的區別 4. nvm (Node Version Manager)4.1 定義與用途4.2 安裝 nvm4.3 常見命令4.4 使用示例 5. 工具…

es6特性-第二部分

Promise 介紹和基本使用 Promise是ES6引入的異步編程的新解決方案&#xff0c;主要用來解決回調地獄問題。語法上 Promise是一個構造函數,用來封裝異步操作并可以獲取其成功或失敗的結果。 Promise構造函數:new Promise() Promise.prototype.then方法 Promise.prototype.ca…

java:如何用 JDBC 連接 TDSQL 數據庫

要使用JDBC連接TDSQL數據庫&#xff08;騰訊云分布式數據庫&#xff0c;兼容MySQL協議&#xff09;&#xff0c;請按照以下步驟編寫Java程序&#xff1a; 1. 添加MySQL JDBC驅動依賴 在項目的pom.xml中添加依賴&#xff08;Maven項目&#xff09;&#xff1a; <dependenc…

2025年四川省高考志愿填報深度分析與專業導向策略報告——基于599分/24000位次考生-AI

2025年四川省高考志愿填報深度分析與專業導向策略報告——基于599分/24000位次考生 摘要 本報告旨在為預估高考成績599分、全省物理類位次在24,000名左右的2025年四川考生&#xff0c;提供一份兼具科學性、前瞻性與專業深度的志愿填報策略方案。報告嚴格遵循“位次法”為核心…

spring boot項目整合百度翻譯

本片文章教大家怎樣在spring boot項目中引入百度翻譯&#xff0c;并且優雅的使用百度翻譯。 首先&#xff0c;我們要了解為什么要使用翻譯插件。為了支持多語言的國際化&#xff1b; 目前市面上最常見的后端國際化就是在resource資源目錄下設置多個語言文檔&#xff0c;這些文…

凌晨2點自動備份mysql 數據庫,mysql_backup.sh

1、編寫備份腳本&#xff1a;vim mysql_backup.sh #!/bin/bash DATE$(date %Y%m%d_%H%M%S) BACKUP_DIR"/data/mysql/backup" USER"backup_user" PASSWORD"backup**"# 邏輯備份所有數據庫 mysqldump -u$USER -p$PASSWORD eblp | gzip > $BA…