• langchain pdf链检索,提问式表单(实体命名识别)


    目录

    PDF检索

    提问式表单


    PDF检索

    stuff 链,重排链,RetrievalQA 链
    
    1. from PyPDF2 import PdfReader
    2. from langchain.text_splitter import CharacterTextSplitter
    3. from langchain.vectorstores import FAISS
    4. from langchain.embeddings import HuggingFaceEmbeddings
    5. from langchain.chains.question_answering import load_qa_chain
    6. from langchain.chains import RetrievalQA
    7. import os
    8. from dotenv import load_dotenv
    9. from langchain_community.llms import Tongyi
    10. load_dotenv('key.env') # 指定加载 env 文件
    11. key = os.getenv('DASHSCOPE_API_KEY') # 获得指定环境变量
    12. DASHSCOPE_API_KEY = os.environ["DASHSCOPE_API_KEY"] # 获得指定环境变量
    13. model = Tongyi(temperature=1)
    14. # 打开 pdf
    15. pdf_data = 'langchain入门/full_course_langchain-main/code/user_cases/impromptu-rh.pdf'
    16. doc_reader = PdfReader(pdf_data)
    17. # 把文本读取进来
    18. raw_text = ''
    19. for i, page in enumerate(doc_reader.pages):
    20. text = page.extract_text()
    21. if text:
    22. raw_text += text
    23. # 文本拆分
    24. text_splitter = CharacterTextSplitter(
    25. separator="\n",
    26. chunk_size=1000,
    27. chunk_overlap=200, #striding over the text
    28. length_function=len,
    29. )
    30. texts = text_splitter.split_text(raw_text)
    31. # 加载 embedding
    32. embeddings = HuggingFaceEmbeddings(model_name='bge-small-zh-v1.5', model_kwargs={'device': 'cpu'})
    33. # 向量存储
    34. docsearch = FAISS.from_texts(texts, embeddings)
    35. # # 创建问答 stuff 链,意思是吧全部检索结果穿给大模型
    36. # chain = load_qa_chain(model, chain_type="stuff")
    37. # # 检索
    38. # query = "这本书是哪些人创作的?请用中文回答"
    39. # docs = docsearch.similarity_search(query, k=6)
    40. # res = chain.run(input_documents=docs, question=query)
    41. # print(res)
    42. # # 重排链,对检索到的文档大模型打分,得到分数最高的座位结果
    43. # chain = load_qa_chain(model,
    44. # chain_type="map_rerank",
    45. # return_intermediate_steps=True # 可以看看到 map_rerank 是如何对检索到的文档打分的
    46. # )
    47. # query = "OpenAI 的创始人是谁?"
    48. # docs = docsearch.similarity_search(query,k=10)
    49. # results = chain({"input_documents": docs, "question": query}, return_only_outputs=True)
    50. # print(results['output_text'])
    51. # print(chain.llm_chain.prompt.template) # 打印提示词模版
    52. # RetrievalQA 链是 Langchain 已经封装好的索引查询问答链。实例化之后,我们可以直接把问题扔给它,而不需要 chain.run()。简化了很多步骤,获得了比较稳定的查询结果
    53. docsearch = FAISS.from_texts(texts, embeddings) # 检索器是向量库数据
    54. retriever = docsearch.as_retriever(search_type="similarity", search_kwargs={"k":4}) # as_retriever
    55. rqa = RetrievalQA.from_chain_type(llm=model,
    56. chain_type="stuff",
    57. retriever=retriever,
    58. return_source_documents=True)
    59. # 如果我们不需要中间步骤和源文档,只需要最终答案,那么我们可以直接请求返回结果。将代码:return_source_documents=True 改为 return_source_documents=False
    60. query = "OpenAI 是什么?"
    61. res = rqa(query)['result']
    62. print(res)

    提问式表单

    通过用户输入的内容,识别需要填写的字段,有点实体命名识别的感觉,当需要从程序中识别特定实体时可以参考

    1. #!/usr/bin/env python
    2. # coding: utf-8
    3. # In[ ]:
    4. get_ipython().system('pip -q install openai tiktoken')
    5. get_ipython().run_line_magic('pip', 'install git+https://github.com/hwchase17/langchain')
    6. # In[2]:
    7. import os
    8. os.environ["OPENAI_API_KEY"] = ""
    9. # In[3]:
    10. get_ipython().system('pip show langchain')
    11. # ## Classification / Tagging
    12. #
    13. # In[44]:
    14. from langchain.chat_models import ChatOpenAI
    15. from langchain.chains import LLMChain
    16. from langchain.prompts import ChatPromptTemplate
    17. from pydantic import BaseModel, Field
    18. from enum import Enum
    19. from langchain.chains.openai_functions import (
    20. create_tagging_chain,
    21. create_tagging_chain_pydantic,
    22. )
    23. # In[11]:
    24. class PersonalDetails(BaseModel):
    25. # 定义数据的类型
    26. name: str = Field(
    27. ...,
    28. description = "这是用户输入的名字"
    29. )
    30. city: str = Field(
    31. ...,
    32. description = "这是用户输入的居住城市"
    33. )
    34. email: str = Field(
    35. ...,
    36. description = "这是用户输入的邮箱地址"
    37. )
    38. # In[7]:
    39. llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo-0613")
    40. # In[22]:
    41. chain = create_tagging_chain_pydantic(PersonalDetails,llm)
    42. # In[184]:
    43. test_str1 = "你好,我是美丽,我住在上海浦东,我的邮箱是: liteli1987@gmail.com"
    44. test_res1 = chain.run(test_str1)
    45. test_res1
    46. # 第二个测试,我只告诉她我的邮箱。机器人只记录了邮箱。
    47. # In[174]:
    48. test_str2 = "我的邮箱是: liteli1987@gmail.com"
    49. test_res2 = chain.run(test_str2)
    50. test_res2
    51. # 我们可以再来第三个测试,不告诉机器人我的名字,但是告诉他邮箱,而且还故意告诉他我弟弟的邮箱。
    52. # In[177]:
    53. test_str3 = "我叫美丽,我弟弟的邮箱是:1106968391@qq.com"
    54. test_res3 = chain.run(test_str3)
    55. test_res3
    56. # 我们可以看到结果是'', 如果没有匹配我们定义的PersonalDetails对象里的数据类型,机器人并不会瞎编乱造。
    57. # In[35]:
    58. user_007_personal_details = PersonalDetails(name="",city="",email="")
    59. # In[36]:
    60. user_007_personal_details
    61. # 定义一个函数,用于检查数据是否填写完整。
    62. # In[37]:
    63. def check_what_is_empty(user_personal_details):
    64. ask_for = []
    65. # 检查项目是否为空
    66. for field,value in user_personal_details.dict().items():
    67. if value in [None, "", 0]:
    68. print(f"Field '{field}' 为空" )
    69. ask_for.append(f'{field}')
    70. return ask_for
    71. # 我们来测试一下用户007是否填写完整了。
    72. # In[38]:
    73. ask_for = check_what_is_empty(user_007_personal_details)
    74. ask_for
    75. # 我们再来定义一个函数,用于获取用户的输入信息并且更新用户的信息。
    76. # In[180]:
    77. def add_non_empty_details(current_details:PersonalDetails, new_details:PersonalDetails):
    78. # 这是已经填好的用户信息
    79. non_empty_details = {k:v for k,v in new_details.dict().items() if v not in [None, "", 0]}
    80. update_details = current_details.copy(update=non_empty_details)
    81. return update_details
    82. # In[181]:
    83. res = chain.run("我的名字007")
    84. user_007_personal_details = add_non_empty_details(user_007_personal_details,res)
    85. user_007_personal_details
    86. # In[149]:
    87. res = chain.run("我住在南京")
    88. user_007_personal_details = add_non_empty_details(user_007_personal_details,res)
    89. user_007_personal_details
    90. # In[150]:
    91. res = chain.run("我的邮箱是XX@qq.com")
    92. user_007_personal_details = add_non_empty_details(user_007_personal_details,res)
    93. user_007_personal_details
    94. # 测试一下哪一项没有填写
    95. # In[182]:
    96. ask_for = check_what_is_empty(user_007_personal_details)
    97. ask_for
    98. # In[152]:
    99. if not ask_for:
    100. print("谢谢您的回答!我没有问题了")
    101. # 使用自定义提示模板,实现机器人发起提问。
    102. # In[61]:
    103. def ask_for_info(ask_for=["name","city","email"]):
    104. # 定义一个提示模板
    105. first_prompt = ChatPromptTemplate.from_template(
    106. """
    107. 假设你现在是一名前台,你现在需要对用户进行询问他个人的具体信息。
    108. 不要跟用户打招呼!你可以解释你需要什么信息。不要说“你好!”!
    109. 接下来你和用户之间的对话都是你来提问,凡是你说的都是问句。
    110. 你每次随机选择{ask_for}列表中的一个项目,向用户提问。
    111. 比如["name","city"]列表,你可以随机选择一个"name", 你的问题就是“请问你的名字是?”
    112. """
    113. )
    114. info_gathering_chain = LLMChain(llm=llm, prompt=first_prompt)
    115. chat_chain = info_gathering_chain.run(ask_for=ask_for)
    116. return chat_chain
    117. # In[183]:
    118. ask_for_info(ask_for=["name","city","email"])
    119. # 定义一个处理模型返回信息的函数。
    120. # In[104]:
    121. def filter_response(text_input, user_details):
    122. # 我们使用到openAI提供的打标签链, 用户的输入可以被这个链解析和映射。
    123. chain = create_tagging_chain_pydantic(PersonalDetails,llm)
    124. res = chain.run(text_input)
    125. # 更新用户信息
    126. user_details = add_non_empty_details(user_details,res)
    127. ask_for = check_what_is_empty(user_details)
    128. return user_details, ask_for
    129. # 测试一下效果,我们要获取的就是最新的用户信息,筛选出来哪些项目还没有填写。
    130. #
    131. # In[155]:
    132. def decide_ask(ask_for=["name","city","email"]):
    133. if ask_for:
    134. ai_res = ask_for_info(ask_for=ask_for)
    135. print(ai_res)
    136. else:
    137. print("全部填写完整")
    138. decide_ask(ask_for)
    139. # In[167]:
    140. user_999_personal_details = PersonalDetails(name="",city="",email="")
    141. user_999_personal_details
    142. # In[168]:
    143. decide_ask(ask_for)
    144. # In[169]:
    145. str999 = "我的名字是999,我住在北京"
    146. # In[170]:
    147. user_999_personal_details, ask_for_999 = filter_response(str999,user_999_personal_details)
    148. decide_ask(ask_for_999)
    149. # In[173]:
    150. str999 = "XX@XX.com"
    151. user_999_personal_details, ask_for_999 = filter_response(str999,user_999_personal_details)
    152. decide_ask(ask_for_999)

  • 相关阅读:
    ChatGLM系列五:Lora微调
    【Spring Boot】实现全局异常处理
    【M365运维】很抱歉、无法打开“https://..../.xlsx”
    Leetcode力扣 MySQL数据库 1811 寻找面试候选人
    记录一下我hive连不上DataGrip的问题
    DNA修饰碳纳米管|DNA修饰单层二硫化钼|DNA修饰二硫化钨(注意事项)
    Maya制作骑自行车的女孩模型
    Android自定义控件(一) 可滑动的进度条
    棋盘(马蹄集)
    智能合约安全,著名的区块链漏洞:双花攻击
  • 原文地址:https://blog.csdn.net/zjkpy_5/article/details/138015669