LangChain-AI应用开发框架(九)

张开发
2026/4/12 18:54:02 15 分钟阅读

分享文章

LangChain-AI应用开发框架(九)
目录一.输出解析器Outputparsers1.概念a.与with_structured_output()的区别2.解析文本输出3.解析结构化对象输出4.解析JSON输出二.文档加载器Document loaders1.RAG介绍2.RAG流程3.RAG示例4.Document文档类5.加载PDF文档6.加载Markdown文件一.输出解析器Outputparsers1.概念a.与with_structured_output()的区别2.解析文本输出from langchain_openai import ChatOpenAI from langchain_core.output_parsers import StrOutputParser model ChatOpenAI(modelgpt-4o-mini) chain model | StrOutputParser() for chunk in chain.stream(写⼀⾸夏天的诗词50字以内。): print(chunk, end|)3.解析结构化对象输出from langchain_core.output_parsers import PydanticOutputParser from langchain_core.prompts import PromptTemplate from langchain_openai import ChatOpenAI import os from pydantic import BaseModel, Field from typing import Optional, List import os os.environ[LANGCHAIN_TRACING_V2] false # 关掉追踪 api_key os.getenv(ZHIPU_API_KEY) model ChatOpenAI( modelglm-5, base_urlhttps://open.bigmodel.cn/api/paas/v4/, api_keyapi_key, temperature0.7 ) # 笑话模型 class Joke(BaseModel): 给用户讲的一个笑话 setup: str Field(description这个笑话的开头) punchline: str Field(description这个笑话的妙语) rating: Optional[int] Field(defaultNone, description1-10分,这个笑话几分?) parser PydanticOutputParser(pydantic_objectJoke) # print(parser.get_format_instructions()) prompt PromptTemplate( template回复用户问题.\n返回结果说明:{format_instructions}\n用户问题: {query}\n, partial_variables{format_instructions: parser.get_format_instructions()},#将返回的结果发送给大模型 input_variables[query], ) # print(prompt.invoke({query: 讲一个关于跳舞的笑话})) #定义链 chain prompt | model | parser print(chain.invoke({query: 讲一个关于跳舞的笑话}))这样我们就能够进行调用了4.解析JSON输出from langchain_core.output_parsers import PydanticOutputParser, JsonOutputParser from langchain_core.prompts import PromptTemplate from langchain_openai import ChatOpenAI import os from pydantic import BaseModel, Field from typing import Optional, List import os os.environ[LANGCHAIN_TRACING_V2] false # 关掉追踪 api_key os.getenv(ZHIPU_API_KEY) model ChatOpenAI( modelglm-5, base_urlhttps://open.bigmodel.cn/api/paas/v4/, api_keyapi_key, temperature0.7 ) # 笑话模型 class Joke(BaseModel): 给用户讲的一个笑话 setup: str Field(description这个笑话的开头) punchline: str Field(description这个笑话的妙语) rating: Optional[int] Field(defaultNone, description1-10分,这个笑话几分?) #Json Schema不好写 #我们可以定义Json的输出解析器 parser JsonOutputParser(pydantic_objectJoke) print(parser.get_format_instructions()) prompt PromptTemplate( template回复用户问题.\n返回结果说明:{format_instructions}\n用户问题: {query}\n, partial_variables{format_instructions: parser.get_format_instructions()},#将返回的结果发送给大模型 input_variables[query], ) # print(prompt.invoke({query: 讲一个关于跳舞的笑话})) #定义链 # chain prompt | model | parser # print(chain.invoke({query: 讲一个关于跳舞的笑话}))这个本质上也是格式限制的一种返回的就是Json值参考链接:https://reference.langchain.com/python/langchain-core二.文档加载器Document loaders1.RAG介绍2.RAG流程3.RAG示例# -*- coding: utf-8 -*- from langchain_openai import OpenAIEmbeddings, ChatOpenAI from langchain_redis import RedisConfig, RedisVectorStore from langchain_core.output_parsers import StrOutputParser from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnablePassthrough # 1. 初始化模型与Redis配置 # 定义聊天模型使用gpt-4o-mini可替换为其他模型如glm-4、qwen-max等 model ChatOpenAI(modelgpt-4o-mini) # 定义嵌入模型用于文本向量化 embeddings OpenAIEmbeddings(modeltext-embedding-3-large) # 配置Redis客户端替换为你的Redis地址 redis_url redis://192.168.100.238:6379 config RedisConfig( index_nameqa, # 索引名称对应RAG检索的库 redis_urlredis_url, metadata_schema[ {name: category, type: tag}, {name: num, type: numeric}, ], ) # 定义Redis向量存储核心存储检索向量 vector_store RedisVectorStore(embeddings, configconfig) # 生成检索器核心根据用户问题检索相关文档 retriever vector_store.as_retriever() # 2. 定义提示词模板 # 修复ChatPromptTemplate.from_messages语法错误列表内元素直接为元组无需外层括号 prompt ChatPromptTemplate.from_messages( [ ( human, 你是负责回答问题的助手。使用以下检索到的上下文片段来回答问题。如果你不知道答案就说你不知道。最多只用三句话回答要简明扼要。 Question: {question} Context: {context} Answer:, ), ] ) # 3. 文档格式化工具 def format_docs(docs): 将检索到的多个文档拼接为字符串作为上下文传入大模型 return \n\n.join(doc.page_content for doc in docs) # 4. 构建RAG链 # 核心逻辑 # 1. retriever | format_docs检索相关文档并拼接 # 2. RunnablePassthrough()透传用户问题 # 3. prompt - model - StrOutputParser生成并解析答案 rag_chain ( {context: retriever | format_docs, question: RunnablePassthrough()} | prompt | model | StrOutputParser() ) # 5. 交互式问答主程序 if __name__ __main__: print( RAG 问答系统已启动输入问题开始对话输入退出/quit结束 \n) while True: # 获取用户输入 question input(请输入您的问题输入退出或quit结束程序).strip() # 检查是否退出 if question.lower() in [退出, quit]: print(程序已结束再见) break # 检查输入是否为空 if not question: print(问题不能为空请重新输入。) continue # 执行链流式输出答案 print(回答, end, flushTrue) chunks [] # 流式获取结果逐字打印 for chunk in rag_chain.stream(question): chunks.append(chunk) print(chunk, end, flushTrue) print(\n) # 换行分隔下一轮对话4.Document文档类from langchain_core.documents import Document documents [ # 单个Document对象通常表示较大文档的一个块 Document( # 内容字符串 page_content狗是很好的伴侣以忠诚和友好而闻名。, # 元数据字典 # 元数据属性可以捕获有关文档源、与其他文档的关系以及其他信息的信息。 metadata{source: mammal-pets-doc}, ), Document( page_content猫是独立的宠物经常享受自己的空间。, metadata{source: mammal-pets-doc}, ), ]5.加载PDF文档from langchain_community.document_loaders import PyPDFLoader file_path ../Docs/PDF/脚⼿架级微服务租房平台QA.pdf loader PyPDFLoader(file_path) # 将 PDF ⽂件的每⼀⻚转换为⼀个独⽴的 Document 对象并存储在列表 docs 中。 docs loader.load()6.加载Markdown文件pip install unstructured[md] nltkfrom langchain_community.document_loaders import UnstructuredMarkdownLoader from langchain_core.documents import Document markdown_path ../Docs/Markdown/脚手架级微服务租房平台QA.md # single 模式加载后默认只有一个 Document 对象 loader UnstructuredMarkdownLoader(markdown_path) data loader.load() assert len(data) 1 assert isinstance(data[0], Document) print(data[0].page_content[:200]) print(data[0].metadata)from langchain_community.document_loaders import UnstructuredMarkdownLoader md_loader UnstructuredMarkdownLoader( ../Docs/markdown/脚手架级微服务租房平台QA.md, modesingle ) docs md_loader.load() #默认将文档加载为1个 print(fMD文档总页数: \n{len(docs)}\n)from langchain_community.document_loaders import UnstructuredMarkdownLoader from langchain_core.documents import Document markdown_path ../Docs/Markdown/脚手架级微服务租房平台QA.md # single 模式加载后默认只有一个 Document 对象 loader UnstructuredMarkdownLoader(markdown_path, modeelements) data loader.load() print(f问文档个数为\n{len(data)}\n) print(问前三个文档数据) for document in data[:3]: print(f{document}\n)链接:https://docs.langchain.com/oss/python/integrations/providers/overview

更多文章