当前位置:   article > 正文

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

langchain pdfreader

目录

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)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/979887
推荐阅读
相关标签
  

闽ICP备14008679号