当前位置: 首页 > news >正文

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.dtcms.com/a/275516.html

相关文章:

  • Android音视频探索之旅 | C++层使用OpenGL ES实现视频渲染
  • CTFHub————Web{信息泄露[Git泄露(log)]}
  • 《Java Web程序设计》实验报告五 Java Script学习汇报
  • Redis Geospatial 功能详解及多边形包含判断实现
  • win10安装Rust Webassembly工具链(wasm-pack)报错。
  • Rust Web 全栈开发(五):使用 sqlx 连接 MySQL 数据库
  • Rust Web 全栈开发(六):在 Web 项目中使用 MySQL 数据库
  • 前端note
  • 【推荐】前端低端机和弱网环境下性能优化
  • 前端面试专栏-算法篇:24. 算法时间与空间复杂度分析
  • 在前端开发中关于reflow(回流)和repaint(重绘)的几点思考
  • MySQL 中图标字符存储问题探究:使用外挂法,毕业论文——仙盟创梦IDE
  • AI驱动的大前端内容创作与个性化推送:资讯类应用实战指南
  • 容器化改造避坑指南:传统应用迁移K8s的10个关键节点(2025实战复盘)
  • CSS flex
  • Capsule Networks:深度学习中的空间关系建模革命
  • GGE Lua 详细教程
  • 《Java Web程序设计》实验报告四 Java Script前端应用和表单验证
  • 基于Java的Markdown到Word文档转换工具的实现
  • 基于大模型的鼻咽癌全周期预测及诊疗优化研究报告
  • EPLAN 电气制图(七):电缆设计全攻略
  • 系统学习Python——并发模型和异步编程:基础实例-[使用进程实现旋转指针]
  • 代码训练LeetCode(45)旋转图像
  • 【算法笔记】7.LeetCode-Hot100-图论专项
  • 【node/vue】css制作可3D旋转倾斜的图片,朝向鼠标
  • 每日算法刷题Day46 7.12:leetcode前缀和3道题和差分2道题,用时1h30min
  • 代码训练LeetCode(46)旋转图像
  • Python爬虫实战:研究python-docx库相关技术
  • AI软件出海SEO教程
  • 26. 删除有序数组中的重复项