AI大模型(七)Langchain核心模塊與實戰(二)

Langchain核心模塊與實戰(二)

    • Langchian向量數據庫檢索
      • Langchian構建向量數據庫和檢索器
      • 批量搜索返回與之相似度最高的第一個
      • 檢索器和模型結合得到非籠統的答案
    • LangChain構建代理
      • 通過代理去調用
    • Langchain構建RAG的對話應用
      • 包含歷史記錄的對話生成

Langchian向量數據庫檢索

Langchian構建向量數據庫和檢索器

支持從向量數據庫和其他來源檢索數據,以便與LLM(大型語言模型)工作流程集成。它們對于應用程序來說非常重要,這些應用程序需要獲取數據以作為模型推理的一部分進行推理,就像檢索增強生成(RAG)的情況一樣需要安裝:pip install langchain-chroma

  • 文檔
  • 向量存儲
  • 檢索器
import osfrom langchain_community.vectorstores import Chroma
from langchain_core.documents import Document
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.chat_message_histories import  ChatMessageHistoryos.environ['LANGCHAIN_TRACING_V2'] = "true"
os.environ['LANGCHAIN_PROJECT'] ="LangchainDemo"
os.environ['LANGCHAIN_API_KEY'] = "xxx"# 準備測試數據,假設我們提供的文檔數據如下:
documents = [Document(page_content="狗是偉大的伴侶,以其忠誠和友好而聞名。",#源數據metadata={"source": "哺乳動物寵物文檔"},),Document(page_content="貓是獨立的寵物,通常喜歡自己的空間。",metadata={"source": "哺乳動物寵物文檔"},),Document(page_content="金魚是初學者的流行寵物,需要相對簡單的護理。",metadata={"source": "魚類寵物文檔"},),Document(page_content="鸚鵡是聰明的鳥類,能夠模仿人類的語言。",metadata={"source": "鳥類寵物文檔"},),Document(page_content="兔子是社交動物,需要足夠的空間跳躍。",metadata={"source": "哺乳動物寵物文檔"},),
]# 將文檔實例化成一個向量數據庫
vector_store = Chroma.from_documents(documents,embedding=OpenAIEmbeddings(openai_api_key="sk-xxx",openai_api_base='https://xiaoai.plus/v1',))#計算向量的相似度(query:需要查詢什么東西) 返回相似的分數,分數越低相似度越高
print(vector_store.similarity_search_with_score('咖啡貓'))
[(Document(metadata={'source': '哺乳動物寵物文檔'}, page_content='貓是獨立的寵物,通常喜歡自己的空間。'), 0.27787065505981445), (Document(metadata={'source': '哺乳動物寵物文檔'}, page_content='兔子是社交動物,需要足夠的空間跳躍。'), 0.4110114872455597), (Document(metadata={'source': '哺乳動物寵物文檔'}, page_content='狗是偉大的伴侶,以其忠誠和友好而聞名。'), 0.4139944612979889), (Document(metadata={'source': '魚類寵物文檔'}, page_content='金魚是初學者的流行寵物,需要相對簡單的護理。'), 0.43892139196395874)]

返回分數,分數越低距離值越低越相似

批量搜索返回與之相似度最高的第一個

import osfrom langchain_community.vectorstores import Chroma
from langchain_core.documents import Document
from langchain_core.runnables import RunnableLambda
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.chat_message_histories import  ChatMessageHistoryos.environ['LANGCHAIN_TRACING_V2'] = "true"
os.environ['LANGCHAIN_PROJECT'] ="LangchainDemo"
os.environ['LANGCHAIN_API_KEY'] = "xx"# 準備測試數據,假設我們提供的文檔數據如下:
documents = [Document(page_content="狗是偉大的伴侶,以其忠誠和友好而聞名。",#源數據metadata={"source": "哺乳動物寵物文檔"},),Document(page_content="貓是獨立的寵物,通常喜歡自己的空間。",metadata={"source": "哺乳動物寵物文檔"},),Document(page_content="金魚是初學者的流行寵物,需要相對簡單的護理。",metadata={"source": "魚類寵物文檔"},),Document(page_content="鸚鵡是聰明的鳥類,能夠模仿人類的語言。",metadata={"source": "鳥類寵物文檔"},),Document(page_content="兔子是社交動物,需要足夠的空間跳躍。",metadata={"source": "哺乳動物寵物文檔"},),
]# 將文檔實例化成一個向量數據庫
vector_store = Chroma.from_documents(documents,embedding=OpenAIEmbeddings(openai_api_key="sk-xx",openai_api_base='https://xiaoai.plus/v1',))#計算向量的相似度(query:需要查詢什么東西) 返回相似的分數,分數越低相似度越高
# print(vector_store.similarity_search_with_score('咖啡貓'))# 檢索器(封裝到runnable對象中) bind(k=1)返回相似度最高的第一個
retriever = RunnableLambda(vector_store.similarity_search).bind(k=1)
print(retriever.batch(['咖啡貓', '鯊魚']))

檢索器和模型結合得到非籠統的答案

import osfrom langchain_community.vectorstores import Chroma
from langchain_core.documents import Document
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableLambda, RunnablePassthrough
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.chat_message_histories import  ChatMessageHistoryos.environ['LANGCHAIN_TRACING_V2'] = "true"
os.environ['LANGCHAIN_PROJECT'] ="LangchainDemo"
os.environ['LANGCHAIN_API_KEY'] = "xx"# 1.創建模型
model = ChatOpenAI(model='gpt-4-turbo',api_key='sk-xx',base_url='https://xiaoai.plus/v1')# 準備測試數據,假設我們提供的文檔數據如下:
documents = [Document(page_content="狗是偉大的伴侶,以其忠誠和友好而聞名。",#源數據metadata={"source": "哺乳動物寵物文檔"},),Document(page_content="貓是獨立的寵物,通常喜歡自己的空間。",metadata={"source": "哺乳動物寵物文檔"},),Document(page_content="金魚是初學者的流行寵物,需要相對簡單的護理。",metadata={"source": "魚類寵物文檔"},),Document(page_content="鸚鵡是聰明的鳥類,能夠模仿人類的語言。",metadata={"source": "鳥類寵物文檔"},),Document(page_content="兔子是社交動物,需要足夠的空間跳躍。",metadata={"source": "哺乳動物寵物文檔"},),
]# 將文檔實例化成一個向量數據庫
vector_store = Chroma.from_documents(documents,embedding=OpenAIEmbeddings(openai_api_key="sk-xx",openai_api_base='https://xiaoai.plus/v1',))#計算向量的相似度(query:需要查詢什么東西) 返回相似的分數,分數越低相似度越高
# print(vector_store.similarity_search_with_score('咖啡貓'))# 檢索器(封裝到runnable對象中) bind(k=1)返回相似度最高的第一個
retriever = RunnableLambda(vector_store.similarity_search).bind(k=1)
# print(retriever.batch(['咖啡貓', '鯊魚']))# context 上下文放檢索器
message ="""
使用提供的上下文僅回答這個問題。
{question}
上下文:
{context}
"""
#元組,字符串,列表是sequence
prompt_temp = ChatPromptTemplate.from_messages([('human',message)])#RunnablePassthrough允許我們將用戶的問題之后再傳遞給prompt和model | 模板 | 模型
chain={'question':RunnablePassthrough(),'context':retriever} | prompt_temp | model
# 會結合上下文給出答案
resp = chain.invoke('請介紹一下貓')
print(resp)

輸出結果如下,此處的輸出就不再是一個籠統的結果了,而是結合上下文輸出的結果

content='貓是一種獨立的寵物,通常喜歡享有自己的空間。' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 30, 'prompt_tokens': 88, 'total_tokens': 118, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'gpt-4-turbo', 'system_fingerprint': 'fp_5603ee5e2e', 'id': 'chatcmpl-NBI72cCvyl95lkf3JYErQmRa01R2X', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None} id='run--86dc4e6a-33bc-414e-8c7f-6da9fb0af42f-0' usage_metadata={'input_tokens': 88, 'output_tokens': 30, 'total_tokens': 118, 'input_token_details': {}, 'output_token_details': {}}

LangChain構建代理

語言模型本身無法執行動作(如直接問大模型最近北京的天氣怎么樣),它們只能輸出文本。代理是使用大型語言模型(LLM)作為推理引擎來確定要執行的操作以及這些操作的輸入應該是什么。然后,這些操作的結果可以反饋到代理中,代理將決定是否需要更多的操作,或者是否可以結束。
pip install langgraph 用來創建代理的API

**
1、定義工具
2、創建代理**

沒有任何代理的情況下:
在這里插入圖片描述
在這里插入圖片描述

import osfrom langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.messages import HumanMessage
from langchain_openai import ChatOpenAI, OpenAIEmbeddingsos.environ['LANGCHAIN_TRACING_V2'] = "true"
os.environ['LANGCHAIN_PROJECT'] ="LangchainDemo"
os.environ['LANGCHAIN_API_KEY'] = "xxx"
os.environ["TAVILY_API_KEY"] = 'tvly-xx'
# 1.創建模型
model = ChatOpenAI(model='gpt-4-turbo',api_key='sk-xxx',base_url='https://xiaoai.plus/v1')# 沒有任何代理的情況下
# result = model.invoke([HumanMessage(content='北京天氣怎么樣?')])
# print(result)# LangChain內置了一個工具,可以輕松地使用Tavily搜索引擎作為工具。
search = TavilySearchResults(max_results=2)  #  max_results: 只返回兩個結果
# print(search.invoke('北京的天氣怎么樣?'))# 讓模型綁定工具
tools = [search]
model_with_tools = model.bind_tools(tools)# 模型可以自動推理:是否需要調用工具去完成用戶的答案
resp = model_with_tools.invoke([HumanMessage(content='中國的首都是哪個城市?')])print(f'Model_Result_Content: {resp.content}')
print(f'Tools_Result_Content: {resp.tool_calls}')resp2 = model_with_tools.invoke([HumanMessage(content='成都天氣怎么樣?')])print(f'Model_Result_Content: {resp2.content}')
print(f'Tools_Result_Content: {resp2.tool_calls}')

resp2得到一個搜索的指令,LLM會根據用戶問的問題判斷是否調工具,如果要調工具會得到一個調用工具的搜素指令

Model_Result_Content: 中國的首都是北京。
Tools_Result_Content: []
Model_Result_Content: 
Tools_Result_Content: [{'name': 'tavily_search_results_json', 'args': {'query': '成都天氣狀況'}, 'id': 'chatcmpl-palFZnWMAbktsQdoCPTp42gIsaZIW', 'type': 'tool_call'}]

通過代理去調用

import osfrom langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.messages import HumanMessage
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langgraph.prebuilt import chat_agent_executoros.environ['LANGCHAIN_TRACING_V2'] = "true"
os.environ['LANGCHAIN_PROJECT'] ="LangchainDemo"
os.environ['LANGCHAIN_API_KEY'] = "xxx"
os.environ["TAVILY_API_KEY"] = 'tvly-xxx'
# 1.創建模型
model = ChatOpenAI(model='gpt-4-turbo',api_key='sk-xx',base_url='https://xiaoai.plus/v1')# 沒有任何代理的情況下
# result = model.invoke([HumanMessage(content='北京天氣怎么樣?')])
# print(result)# LangChain內置了一個工具,可以輕松地使用Tavily搜索引擎作為工具。
search = TavilySearchResults(max_results=2)  #  max_results: 只返回兩個結果
# print(search.invoke('北京的天氣怎么樣?'))# 讓模型綁定工具
tools = [search]
model_with_tools = model.bind_tools(tools)# 模型可以自動推理:是否需要調用工具去完成用戶的答案
# resp = model_with_tools.invoke([HumanMessage(content='中國的首都是哪個城市?')])
#
# print(f'Model_Result_Content: {resp.content}')
# print(f'Tools_Result_Content: {resp.tool_calls}')
#
# resp2 = model_with_tools.invoke([HumanMessage(content='成都天氣怎么樣?')])
#
# print(f'Model_Result_Content: {resp2.content}')
# print(f'Tools_Result_Content: {resp2.tool_calls}')# 創建代理,模型會自動調用工具
# 代理執行器
agent_executor = chat_agent_executor.create_tool_calling_executor(model,tools)resp = agent_executor.invoke({'messages': [HumanMessage(content='中國的首都是哪個城市?')]})
print(resp['messages'])resp2 = agent_executor.invoke({'messages': [HumanMessage(content='北京天氣怎么樣?')]})
print(resp2['messages'])print(resp2['messages'][2].content)
[HumanMessage(content='中國的首都是哪個城市?', additional_kwargs={}, response_metadata={}, id='efffa452-42cf-4197-a2b3-ef62b326e8ba'), AIMessage(content='中國的首都是北京。', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 8, 'prompt_tokens': 92, 'total_tokens': 100, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'gpt-4-turbo', 'system_fingerprint': 'fp_5603ee5e2e', 'id': 'chatcmpl-wXponqYpA2fleDkK2GpdehWTQvxWM', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None}, id='run--7fcfa616-7b61-4ae3-a19c-bf000e262ab0-0', usage_metadata={'input_tokens': 92, 'output_tokens': 8, 'total_tokens': 100, 'input_token_details': {}, 'output_token_details': {}})]
[HumanMessage(content='北京天氣怎么樣?', additional_kwargs={}, response_metadata={}, id='9848deca-5ef9-4920-b02d-bfccc108992c'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'chatcmpl-W7E8k525XQPXUh90ZIjCeJTXzqTBQ', 'function': {'arguments': '{"query":"北京當前天氣"}', 'name': 'tavily_search_results_json'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 22, 'prompt_tokens': 90, 'total_tokens': 112, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'gpt-4-turbo', 'system_fingerprint': 'fp_5603ee5e2e', 'id': 'chatcmpl-W7E8k525XQPXUh90ZIjCeJTXzqTBQ', 'service_tier': None, 'finish_reason': 'tool_calls', 'logprobs': None}, id='run--06dc9a8b-5764-4fd9-bb43-c520204f2d9f-0', tool_calls=[{'name': 'tavily_search_results_json', 'args': {'query': '北京當前天氣'}, 'id': 'chatcmpl-W7E8k525XQPXUh90ZIjCeJTXzqTBQ', 'type': 'tool_call'}], usage_metadata={'input_tokens': 90, 'output_tokens': 22, 'total_tokens': 112, 'input_token_details': {}, 'output_token_details': {}}), ToolMessage(content='[{"title": "中國氣象局-天氣預報- 北京", "url": "https://weather.cma.cn/web/weather/54511", "content": "| 氣壓 | 1010.2hPa | 1009.9hPa | 1006.9hPa | 1004.4hPa | 1004.2hPa | 1004.9hPa | 1004hPa | 1004.2hPa |\\n| 濕度 | 71.7% | 66% | 62.4% | 60.2% | 59.4% | 65% | 84.4% | 96.6% |\\n| 云量 | 44.5% | 31.9% | 27.2% | 10.1% | 79.9% | 79.9% | 79.9% | 79.9% | [...] | 氣壓 | 1007.6hPa | 1007.7hPa | 1006.3hPa | 1005.7hPa | 1007.6hPa | 1009.3hPa | 1009.5hPa | 1009.3hPa |\\n| 濕度 | 68.9% | 59% | 55.5% | 58.8% | 49% | 76% | 82.3% | 91% |\\n| 云量 | 79.9% | 80% | 80% | 80% | 86.6% | 66.7% | 72.2% | 79.9% | [...] | 氣壓 | 1001.4hPa | 999.8hPa | 998.3hPa | 999.7hPa | 1001.2hPa | 1005.1hPa | 1009.1hPa | 1010.7hPa |\\n| 濕度 | 46.2% | 29.2% | 17% | 24.7% | 25.7% | 53.5% | 46.7% | 39.9% |\\n| 云量 | 41.2% | 10% | 10% | 10% | 4.6% | 4.6% | 4.5% | 4.4% |", "score": 0.7636429}, {"title": "北京-天氣預報 - 中央氣象臺", "url": "https://www.nmc.cn/publish/forecast/ABJ/beijing.html", "content": "土壤水分監測\\n       農業干旱綜合監測\\n       關鍵農時農事\\n       農業氣象周報\\n       農業氣象月報\\n       農業氣象專報\\n       生態氣象監測評估\\n       作物發育期監測\\n\\n   數值預報\\n\\n       CMA全球天氣模式\\n       CMA全球集合模式\\n       CMA區域模式\\n       CMA區域集合模式\\n       CMA臺風模式\\n       海浪模式\\n\\n1.    當前位置:首頁\\n2.   北京市\\n3.   北京天氣預報\\n\\n省份:城市:\\n\\n09:50更新\\n\\n日出04:45\\n\\n 北京 \\n\\n30℃\\n\\n日落19:43\\n\\n 降水量 \\n\\n0mm\\n\\n西南風\\n\\n3級\\n\\n 相對濕度 \\n\\n43%\\n\\n 體感溫度 \\n\\n29.9℃\\n\\n空氣質量:良 \\n\\n舒適度:溫暖,較舒適\\n\\n 雷達圖 \\n\\nImage 4\\n\\n24小時預報7天預報10天預報11-30天預報\\n\\n 發布時間:06-12 08:00 \\n\\n 06/12 \\n\\n周四 \\n\\nImage 5\\n\\n 多云 \\n\\n 南風 \\n\\n 3~4級 \\n\\n 35℃ \\n\\n 23℃ \\n\\nImage 6", "score": 0.741169}]', name='tavily_search_results_json', id='2cc11dce-0bd7-4654-8def-fcf10e333a22', tool_call_id='chatcmpl-W7E8k525XQPXUh90ZIjCeJTXzqTBQ', artifact={'query': '北京當前天氣', 'follow_up_questions': None, 'answer': None, 'images': [], 'results': [{'url': 'https://weather.cma.cn/web/weather/54511', 'title': '中國氣象局-天氣預報- 北京', 'content': '| 氣壓 | 1010.2hPa | 1009.9hPa | 1006.9hPa | 1004.4hPa | 1004.2hPa | 1004.9hPa | 1004hPa | 1004.2hPa |\n| 濕度 | 71.7% | 66% | 62.4% | 60.2% | 59.4% | 65% | 84.4% | 96.6% |\n| 云量 | 44.5% | 31.9% | 27.2% | 10.1% | 79.9% | 79.9% | 79.9% | 79.9% | [...] | 氣壓 | 1007.6hPa | 1007.7hPa | 1006.3hPa | 1005.7hPa | 1007.6hPa | 1009.3hPa | 1009.5hPa | 1009.3hPa |\n| 濕度 | 68.9% | 59% | 55.5% | 58.8% | 49% | 76% | 82.3% | 91% |\n| 云量 | 79.9% | 80% | 80% | 80% | 86.6% | 66.7% | 72.2% | 79.9% | [...] | 氣壓 | 1001.4hPa | 999.8hPa | 998.3hPa | 999.7hPa | 1001.2hPa | 1005.1hPa | 1009.1hPa | 1010.7hPa |\n| 濕度 | 46.2% | 29.2% | 17% | 24.7% | 25.7% | 53.5% | 46.7% | 39.9% |\n| 云量 | 41.2% | 10% | 10% | 10% | 4.6% | 4.6% | 4.5% | 4.4% |', 'score': 0.7636429, 'raw_content': None}, {'url': 'https://www.nmc.cn/publish/forecast/ABJ/beijing.html', 'title': '北京-天氣預報 - 中央氣象臺', 'content': '土壤水分監測\n       農業干旱綜合監測\n       關鍵農時農事\n       農業氣象周報\n       農業氣象月報\n       農業氣象專報\n       生態氣象監測評估\n       作物發育期監測\n\n   數值預報\n\n       CMA全球天氣模式\n       CMA全球集合模式\n       CMA區域模式\n       CMA區域集合模式\n       CMA臺風模式\n       海浪模式\n\n1.    當前位置:首頁\n2.   北京市\n3.   北京天氣預報\n\n省份:城市:\n\n09:50更新\n\n日出04:45\n\n 北京 \n\n30℃\n\n日落19:43\n\n 降水量 \n\n0mm\n\n西南風\n\n3級\n\n 相對濕度 \n\n43%\n\n 體感溫度 \n\n29.9℃\n\n空氣質量:良 \n\n舒適度:溫暖,較舒適\n\n 雷達圖 \n\nImage 4\n\n24小時預報7天預報10天預報11-30天預報\n\n 發布時間:06-12 08:00 \n\n 06/12 \n\n周四 \n\nImage 5\n\n 多云 \n\n 南風 \n\n 3~4級 \n\n 35℃ \n\n 23℃ \n\nImage 6', 'score': 0.741169, 'raw_content': None}], 'response_time': 0.85}), AIMessage(content='當前北京的天氣是晴朗,溫度大約為30℃,相對濕度約43%。西南風,3級風速。空氣質量為良,體感溫度約29.9℃,境況整體溫暖且較舒適。沒有降水。\n\n更多詳細天氣信息,您可以訪問[中國中央氣象臺提供的北京天氣預報](https://www.nmc.cn/publish/forecast/ABJ/beijing.html)。', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 141, 'prompt_tokens': 1172, 'total_tokens': 1313, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'gpt-4-turbo', 'system_fingerprint': 'fp_5603ee5e2e', 'id': 'chatcmpl-wikxZewxU0WqV8Bc66hx68DkE2xcM', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None}, id='run--a6c255f9-4b6b-48e5-b16d-e7a8e3864b6b-0', usage_metadata={'input_tokens': 1172, 'output_tokens': 141, 'total_tokens': 1313, 'input_token_details': {}, 'output_token_details': {}})]
[{"title": "中國氣象局-天氣預報- 北京", "url": "https://weather.cma.cn/web/weather/54511", "content": "| 氣壓 | 1010.2hPa | 1009.9hPa | 1006.9hPa | 1004.4hPa | 1004.2hPa | 1004.9hPa | 1004hPa | 1004.2hPa |\n| 濕度 | 71.7% | 66% | 62.4% | 60.2% | 59.4% | 65% | 84.4% | 96.6% |\n| 云量 | 44.5% | 31.9% | 27.2% | 10.1% | 79.9% | 79.9% | 79.9% | 79.9% | [...] | 氣壓 | 1007.6hPa | 1007.7hPa | 1006.3hPa | 1005.7hPa | 1007.6hPa | 1009.3hPa | 1009.5hPa | 1009.3hPa |\n| 濕度 | 68.9% | 59% | 55.5% | 58.8% | 49% | 76% | 82.3% | 91% |\n| 云量 | 79.9% | 80% | 80% | 80% | 86.6% | 66.7% | 72.2% | 79.9% | [...] | 氣壓 | 1001.4hPa | 999.8hPa | 998.3hPa | 999.7hPa | 1001.2hPa | 1005.1hPa | 1009.1hPa | 1010.7hPa |\n| 濕度 | 46.2% | 29.2% | 17% | 24.7% | 25.7% | 53.5% | 46.7% | 39.9% |\n| 云量 | 41.2% | 10% | 10% | 10% | 4.6% | 4.6% | 4.5% | 4.4% |", "score": 0.7636429}, {"title": "北京-天氣預報 - 中央氣象臺", "url": "https://www.nmc.cn/publish/forecast/ABJ/beijing.html", "content": "土壤水分監測\n       農業干旱綜合監測\n       關鍵農時農事\n       農業氣象周報\n       農業氣象月報\n       農業氣象專報\n       生態氣象監測評估\n       作物發育期監測\n\n   數值預報\n\n       CMA全球天氣模式\n       CMA全球集合模式\n       CMA區域模式\n       CMA區域集合模式\n       CMA臺風模式\n       海浪模式\n\n1.    當前位置:首頁\n2.   北京市\n3.   北京天氣預報\n\n省份:城市:\n\n09:50更新\n\n日出04:45\n\n 北京 \n\n30℃\n\n日落19:43\n\n 降水量 \n\n0mm\n\n西南風\n\n3級\n\n 相對濕度 \n\n43%\n\n 體感溫度 \n\n29.9℃\n\n空氣質量:良 \n\n舒適度:溫暖,較舒適\n\n 雷達圖 \n\nImage 4\n\n24小時預報7天預報10天預報11-30天預報\n\n 發布時間:06-12 08:00 \n\n 06/12 \n\n周四 \n\nImage 5\n\n 多云 \n\n 南風 \n\n 3~4級 \n\n 35℃ \n\n 23℃ \n\nImage 6", "score": 0.741169}]Process finished with exit code 0

Langchain構建RAG的對話應用

本案例是:復雜的問答 (Q&A) 聊天機器人。應用程序可以回答有關特定源信息的問題。使用一種稱為檢索增強生成 (RAG) 的技術。
RAG是一種增強大型語言模型(LLM)知識的方法,它通過引入額外的數據來實現。
pip install langgraph 用來創建代理的API
實現思路:
加載:首先,我們需要加載數據。這是通過DocumentLoaders完成的。
分割: Text splitters將大型文檔分割成更小的塊。這對于索引數據和將其傳遞給模型很有用,因為大塊數據更難搜索,并且不適合模型的有限上下文窗口。
存儲:我們需要一個地方來存儲和索引我們的分割,以便以后可以搜索。這通常使用VectorStore和Embeddings模型完成。
檢索:給定用戶輸入,使用檢索器從存儲中檢索相關分割。
生成:ChatModel / LLM使用包括問題和檢索到的數據的提示生成答案。

大文本切割

# 2、大文本的切割 每個片段包含20個字符,允許四個字符重復
text = "hello world, how about you? thanks, I am fine.  the machine learning class. So what I wanna do today is just spend a little time going over the logistics of the class, and then we'll start to talk a bit about machine learning"
splitter = RecursiveCharacterTextSplitter(chunk_size=20,chunk_overlap=4)
res = splitter.split_text(text)
for r in res:print(r,end='**\n')

在這里插入圖片描述

import os
import bs4
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain.chains.history_aware_retriever import create_history_aware_retriever
from langchain.chains.retrieval import create_retrieval_chain
from langchain_chroma import Chroma
from langchain_community.document_loaders import WebBaseLoader
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables import RunnableWithMessageHistory
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitteros.environ['LANGCHAIN_TRACING_V2'] = "true"
os.environ['LANGCHAIN_PROJECT'] ="LangchainDemo"
os.environ['LANGCHAIN_API_KEY'] = "xxx"
os.environ["TAVILY_API_KEY"] = 'tvly-xxx'
# 1.創建模型
model = ChatOpenAI(model='gpt-4-turbo',api_key='sk-xx',base_url='https://xiaoai.plus/v1')# 1、加載數據: 一篇博客內容數據
loader = WebBaseLoader(web_paths=['https://lilianweng.github.io/posts/2023-06-23-agent/'],bs_kwargs=dict(parse_only=bs4.SoupStrainer(class_=('post-header', 'post-title', 'post-content')))
)docs = loader.load()# print(len(docs))
# print(docs)# 2、大文本的切割
# text = "hello world, how about you? thanks, I am fine.  the machine learning class. So what I wanna do today is just spend a little time going over the logistics of the class, and then we'll start to talk a bit about machine learning"
splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)splits = splitter.split_documents(docs)# 2、存儲
vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings())# 3、檢索器
retriever = vectorstore.as_retriever()# 整合# 創建一個問題的模板
system_prompt = """You are an assistant for question-answering tasks. 
Use the following pieces of retrieved context to answer 
the question. If you don't know the answer, say that you 
don't know. Use three sentences maximum and keep the answer concise.\n{context}
"""##
# {context} 這個占位符是由 LangChain 框架自動處理的。在 RAG (Retrieval-Augmented Generation) 應用中,這個占位符會被 LangChain 在運行時動態替換為實際檢索到的相關上下文內容。
#
# 具體來說,工作流程是這樣的:
#
# 當用戶提問時,LangChain 會先通過檢索器(Retriever)從知識庫中查找與問題相關的文檔片段
# 這些檢索到的文檔片段會被自動填充到 {context} 的位置
# 然后連同用戶的問題一起組成完整的提示詞(Prompt)發送給大模型
# 大模型基于這個包含上下文的提示詞生成最終回答
# 所以你不需要手動傳遞 {context} 的值,這是 LangChain RAG 鏈(RAG chain)的標準工作方式。框架會自動處理檢索和上下文注入的過程。
#
# 這種設計是 LangChain 的常見模式,它通過模板和鏈(Chain)的概念,將檢索、提示詞構建和生成等步驟自動化地串聯起來。
# #prompt = ChatPromptTemplate.from_messages(  # 提問和回答的 歷史記錄  模板[("system", system_prompt),MessagesPlaceholder("chat_history"),  #("human", "{input}"),]
)# 得到chain (創建的是多個文本的)提示模板
chain1 = create_stuff_documents_chain(model, prompt)chain2 = create_retrieval_chain(retriever, chain1)resp = chain2.invoke({'input': "What is Task Decomposition?"})print(resp['answer'])

在這里插入圖片描述

包含歷史記錄的對話生成

import os
import bs4
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain.chains.history_aware_retriever import create_history_aware_retriever
from langchain.chains.retrieval import create_retrieval_chain
from langchain_chroma import Chroma
from langchain_community.document_loaders import WebBaseLoader
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables import RunnableWithMessageHistory
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitteros.environ['LANGCHAIN_TRACING_V2'] = "true"
os.environ['LANGCHAIN_PROJECT'] ="LangchainDemo"
os.environ['LANGCHAIN_API_KEY'] = ""
os.environ["TAVILY_API_KEY"] = 'tvly-xxx'
# 1.創建模型
model = ChatOpenAI(model='gpt-4-turbo',api_key='sk-xx',base_url='https://xiaoai.plus/v1')# 1、加載數據: 一篇博客內容數據
loader = WebBaseLoader(web_paths=['https://lilianweng.github.io/posts/2023-06-23-agent/'],bs_kwargs=dict(parse_only=bs4.SoupStrainer(class_=('post-header', 'post-title', 'post-content')))
)docs = loader.load()# print(len(docs))
# print(docs)# 2、大文本的切割
# text = "hello world, how about you? thanks, I am fine.  the machine learning class. So what I wanna do today is just spend a little time going over the logistics of the class, and then we'll start to talk a bit about machine learning"
splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)splits = splitter.split_documents(docs)# 2、存儲
vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings())# 3、檢索器
retriever = vectorstore.as_retriever()# 整合# 創建一個問題的模板
system_prompt = """You are an assistant for question-answering tasks. 
Use the following pieces of retrieved context to answer 
the question. If you don't know the answer, say that you 
don't know. Use three sentences maximum and keep the answer concise.\n{context}
"""##
# {context} 這個占位符是由 LangChain 框架自動處理的。在 RAG (Retrieval-Augmented Generation) 應用中,這個占位符會被 LangChain 在運行時動態替換為實際檢索到的相關上下文內容。
#
# 具體來說,工作流程是這樣的:
#
# 當用戶提問時,LangChain 會先通過檢索器(Retriever)從知識庫中查找與問題相關的文檔片段
# 這些檢索到的文檔片段會被自動填充到 {context} 的位置
# 然后連同用戶的問題一起組成完整的提示詞(Prompt)發送給大模型
# 大模型基于這個包含上下文的提示詞生成最終回答
# 所以你不需要手動傳遞 {context} 的值,這是 LangChain RAG 鏈(RAG chain)的標準工作方式。框架會自動處理檢索和上下文注入的過程。
#
# 這種設計是 LangChain 的常見模式,它通過模板和鏈(Chain)的概念,將檢索、提示詞構建和生成等步驟自動化地串聯起來。
# #prompt = ChatPromptTemplate.from_messages(  # 提問和回答的 歷史記錄  模板[("system", system_prompt),MessagesPlaceholder("chat_history"),  #("human", "{input}"),]
)# 得到chain (創建的是多個文本的)提示模板
chain1 = create_stuff_documents_chain(model, prompt)# chain2 = create_retrieval_chain(retriever, chain1)# resp = chain2.invoke({'input': "What is Task Decomposition?"})
#
# print(resp['answer'])'''
注意:
一般情況下,我們構建的鏈(chain)直接使用輸入問答記錄來關聯上下文。但在此案例中,查詢檢索器也需要對話上下文才能被理解。解決辦法:
添加一個子鏈(chain),它采用最新用戶問題和聊天歷史,并在它引用歷史信息中的任何信息時重新表述問題。這可以被簡單地認為是構建一個新的“歷史感知”檢索器。
這個子鏈的目的:讓檢索過程融入了對話的上下文。
'''# 創建一個子鏈
# 子鏈的提示模板
contextualize_q_system_prompt = """Given a chat history and the latest user question 
which might reference context in the chat history, 
formulate a standalone question which can be understood 
without the chat history. Do NOT answer the question, 
just reformulate it if needed and otherwise return it as is."""retriever_history_temp = ChatPromptTemplate.from_messages([('system', contextualize_q_system_prompt),MessagesPlaceholder('chat_history'),("human", "{input}"),]
)# 創建一個子鏈
history_chain = create_history_aware_retriever(model, retriever, retriever_history_temp)# 保持問答的歷史記錄
store = {}class ChatMessageHistory:passdef get_session_history(session_id: str):if session_id not in store:store[session_id] = ChatMessageHistory()return store[session_id]# 創建父鏈chain: 把前兩個鏈整合
chain = create_retrieval_chain(history_chain, chain1)result_chain = RunnableWithMessageHistory(chain,get_session_history,input_messages_key='input',history_messages_key='chat_history',output_messages_key='answer'
)# 第一輪對話
resp1 = result_chain.invoke({'input': 'What is Task Decomposition?'},config={'configurable': {'session_id': 'zs123456'}}
)print(resp1['answer'])# 第二輪對話
resp2 = result_chain.invoke({'input': 'What are common ways of doing it?'},config={'configurable': {'session_id': 'ls123456'}}
)print(resp2['answer'])

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

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

相關文章

Flutter基礎(前端教程①-容器和控件位置)

一個紅色背景的 Container垂直排列的 Column 布局中央的 ElevatedButton按鈕下方的白色文本import package:flutter/material.dart;void main() {runApp(const MyApp()); }class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);overrideWidget bu…

CSS flex

目錄 flex-box和flex-item 主軸和副軸 ?編輯 flex-box的屬性 flex-direction flex-wrap flex-flow justify-content ?編輯?align-items align-content flex-item的屬性 flex-basis flex-grow flex-shrink flex flex-box和flex-item 當把一個塊級元素的displ…

【JMeter】執行系統命令

步驟如下: 添加JSP233 Sampler:右擊線程組>添加>取樣器>JSR223 Sampler2.填寫腳本,執行后查看日志。res "ipconfig".execute().text log.info(res)res "python -c \"print(11)\"".execute().text l…

AI Agent開發學習系列 - langchain之memory(1):內存中的短時記憶

內存中的短時記憶,在 LangChain 中通常指 ConversationBufferMemory 這類“對話緩沖記憶”工具。它的作用是:在內存中保存最近的對話歷史,讓大模型能理解上下文,實現連續對話。 對話緩沖記憶”工具 主要特點 只保留最近的對話內容…

uniapp實現微信小程序端圖片保存到相冊

效果圖展示 安裝插件海報畫板導入到項目里面&#xff0c;在頁面直接使用 <template><view><button click"saveToAlbum" class"save-button">保存到相冊</button><image :src"path" mode"widthFix" v-if&qu…

Java生產帶文字、帶邊框的二維碼

Java 生成帶文字、帶邊框的二維碼1、Java 生成帶文字的二維碼1.1、導入jar包1.2、普通單一的二維碼1.2.1、代碼示例1.2.2、效果1.3、帶文字的二維碼1.&#xff13;.&#xff11;、代碼示例1.3.2、效果2、帶邊框的二維碼2.1、代碼示例2.2、帶邊框的二維碼效果 1、Java 生成帶文字…

ARM單片機啟動流程(三)(棧空間綜合理解及相關實際應用)

文章目錄1、引出棧空間問題2、解決問題2.1、RAM空間2.2、RAM空間具體分布2.3、關于棧空間的使用2.4、棧溢出2.5、變量的消亡2.6、回到關鍵字static2.7、合法性的判斷1、引出棧空間問題 從static關鍵字引出該部分內容。 為什么能從static引出來&#xff1f; 在使用該關鍵字的…

【RK3568+PG2L50H開發板實驗例程】FPGA部分 | 鍵控LED實驗

本原創文章由深圳市小眼睛科技有限公司創作&#xff0c;版權歸本公司所有&#xff0c;如需轉載&#xff0c;需授權并注明出處&#xff08;www.meyesemi.com) 1.實驗簡介 實驗目的&#xff1a; 從創建工程到編寫代碼&#xff0c;完成引腳約束&#xff0c;最后生成 bit 流下載到…

【Python練習】039. 編寫一個函數,反轉一個單鏈表

039. 編寫一個函數,反轉一個單鏈表 039. 編寫一個函數,反轉一個單鏈表方法 1:迭代實現運行結果代碼解釋方法 2:遞歸實現運行結果代碼解釋選擇方法迭代法與遞歸法的區別039. 編寫一個函數,反轉一個單鏈表 在 Python 中,可以通過迭代或遞歸的方式反轉一個單鏈表。 方法 1…

BERT代碼簡單筆記

參考視頻&#xff1a;BERT代碼(源碼)從零解讀【Pytorch-手把手教你從零實現一個BERT源碼模型】_嗶哩嗶哩_bilibili 一、BertTokenizer BertTokenizer 是基于 WordPiece 算法的 BERT 分詞器&#xff0c;繼承自 PreTrainedTokenizer。 繼承的PretrainedTokenizer&#xff0c;具…

PID控制算法理論學習基礎——單級PID控制

這是一篇我在學習PID控制算法的過程中的學習記錄。在一開始學習PID的時候&#xff0c;我也看了市面上許多的資料&#xff0c;好的資料固然有&#xff0c;但是更多的是不知所云。&#xff08;有的是寫的太過深奧&#xff0c;有的則是照搬挪用&#xff0c;對原理則一問三不知&…

【Elasticsearch】function_score與rescore

它們倆都是用來“**干涉評分**”的&#xff0c;但**工作階段不同、性能開銷不同、能做的事也不同**。一句話總結&#xff1a;> **function_score** 在 **第一次算分** 時就動手腳&#xff1b; > **rescore** 在 **拿到 Top-N 結果后** 再“重新打分”。下面把“能干嘛”…

無廣告純凈體驗 WPS2016 精簡版:移除聯網模塊 + 非核心組件,古董電腦也能跑

各位辦公小能手們&#xff01;今天給你們介紹一款超神的辦公軟件——WPS2016精簡版&#xff01;它有多小呢&#xff1f;才33MB&#xff0c;簡直就是軟件界的小不點兒&#xff01;別看它個頭小&#xff0c;功能可一點兒都不含糊&#xff0c;文字、表格、演示這三大功能它全都有。…

《PyWin32:Python與Windows的橋梁,解鎖系統自動化新姿勢》

什么是 PyWin32在 Windows 平臺的 Python 開發領域中&#xff0c;PyWin32 是一個舉足輕重的庫&#xff0c;它為 Python 開發者打開了一扇直接通往 Windows 操作系統底層功能的大門。簡單來說&#xff0c;PyWin32 是用于 Python 訪問 Windows API&#xff08;Application Progra…

vite如何生成gzip,并在服務器上如何設置開啟

1. 安裝插件npm install vite-plugin-compression -D2. 在 vite.config.ts 中配置TypeScriptimport { defineConfig } from vite import compression from vite-plugin-compressionexport default defineConfig({plugins: [compression({algorithm: gzip,ext: .gz,threshold: 1…

1068萬預算!中國足協大模型項目招標,用AI技術驅動足球革命

中國足協啟動國際足聯“前進計劃”下的大數據模型項目&#xff0c;預算1068萬元。該項目將建立足球大數據分析平臺&#xff0c;利用AI技術為國家隊、青少年足球、業余球員及教練員裁判員提供精準數據分析服務&#xff0c;旨在通過科技手段提升中國足球競技水平。 中國足球迎來數…

AI產品經理面試寶典第12天:AI產品經理的思維與轉型路徑面試題與答法

多樣化思維:如何跳出單一框架解題? 面試官:AI產品常面臨復雜場景,請舉例說明你如何運用多樣化思維解決問題? 你的回答:我會從三個維度展開:多角度拆解需求本質,多層級融合思維模式,多變量尋找最優解。比如設計兒童教育機器人時,不僅考慮功能實現(技術層),還融入情…

vscode.window對象講解

一、vscode.window 核心架構圖 #mermaid-svg-fyCxPz1vVhkf96nE {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-fyCxPz1vVhkf96nE .error-icon{fill:#552222;}#mermaid-svg-fyCxPz1vVhkf96nE .error-text{fill:#5522…

為什么一個 @Transactional 注解就能開啟事務?揭秘 Spring AOP 的底層魔法

你是否也曾深陷在各種“額外”邏輯的泥潭&#xff0c;為了給一個核心業務方法增加日志、權限校驗或緩存&#xff0c;而不得不將這些非核心代碼硬塞進業務類中&#xff0c;導致代碼臃腫、職責不清&#xff1f;是時候用代理設計模式 (Proxy Design Pattern) 來解脫了&#xff01;…

《Spring 中上下文傳遞的那些事兒》Part 8:構建統一上下文框架設計與實現(實戰篇)

&#x1f4dd; Part 8&#xff1a;構建統一上下文框架設計與實現&#xff08;實戰篇&#xff09; 在實際項目中&#xff0c;我們往往需要處理多種上下文來源&#xff0c;例如&#xff1a; Web 請求上下文&#xff08;RequestContextHolder&#xff09;日志追蹤上下文&#xf…