news 2026/1/30 22:30:54

【大模型】-LangChain--RAG文档系统

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【大模型】-LangChain--RAG文档系统

文章目录

  • 1.完整代码
  • 2.结果展示
  • 3. RAG介绍

1.完整代码

由于使用的是通义,所以代码改造了下,因为openAI需要钱

importstreamlitasstimporttempfileimportosfromlangchain_classic.memoryimportConversationBufferMemoryfromlangchain_community.chat_message_historiesimportStreamlitChatMessageHistoryfromlangchain_community.document_loadersimportTextLoaderfromlangchain_community.vectorstoresimportChromafromlangchain_community.embeddingsimportDashScopeEmbeddingsfromlangchain_core.promptsimportPromptTemplatefromlangchain_text_splittersimportRecursiveCharacterTextSplitterfromlangchain_classic.agentsimportAgentExecutor,create_tool_calling_agentfromlangchain_community.callbacks.streamlitimportStreamlitCallbackHandlerfromlangchain_openaiimportChatOpenAIfromlangchain_community.chat_modelsimportChatTongyifromlangchain_core.toolsimporttool,create_retriever_toolfromdotenvimportload_dotenv load_dotenv()# 设置Streamlit应用的页面标题和布局st.set_page_config(page_title="文档问答",layout="wide")# 设置应用的标题st.title("📚 文档问答系统")# 上传txt文件,允许上传多个文件uploaded_files=st.sidebar.file_uploader(label="上传txt文件",type=["txt"],accept_multiple_files=True)# 如果没有上传文件,提示用户上传文件并停止运行ifnotuploaded_files:st.info("请先上传按TXT文档。")st.stop()@st.cache_resource(ttl="1h")defconfigure_retriever(uploaded_files):# 读取上传的文档,并写入一个临时目录docs=[]temp_dir=tempfile.TemporaryDirectory(dir=r"D:\蒋辉\AI大模型")forfileinuploaded_files:temp_filepath=os.path.join(temp_dir.name,file.name)withopen(temp_filepath,"wb")asf:f.write(file.getvalue())# 使用TextLoader加载文本文件loader=TextLoader(temp_filepath,encoding="utf-8")docs.extend(loader.load())# 进行文档分割text_splitter=RecursiveCharacterTextSplitter(chunk_size=1000,chunk_overlap=200)splits=text_splitter.split_documents(docs)# 使用向量模型生成文档的向量表示embeddings=DashScopeEmbeddings(model="text-embedding-v3",dashscope_api_key="sk-秘钥")vectordb=Chroma.from_documents(splits,embeddings)# 创建文档检索器retriever=vectordb.as_retriever()returnretriever# 配置检索器retriever=configure_retriever(uploaded_files)# 如果session_state中没有消息记录或用户点击了清空聊天记录按钮,则初始化消息记录if"messages"notinst.session_stateorst.sidebar.button("清空聊天记录"):st.session_state["messages"]=[{"role":"assistant","content":"您好,我是文档问答助手"}]# 加载历史聊天记录formsginst.session_state.messages:st.chat_message(msg["role"]).write(msg["content"])# 创建用于文档检索的工具retrieval_tool=create_retriever_tool(retriever,name="文档检索",description="用于检索用户提出的问题,并基于检索到的文档内容进行回复.",)tools=[retrieval_tool]# 创建聊天消息历史记录msgs=StreamlitChatMessageHistory()# 创建对话缓冲区内存memory=ConversationBufferMemory(chat_memory=msgs,return_messages=True,memory_key="chat_history",output_key="output")# 指令模板instructions="""您是一个设计用于查询文档来回答问题的代理。 您可以使用文档检索工具,并基于检索内容来回答问题 您可能不查询文档就知道答案,但是您仍然应该查询文档来获得答案。 如果您从文档中找不到任何信息用于回答问题,则只需返回“抱歉,这个问题我还不知道。”作为答案。 """# 基础提示模板 - 修改这里!base_prompt_template=""" {instructions} TOOLS: ------ You have access to the following tools: {tools} To use a tool, please use the following format: Thought: Do I need to use a tool? Yes Action: The action to take, should be one of [{tool_names}] Action Input: {input} Observation: the result of the action When you have a response to say to the Human, or if you do not need to use a tool, you MUST use the format: Thought: Do I need to use a tool? No Final Answer: [your response here] Begin! Previous conversation history: {chat_history} New input: {input} {agent_scratchpad}"""# 创建基础提示模板 - 修改这里!# 需要传递tools和tool_namestool_names=", ".join([tool.namefortoolintools])tool_descriptions="\n".join([f"{tool.name}:{tool.description}"fortoolintools])base_prompt=PromptTemplate(template=base_prompt_template,input_variables=["agent_scratchpad","chat_history","input"],partial_variables={"instructions":instructions,"tools":tool_descriptions,"tool_names":tool_names})# 创建Llmllm=ChatTongyi(model="qwen-plus")# 创建react Agentagent=create_tool_calling_agent(llm,tools,base_prompt)# 创建Agent执行器''' AgentExecutor 的这几个参数作用如下: agent=agent: 指定要使用的 Agent 实例,这里是通过 create_tool_calling_agent 创建的工具调用代理 tools=tools: 传入可用的工具列表,代理会根据需要调用这些工具(如文档检索工具) memory=memory: 配置对话内存,用于保存对话历史,使代理能够记住之前的交互内容 verbose=True: 启用详细日志输出,方便调试和查看代理的思考过程 handle_parsing_errors=True: 启用解析错误处理机制,当 Agent 输出格式不正确时自动处理而不是抛出异常 '''agent_executor=AgentExecutor(agent=agent,tools=tools,memory=memory,verbose=True,handle_parsing_errors=True)# 创建聊天输入框user_query=st.chat_input(placeholder="请开始提问吧!")# 如果有用户输入的查询ifuser_query:# 添加用户消息到session_statest.session_state.messages.append({"role":"user","content":user_query})# 显示用户消息st.chat_message("user").write(user_query)withst.chat_message("assistant"):# 创建streamlit回调处理器st_cb=StreamlitCallbackHandler(st.container())# agent执行过程日志回调显示在Streamlit Containerconfig={"callbacks":[st_cb]}try:# 执行Agent并获取响应response=agent_executor.invoke({"input":user_query},config=config)# 添加助手消息到session_statest.session_state.messages.append({"role":"assistant","content":response["output"]})# 显示助手响应st.write(response["output"])exceptExceptionase:st.error(f"处理问题时出错:{str(e)}")st.session_state.messages.append({"role":"assistant","content":"抱歉,处理您的问题时出现了错误。"})

2.结果展示

控制台执行命令

streamlit run D:/jhproject/python_project/LLM/jh-langserve-app/app/RAG_问答系统.py

上传txt文件,目前demo支持txt,可以改造成支持多种文档格式,直接问AI就行,这里就不展示了

每次询问和程序员相关的,他会查询出对应结果,因为知识库来自上传的文档

如果询问奥特曼或者非知识库的内容,它答不上来

之前配置的监控也会看出,smith平台,如何配置请看LangSmith监控

3. RAG介绍

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/29 12:28:27

昇腾CANN从单算子到融合优化实战

目录 1 摘要 2 技术原理 2.1 架构设计理念解析 2.2 核心算法实现 2.2.1 三级流水线设计原理 2.2.2 Tiling策略与数据重用 2.3 性能特性分析 2.3.1 理论性能模型 2.3.2 实测性能数据 3 实战部分 3.1 完整可运行代码示例 3.2 分步骤实现指南 步骤1:环境配…

作者头像 李华
网站建设 2026/1/29 12:28:15

大数据项目阿里云抢占式服务器

一、学生有免费额度可以使用 查看是否有免费的额度: https://university.aliyun.com/?spm5176.29458888.J_9220772140.19.6e632868x2bj7D 或者: https://free.aliyun.com/?spm5176.28623341.J_9220772140.18.4c044519hKalBC 二、购买抢占式资源服务…

作者头像 李华
网站建设 2026/1/29 14:43:12

Flink源码阅读:如何生成JobGraph

前文我们介绍了 Flink 的四种执行图,并且通过源码了解了 Flink 的 StreamGraph 是怎么生成的,本文我们就一起来看下 Flink 的另一种执行图——JobGraph 是如何生成的。 StreamGraph 和 JobGraph 的区别 在正式开始之前,我们再来回顾一下 Stre…

作者头像 李华
网站建设 2026/1/29 13:47:19

21、GNU 开发实用工具:函数、变量与调试技巧

GNU 开发实用工具:函数、变量与调试技巧 1. 关联数组与命名栈 在开发过程中,关联数组和命名栈是非常实用的数据结构。对于关联数组,可使用 defined 函数来测试键是否存在。 defined Arguments: 1: Name of associative array2: The key to test Returns: $(true) if …

作者头像 李华
网站建设 2026/1/29 13:46:05

YOLOv8+PyQt5车辆类型检测(可以重新训练,yolov8模型,从图像、视频和摄像头三种路径识别检测,包含登陆页面、注册页面和检测页面)

资源包含可视化的车辆类型检测系统,基于最新的YOLOv8训练的车辆类型检测模型,和基于PyQt5制作的可视化车辆类型检测系统,包含登陆页面、注册页面和检测页面,该系统可自动检测和识别图片或视频当中出现的21种车辆类型,包…

作者头像 李华
网站建设 2026/1/29 13:10:02

打开软件出现找不到vcruntime140.dll文件 无法运行的情况 下载修复解决

在使用电脑系统时经常会出现丢失找不到某些文件的情况,由于很多常用软件都是采用 Microsoft Visual Studio 编写的,所以这类软件的运行需要依赖微软Visual C运行库,比如像 QQ、迅雷、Adobe 软件等等,如果没有安装VC运行库或者安装…

作者头像 李华