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

【基于langchain + streamlit 完整的与文档对话RAG】

本地部署文档问答webdemo

  • 支持 pdf
  • 支持 txt
  • 支持 doc/docx
  • 支持 源文档索引

你的点赞收藏是我持续分享优质内容的动力哦~

废话不多说直接看效果

在这里插入图片描述

准备

  • 首先创建一个新环境(选择性)
conda create -n chatwithdocs python=3.11
conda activate chatwithdocs
  • 新建一个requirements.txt文件
streamlit
python-docx
PyPDF2
faiss-gpu
langchain
langchain-core
langchain-community
  • 然后安装相应的包
pip install -r requirements.txt -U

代码

创建一个app.py文件, 把下边的复制进去
注意:替换你自己的api-keybase-url

import streamlit as st
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import FAISS
from langchain_openai import ChatOpenAI
from langchain_openai import OpenAIEmbeddings
from langchain_core.documents import Document
from langchain.chains import ConversationalRetrievalChain
import docx
from PyPDF2 import PdfReaderimport os
os.environ['OPENAI_API_KEY']='xxx'
# os.environ['OPENAI_BASE_URL']='xxx' # 看你的情况st.set_page_config(page_title="Chat with Documents", page_icon=":robot:", layout="wide")st.markdown("""<style>
.chat-message {padding: 1.5rem; border-radius: 0.5rem; margin-bottom: 1rem; display: flex
}
.chat-message.user {background-color: #2b313e
}
.chat-message.bot {background-color: #475063
}
.chat-message .avatar {width: 20%;
}
.chat-message .avatar img {max-width: 78px;max-height: 78px;border-radius: 50%;object-fit: cover;
}
.chat-message .message {width: 80%;padding: 0 1.5rem;color: #fff;
}
.stDeployButton {visibility: hidden;}
#MainMenu {visibility: hidden;}
footer {visibility: hidden;}.block-container {padding: 2rem 4rem 2rem 4rem;
}.st-emotion-cache-16txtl3 {padding: 3rem 1.5rem;
}
</style>
# """,unsafe_allow_html=True,
)bot_template = """
<div class="chat-message bot"><div class="avatar"><img src="https://cdn.icon-icons.com/icons2/1371/PNG/512/robot02_90810.png" style="max-height: 78px; max-width: 78px; border-radius: 50%; object-fit: cover;"></div><div class="message">{{MSG}}</div>
</div>
"""user_template = """
<div class="chat-message user"><div class="avatar"><img src="https://www.shareicon.net/data/512x512/2015/09/18/103160_man_512x512.png" ></div>    <div class="message">{{MSG}}</div>
</div>
"""def get_pdf_text(pdf_docs):docs = []for document in pdf_docs:if document.type == "application/pdf":pdf_reader = PdfReader(document)for idx, page in enumerate(pdf_reader.pages):docs.append(Document(page_content=page.extract_text(),metadata={"source": f"{document.name} on page {idx}"},))elif (document.type== "application/vnd.openxmlformats-officedocument.wordprocessingml.document"):doc = docx.Document(document)for idx, paragraph in enumerate(doc.paragraphs):docs.append(Document(page_content=paragraph.text,metadata={"source": f"{document.name} in paragraph {idx}"},))elif document.type == "text/plain":text = document.getvalue().decode("utf-8")docs.append(Document(page_content=text, metadata={"source": document.name}))return docsdef get_text_chunks(docs):text_splitter = RecursiveCharacterTextSplitter(chunk_size=512, chunk_overlap=0)docs_chunks = text_splitter.split_documents(docs)return docs_chunksdef get_vectorstore(docs_chunks):embeddings = OpenAIEmbeddings()vectorstore = FAISS.from_documents(docs_chunks, embedding=embeddings)return vectorstoredef get_conversation_chain(vectorstore):llm = ChatOpenAI()conversation_chain = ConversationalRetrievalChain.from_llm(llm=llm,retriever=vectorstore.as_retriever(),return_source_documents=True,)return conversation_chaindef handle_userinput_pdf(user_question):chat_history = st.session_state.chat_historyresponse = st.session_state.conversation({"question": user_question, "chat_history": chat_history})st.session_state.chat_history.append(("user", user_question))st.session_state.chat_history.append(("assistant", response["answer"]))st.write(user_template.replace("{{MSG}}", user_question),unsafe_allow_html=True,)sources = response["source_documents"]source_names = set([i.metadata["source"] for i in sources])src = "\n\n".join(source_names)src = f"\n\n> source : {src}"message = st.session_state.chat_history[-1]st.write(bot_template.replace("{{MSG}}", message[1] + src), unsafe_allow_html=True)def show_history():chat_history = st.session_state.chat_historyfor i, message in enumerate(chat_history):if i % 2 == 0:st.write(user_template.replace("{{MSG}}", message[1]),unsafe_allow_html=True,)else:st.write(bot_template.replace("{{MSG}}", message[1]), unsafe_allow_html=True)def main():st.header("Chat with Documents")# 初始化会话状态if "conversation" not in st.session_state:st.session_state.conversation = Noneif "chat_history" not in st.session_state:st.session_state.chat_history = []with st.sidebar:st.title("文档管理")pdf_docs = st.file_uploader("选择文件",type=["pdf", "txt", "doc", "docx"],accept_multiple_files=True,)if st.button("处理文档",on_click=lambda: setattr(st.session_state, "last_action", "pdf"),use_container_width=True,):if pdf_docs:with st.spinner("Processing"):docs = get_pdf_text(pdf_docs)docs_chunks = get_text_chunks(docs)vectorstore = get_vectorstore(docs_chunks)st.session_state.conversation = get_conversation_chain(vectorstore)else:st.warning("记得上传文件哦~~")def clear_history():st.session_state.chat_history = []if st.session_state.chat_history:st.button("清空对话", on_click=clear_history, use_container_width=True)with st.container():user_question = st.chat_input("输入点什么~")with st.container(height=400):show_history()if user_question:if st.session_state.conversation is not None:handle_userinput_pdf(user_question)else:st.warning("记得上传文件哦~~")if __name__ == "__main__":main()

启动

  • 自动在浏览器打开
streamlit run app.py

相关文章:

  • Sqoop 学习
  • pytorch 函数整理
  • Python 进行把图片转换为pdf
  • 设计模式前置了解uml图
  • 小波散射网络及其应用
  • Sklearn交叉验证
  • 捍卫数据保护:预防和缓解.mallox勒索病毒的威胁
  • Lwip之TCP服务端示例记录(1对1)
  • RHEL9 DNF/YUM仓库管理软件包
  • 【More Effective C++】条款24:了解虚函数的成本
  • day16_购物车(添加购物车,购物车列表查询,删除购物车商品,更新选中商品状态,完成购物车商品的全选,清空购物车)
  • springboot单体项目链路日志跟踪及接口耗时
  • Sklearn线性回归
  • WebSocket:实现客户端与服务器实时通信的技术
  • 考研复习C语言初阶(4)+标记和BFS展开的扫雷游戏
  • 【译】理解JavaScript:new 关键字
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • Flex布局到底解决了什么问题
  • Intervention/image 图片处理扩展包的安装和使用
  • Java,console输出实时的转向GUI textbox
  • js中的正则表达式入门
  • Mac转Windows的拯救指南
  • Mysql5.6主从复制
  • php面试题 汇集2
  • 漂亮刷新控件-iOS
  • 通过来模仿稀土掘金个人页面的布局来学习使用CoordinatorLayout
  • 因为阿里,他们成了“杭漂”
  • 原生js练习题---第五课
  • 在Unity中实现一个简单的消息管理器
  • 你对linux中grep命令知道多少?
  • 【干货分享】dos命令大全
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • ​LeetCode解法汇总518. 零钱兑换 II
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #Java第九次作业--输入输出流和文件操作
  • #LLM入门|Prompt#1.8_聊天机器人_Chatbot
  • #NOIP 2014# day.1 T3 飞扬的小鸟 bird
  • ()、[]、{}、(())、[[]]命令替换
  • (06)金属布线——为半导体注入生命的连接
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (六)软件测试分工
  • (一)appium-desktop定位元素原理
  • (转)es进行聚合操作时提示Fielddata is disabled on text fields by default
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)...
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查
  • .net和php怎么连接,php和apache之间如何连接
  • .w文件怎么转成html文件,使用pandoc进行Word与Markdown文件转化
  • @autowired注解作用_Spring Boot进阶教程——注解大全(建议收藏!)
  • @Responsebody与@RequestBody
  • [C#C++]类CLASS
  • [excel与dict] python 读取excel内容并放入字典、将字典内容写入 excel文件
  • [Firefly-Linux] RK3568修改控制台DEBUG为普通串口UART