开启左侧

Langchain的使用

[复制链接]
RomaQ34306 发表于 5 天前 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
作者:天天牛马水
一、课程地址

java版本
java版本的笔记
py版本
py版本的笔记
py坑,之前版本好像Langchain好像没有中断流式输出的方法----来源别的课程老师说的
二、介绍

1、是什么

LangChain是一个用于开发自由语言模型驱动的应用程序的框架
Langchain的使用-1.png


2、为什么使用

Langchain的使用-2.png


3、核心

Langchain的使用-3.png


4、底层原理

Langchain的使用-4.png


5、应用场景

Langchain的使用-5.png


三、简单的调用(包含LangServe)

1、安装
  1. pip install langchain
  2. # 如果使用openai模型就需要执行下面
  3. pip install langchain-openai
复制代码
2、监控工具介绍(LangSmish)

日志分析的工具:登录获取key
获取apiKey
Langchain的使用-6.png


Langchain的使用-7.png

Langchain的使用-8.png

Langchain的使用-9.png


3、配置open的apikey

Langchain的使用-10.png


4、代码

1、调试

localhost:8000/chainDemo/playground/
进行调试

Langchain的使用-11.png


2、代码
  1. import os
  2. from fastapi import FastAPI
  3. from langchain_core.messages import SystemMessage, HumanMessage
  4. from langchain_core.output_parsers import StrOutputParser
  5. from langchain_core.prompts import ChatPromptTemplate
  6. from langchain_openai import ChatOpenAI
  7. from langserve import add_routes
  8. # 代理设置
  9. os.environ['http_proxy']='127.0.0.1:7890'
  10. os.environ['https_proxy']='127.0.0.1:7890'# 是否代码追踪  不设置为true会默认使用v1  也可以不使用以下追踪
  11. os.environ["LANGCHAIN_TRACING_V2"]="true"# os.environ["LANGCHAIN_ENDPOINT"] = "https://api.smith.langchain.com"
  12. os.environ["LANGCHAIN_PROJECT"]="LangchainDemo"
  13. os.environ["LANGCHAIN_API_KEY"]='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'# 调用大语言模型# 创建模型
  14. model = ChatOpenAI(model='gpt-4-turbo')# 2、准备prompt
  15. msg =[
  16.     SystemMessage(content='请将以下的内容翻译成意大利语'),# 系统指令
  17.     HumanMessage(content='你好,请问你要去哪里?')# 普通用户]# 直接返回数据显示消耗的token等# result = model.invoke(msg)# print(result)# 简单的解析响应数据 只输出回复内容 不显示消耗的token等# 3、创建返回的数据解析器
  18. parser = StrOutputParser()# 只打印文本# print(parser.invoke(result))# 定义提示模板
  19. prompt_template = ChatPromptTemplate.from_messages([('system','请将下面的内容翻译成{language}'),('user',"{text}")])# 4、得到链
  20. chain = prompt_template | model | parser
  21. # 5、 直接使用chain来调用# print(chain.invoke(msg))print(chain.invoke({'language':'English','text':'我下午还有一节课,不能去打球了。'}))# 把我们的程序部署成服务# 创建fastAPI的应用
  22. app = FastAPI(title='我的Langchain服务', version='V1.0', description='使用Langchain翻译任何语句的服务器')
  23. add_routes(
  24.     app,
  25.     chain,
  26.     path="/chainDemo",)if __name__ =="__main__":import uvicorn
  27.     uvicorn.run(app, host="localhost", port=8000)
复制代码
5、调用

Langchain的使用-12.png

  1. from langserve import RemoteRunnable
  2. if __name__ =='__main__':
  3.     client = RemoteRunnable('http://127.0.0.1:8000/chainDemo/')print(client.invoke({'language':'italian','text':'你好!'})
复制代码
6、拓展

如果使用别的模型可以从一中py课件中替换别的模型进行pip和导入包,可以找ai去问
Langchain的使用-13.png


四、保存历史记录和流式输出

1、基于内存

第三轮为流式输出
  1. import os
  2. from langchain_community.chat_message_histories import ChatMessageHistory
  3. from langchain_core.messages import HumanMessage
  4. from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
  5. from langchain_core.runnables import RunnableWithMessageHistory
  6. from langchain_openai import ChatOpenAI
  7. from langserve import add_routes
  8. os.environ['http_proxy']='127.0.0.1:7890'
  9. os.environ['https_proxy']='127.0.0.1:7890'
  10. os.environ["LANGCHAIN_TRACING_V2"]="true"
  11. os.environ["LANGCHAIN_PROJECT"]="LangchainDemo"
  12. os.environ["LANGCHAIN_API_KEY"]='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'# 聊天机器人案例# 创建模型
  13. model = ChatOpenAI(model='gpt-4-turbo')# 定义提示模板
  14. prompt_template = ChatPromptTemplate.from_messages([('system','你是一个乐于助人的助手。用{language}尽你所能回答所有问题。'),
  15.     MessagesPlaceholder(variable_name='my_msg')])# 得到链
  16. chain = prompt_template | model
  17. # 保存聊天的历史记录
  18. store ={}# 所有用户的聊天记录都保存到store。   key: sessionId,value: 历史聊天记录对象# 此函数预期将接收一个session_id并返回一个消息历史记录对象。defget_session_history(session_id:str):if session_id notin store:
  19.         store[session_id]= ChatMessageHistory()return store[session_id]
  20. do_message = RunnableWithMessageHistory(
  21.     chain,
  22.     get_session_history,
  23.     input_messages_key='my_msg'# 每次聊天时候发送msg的key)
  24. config ={'configurable':{'session_id':'zs1234'}}# 给当前会话定义一个sessionId# 第一轮
  25. resp1 = do_message.invoke({'my_msg':[HumanMessage(content='你好啊! 我是LaoXiao')],'language':'中文'},
  26.     config=config
  27. )print(resp1.content)# 第二轮
  28. resp2 = do_message.invoke({'my_msg':[HumanMessage(content='请问:我的名字是什么?')],'language':'中文'},
  29.     config=config
  30. )print(resp2.content)# 第3轮: 返回的数据是流式的
  31. config ={'configurable':{'session_id':'lis2323'}}# 给当前会话定义一个sessionIdfor resp in do_message.stream({'my_msg':[HumanMessage(content='请给我讲一个笑话?')],'language':'English'},
  32.                               config=config):# 每一次resp都是一个tokenprint(resp.content, end='-')
复制代码
2、 持久化
  1. import os
  2. from pymongo import MongoClient
  3. from langchain_community.chat_message_histories import ChatMessageHistory
  4. from langchain_core.messages import HumanMessage
  5. from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
  6. from langchain_core.runnables import RunnableWithMessageHistory
  7. from langchain_openai import ChatOpenAI
  8. # ---------- 环境变量 ----------
  9. os.environ['http_proxy']='127.0.0.1:7890'
  10. os.environ['https_proxy']='127.0.0.1:7890'
  11. os.environ["LANGCHAIN_TRACING_V2"]="true"
  12. os.environ["LANGCHAIN_PROJECT"]="LangchainDemo"
  13. os.environ["LANGCHAIN_API_KEY"]='你的API_KEY'# ---------- MongoDB 配置 ----------
  14. client = MongoClient('mongodb://localhost:27017')
  15. db = client['chat_db']
  16. collection = db['chat_history']defsave_history_to_db(session_id, history: ChatMessageHistory):
  17.     messages =[{'role': m.type,'content': m.content}for m in history.messages]
  18.     collection.update_one({'session_id': session_id},{'$set':{'messages': messages}},
  19.         upsert=True)defload_history_from_db(session_id)-> ChatMessageHistory:
  20.     doc = collection.find_one({'session_id': session_id})
  21.     hist = ChatMessageHistory()if doc:for m in doc['messages']:if m['role']=='human':
  22.                 hist.add_user_message(m['content'])else:
  23.                 hist.add_ai_message(m['content'])return hist
  24. # ---------- 聊天机器人初始化 ----------
  25. model = ChatOpenAI(model='gpt-4-turbo')
  26. prompt_template = ChatPromptTemplate.from_messages([('system','你是一个乐于助人的助手。用{language}尽你所能回答所有问题。'),
  27.     MessagesPlaceholder(variable_name='my_msg')])
  28. chain = prompt_template | model
  29. # ---------- 带持久化的 Runnable ----------
  30. store ={}# 内存缓存defget_session_history(session_id:str):if session_id notin store:
  31.         store[session_id]= load_history_from_db(session_id)return store[session_id]classPersistedRunnableWithMessageHistory(RunnableWithMessageHistory):definvoke(self,input, config=None):
  32.         result =super().invoke(input, config=config)# 每次调用完成后自动保存
  33.         session_id = config['configurable']['session_id']
  34.         save_history_to_db(session_id, store[session_id])return result
  35.     defstream(self,input, config=None):for token insuper().stream(input, config=config):yield token
  36.         # 流结束后保存历史
  37.         session_id = config['configurable']['session_id']
  38.         save_history_to_db(session_id, store[session_id])
  39. do_message = PersistedRunnableWithMessageHistory(
  40.     chain,
  41.     get_session_history,
  42.     input_messages_key='my_msg')# ---------- 测试 ----------
  43. config ={'configurable':{'session_id':'user123'}}# 第一轮
  44. resp1 = do_message.invoke({'my_msg':[HumanMessage(content='你好,我是LaoXiao')],'language':'中文'},
  45.     config=config
  46. )print(resp1.content)# 第二轮
  47. resp2 = do_message.invoke({'my_msg':[HumanMessage(content='你还记得我是谁吗?')],'language':'中文'},
  48.     config=config
  49. )print(resp2.content)# 第三轮,流式输出for resp in do_message.stream({'my_msg':[HumanMessage(content='讲个笑话给我听吧')],'language':'中文'},
  50.         config=config):print(resp.content, end='')
复制代码
3、 封装好的持久化

Langchain的使用-14.png

Langchain的使用-15.png


五、构建代理(工具的使用)

1、 代理+工具
  1. import os
  2. from langchain_community.tools.tavily_search import TavilySearchResults
  3. from langchain_core.messages import HumanMessage
  4. from langchain_openai import ChatOpenAI, OpenAIEmbeddings
  5. from langgraph.prebuilt import chat_agent_executor
  6. from langserve import add_routes
  7. os.environ['http_proxy']='127.0.0.1:7890'
  8. os.environ['https_proxy']='127.0.0.1:7890'
  9. os.environ["LANGCHAIN_TRACING_V2"]="true"
  10. os.environ["LANGCHAIN_PROJECT"]="LangchainDemo"
  11. os.environ["LANGCHAIN_API_KEY"]='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'# 工具的key
  12. os.environ["TAVILY_API_KEY"]='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'# 聊天机器人案例# 创建模型
  13. model = ChatOpenAI(model='gpt-4-turbo')# 没有任何代理的情况下# result = model.invoke([HumanMessage(content='北京天气怎么样?')])# print(result)# LangChain内置了一个工具,可以轻松地使用Tavily搜索引擎作为工具。
  14. search = TavilySearchResults(max_results=2)#  max_results: 只返回两个结果# print(search.invoke('北京的天气怎么样?'))# 让模型绑定工具
  15. 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}')#  创建代理
  16. agent_executor = chat_agent_executor.create_tool_calling_executor(model, tools)# 其实也不需要给key,这里给key是为了后面取值方便
  17. resp = agent_executor.invoke({'messages':[HumanMessage(content='中国的首都是哪个城市?')]})print(resp['messages'])
  18. resp2 = agent_executor.invoke({'messages':[HumanMessage(content='北京天气怎么样?')]})print(resp2['messages'])print(resp2['messages'][2].content)
复制代码
2、 自定义工具

1. 方式一
  1. from langchain_core.tools import tool
  2. # 自定义一个工具:比如计算字符串的长度@tooldefget_text_length(text:str)->int:"""返回输入文本的长度"""returnlen(text)# 使用方法print(get_text_length.invoke("你好世界"))# 输出 4
复制代码
使用
  1. from langchain_openai import ChatOpenAI
  2. from langgraph.prebuilt import chat_agent_executor
  3. model = ChatOpenAI(model="gpt-4-turbo")# 工具列表
  4. tools =[get_text_length]# 创建代理
  5. agent_executor = chat_agent_executor.create_tool_calling_executor(model, tools)
  6. resp = agent_executor.invoke({"messages":[{"role":"user","content":"请帮我算一下 'LangChain' 有几个字符?"}]})print(resp["messages"][-1].content)
复制代码
2. 方式二
  1. from langchain_core.tools import BaseTool
  2. classReverseStringTool(BaseTool):
  3.     name ="reverse_string"
  4.     description ="把输入的字符串反转"def_run(self, text:str)->str:return text[::-1]# 创建工具实例
  5. reverse_tool = ReverseStringTool()# 测试print(reverse_tool.invoke("LangChain"))# 输出 "niahCgnaL"
复制代码
使用reverse_tool 放到tools中即可
六、构建向量数据库和检索器(RAG)

输出的条数限制等情况,其实不太适合作为查某个字出现多少条的
  1. import os
  2. from langchain_chroma import Chroma
  3. from langchain_community.chat_message_histories import ChatMessageHistory
  4. from langchain_core.documents import Document
  5. from langchain_core.messages import HumanMessage
  6. from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
  7. from langchain_core.runnables import RunnableWithMessageHistory, RunnableLambda, RunnablePassthrough
  8. from langchain_openai import ChatOpenAI, OpenAIEmbeddings
  9. from langserve import add_routes
  10. os.environ['http_proxy']='127.0.0.1:7890'
  11. os.environ['https_proxy']='127.0.0.1:7890'
  12. os.environ["LANGCHAIN_TRACING_V2"]="true"
  13. os.environ["LANGCHAIN_PROJECT"]="LangchainDemo"
  14. os.environ["LANGCHAIN_API_KEY"]='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'# 聊天机器人案例# 创建模型
  15. model = ChatOpenAI(model='gpt-4-turbo')# 准备测试数据 ,假设我们提供的文档数据如下:
  16. documents =[
  17.     Document(
  18.         page_content="狗是伟大的伴侣,以其忠诚和友好而闻名。",
  19.         metadata={"source":"哺乳动物宠物文档"},),
  20.     Document(
  21.         page_content="猫是独立的宠物,通常喜欢自己的空间。",
  22.         metadata={"source":"哺乳动物宠物文档"},),
  23.     Document(
  24.         page_content="金鱼是初学者的流行宠物,需要相对简单的护理。",
  25.         metadata={"source":"鱼类宠物文档"},),
  26.     Document(
  27.         page_content="鹦鹉是聪明的鸟类,能够模仿人类的语言。",
  28.         metadata={"source":"鸟类宠物文档"},),
  29.     Document(
  30.         page_content="兔子是社交动物,需要足够的空间跳跃。",
  31.         metadata={"source":"哺乳动物宠物文档"},),]# 实例化一个向量数空间
  32. vector_store = Chroma.from_documents(documents, embedding=OpenAIEmbeddings())# 相似度的查询: 返回相似的分数, 分数越低相似度越高# print(vector_store.similarity_search_with_score('咖啡猫'))# 检索器: bind(k=1) 返回相似度最高的第一个
  33. retriever = RunnableLambda(vector_store.similarity_search).bind(k=1)# print(retriever.batch(['咖啡猫', '鲨鱼']))# 提示模板
  34. message ="""
  35. 使用提供的上下文仅回答这个问题:
  36. {question}
  37. 上下文:
  38. {context}
  39. """
  40. prompt_temp = ChatPromptTemplate.from_messages([('human', message)])# RunnablePassthrough允许我们将用户的问题之后再传递给prompt和model。
  41. chain ={'question': RunnablePassthrough(),'context': retriever}| prompt_temp | model
  42. resp = chain.invoke('请介绍一下猫?')print(resp.content)
复制代码
七、RAG对话应用(切割)

1、思路

Langchain的使用-16.png


2、切割

一句话几个字符,后面是重复的

Langchain的使用-17.png


3、代码(RAG中检索库不能理解上下文中连贯的内容意思解决方案)
  1. import os
  2. import bs4
  3. from langchain.chains.combine_documents import create_stuff_documents_chain
  4. from langchain.chains.history_aware_retriever import create_history_aware_retriever
  5. from langchain.chains.retrieval import create_retrieval_chain
  6. from langchain_chroma import Chroma
  7. from langchain_community.document_loaders import WebBaseLoader
  8. from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
  9. from langchain_core.runnables import RunnableWithMessageHistory
  10. from langchain_text_splitters import RecursiveCharacterTextSplitter
  11. from langchain_community.chat_message_histories import ChatMessageHistory
  12. from langchain_openai import ChatOpenAI, OpenAIEmbeddings
  13. os.environ['http_proxy']='127.0.0.1:7890'
  14. os.environ['https_proxy']='127.0.0.1:7890'
  15. os.environ["LANGCHAIN_TRACING_V2"]="true"
  16. os.environ["LANGCHAIN_PROJECT"]="LangchainDemo"
  17. os.environ["LANGCHAIN_API_KEY"]='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'# os.environ["TAVILY_API_KEY"] = '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'# 聊天机器人案例# 创建模型
  18. model = ChatOpenAI(model='gpt-4-turbo')# 1、加载数据: 一篇博客内容数据
  19. loader = WebBaseLoader(
  20.     web_paths=['https://lilianweng.github.io/posts/2023-06-23-agent/'],
  21.     bs_kwargs=dict(
  22.         parse_only=bs4.SoupStrainer(class_=('post-header','post-title','post-content'))))
  23. 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"
  24. splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)# 一篇1000个字符的文本进行切割,重复200字符
  25. splits = splitter.split_documents(docs)# 2、存储 落到库里是向量+文本+元信息"""
  26. 例如
  27. {
  28.   "id": "uuid-123456",        // 唯一ID
  29.   "embedding": [0.0123, -0.98, ...],  // 向量,高维浮点数组
  30.   "document": "这是原始的文本片段",  // 你切分后的文本
  31.   "metadata": {                // 附带的元信息
  32.     "source": "example.txt",
  33.     "page": 12,
  34.     "chunk": 1
  35.   }
  36. }
  37. """
  38. vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings())# 3、检索器
  39. retriever = vectorstore.as_retriever()# 整合# 创建一个问题的模板
  40. system_prompt ="""You are an assistant for question-answering tasks.
  41. Use the following pieces of retrieved context to answer
  42. the question. If you don't know the answer, say that you
  43. don't know. Use three sentences maximum and keep the answer concise.\n
  44. {context}
  45. """
  46. prompt = ChatPromptTemplate.from_messages(# 提问和回答的 历史记录  模板[("system", system_prompt),
  47.         MessagesPlaceholder("chat_history"),#第一个输出报错就注释掉这个("human","{input}"),])# 得到chain
  48. chain1 = create_stuff_documents_chain(model, prompt)# chain2 = create_retrieval_chain(retriever, chain1)# resp = chain2.invoke({'input': "What is Task Decomposition?"})## print(resp['answer'])'''
  49. 注意:
  50. 一般情况下,我们构建的链(chain)直接使用输入问答记录来关联上下文。但在此案例中,查询检索器也需要对话上下文才能被理解。
  51. 解决办法:
  52. 添加一个子链(chain),它采用最新用户问题和聊天历史,并在它引用历史信息中的任何信息时重新表述问题。这可以被简单地认为是构建一个新的“历史感知”检索器。
  53. 这个子链的目的:让检索过程融入了对话的上下文。
  54. '''# 创建一个子链# 子链的提示模板# 帮助检索器理解上下文的
  55. contextualize_q_system_prompt ="""Given a chat history and the latest user question
  56. which might reference context in the chat history,
  57. formulate a standalone question which can be understood
  58. without the chat history. Do NOT answer the question,
  59. just reformulate it if needed and otherwise return it as is."""
  60. retriever_history_temp = ChatPromptTemplate.from_messages([('system', contextualize_q_system_prompt),
  61.         MessagesPlaceholder('chat_history'),("human","{input}"),])# 创建一个子链
  62. history_chain = create_history_aware_retriever(model, retriever, retriever_history_temp)# 保持问答的历史记录
  63. store ={}defget_session_history(session_id:str):if session_id notin store:
  64.         store[session_id]= ChatMessageHistory()return store[session_id]# 创建父链chain: 把前两个链整合
  65. chain = create_retrieval_chain(history_chain, chain1)
  66. result_chain = RunnableWithMessageHistory(
  67.     chain,
  68.     get_session_history,
  69.     input_messages_key='input',
  70.     history_messages_key='chat_history',
  71.     output_messages_key='answer'# 输出的键定义)# 第一轮对话
  72. resp1 = result_chain.invoke({'input':'What is Task Decomposition?'},
  73.     config={'configurable':{'session_id':'zs123456'}})print(resp1['answer'])# 第二轮对话
  74. resp2 = result_chain.invoke({'input':'What are common ways of doing it?'},
  75.     config={'configurable':{'session_id':'ls123456'}})print(resp2['answer'])
复制代码
八、读取数据库

1、 链接数据库(SQLAlchemy)

简单介绍地址
2、 代码1 gpt4不能用

Langchain的使用-18.png

  1. import os
  2. from operator import itemgetter
  3. import bs4
  4. from langchain.chains.combine_documents import create_stuff_documents_chain
  5. from langchain.chains.history_aware_retriever import create_history_aware_retriever
  6. from langchain.chains.retrieval import create_retrieval_chain
  7. from langchain.chains.sql_database.query import create_sql_query_chain
  8. from langchain_chroma import Chroma
  9. from langchain_community.document_loaders import WebBaseLoader
  10. from langchain_community.tools import QuerySQLDataBaseTool
  11. from langchain_community.utilities import SQLDatabase
  12. from langchain_core.output_parsers import StrOutputParser
  13. from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder, PromptTemplate
  14. from langchain_core.runnables import RunnableWithMessageHistory, RunnablePassthrough
  15. from langchain_text_splitters import RecursiveCharacterTextSplitter
  16. from langchain_community.chat_message_histories import ChatMessageHistory
  17. from langchain_openai import ChatOpenAI, OpenAIEmbeddings
  18. os.environ['http_proxy']='127.0.0.1:7890'
  19. os.environ['https_proxy']='127.0.0.1:7890'
  20. os.environ["LANGCHAIN_TRACING_V2"]="true"
  21. os.environ["LANGCHAIN_PROJECT"]="LangchainDemo"
  22. os.environ["LANGCHAIN_API_KEY"]='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'# os.environ["TAVILY_API_KEY"] = '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'# 聊天机器人案例# 创建模型
  23. model = ChatOpenAI(model='gpt-3.5-turbo')# sqlalchemy 初始化MySQL数据库的连接
  24. HOSTNAME ='127.0.0.1'
  25. PORT ='3306'
  26. DATABASE ='test_db8'
  27. USERNAME ='root'
  28. PASSWORD ='123123'# mysqlclient驱动URL
  29. MYSQL_URI ='mysql+mysqldb://{}:{}@{}:{}/{}?charset=utf8mb4'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)
  30. db = SQLDatabase.from_uri(MYSQL_URI)# 测试连接是否成功# print(db.get_usable_table_names())# print(db.run('select * from t_emp limit 10;'))# 直接使用大模型和数据库整合, 只能根据你的问题生成SQL# 初始化生成SQL的chain
  31. test_chain = create_sql_query_chain(model, db)# resp = test_chain.invoke({'question': '请问:员工表中有多少条数据?'})# print(resp) # 输出:SELECT COUNT(*) FROM t_emp;
  32. answer_prompt = PromptTemplate.from_template("""给定以下用户问题、SQL语句和SQL执行后的结果,回答用户问题。
  33.     Question: {question}
  34.     SQL Query: {query}
  35.     SQL Result: {result}
  36.     回答: """)# 创建一个执行sql语句的工具
  37. execute_sql_tool = QuerySQLDataBaseTool(db=db)#  itemgetter('query')是取值的方法 ,然后结果给这个# data = {'query': 'hello', 'count': 10}# get_query = itemgetter('query')# print(get_query(data))  # 输出: hello# 1、RunnablePassthrough.assign(query=test_chain)生成SQL# 2、.assign(result=itemgetter('query') | execute_sql_tool)其中itemgetter('query') | execute_sql_tool是先获取sql交给工具执行,然后赋值给result# 前面的query和result是放入到消息模板中answer_prompt
  38. chain =(RunnablePassthrough.assign(query=test_chain).assign(result=itemgetter('query')| execute_sql_tool)| answer_prompt
  39.          | model
  40.          | StrOutputParser())
  41. rep = chain.invoke(input={'question':'请问:员工表中有多少条数据?'})print(rep)
复制代码
3、 代码2 使用代理工具
  1. import os
  2. from langchain_community.agent_toolkits import SQLDatabaseToolkit
  3. from langchain_community.utilities import SQLDatabase
  4. from langchain_core.messages import SystemMessage, HumanMessage
  5. from langchain_openai import ChatOpenAI, OpenAIEmbeddings
  6. from langgraph.prebuilt import chat_agent_executor
  7. os.environ['http_proxy']='127.0.0.1:7890'
  8. os.environ['https_proxy']='127.0.0.1:7890'
  9. os.environ["LANGCHAIN_TRACING_V2"]="true"
  10. os.environ["LANGCHAIN_PROJECT"]="LangchainDemo"
  11. os.environ["LANGCHAIN_API_KEY"]='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'# os.environ["TAVILY_API_KEY"] = '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'# 聊天机器人案例# 创建模型
  12. model = ChatOpenAI(model='gpt-4-turbo')# sqlalchemy 初始化MySQL数据库的连接
  13. HOSTNAME ='127.0.0.1'
  14. PORT ='3306'
  15. DATABASE ='test_db8'
  16. USERNAME ='root'
  17. PASSWORD ='123123'# mysqlclient驱动URL
  18. MYSQL_URI ='mysql+mysqldb://{}:{}@{}:{}/{}?charset=utf8mb4'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)
  19. db = SQLDatabase.from_uri(MYSQL_URI)# 创建工具
  20. toolkit = SQLDatabaseToolkit(db=db, llm=model)
  21. tools = toolkit.get_tools()# 使用agent完整整个数据库的整合
  22. system_prompt ="""
  23. 您是一个被设计用来与SQL数据库交互的代理。
  24. 给定一个输入问题,创建一个语法正确的SQL语句并执行,然后查看查询结果并返回答案。
  25. 除非用户指定了他们想要获得的示例的具体数量,否则始终将SQL查询限制为最多10个结果。
  26. 你可以按相关列对结果进行排序,以返回MySQL数据库中最匹配的数据。
  27. 您可以使用与数据库交互的工具。在执行查询之前,你必须仔细检查。如果在执行查询时出现错误,请重写查询SQL并重试。
  28. 不要对数据库做任何DML语句(插入,更新,删除,删除等)。
  29. 首先,你应该查看数据库中的表,看看可以查询什么。
  30. 不要跳过这一步。
  31. 然后查询最相关的表的模式。
  32. """
  33. system_message = SystemMessage(content=system_prompt)# 创建代理
  34. agent_executor = chat_agent_executor.create_tool_calling_executor(model, tools, system_message)# resp = agent_executor.invoke({'messages': [HumanMessage(content='请问:员工表中有多少条数据?')]})# resp = agent_executor.invoke({'messages': [HumanMessage(content='那种性别的员工人数最多?')]})
  35. resp = agent_executor.invoke({'messages':[HumanMessage(content='哪个部门下面的员工人数最多?')]})
  36. result = resp['messages']print(result)print(len(result))# 最后一个才是真正的答案print(result[len(result)-1])
复制代码
九、爬取youtube字幕并构建向量数据库(查询出来文章,不进行自然语言转换)

1、流程

    先爬取数据,存到向量库中加载向量库定义数据模型得到检索指令
2、pydantic数据管理

pydantic自行找资料学下
api地址
3、 代码(查询出来文章,不进行自然语言转换)
  1. import os
  2. from typing import Optional, List
  3. from langchain_chroma import Chroma
  4. from langchain_core.documents import Document
  5. from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder, PromptTemplate
  6. from langchain_core.runnables import RunnableWithMessageHistory, RunnablePassthrough
  7. from langchain_openai import ChatOpenAI, OpenAIEmbeddings
  8. from pydantic.v1 import BaseModel, Field
  9. os.environ['http_proxy']='127.0.0.1:7890'
  10. os.environ['https_proxy']='127.0.0.1:7890'
  11. os.environ["LANGCHAIN_TRACING_V2"]="true"
  12. os.environ["LANGCHAIN_PROJECT"]="LangchainDemo"
  13. os.environ["LANGCHAIN_API_KEY"]='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'# os.environ["TAVILY_API_KEY"] = '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'# 创建模型
  14. model = ChatOpenAI(model='gpt-4-turbo')
  15. embeddings = OpenAIEmbeddings(model='text-embedding-3-small')
  16. persist_dir ='chroma_data_dir'# 存放向量数据库的目录# 一些YouTube的视频连接
  17. urls =["https://www.youtube.com/watch?v=HAn9vnJy6S4","https://www.youtube.com/watch?v=dA1cHGACXCo","https://www.youtube.com/watch?v=ZcEMLz27sL4","https://www.youtube.com/watch?v=hvAPnpSfSGo","https://www.youtube.com/watch?v=EhlPDL4QrWY","https://www.youtube.com/watch?v=mmBo8nlu2j0","https://www.youtube.com/watch?v=rQdibOsL1ps","https://www.youtube.com/watch?v=28lC4fqukoc","https://www.youtube.com/watch?v=es-9MgxB-uc","https://www.youtube.com/watch?v=wLRHwKuKvOE","https://www.youtube.com/watch?v=ObIltMaRJvY","https://www.youtube.com/watch?v=DjuXACWYkkU","https://www.youtube.com/watch?v=o7C9ld6Ln-M",]# docs = []  # document的数组# for url in urls:#     # 一个Youtube的视频对应一个document#     docs.extend(YoutubeLoader.from_youtube_url(url, add_video_info=True).load())## print(len(docs))# print(docs[0])# # 给doc添加额外的元数据: 视频发布的年份# for doc in docs:#     doc.metadata['publish_year'] = int(#         datetime.datetime.strptime(doc.metadata['publish_date'], '%Y-%m-%d %H:%M:%S').strftime('%Y'))### print(docs[0].metadata)# print(docs[0].page_content[:500])  # 第一个视频的字幕内容## # 根据多个doc构建向量数据库# text_splitter = RecursiveCharacterTextSplitter(chunk_size=2000, chunk_overlap=30)# split_doc = text_splitter.split_documents(docs)# # 向量数据库的持久化# vectorstore = Chroma.from_documents(split_doc, embeddings, persist_directory=persist_dir)  # 并且把向量数据库持久化到磁盘# 加载磁盘中的向量数据库
  18. vectorstore = Chroma(persist_directory=persist_dir, embedding_function=embeddings)# 测试向量数据库的相似检索# result = vectorstore.similarity_search_with_score('how do I build a RAG agent')# print(result[0])# print(result[0][0].metadata['publish_year'])
  19. system ="""You are an expert at converting user questions into database queries. \
  20. You have access to a database of tutorial videos about a software library for building LLM-powered applications. \
  21. Given a question, return a list of database queries optimized to retrieve the most relevant results.
  22. If there are acronyms or words you are not familiar with, do not try to rephrase them."""
  23. prompt = ChatPromptTemplate.from_messages([("system", system),("human","{question}"),])# pydantic  搜索条件的入参实体classSearch(BaseModel):"""
  24.     定义了一个数据模型
  25.     """# 内容的相似性和发布年份
  26.     query:str= Field(None, description='Similarity search query applied to video transcripts.')
  27.     publish_year: Optional[int]= Field(None, description='Year video was published')# 转换为对象给模型对象如下图解释
  28. chain ={'question': RunnablePassthrough()}| prompt | model.with_structured_output(Search)# resp1 = chain.invoke('how do I build a RAG agent?')# print(resp1)# resp2 = chain.invoke('videos on RAG published in 2023')# print(resp2)defretrieval(search: Search)-> List[Document]:
  29.     _filter =Noneif search.publish_year:# 根据publish_year,存在得到一个检索条件# "$eq"是Chroma向量数据库的固定语法
  30.         _filter ={'publish_year':{"$eq": search.publish_year}}return vectorstore.similarity_search(search.query,filter=_filter)
  31. new_chain = chain | retrieval
  32. # result = new_chain.invoke('videos on RAG published in 2023')
  33. result = new_chain.invoke('RAG tutorial')print([(doc.metadata['title'], doc.metadata['publish_year'])for doc in result])
复制代码
Langchain的使用-19.png


十、提取结构化的数据

1、一句话提取出来-用户对象的信息

一句话,提出出来实体类
  1. import os
  2. from typing import Optional, List
  3. from langchain_core.prompts import ChatPromptTemplate
  4. from langchain_core.runnables import RunnablePassthrough
  5. from langchain_openai import ChatOpenAI
  6. from pydantic.v1 import BaseModel, Field
  7. os.environ['http_proxy']='127.0.0.1:7890'
  8. os.environ['https_proxy']='127.0.0.1:7890'
  9. os.environ["LANGCHAIN_TRACING_V2"]="true"
  10. os.environ["LANGCHAIN_PROJECT"]="LangchainDemo"
  11. os.environ["LANGCHAIN_API_KEY"]='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'# os.environ["TAVILY_API_KEY"] = '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'# 创建模型
  12. model = ChatOpenAI(model='gpt-4-turbo')# pydantic: 处理数据,验证数据, 定义数据的格式, 虚拟化和反虚拟化,类型转换等等。# 定义一个数据,classPerson(BaseModel):"""
  13.     关于一个人的数据模型
  14.     """
  15.     name: Optional[str]= Field(default=None, description='表示人的名字')
  16.     hair_color: Optional[str]= Field(
  17.         default=None, description="如果知道的话,这个人的头发颜色")
  18.     height_in_meters: Optional[str]= Field(
  19.         default=None, description="以米为单位测量的高度")classManyPerson(BaseModel):"""
  20.     数据模型类: 代表多个人
  21.     """
  22.     people: List[Person]# 定义自定义提示以提供指令和任何其他上下文。# 1) 你可以在提示模板中添加示例以提高提取质量# 2) 引入额外的参数以考虑上下文(例如,包括有关提取文本的文档的元数据。)
  23. prompt = ChatPromptTemplate.from_messages([("system","你是一个专业的提取算法。只从未结构化文本中提取相关信息。如果你不知道要提取的属性的值,返回该属性的值为null。",),# 请参阅有关如何使用参考记录消息历史的案例# MessagesPlaceholder('examples'),("human","{text}"),])# with_structured_output 模型的输出是一个结构化的数据
  24. chain ={'text': RunnablePassthrough()}| prompt | model.with_structured_output(schema=ManyPerson)# text = '马路上走来一个女生,长长的黑头发披在肩上,大概1米7左右,'# text = "马路上走来一个女生,长长的黑头发披在肩上,大概1米7左右。走在她旁边的是她的男朋友,叫:刘海;比她高10厘米。"
  25. text ="My name is Jeff, my hair is black and i am 6 feet tall. Anna has the same color hair as me."
  26. resp = chain.invoke(text)print(resp)
复制代码
2、避免英文

上面可能有英文的输出比如
Langchain的使用-20.png


解决:再加一个链路,让他翻译成中文 或者 修改系统提示词
  1. translate_prompt = ChatPromptTemplate.from_messages([("system","你是一个翻译算法,请把输入的结构化 JSON(英文字段)翻译为中文字段,并保持结构化。"),("human","{data}")])
  2. translate_chain =({"data": RunnablePassthrough()}| translate_prompt
  3.     | model.with_structured_output(schema=ManyPersonZh))# 第二步:翻译并保持结构化
  4. translated = translate_chain.invoke(resp.dict())
复制代码
十一、ai自动生成数据

Langchain的使用-21.png


1、生成一些文本数据
  1. import os
  2. from langchain_experimental.synthetic_data import create_data_generation_chain
  3. from langchain_openai import ChatOpenAI
  4. os.environ['http_proxy']='127.0.0.1:7890'
  5. os.environ['https_proxy']='127.0.0.1:7890'
  6. os.environ["LANGCHAIN_TRACING_V2"]="true"
  7. os.environ["LANGCHAIN_PROJECT"]="LangchainDemo"
  8. os.environ["LANGCHAIN_API_KEY"]='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'# os.environ["TAVILY_API_KEY"] = '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'# 聊天机器人案例# 创建模型
  9. model = ChatOpenAI(model='gpt-3.5-turbo', temperature=0.8)# 创建链
  10. chain = create_data_generation_chain(model)# 生成数据# result = chain(  # 给于一些关键词, 随机生成一句话#     {#         "fields": ['蓝色', '黄色'],#         "preferences": {}#     }# )
  11. result = chain(# 给于一些关键词, 随机生成一句话{"fields":{"颜色":['蓝色','黄色']},"preferences":{"style":"让它像诗歌一样。"}})print(result)
复制代码
2、生成结构化数据
  1. import os
  2. from langchain_core.prompts import PromptTemplate, FewShotPromptTemplate
  3. from langchain_experimental.tabular_synthetic_data.openai import create_openai_data_generator
  4. from langchain_experimental.tabular_synthetic_data.prompts import SYNTHETIC_FEW_SHOT_PREFIX, SYNTHETIC_FEW_SHOT_SUFFIX
  5. from langchain_openai import ChatOpenAI
  6. from pydantic.v1 import BaseModel
  7. os.environ['http_proxy']='127.0.0.1:7890'
  8. os.environ['https_proxy']='127.0.0.1:7890'
  9. os.environ["LANGCHAIN_TRACING_V2"]="true"
  10. os.environ["LANGCHAIN_PROJECT"]="LangchainDemo"
  11. os.environ["LANGCHAIN_API_KEY"]='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'# os.environ["TAVILY_API_KEY"] = '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'# 创建模型
  12. model = ChatOpenAI(model='gpt-3.5-turbo', temperature=0.8)# 生成一些结构化的数据: 5个步骤# 1、定义数据模型classMedicalBilling(BaseModel):
  13.     patient_id:int# 患者ID,整数类型
  14.     patient_name:str# 患者姓名,字符串类型
  15.     diagnosis_code:str# 诊断代码,字符串类型
  16.     procedure_code:str# 程序代码,字符串类型
  17.     total_charge:float# 总费用,浮点数类型
  18.     insurance_claim_amount:float# 保险索赔金额,浮点数类型# 2、 提供一些样例数据,给AI
  19. examples =[{"example":"Patient ID: 123456, Patient Name: 张娜, Diagnosis Code: J20.9, Procedure Code: 99203, Total Charge: $500, Insurance Claim Amount: $350"},{"example":"Patient ID: 789012, Patient Name: 王兴鹏, Diagnosis Code: M54.5, Procedure Code: 99213, Total Charge: $150, Insurance Claim Amount: $120"},{"example":"Patient ID: 345678, Patient Name: 刘晓辉, Diagnosis Code: E11.9, Procedure Code: 99214, Total Charge: $300, Insurance Claim Amount: $250"},]# 3、创建一个提示模板, 用来指导AI生成符合规定的数据
  20. openai_template = PromptTemplate(input_variables=['example'], template="{example}")# subject主题是什么,extra额外的要求
  21. prompt_template = FewShotPromptTemplate(
  22.     prefix=SYNTHETIC_FEW_SHOT_PREFIX,
  23.     suffix=SYNTHETIC_FEW_SHOT_SUFFIX,
  24.     examples=examples,
  25.     example_prompt=openai_template,
  26.     input_variables=['subject','extra'])# 4、创建一个结构化数据的生成器
  27. generator = create_openai_data_generator(
  28.     output_schema=MedicalBilling,# 指定输出数据的格式
  29.     llm=model,
  30.     prompt=prompt_template
  31. )# 5、调用生成器
  32. result = generator.generate(
  33.     subject='医疗账单',# 指定生成数据的主题
  34.     extra='医疗总费用呈现正态分布,最小的总费用为1000',# 额外的一些指导信息
  35.     runs=10# 指定生成数据的数量)print(result)
复制代码
十二、文本分类

Langchain的使用-22.png


因为回答不能上一次是情感分类,下一次就进入了新闻分类,要固定
  1. import os
  2. from langchain_core.prompts import PromptTemplate, FewShotPromptTemplate, ChatPromptTemplate
  3. from langchain_experimental.synthetic_data import create_data_generation_chain
  4. from langchain_experimental.tabular_synthetic_data.openai import create_openai_data_generator
  5. from langchain_experimental.tabular_synthetic_data.prompts import SYNTHETIC_FEW_SHOT_PREFIX, SYNTHETIC_FEW_SHOT_SUFFIX
  6. from langchain_openai import ChatOpenAI
  7. from pydantic.v1 import BaseModel, Field
  8. os.environ['http_proxy']='127.0.0.1:7890'
  9. os.environ['https_proxy']='127.0.0.1:7890'
  10. os.environ["LANGCHAIN_TRACING_V2"]="true"
  11. os.environ["LANGCHAIN_PROJECT"]="LangchainDemo"
  12. os.environ["LANGCHAIN_API_KEY"]='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'# os.environ["TAVILY_API_KEY"] = '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'# 创建模型  temperature是0-1,随机性语言太多了,所以我们就要他直接输出少多样化回复
  13. model = ChatOpenAI(model='gpt-3.5-turbo', temperature=0)# class Classification(BaseModel):#     """#         定义一个Pydantic的数据模型,未来需要根据该类型,完成文本的分类#     """#     # 文本的情感倾向,预期为字符串类型#     sentiment: str = Field(description="文本的情感")##     # 文本的攻击性,预期为1到10的整数#     aggressiveness: int = Field(#         description="描述文本的攻击性,数字越大表示越攻击性"#     )##     # 文本使用的语言,预期为字符串类型#     language: str = Field(description="文本使用的语言")classClassification(BaseModel):"""
  14.         定义一个Pydantic的数据模型,未来需要根据该类型,完成文本的分类
  15.     """# 文本的情感倾向,预期为字符串类型
  16.     sentiment:str= Field(..., enum=["happy","neutral","sad"], description="文本的情感")# 文本的攻击性,预期为1到5的整数
  17.     aggressiveness:int= Field(..., enum=[1,2,3,4,5], description="描述文本的攻击性,数字越大表示越攻击性")# 文本使用的语言,预期为字符串类型
  18.     language:str= Field(..., enum=["spanish","english","french","中文","italian"], description="文本使用的语言")# 创建一个用于提取信息的提示模板
  19. tagging_prompt = ChatPromptTemplate.from_template("""
  20.     从以下段落中提取所需信息。
  21.     只提取'Classification'类中提到的属性。
  22.     段落:
  23.     {input}
  24.     """)
  25. chain = tagging_prompt | model.with_structured_output(Classification)
  26. input_text ="中国人民大学的王教授:师德败坏,做出的事情实在让我生气!"# input_text = "Estoy increiblemente contento de haberte conocido! Creo que seremos muy buenos amigos!"
  27. result: Classification = chain.invoke({'input': input_text})print(result)
复制代码
十三、文本的自动摘要(超过一次最大发送token,处理方案)

用的最多的还是前两种
Langchain的使用-23.png


1、Stuff使用

    Stuff只能解决小文档片段,超过了一次性的token就不行
  1. import os
  2. from langchain.chains.combine_documents.stuff import StuffDocumentsChain
  3. from langchain.chains.llm import LLMChain
  4. from langchain_community.document_loaders import WebBaseLoader
  5. from langchain_core.prompts import PromptTemplate
  6. from langchain_openai import ChatOpenAI
  7. os.environ['http_proxy']='127.0.0.1:7890'
  8. os.environ['https_proxy']='127.0.0.1:7890'
  9. os.environ["LANGCHAIN_TRACING_V2"]="true"
  10. os.environ["LANGCHAIN_PROJECT"]="LangchainDemo"
  11. os.environ["LANGCHAIN_API_KEY"]='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'# 创建模型
  12. model = ChatOpenAI(model='gpt-3.5-turbo', temperature=0)# 加载我们的文档。我们将使用 WebBaseLoader 来加载博客文章:
  13. loader = WebBaseLoader('https://lilianweng.github.io/posts/2023-06-23-agent/')
  14. docs = loader.load()# 得到整篇文章# 第一种: Stuff# Stuff的第一种写法(使用的不多)# chain = load_summarize_chain(model, chain_type='stuff')# result = chain.invoke(docs)# print(result['output_text'])# Stuff的第二种写法# 定义提示
  15. prompt_template ="""针对下面的内容,写一个简洁的总结摘要:
  16. "{text}"
  17. 简洁的总结摘要:"""
  18. prompt = PromptTemplate.from_template(prompt_template)# model和prompt关联
  19. llm_chain = LLMChain(llm=model, prompt=prompt)
  20. stuff_chain = StuffDocumentsChain(llm_chain=llm_chain, document_variable_name='text')
  21. result = stuff_chain.invoke(docs)print(result['output_text'])
复制代码
2、MapReduce使用

    MapReduce:当出现文本时文章,字数比较多,超过了最大token限制,可以使用这个方法
案例
假设文本50万字,切割5000字一份,每一份有500字,每个500字都交给大模型,然后得到小段落结论摘要s1,很多个s。
问题:小段落结论摘要又有很多不能一次性丢给ai ,假设小段落有5000个小摘要,ai最多接受1000字
可以再进行一次摘要提取,得到ss,然后ss再进行获取总摘要,再多的循环类推直到解决。
  1. import os
  2. from langchain.chains.combine_documents.map_reduce import MapReduceDocumentsChain
  3. from langchain.chains.combine_documents.reduceimport ReduceDocumentsChain
  4. from langchain.chains.combine_documents.stuff import StuffDocumentsChain
  5. from langchain.chains.llm import LLMChain
  6. from langchain_community.document_loaders import WebBaseLoader
  7. from langchain_core.prompts import PromptTemplate
  8. from langchain_openai import ChatOpenAI
  9. from langchain_text_splitters import CharacterTextSplitter
  10. os.environ['http_proxy']='127.0.0.1:7890'
  11. os.environ['https_proxy']='127.0.0.1:7890'
  12. os.environ["LANGCHAIN_TRACING_V2"]="true"
  13. os.environ["LANGCHAIN_PROJECT"]="LangchainDemo"
  14. os.environ["LANGCHAIN_API_KEY"]='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'# 创建模型
  15. model = ChatOpenAI(model='gpt-3.5-turbo', temperature=0)# 加载我们的文档。我们将使用 WebBaseLoader 来加载博客文章:
  16. loader = WebBaseLoader('https://lilianweng.github.io/posts/2023-06-23-agent/')
  17. docs = loader.load()# 得到整篇文章# 第二种: Map-Reduce# 第一步: 切割阶段# 每一个小docs为1000个token
  18. text_splitter = CharacterTextSplitter.from_tiktoken_encoder(chunk_size=1000, chunk_overlap=0)
  19. split_docs = text_splitter.split_documents(docs)# 第二步: map阶段
  20. map_template ="""以下是一组文档(documents)
  21. "{docs}"
  22. 根据这个文档列表,请给出总结摘要:"""
  23. map_prompt = PromptTemplate.from_template(map_template)
  24. map_llm_chain = LLMChain(llm=model, prompt=map_prompt)# 第三步: reduce阶段: (combine和 最终的reduce)
  25. reduce_template ="""以下是一组总结摘要:
  26. {docs}
  27. 将这些内容提炼成一个最终的、统一的总结摘要:"""
  28. reduce_prompt = PromptTemplate.from_template(reduce_template)
  29. reduce_llm_chain = LLMChain(llm=model, prompt=reduce_prompt)'''
  30. reduce的思路:
  31. 如果map之后文档的累积token数超过了 4000个,那么我们将递归地将文档以<= 4000 个token的批次传递给我们的 StuffDocumentsChain 来创建批量摘要。
  32. 一旦这些批量摘要的累积大小小于 4000 个token,我们将它们全部传递给 StuffDocumentsChain 最后一次,以创建最终摘要。
  33. '''# 定义一个combine的chain
  34. combine_chain = StuffDocumentsChain(llm_chain=reduce_llm_chain, document_variable_name='docs')
  35. reduce_chain = ReduceDocumentsChain(# 这是最终调用的链。
  36.     combine_documents_chain=combine_chain,# 中间的汇总的脸
  37.     collapse_documents_chain=combine_chain,# 将文档分组的最大令牌数。
  38.     token_max=4000)# 第四步:合并所有链
  39. map_reduce_chain = MapReduceDocumentsChain(
  40.     llm_chain=map_llm_chain,
  41.     reduce_documents_chain=reduce_chain,
  42.     document_variable_name='docs',
  43.     return_intermediate_steps=False#是否打印中间的汇总)# 第五步: 调用最终的链
  44. result = map_reduce_chain.invoke(split_docs)print(result['output_text'])
复制代码
3、Refine使用

文档链通过循环遍历输入文档并逐步更新其答案来构建响应。对于每个文档,它将当前文档和最新的中间答案传递给LLM链,以获得新的答案。 性能慢
拆分5000份,然后再得到第一个摘要s,和拆分5000份的第二份,进行摘要,依此类推
  1. import os
  2. from langchain.chains.summarize import load_summarize_chain
  3. from langchain_community.document_loaders import WebBaseLoader
  4. from langchain_openai import ChatOpenAI
  5. from langchain_text_splitters import CharacterTextSplitter
  6. os.environ['http_proxy']='127.0.0.1:7890'
  7. os.environ['https_proxy']='127.0.0.1:7890'
  8. os.environ["LANGCHAIN_TRACING_V2"]="true"
  9. os.environ["LANGCHAIN_PROJECT"]="LangchainDemo"
  10. os.environ["LANGCHAIN_API_KEY"]='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'# os.environ["TAVILY_API_KEY"] = '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'# 创建模型
  11. model = ChatOpenAI(model='gpt-3.5-turbo', temperature=0)# 加载我们的文档。我们将使用 WebBaseLoader 来加载博客文章:
  12. loader = WebBaseLoader('https://lilianweng.github.io/posts/2023-06-23-agent/')
  13. docs = loader.load()# 得到整篇文章# 第三种: Refine'''
  14. Refine: RefineDocumentsChain 类似于map-reduce:
  15. 文档链通过循环遍历输入文档并逐步更新其答案来构建响应。对于每个文档,它将当前文档和最新的中间答案传递给LLM链,以获得新的答案。
  16. '''# 第一步: 切割阶段# 每一个小docs为1000个token
  17. text_splitter = CharacterTextSplitter.from_tiktoken_encoder(chunk_size=1000, chunk_overlap=0)
  18. split_docs = text_splitter.split_documents(docs)# 指定chain_type为: refine
  19. chain = load_summarize_chain(model, chain_type='refine')
  20. result = chain.invoke(split_docs)print(result['output_text'])
复制代码
增加提示词
  1. import os
  2. from langchain.chains.summarize import load_summarize_chain
  3. from langchain_community.document_loaders import WebBaseLoader
  4. from langchain_core.prompts import PromptTemplate
  5. from langchain_openai import ChatOpenAI
  6. from langchain_text_splitters import CharacterTextSplitter
  7. os.environ['http_proxy']='127.0.0.1:7890'
  8. os.environ['https_proxy']='127.0.0.1:7890'
  9. os.environ["LANGCHAIN_TRACING_V2"]="true"
  10. os.environ["LANGCHAIN_PROJECT"]="LangchainDemo"
  11. os.environ["LANGCHAIN_API_KEY"]='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'# os.environ["TAVILY_API_KEY"] = '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'# 创建模型
  12. model = ChatOpenAI(model='gpt-3.5-turbo', temperature=0)# 首先我们加载我们的文档。我们将使用 WebBaseLoader 来加载博客文章:
  13. loader = WebBaseLoader("https://lilianweng.github.io/posts/2023-06-23-agent/")
  14. docs = loader.load()# 没有切割的'''
  15. Refine: RefineDocumentsChain 类似于映射-归约:
  16. 细化文档链通过循环遍历输入文档并逐步更新其答案来构建响应。对于每个文档,它将当前文档和最新的中间答案传递给LLM链,以获得新的答案。
  17. '''# 定义提示
  18. prompt_template ="""针对下面的内容,写一个简洁的总结摘要:
  19. "{text}"
  20. 简洁的总结摘要:"""
  21. prompt = PromptTemplate.from_template(prompt_template)
  22. refine_template =("Your job is to produce a final summary\n""We have provided an existing summary up to a certain point: {existing_answer}\n""We have the opportunity to refine the existing summary""(only if needed) with some more context below.\n""------------\n""{text}\n""------------\n""\n""Given the new context, refine the original summary in Chinese""If the context isn't useful, return the original summary.")# refine_template = (#     "你的工作是做出一个最终的总结摘要。\n"#     "我们提供了一个到某个点的现有摘要:{existing_answer}\n"#     "我们有机会完善现有的摘要,基于下面更多的文本内容\n"#     "------------\n"#     "{text}\n"#     "------------\n"# )
  23. refine_prompt = PromptTemplate.from_template(refine_template)
  24. chain = load_summarize_chain(
  25.     llm=model,
  26.     chain_type="refine",
  27.     question_prompt=prompt,
  28.     refine_prompt=refine_prompt,
  29.     return_intermediate_steps=False,
  30.     input_key="input_documents",
  31.     output_key="output_text",)
  32. text_splitter = CharacterTextSplitter.from_tiktoken_encoder(
  33.     chunk_size=1000, chunk_overlap=0)
  34. split_docs = text_splitter.split_documents(docs)
  35. result = chain.invoke({"input_documents": split_docs}, return_only_outputs=True)print(result["output_text"])
复制代码
十四、更换不通模型(工厂模型)

1、定义模型

Langchain的使用-24.png


2、模型配置

下图画线的是模型,然后图中的key作为你要选用的模型去进行调用看完3你就明白了,gpt是默认的一个模型

Langchain的使用-25.png


3、跟据配置id和对应的key选择模型使用

图中llm是文件id,ernie是你定义模型key,也可改为gpt

Langchain的使用-26.png


十五、ReAct(选择工具,然后思考)

一、流程图

将一个任务拆分,多次进行调用工具思考,然后最终完成大的任务的一个流程

Langchain的使用-27.png


二、demo

这是一个简单的demo,大概就是拉一个模板下来,然后进行调用
安装
Langchain的使用-28.png

定义两个工具

Langchain的使用-29.png

Langchain的使用-30.png


拉下来模板

Langchain的使用-31.png

模板解读,大概就是有哪些工具,循环然后获取结果然后进行调用工具,解决这个问题

Langchain的使用-32.png

调用
其中agent_executor会进行执行工具然后再反复执行,直到结束

Langchain的使用-33.png


十六、SelfAskWithSearch(只用一个工具搜索,然后不断的反问)

比如问一个问题,就是xxx老婆是谁,演过什么电影,然后不断搜索直到出来结果
案例

Langchain的使用-34.png

Langchain的使用-35.png


后续、后续课程的笔记

换到下一篇章博文

原文地址:https://blog.csdn.net/weixin_49390750/article/details/151353838
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

发布主题
阅读排行更多+

Powered by Discuz! X3.4© 2001-2013 Discuz Team.( 京ICP备17022993号-3 )