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

这篇具有很好参考价值的文章主要介绍了langchain pdf链检索,提问式表单(实体命名识别)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

PDF检索

提问式表单


PDF检索

stuff 链,重排链,RetrievalQA 链
from PyPDF2 import PdfReader
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import FAISS
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.chains.question_answering import load_qa_chain
from langchain.chains import RetrievalQA
import os
from dotenv import load_dotenv
from langchain_community.llms import Tongyi


load_dotenv('key.env')  # 指定加载 env 文件
key = os.getenv('DASHSCOPE_API_KEY')  # 获得指定环境变量
DASHSCOPE_API_KEY = os.environ["DASHSCOPE_API_KEY"]  # 获得指定环境变量
model = Tongyi(temperature=1)

# 打开 pdf
pdf_data = 'langchain入门/full_course_langchain-main/code/user_cases/impromptu-rh.pdf'
doc_reader = PdfReader(pdf_data)

# 把文本读取进来
raw_text = ''
for i, page in enumerate(doc_reader.pages):
    text = page.extract_text()
    if text:
        raw_text += text

# 文本拆分
text_splitter = CharacterTextSplitter(
    separator="\n",
    chunk_size=1000,
    chunk_overlap=200, #striding over the text
    length_function=len,
)
texts = text_splitter.split_text(raw_text)

# 加载 embedding
embeddings = HuggingFaceEmbeddings(model_name='bge-small-zh-v1.5', model_kwargs={'device': 'cpu'})

# 向量存储
docsearch = FAISS.from_texts(texts, embeddings)



# # 创建问答 stuff 链,意思是吧全部检索结果穿给大模型
# chain = load_qa_chain(model, chain_type="stuff")
# # 检索
# query = "这本书是哪些人创作的?请用中文回答"
# docs = docsearch.similarity_search(query, k=6)
# res = chain.run(input_documents=docs, question=query)
# print(res)



# # 重排链,对检索到的文档大模型打分,得到分数最高的座位结果
# chain = load_qa_chain(model,
#                       chain_type="map_rerank",
#                       return_intermediate_steps=True  # 可以看看到 map_rerank 是如何对检索到的文档打分的
#                       )
# query = "OpenAI 的创始人是谁?"
# docs = docsearch.similarity_search(query,k=10)
# results = chain({"input_documents": docs, "question": query}, return_only_outputs=True)
# print(results['output_text'])
# print(chain.llm_chain.prompt.template)  # 打印提示词模版


# RetrievalQA 链是 Langchain 已经封装好的索引查询问答链。实例化之后,我们可以直接把问题扔给它,而不需要 chain.run()。简化了很多步骤,获得了比较稳定的查询结果
docsearch = FAISS.from_texts(texts, embeddings) # 检索器是向量库数据
retriever = docsearch.as_retriever(search_type="similarity", search_kwargs={"k":4})  # as_retriever
rqa = RetrievalQA.from_chain_type(llm=model,
                                  chain_type="stuff",
                                  retriever=retriever,
                                  return_source_documents=True)
# 如果我们不需要中间步骤和源文档,只需要最终答案,那么我们可以直接请求返回结果。将代码:return_source_documents=True  改为 return_source_documents=False
query = "OpenAI 是什么?"
res = rqa(query)['result']
print(res)

提问式表单

通过用户输入的内容,识别需要填写的字段,有点实体命名识别的感觉,当需要从程序中识别特定实体时可以参考文章来源地址https://www.toymoban.com/news/detail-857859.html

#!/usr/bin/env python
# coding: utf-8

# In[ ]:


get_ipython().system('pip -q install  openai tiktoken')
get_ipython().run_line_magic('pip', 'install git+https://github.com/hwchase17/langchain')


# In[2]:


import os

os.environ["OPENAI_API_KEY"] = ""


# In[3]:


get_ipython().system('pip show langchain')


# ## Classification / Tagging
# 

# In[44]:


from langchain.chat_models import ChatOpenAI
from langchain.chains import LLMChain
from langchain.prompts import ChatPromptTemplate
from pydantic import BaseModel, Field
from enum import Enum
from langchain.chains.openai_functions import (
    create_tagging_chain,
    create_tagging_chain_pydantic,
)


# In[11]:


class PersonalDetails(BaseModel):
    # 定义数据的类型
    name: str = Field(
        ...,
        description = "这是用户输入的名字"
    )
    city: str = Field(
        ...,
        description = "这是用户输入的居住城市"
    )
    email: str = Field(
        ...,
        description = "这是用户输入的邮箱地址"
    )


# In[7]:


llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo-0613")


# In[22]:


chain = create_tagging_chain_pydantic(PersonalDetails,llm)


# In[184]:


test_str1 = "你好,我是美丽,我住在上海浦东,我的邮箱是: liteli1987@gmail.com"
test_res1 = chain.run(test_str1)
test_res1


# 第二个测试,我只告诉她我的邮箱。机器人只记录了邮箱。

# In[174]:


test_str2 = "我的邮箱是: liteli1987@gmail.com"
test_res2 = chain.run(test_str2)
test_res2


# 我们可以再来第三个测试,不告诉机器人我的名字,但是告诉他邮箱,而且还故意告诉他我弟弟的邮箱。

# In[177]:


test_str3 = "我叫美丽,我弟弟的邮箱是:1106968391@qq.com"
test_res3 = chain.run(test_str3)
test_res3


# 我们可以看到结果是'', 如果没有匹配我们定义的PersonalDetails对象里的数据类型,机器人并不会瞎编乱造。

# In[35]:


user_007_personal_details = PersonalDetails(name="",city="",email="")


# In[36]:


user_007_personal_details


# 定义一个函数,用于检查数据是否填写完整。

# In[37]:


def check_what_is_empty(user_personal_details):
    ask_for = []
    # 检查项目是否为空
    for field,value in user_personal_details.dict().items():
        if value in [None, "", 0]: 
            print(f"Field '{field}' 为空" )
            ask_for.append(f'{field}')
    return ask_for        


# 我们来测试一下用户007是否填写完整了。

# In[38]:


ask_for = check_what_is_empty(user_007_personal_details)
ask_for


# 我们再来定义一个函数,用于获取用户的输入信息并且更新用户的信息。

# In[180]:


def add_non_empty_details(current_details:PersonalDetails, new_details:PersonalDetails):
    # 这是已经填好的用户信息
    non_empty_details = {k:v for k,v in new_details.dict().items() if v not in [None, "", 0]}
    update_details = current_details.copy(update=non_empty_details)
    return update_details


# In[181]:


res = chain.run("我的名字007") 
user_007_personal_details = add_non_empty_details(user_007_personal_details,res)
user_007_personal_details


# In[149]:


res = chain.run("我住在南京") 
user_007_personal_details = add_non_empty_details(user_007_personal_details,res)
user_007_personal_details


# In[150]:


res = chain.run("我的邮箱是XX@qq.com") 
user_007_personal_details = add_non_empty_details(user_007_personal_details,res)
user_007_personal_details


# 测试一下哪一项没有填写

# In[182]:


ask_for = check_what_is_empty(user_007_personal_details)
ask_for


# In[152]:


if not ask_for:
    print("谢谢您的回答!我没有问题了")


# 使用自定义提示模板,实现机器人发起提问。

# In[61]:


def ask_for_info(ask_for=["name","city","email"]):
    # 定义一个提示模板
    first_prompt = ChatPromptTemplate.from_template(
        """
        假设你现在是一名前台,你现在需要对用户进行询问他个人的具体信息。
        不要跟用户打招呼!你可以解释你需要什么信息。不要说“你好!”!
        接下来你和用户之间的对话都是你来提问,凡是你说的都是问句。
        你每次随机选择{ask_for}列表中的一个项目,向用户提问。
        比如["name","city"]列表,你可以随机选择一个"name", 你的问题就是“请问你的名字是?”
        """
    )
    info_gathering_chain = LLMChain(llm=llm, prompt=first_prompt)
    chat_chain = info_gathering_chain.run(ask_for=ask_for)
    return chat_chain
    


# In[183]:


ask_for_info(ask_for=["name","city","email"])


# 定义一个处理模型返回信息的函数。

# In[104]:


def filter_response(text_input, user_details):
    # 我们使用到openAI提供的打标签链, 用户的输入可以被这个链解析和映射。
    chain = create_tagging_chain_pydantic(PersonalDetails,llm)
    res = chain.run(text_input)
    # 更新用户信息
    user_details = add_non_empty_details(user_details,res)
    ask_for = check_what_is_empty(user_details)
    return user_details, ask_for


# 测试一下效果,我们要获取的就是最新的用户信息,筛选出来哪些项目还没有填写。
# 

# In[155]:


def decide_ask(ask_for=["name","city","email"]):
    if ask_for:
        ai_res = ask_for_info(ask_for=ask_for)
        print(ai_res)
    else:
        print("全部填写完整")
decide_ask(ask_for)        


# In[167]:


user_999_personal_details = PersonalDetails(name="",city="",email="")
user_999_personal_details


# In[168]:


decide_ask(ask_for)


# In[169]:


str999 = "我的名字是999,我住在北京"


# In[170]:


user_999_personal_details, ask_for_999 = filter_response(str999,user_999_personal_details)
decide_ask(ask_for_999)


# In[173]:


str999 = "XX@XX.com"
user_999_personal_details, ask_for_999 = filter_response(str999,user_999_personal_details)
decide_ask(ask_for_999)

到了这里,关于langchain pdf链检索,提问式表单(实体命名识别)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包