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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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…