LangChain与大语言模型应用开发实战-第3、4章 基础应用开发、高级应用开发_第1页
LangChain与大语言模型应用开发实战-第3、4章 基础应用开发、高级应用开发_第2页
LangChain与大语言模型应用开发实战-第3、4章 基础应用开发、高级应用开发_第3页
LangChain与大语言模型应用开发实战-第3、4章 基础应用开发、高级应用开发_第4页
LangChain与大语言模型应用开发实战-第3、4章 基础应用开发、高级应用开发_第5页
已阅读5页,还剩96页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

LangChain与大语言模型应用开发实战第三章:基础应用开发讲师:XXX|XXX年X月开篇引言:解锁LangChain的无限可能想象一下,你想构建一个智能客服机器人。它需要满足四个关键需求,而这正好对应了本章要学习的四大核心模块:01.模型调用(ModelI/O)调用大语言模型(LLM)来理解用户的复杂问题,并生成准确、自然的回答。02.提示模板(PromptTemplates)根据用户的具体问题动态调整提示词,提供针对性的引导,让模型输出更可控。03.链式调用(Chains)将多个独立任务串联起来,比如先查询数据库订单状态,再结合结果给出建议。04.对话记忆(Memory)在多轮对话中持久化并引用历史信息,理解上下文,让交互体验更连贯自然。本章教学目标理解LangChain的四大核心模块深入理解模型、提示、链、记忆模块的底层逻辑与协作方式。掌握模型的统一调用接口学会使用统一标准,灵活调用LLMs、ChatModels及EmbeddingModels。熟练运用动态提示模板技术使用PromptTemplate与ChatPromptTemplate精准控制并引导模型输出。学会任务的链式调用组合通过LLMChain与SequentialChain将多个简单任务串联成复杂的AI工作流。实现具备上下文感知的对话系统利用Memory模块管理对话历史,让AI具备长期记忆和多轮对话能力。具备基础LLM应用独立开发能力能够针对不同的业务场景,自主选择合适的组件与策略,落地完整的AI应用。PART01模型调用基础接口ModelI/O1.1引言:为什么需要统一的模型接口?开发痛点📚学习成本高

每个模型厂商都有自己的API规范,需要重复学习不同的调用方法、参数定义与响应格式。🔧代码复用性差

更换底层模型意味着大量的代码重构,无法快速复用之前的开发逻辑。🛠️系统维护困难

业务代码与具体模型的API细节深度耦合,导致后期维护成本高昂,难以扩展。LangChain的方案提供统一的抽象接口屏蔽底层不同模型厂商的差异,为开发者提供一致的开发体验。只需学习一次接口标准,即可无缝切换调用OpenAI、Anthropic、Google等任意模型,大幅降低开发门槛与维护成本。三大核心抽象🖥️LLM(大语言模型接口)

用于与纯文本生成模型进行交互,处理补全任务。💬ChatModel(对话模型接口)

专门为聊天机器人场景设计,基于“消息”列表进行交互。🧠Embeddings(嵌入模型接口)

用于将文本转换为数值向量,是实现检索增强生成(RAG)的基础。1.2三大核心接口概览:LLMLLM(LargeLanguageModel)·语言模型核心用途适用于通用的自然语言生成任务,例如文章续写、摘要总结、多语言翻译、聊天对话等场景。输入与输出输入:一段文本字符串(Prompt/提示词)

输出:一段文本字符串(Completion/补全)典型模型•OpenAI:text-davinci-003

•HuggingFace:GPT2,LLaMA,Mistral系列UserInput用户输入(TextString)LLMModel模型推理与计算ModelOutput模型输出(Completion)1.2三大核心接口概览:ChatModelChatModel(对话模型)核心用途专为多轮对话场景设计,能够基于历史对话信息更好地理解上下文逻辑,维持对话的连贯性。输入规范(Input)输入为结构化的消息列表List[BaseMessage],每个消息包含role(system/user/assistant)与content字段。输出格式(Output)返回一个标准的AIMessage对象,其核心content字段即包含模型生成的自然语言回复内容。典型代表模型OpenAI的gpt-3.5-turbo、gpt-4系列模型;以及Anthropic的Claude系列对话模型等。UserInput(MessageList)➜ChatModel处理上下文➜ModelOutput(AIMessage)1.2三大核心接口概览:EmbeddingsEmbeddings(文本嵌入模型):从“文字”到“数字”的语义翻译官⚡核心工作流程输入文本

Text(String)Embedding模型

语义编码向量输出

Vector(Float)注:转换后的向量可用于计算“语义相似度”与“检索”主要用途:将非结构化文本转换为高维向量,广泛应用于语义搜索、文本相似度计算、文档聚类等任务,是实现RAG(检索增强生成)的基石。输入与输出:输入:任意自然语言字符串;输出:一组代表语义特征的浮点型数值列表。典型模型:•OpenAI:text-embedding-ada-002(平衡性价比)

•SentenceTransformers:all-MiniLM-L6-v2(轻量开源)1.3LLM接口实战:代码示例PythonImplementation(LangChain+OpenAI)#1.导入必要的库并初始化模型(设置温度和最大Token数)

fromlangchain.llmsimportOpenAIfrommptsimportPromptTemplate

llm=OpenAI(model_name="text-davinci-003",temperature=0.7,max_tokens=150)

#2.定义提示词模板,使用占位符动态生成内容

prompt=PromptTemplate(

input_variables=["topic"],

template="请围绕{topic}写一段约100字的通俗介绍。"

).format(topic="人工智能")

#3.核心:一行代码调用LLM并处理输出

response=llm(prompt)

print("模型的输出:",response.strip())1.3LLM接口实战:代码解析01.初始化模型`OpenAI()`类是LangChain对OpenAIAPI的封装。我们可以在初始化时,灵活指定使用的模型名称、控制生成随机性的`temperature`参数以及限制输出长度的`max_tokens`参数。02.提示模板(PromptTemplate)利用`PromptTemplate`可以轻松实现提示词的动态生成,避免了手动拼接字符串的繁琐操作,不仅让代码逻辑更清晰,也大大降低了后期维护和修改提示词的成本。03.调用模型API调用过程非常直观。完成初始化和提示词构建后,直接通过`llm(prompt)`的函数调用方式,即可向大模型发起请求并同步获取文本输出。04.处理响应结果接口返回的响应通常是一个结构清晰的纯字符串对象。我们可以直接将其展示给用户,或者根据业务需求,对其进行解析、格式化或进一步的逻辑处理。1.4`ChatModel`接口实战:代码示例Python代码演示:基于消息列表的连续对话逻辑#1.导入核心库与消息类定义fromlangchain.chat_modelsimportChatOpenAIfromlangchain.schemaimportHumanMessage,SystemMessage,AIMessage#2.初始化模型与构建上下文消息列表chat=ChatOpenAI(model_name="gpt-3.5-turbo",temperature=0.5)history=[SystemMessage(content="你是一位简洁准确的知识助手。"),HumanMessage(content="什么是量子计算?")]#3.循环对话:追加消息以保持上下文history.append(chat(history))#接收回答并加入历史history.append(HumanMessage(content="它和经典计算有什么本质区别?"))print("FinalAnswer:"+chat(history).content)1.4ChatModel接口实战:代码解析01/初始化模型使用ChatOpenAI类来实例化模型对象,这是调用OpenAI对话模型(如GPT-4o)的核心入口,用于发起对话请求。02/消息列表(MessageList)对话以列表形式组织,每条消息都包含明确的角色(如system/user/assistant)。SystemMessage用于设定AI助手的角色定位与回答准则。03/上下文感知能力每一次API调用都会将完整的历史消息列表发送给模型,从而让模型理解多轮对话逻辑,准确识别代词(如“它”、“上文”)的指代内容。04/响应对象解析API返回的是一个结构化的AIMessage对象,其中.content属性存储了最终的文本回复,而其他属性包含了token消耗等元数据。1.5Embeddings接口实战:代码示例#导入必要的库fromlangchain.embeddingsimportOpenAIEmbeddingsimportnumpyasnpfromscipy.spatial.distanceimportcosine#1.初始化Embedding模型embeddings=OpenAIEmbeddings(model="text-embedding-ada-002")#2.定义待比较的文本&3.获取文本向量v1=embeddings.embed_query("猫喜欢吃鱼");v2=embeddings.embed_query("狗喜欢啃骨头")v3=embeddings.embed_query("小猫爱吃鱼")#4.计算余弦相似度并输出sim_12=1-cosine(v1,v2);sim_13=1-cosine(v1,v3)print(f"猫vs狗:{sim_12:.4f}|猫vs小猫:{sim_13:.4f}")1.5Embeddings接口实战:代码解析01.初始化模型使用OpenAIEmbeddings类实例化客户端,作为调用OpenAI嵌入模型的入口。提示:确保在环境变量中正确配置APIKey,以建立连接。02.获取向量将文本转化为高维向量是核心步骤:•单条查询:embed_query()方法

•批量文档:embed_documents()方法03.计算相似度利用余弦相似度算法,计算向量夹角,从而量化文本的语义相似性。案例:"猫喜欢吃鱼"与"小猫爱吃鱼"的相似度远高于其与"今天天气不错"的相似度。1.6参数调优:控制模型的“性格”temperature(温度)💡核心作用控制模型生成内容的随机性与创造性,决定了模型的“发散”程度。📉低值(0.0-0.3)输出确定性强、更聚焦。适合事实问答、代码编写、专业文档等需要精准的任务。📈高值(0.7-1.0)输出更多样、更具想象力。适合头脑风暴、故事创作、文案创意等场景。max_tokens(长度限制)⚙️核心作用硬性限制模型生成的最大Token数量。Token可以理解为“单词块”或“字节”,直接决定了文本的篇幅长短。💰主要用途1.防止模型“话痨”,保证回答简洁聚焦。

2.避免生成超长文本,有效控制API调用成本。top_p(核采样)🎛️核心机制一种替代Temperature的随机性控制方法。它不改变概率分布,而是动态选择累计概率之和达到P的词汇子集进行采样。简单来说,就是“只从热门词汇里挑”。💡重要建议通常建议只调整temperature或top_p其中一个参数,同时调整两者可能会产生不可预知的效果。1.7错误处理与最佳实践重试机制(RetryMechanism)对于网络波动、服务暂时不可用等问题,配置合理的自动重试策略能有效提升系统稳定性。格式强制(FormatEnforcement)在提示词中明确指定输出格式(如JSON、XML或特定分隔符),确保模型返回结果可被程序正确解析。日志记录(Logging)完整记录每次调用的提示词、参数及响应,是排查故障、分析模型行为及优化提示词的基础。清晰提示使用明确、具体、结构化的指令引导模型输出符合预期的结果。参数优化针对任务类型,合理调整Temperature和MaxTokens等参数。错误处理实现重试逻辑和格式校验机制,构建高容错、高健壮性的应用。全链路日志详细记录关键节点的输入输出,便于事后复盘、调试和分析。测试驱动在大规模部署前,建立测试集,验证提示词与系统逻辑的有效性。第二部分动态提示模板设计PROMPTENGINEERING2.1引言:什么是提示工程?什么是提示工程?提示工程(PromptEngineering)是一门通过设计和优化输入(Prompt)来引导大语言模型(LLM)生成高质量、符合预期输出的艺术和科学。它是连接人类意图与AI能力的关键桥梁。为何需要动态模板?在真实场景中,输入和输出往往是多变的。例如翻译工具需要适配不同的文本内容和目标语言。如果将提示硬编码,会导致代码极度冗余、维护成本高昂且缺乏灵活性。LangChain解决方案LangChain提供了强大的`PromptTemplate`类,允许开发者预先定义包含变量的通用模板,在运行时根据实际需求动态填充变量,从而高效生成最终提示,极大提升了开发效率。2.2PromptTemplate实战:代码示例💻代码实现frommptsimportPromptTemplate#1.定义模板,包含两个变量product_template=PromptTemplate(input_variables=["product_name","feature"],template="请为{product_name}写一段{feature}功能的营销文案,生动且不超过50字。")#2.传入不同参数,生成不同提示词p1=product_template.format(product_name="智能音箱",feature="语音助手")p2=product_template.format(product_name="无线耳机",feature="主动降噪")📋输出结果Prompt1:请为一款名为智能音箱的产品,撰写一段关于其语音助手功能的营销文案,要求语言生动,不超过50字。Prompt2:请为一款名为无线耳机的产品,撰写一段关于其主动降噪功能的营销文案,要求语言生动,不超过50字。💡核心价值:通过定义模板和变量分离,我们只需要维护一份通用逻辑,即可快速扩展到不同的业务场景。2.2`PromptTemplate`实战:代码解析模板定义(Definition)•占位符:在模板字符串中,使用{product_name}与{feature}作为变量标记,明确待填充内容的位置。•变量声明:通过input_variables列表显式定义所有变量名称,确保模板结构严谨且可维护。模板格式化(Formatting)•参数注入:调用.format()方法并传入关键字参数,将具体的数值动态填充至模板的对应位置。•生成结果:自动将变量替换为真实内容,快速拼接并生成最终可直接发送给模型的提示词字符串。开发价值总结:通过分离“模板结构”与“具体数据”,我们实现了提示词逻辑的模块化设计。这种模式不仅提高了代码的复用性,更降低了维护成本,让开发人员能够专注于提示词逻辑本身,从而显著提升了LLM应用的开发与迭代效率。2.3`ChatPromptTemplate`实战:代码示例💻代码实现(Python)frommptsimportChatPromptTemplate#1.使用from_messages方法定义多轮对话模板chat_template=ChatPromptTemplate.from_messages([("system","你是一个专业的美食评论家,回答需富有文采。"),("human","请推荐一道适合夏天吃的{cuisine}菜。"),("ai","当然,我推荐的是经典的{recommendation}。"),("human","它的主要食材是什么?")])#2.填充变量并格式化生成对话列表messages=chat_template.format_messages(cuisine="中式",recommendation="凉拌黄瓜")📤运行输出结果system:你是一个专业的美食评论家,你的回答应该富有文采。human:请推荐一道适合夏天吃的中式菜。ai:当然,我推荐的是经典的凉拌黄瓜。human:它的主要食材是什么?2.3ChatPromptTemplate实战:代码解析结构化定义`from_messages`方法允许我们以一种非常直观的方式定义包含系统、用户、助手角色的对话流程,清晰界定每一轮交互的主体。变量填充`format_messages()`方法同样支持接收外部变量,并自动将其动态填充到模板的对应占位符位置,让对话模板灵活复用。直接使用模板生成的`messages`列表可以直接、无缝地传递给`ChatModel`进行推理调用,无需额外的数据格式转换。2.4高级技巧:少样本学习(Few-ShotLearning)少样本学习是一种强大的提示技巧,通过在提示中提供少量示例(Demo)来引导模型完成特定任务,尤其适用于复杂或未见过的任务场景。LangChain提供了专用的FewShotPromptTemplate工具,帮助开发者高效构建和管理这类提示。01定义示例准备与任务目标一致的高质量输入输出对。示例越贴合实际应用场景,模型生成的效果通常越好。这一步是引导模型理解任务的基础。02定义示例格式使用`PromptTemplate`来定义单个示例在最终提示中的展示方式。例如,明确输入字段和输出字段之间的分隔符或关键词,确保格式统一、清晰。03构建少样本模板组合定义好的示例列表、示例格式、引导语(Instruction)和最终的用户输入槽位。将它们封装成一个完整的`FewShotPromptTemplate`以便直接调用。2.4少样本学习实战:代码示例frommptsimportFewShotPromptTemplate,PromptTemplate#1.定义示例数据examples=[{"text":"这部电影太棒了!","sentiment":"正面"},{"text":"今天天气真差。","sentiment":"负面"},{"text":"会议延迟了,但达成了共识。","sentiment":"中性"}]#2.定义单条示例的格式化模板example_prompt=PromptTemplate(input_variables=["text","sentiment"],template="文本:{text}\n情感:{sentiment}\n")#3.组装少样本提示词并进行格式化prompt=FewShotPromptTemplate(examples=examples,example_prompt=example_prompt,prefix="请分析以下文本的情感倾向:",suffix="文本:{input}\n情感:").format(input="这款新手机的电池续航超出了我的预期。")2.4少样本学习实战:生成的提示📋任务指令与示例:请分析以下文本的情感倾向,只需回答「正面」、「负面」或「中性」。以下是一些例子:🗣️文本:这部电影太棒了!→情感:正面|🗣️文本:今天天气真差。→情感:负面🗣️文本:会议延迟了,但达成了共识。→情感:中性❓待分析:文本:这款新手机的电池续航超出了我的预期。情感:______💡核心原理:通过提供少量的任务范例,建立“输入-输出”的映射逻辑,我们可以有效引导模型学会如何完成它可能不熟悉的特定任务,而无需额外的模型微调。2.5高级技巧:LCEL(LangChainExpressionLanguage)什么是LCEL?LCEL是一种声明式语言,专门用于将LLM应用的各个独立组件组合成端到端的处理流程。它支持流式处理、异步操作以及多模态输入输出,并让代码结构更清晰、更具可维护性。prompt|model|output_parser使用管道符`|`串联组件,逻辑一目了然核心思想:管道化(Pipelining)将复杂的应用逻辑抽象为一个“数据管道”。数据从管道的一端流入,依次经过提示模板格式化、大模型推理、结果解析等预设的处理步骤,最终转化为可直接使用的结果从另一端流出。▶优势:组件复用性强、支持动态编排,且内置了对错误处理和上下文管理的支持。2.5LCEL实战:代码示例#1.初始化组件:导入并定义基础模块fromlangchain.chat_modelsimportChatOpenAIfrommptsimportChatPromptTemplatefromlangchain.schema.output_parserimportStrOutputParser#2.LCEL核心:用管道符`|`连接各组件,构建处理链chain=ChatPromptTemplate.from_messages([("system","你是一个乐于助人的助手。"),("human","{user_input}")])|ChatOpenAI(model_name="gpt-3.5-turbo")|StrOutputParser()#3.调用执行:输入数据自动流经管道,返回结果response=chain.invoke({"user_input":"解释一下什么是光合作用?"})print(response)2.5LCEL实战:代码解析组件组合prompt_template|chat_model

|output_parser将不同的原子组件通过管道符(|)串联,构建一个端到端的AI应用处理流程,而非分散的函数调用。数据流动1.输入:字典形式的用户参数

2.生成:消息列表传递给LLM

3.解析:AIMessage转为最终字符串

整个过程自动完成,无需手动处理中间数据格式转换。极致简洁对比传统手动编写:

✅省略大量样板代码

✅减少变量定义与传递

✅逻辑结构一目了然

让开发者聚焦于“做什么”,而非“怎么做”。2.6提示设计原则与案例分析清晰性Clarity使用明确、具体的语言描述任务,避免模糊不清的表述,让模型准确理解意图。完整性Completeness提供足够的背景信息和上下文细节,为模型的推理和回答提供坚实基础。指令性Directiveness善用“总结”、“分析”、“创作”等命令式动词,直接、明确地告诉模型要执行的动作。格式化Formatting根据使用场景明确指定输出格式,如列表、表格、JSON等,便于直接使用结果。迭代优化Iteration没有完美的提示,通过不断测试、分析结果并调整提示词,持续提升回答质量。2.6案例分析:代码生成任务目标请生成一个Python函数,实现以下功能:•函数名称:fibonacci•输入参数:一个整数n•核心逻辑:计算并返回斐波那契数列的第n项。优秀提示词示例请编写一个Python函数,名为fibonacci,它接受一个整数n作为参数,返回斐波那契数列的第n项。定义规则:

-fibonacci(0)=0

-fibonacci(1)=1

-fibonacci(n)=fib(n-1)+fib(n-2)(n>1)

要求:代码需包含适当的注释。设计亮点分析这是一个典型的“高质量指令”,它成功的关键在于:1.定义清晰:明确了函数的名称、输入参数和输出目标,避免歧义。2.规则明确:准确描述了数学定义,确保模型不会偏离核心逻辑。3.格式约束:明确提出代码风格要求(添加注释),让生成结果更具可读性。PART03链式调用方法实践Chains3.1引言:什么是链式调用?现实中的复杂任务许多任务并非一步到位,而是由多个逻辑紧密相连的步骤组成。以“文档问答”为例,它的执行流程就包含了多个环节:1.用户提出具体的问题。

2.根据问题,在知识库中检索出相关的文档片段。

3.将问题与检索到的片段一起发送给大语言模型(LLM)。

4.模型结合上下文生成准确的最终答案。LangChain的解决方案:Chains如果手动编写代码将这些独立步骤串联起来,不仅代码冗长、开发繁琐,且难以维护和扩展。

为此,LangChain提供了Chains(链)模块。预构建组件·流程化管道·可复用

将多个任务逻辑像“搭积木”一样组合,形成一个端到端的自动化处理链路。3.2LLMChain实战:代码示例#导入必要的库fromlangchain.chainsimportLLMChainfromlangchain.llmsimportOpenAIfrommptsimportPromptTemplate#1.初始化核心组件:大模型与提示词模板llm=OpenAI(temperature=0.8)#设置随机性为0.8prompt=PromptTemplate(input_variables=["topic"],template="请以{topic}为主题,写一首现代诗,大约4-6行。")#2.组装并运行LLMChainpoem_chain=LLMChain(llm=llm,prompt=prompt)result=poem_chain.run(topic="星空")#输入主题,一键生成内容print(result)3.2LLMChain实战:代码解析组件组合将提示词模板(PromptTemplate)与大语言模型(LLM)进行封装,构建一个标准化的执行单元,让提示词与模型逻辑紧密耦合,便于复用与管理。简化调用流程通过run()方法直接接收输入变量,内部自动完成提示词格式化、模型调用等繁琐步骤,一步返回最终文本输出。“LLMChain是构建所有更复杂应用链(Chains)的基石。”掌握它是深入学习LangChain框架的第一步。3.3SequentialChain实战:代码示例#1.导入依赖库fromlangchain.chainsimportLLMChain,SequentialChainfromlangchain.llmsimportOpenAI;frommptsimportPromptTemplatellm=OpenAI(temperature=0.5)#2.定义子任务链(摘要->提问)sum_prompt=PromptTemplate(input_variables=["text"],template="总结内容,不超过50字:{text}")sum_chain=LLMChain(llm=llm,prompt=sum_prompt,output_key="summary")q_prompt=PromptTemplate(input_variables=["summary"],template="基于摘要提问:{summary}")q_chain=LLMChain(llm=llm,prompt=q_prompt,output_key="question")#3.组装并运行顺序链overall_chain=SequentialChain(chains=[sum_chain,q_chain],input_variables=["text"],output_variables=["summary","question"],verbose=True)result=overall_chain({"text":"人工智能是一门模拟人类智能的技术科学..."})3.3SequentialChain实战:代码解析output_key输出标识每个子链都必须指定一个专属的output_key。它就像数据的“标签”,作用是唯一标识该链的输出结果,从而让后续的链能够准确引用和获取数据。输入与输出变量需要在SequentialChain初始化时,显式声明整个流程的input_variables(输入变量)与output_variables(最终输出变量)。内部子链之间的数据传递会由框架自动完成,无需手动处理。verbose调试模式建议在调试时将verbose参数设置为True。开启后,控制台会实时打印详细日志,完整展示数据在各个子链之间的流转路径和状态,便于排查逻辑错误。3.4RetrievalQA链详解(RAG核心)`RetrievalQA`是实现检索增强生成(Retrieval-AugmentedGeneration,RAG)的核心链。它巧妙结合了向量检索技术与大语言模型(LLM)的生成能力,赋予模型利用外部私有或最新的知识库回答问题的能力,有效解决了模型幻觉与知识更新滞后问题。01.加载与向量化将非结构化的知识库文档(如PDF、TXT等)加载并切分,利用Embedding模型将其转换为高维向量,最终存入向量数据库中,建立可检索的索引。02.相关性检索当用户发起提问时,系统首先将问题向量化,随后在向量数据库中通过余弦相似度等算法,快速检索出与问题最匹配、最相关的文档片段作为“上下文”。03.知识生成将用户的原始问题与检索到的上下文信息整合,构造提示词(Prompt)并发送给LLM。模型基于提供的外部知识生成准确、有据可依的回答。3.4RetrievalQA链实战:代码示例(1/2)📝核心步骤:文档加载→文本分割→向量入库(IngestionPipeline)#导入所需库fromlangchain.chainsimportRetrievalQA;fromlangchain.llmsimportOpenAIfromlangchain.vectorstoresimportChroma;fromlangchain.embeddingsimportOpenAIEmbeddingsfromlangchain.document_loadersimportTextLoader;fromlangchain.text_splitterimportCharacterTextSplitter#1.加载并切分文档(Chunking)loader=TextLoader("knowledge_base.txt")#替换为你的知识库文件路径texts=CharacterTextSplitter(chunk_size=1000,chunk_overlap=0).split_documents(loader.load())#2.向量化并构建本地向量数据库(VectorDB)embedding_model=OpenAIEmbeddings()#转换文本为向量的核心模型vector_db=Chroma.from_documents(texts,embedding_model)#存入ChromaDB3.4`RetrievalQA`链实战:代码示例(2/2)Python代码:构建检索增强问答(RAG)工作流#3.创建检索器:从向量数据库获取,返回最相关的3个文档块retriever=db.as_retriever(search_kwargs={"k":3})#4.构建RetrievalQA链:使用"stuff"模式将检索结果填入promptqa_chain=RetrievalQA.from_chain_type(llm=OpenAI(temperature=0),chain_type="stuff",retriever=retriever,return_source_documents=True)#5.发起查询并解析结果,打印回答及引用来源query="公司的年假政策是怎样的?";result=qa_chain({"query":query})print("答案:"+result["result"])#输出模型生成的回答fordocinresult["source_documents"]:print(f"-来源:{doc.metadata['source']}...")3.4`RetrievalQA`链实战:代码解析核心参数:`chain_type`•`stuff`模式(推荐入门):最简单直接的处理方式。将所有检索到的相关文档块,直接“填充”到Prompt上下文窗口中,一次性发送给大模型进行回答。•进阶替代:若文档内容庞大,单轮无法容纳,可尝试使用`map_reduce`(分块处理后整合)或`refine`(逐步优化答案)等策略。关键开关:`return_source_documents`•设为`True`:开启“溯源模式”。模型在生成答案的同时,会附带输出原始知识库中被检索到并引用的文档片段。•核心价值:极大提升问答系统的可信度与透明度,避免生成“幻觉”而无法验证,同时也便于调试检索效果。3.5自定义Chain开发:代码示例#导入必要的基础模块与类型定义fromlangchain.chains.baseimportChainfromlangchain.llmsimportOpenAIfrommptsimportPromptTemplatefromtypingimportDict,ListclassTranslationSummaryChain(Chain):#1.定义组件:LLM模型与两个Prompt模板llm:OpenAI;translation_prompt:PromptTemplate;summary_prompt:PromptTemplate#2.定义输入输出Keys,供框架识别@propertydefinput_keys(self)->List[str]:return["text","target_language"]@propertydefoutput_keys(self)->List[str]:return["translated_text","summary"]#3.实现核心逻辑_call:串联翻译与总结任务def_call(self,inputs:Dict[str,str])->Dict[str,str]:#省略具体的翻译与总结步骤...return{"translated_text":translated_text,"summary":summary}3.5自定义Chain开发:代码解析继承`Chain`类自定义链的第一步是继承`langchain.chains.base.Chain`基类,这是所有链的标准接口规范。定义输入输出Keys通过实现`input_keys`和`output_keys`属性,明确告诉LangChain框架,该链期望接收什么数据,以及最终会产生什么结果。实现核心`_call`方法这是自定义链的“大脑”。在这个方法中编写业务逻辑:接收输入字典,执行一系列处理步骤(如调用模型、数据转换等),最后返回包含结果的字典。💡核心价值:自定义链提供了最大的灵活性,打破了预定义链的限制,允许开发者将LLM能力与业务逻辑深度结合,实现任何复杂的工作流编排。第四部分对话记忆机制实现MEMORY4.1引言:为什么需要对话记忆?🤔想象一下你正在和一个客服机器人对话:你:“我想买一款笔记本电脑。”机器人:“好的,我们有多种型号,请问您有什么偏好吗?”你:“我想要续航长的。”❌如果没有记忆,体验会非常糟糕机器人可能会“断片”,重复问:“好的,我们有多种产品,请问您需要什么?”

这显然不符合预期。用户期望AI能记住上下文,理解“它”指代的是刚才提到的“笔记本电脑”,并针对性推荐续航长的型号。✅LangChain的解决方案:`Memory`模块为了解决“健忘”问题,LangChain提供了专门的`Memory`模块。

它包含多种功能组件,可灵活存储、积累和管理多轮对话的历史上下文,赋予LLM短期记忆能力,从而实现像人与人一样自然、连贯的连续交互体验。4.2核心记忆类型概览与对比ConversationBufferMemory💡原理:简单按顺序存储所有对话历史,不做任何修改。👍优点:实现逻辑最简单,完整保留上下文细节,无信息丢失。👎缺点:对话过长时,上下文Token消耗激增,成本高。🎯场景:短轮次对话、应用初期的调试与开发阶段。ConversationSummaryMemory💡原理:定期调用LLM将长对话历史总结为一段精简摘要。👍优点:大幅减少上下文Token占用,完美适配超长对话场景。👎缺点:摘要过程可能丢失细节信息,或引入LLM的幻觉。🎯场景:持续数小时的客服咨询、长时间的角色扮演或头脑风暴。ConversationBufferWindowMemory💡原理:设定一个滑动窗口,仅保留最近k轮的对话记录。👍优点:在上下文保留与Token成本之间取得了极佳平衡。👎缺点:若早期对话包含关键信息,窗口滑动后会导致遗忘。🎯场景:大多数通用型对话机器人、聊天应用。VectorStoreRetrieverMemory💡原理:将历史对话存入向量数据库,通过相似度检索“唤醒”记忆。👍优点:理论上支持无限长对话,能精准回顾久远的细节。👎缺点:架构复杂,需引入向量数据库组件,增加维护成本。🎯场景:知识库问答、个人AI助理(需记忆长期偏好)。4.3ConversationBufferMemory实战:代码示例#导入必要的库与模块

fromlangchain.chainsimportConversationChain

fromlangchain.memoryimportConversationBufferMemory

fromlangchain.llmsimportOpenAI#1.初始化记忆模块与大语言模型(LLM)

memory=ConversationBufferMemory()

llm=OpenAI(temperature=0)#2.将记忆注入对话链,创建具备记忆的对话机器人

conversation=ConversationChain(llm=llm,memory=memory,verbose=True)#3.模拟多轮对话交互

conversation.run("我叫小明,我喜欢编程。")

conversation.run("我刚才提到了我的什么爱好?")#查看并打印存储在“记忆”中的完整对话历史

print("\n记忆中的对话历史:")

print(memory.buffer)4.3ConversationBufferMemory实战:输出解析Step1:初次交互>EnteringnewConversationChain...Promptafterformatting:Human:我叫小明,我喜欢编程。AI:你好小明!很高兴认识你。编程是一项非常有趣和创造性的技能。你喜欢用哪种编程语言呢?>Finishedchain.Step2:上下文询问>EnteringnewConversationChain...Promptafterformatting:[Previoushistoryincluded...]Human:我刚才提到了我的什么爱好?AI:你提到了你喜欢编程。>Finishedchain.Memory:存储快照对话历史完整记录(memory.buffer):Human:我叫小明,我喜欢编程。

AI:你好小明!很高兴认识你...

Human:我刚才提到了我的什么爱好?

AI:你提到了你喜欢编程。💡要点:模型生成回答时,会把完整的对话历史拼接到prompt中,从而实现“记忆”效果。4.4ConversationSummaryMemory实战:代码示例#导入必要的库与模块fromlangchain.chainsimportConversationChainfromlangchain.memoryimportConversationSummaryMemoryfromlangchain.llmsimportOpenAIllm=OpenAI(temperature=0)#初始化基础LLM模型#1.初始化摘要记忆:核心在于传入LLM以生成摘要,实现Token节省memory=ConversationSummaryMemory(llm=llm)conversation=ConversationChain(llm=llm,memory=memory,verbose=True)#2.进行多轮长对话模拟,系统将自动对历史内容进行摘要压缩conversation.run("我计划这个周末去爬山,有什么推荐的装备吗?")conversation.run("我是一个初学者,体力一般。路线方面有什么建议吗?")#3.查看摘要记忆的内容,验证对话是否被有效总结print("\n记忆中的对话摘要:\n",memory.buffer)4.4`ConversationSummaryMemory`实战:输出解析💡记忆中的对话摘要:用户计划周末去爬山,作为一名体力一般的初学者,他询问了推荐的装备和路线建议。最后,他询问刚才讨论的活动主题。摘要生成:节省Token`ConversationSummaryMemory`会自动将早期的对话历史提炼总结成一段简洁的文字,丢弃冗余信息,从而大幅减少发送给大模型的Token消耗,降低成本并提升效率。上下文保留:逻辑连贯即便对话很长,通过摘要的方式,模型依然能准确理解语境中的指代关系。例如,当用户问“我刚才问的是关于什么活动的建议?”时,模型能精准关联到之前的“爬山”主题。4.5高级记忆管理技巧结合多种记忆类型:ConversationSummaryBufferMemory它结合了`BufferMemory`保留近期对话细节和`SummaryMemory`长期存储摘要的双重优势。系统会维护一个最近对话的缓冲区,当达到预设的Token阈值时,自动将缓冲区内容总结并整合到长期摘要中。fromlangchain.memoryimportConversationSummaryBufferMemorymemory=ConversationSummaryBufferMemory(

llm=llm,max_token_limit=100#缓冲区最大Token数)自定义记忆提示(CustomPrompt)默认的摘要生成逻辑可能无法满足所有需求。开发者可以完全控制用于生成对话摘要的提示词(Prompt),从而定制摘要的详细程度、语言风格、重点提取逻辑等,让AI的“记忆”更符合业务场景。💡应用场景:•在客服系统中,让摘要仅聚焦于“用户问题”和“解决方案”。

•在创意协作中,要求摘要保留“发散性思维”和“关键灵感”。4.6案例分析:智能客服机器人核心任务:构建记忆型客服机器人目标是让AI不仅能回答问题,还能准确记住并关联对话中的上下文信息,例如:用户的订单编号、购买的具体产品型号、个人偏好等关键信息,提供连贯的个性化服务体验。Python实现:自定义提示词+对话记忆(ConversationBufferMemory)#1.引入核心依赖库fromlangchain.chainsimportConversationChain;fromlangchain.memoryimportConversationBufferMemory#2.自定义提示词模板:明确告知模型“需记住订单号、产品名等关键信息”prompt=PromptTemplate(template="以下是客服对话,你需要准确记住所有信息,特别是{订单号,产品名}。\n历史记录:{history}\n用户问:{input}\n客服答:",input_variables=["history","input"])#3.初始化对话链,注入Memory组件以保存上下文chain=ConversationChain(llm=OpenAI(temperature=0),memory=ConversationBufferMemory(),prompt=prompt)4.6案例分析:智能客服机器人(对话)模拟对话(输入)#模拟用户连续提问print(conversation.run("你好,我的订单号是ORD12345,什么时候能发货?"))print(conversation.run("能帮我查一下ORD12345的物流状态吗?"))print(conversation.run("如果还没发货,能帮我改成加急吗?"))智能回复(输出)💬客服:您好,关于订单ORD12345,我们查询到预计将在今天下午发货。💬客服:好的,正在为您查询。目前显示订单已出库,正在送往配送中心。💬客服:当然可以。我已经为您将订单修改为加急,预计您明天就能收到包裹。核心能力解析🔑上下文理解能力机器人在多轮对话中,能够准确捕捉并记忆关键信息(如“ORD12345”),并理解后续对话中代词(“它”)的指代对象。这体现了模型的长短期记忆能力和知识关联能力,让对话像人与人交流一样连贯自然。本章总结模型调用(ModelI/O)学会了如何通过统一的接口调用LLM,ChatModel,和Embeddings,为应用提供强大的AI推理能力。提示模板(PromptEngineering)掌握了使用PromptTemplate和ChatPromptTemplate动态生成提示的技巧,以精准引导模型输出。链式调用(Chains)理解了如何使用LLMChain,SequentialChain和RetrievalQA将多个任务组合成复杂的自动化工作流。对话记忆(Memory)学会了使用不同的记忆组件来有效管理对话历史,实现上下文感知的自然交互体验。课后练习翻译增强器创建一个链,它接收一个英文句子,首先将其翻译成中文,然后对中文翻译进行润色,使其更优美。知识库问答系统选择一篇你感兴趣的文章(TXT格式),使用`RetrievalQA`链构建一个可以基于该文章内容回答问题的系统。创意故事生成器使用`SequentialChain`。第一个链根据用户输入的主题生成故事大纲,第二个链根据大纲生成完整的故事。上下文感知的聊天机器人扩展本章的客服机器人案例,使其能够处理更复杂的上下文。Q&A感谢观看THANKSFORWATCHINGLangChain与大语言模型应用开发实战第四章:高级应用开发讲师:XXX|XXX年X月课堂导入:企业面临的挑战数据孤岛关键知识散落在PDF、Word、网页等各种非结构化文档中,难以检索与利用。信息过载面对海量且不断增长的业务数据,如何从中快速定位、精准找到所需答案?流程繁琐大量重复性、多步骤的人工业务流程,消耗大量人力且难以保证一致性。智能不足传统系统缺乏对自然语言的理解能力,难以实现像人与人那样的自然、高效的智能化交互。本章目标:本章将探讨如何利用LangChain框架和大语言模型攻克上述挑战,实现文档数据的智能处理、文本信息的深度分析、任务的自动化执行以及复杂业务流程的整体优化。本章教学目标掌握文档数据连接器•理解其作用与原理,打通多源异构数据壁垒。

•掌握加载多种格式文档(如PDF/Word/Excel)的方法。掌握文本向量化处理工具•理解文本向量化的概念、意义及核心算法逻辑。

•掌握嵌入模型的调用与向量数据库的构建和使用。熟悉智能代理开发•理解智能代理的核心原理、Memory与工作流程。

•掌握开发具备自主思考、决策和执行能力的智能代理。掌握复杂业务链设计•理解复杂业务链“解耦-重组”的模块化设计思想。

•掌握组合多个简单的原子链,以完成复杂的端到端任务。PART01文档数据连接器应用DocumentsLoader4.1.1文档数据连接器概述定义DefinitionLangChain框架中的核心组件,充当外部文档与LangChain应用之间的桥梁。它是连接底层数据存储与上层应用逻辑的关键一环,确保数据的有效流转。作用Function负责读取、解析各种格式的文档数据(如PDF、Word、Markdown等),并将异构的原始数据统一转换为LangChain内部可以处理的标准化Document对象。本质Essence从根本上解决了大语言模型(LLM)无法直接访问外部知识库的关键限制,通过引入实时或私有文档数据,赋予LLM处理特定领域、特定场景下最新信息的能力。4.1.1为什么需要文档数据连接器?打破知识边界让LLM能够“阅读”并理解企业内部文档、行业报告、学术论文等专业资料,突破通用模型的知识局限性。提升应用价值基于特定领域的私有文档内容进行精准推理和回答,让通用AI真正落地为解决垂直业务难题的“专家”,大大提升应用价值。实现数据驱动将企业海量的非结构化文本数据转化为可被LLM利用的结构化知识,为构建智能知识库问答、商业智能分析等高级应用奠定坚实基础。4.1.1LangChain中的文档处理管道数据源支持多种来源:

本地文件(PDF,DOCX)

网页/数据库

第三方API接口等加载(Load)使用DocumentLoader

统一接口读取

异构原始数据

提取纯文本内容分割(Split)使用TextSplitter

解决上下文窗口限制

将长文档切分为

语义完整的小块向量化(Embed)调用EmbeddingModel

将文本转化为

计算机可理解的

高维向量(Embedding)存储(Store)存入VectorStore

实现高效的相似性检索

常用:Chroma,FAISS

Pinecone,Milvus等检索(Retrieve)使用Retriever

根据用户查询向量

快速查找最相关的

Top-K文本片段生成(Generate)结合检索到的上下文

通过LLM(大语言模型)

生成精准、有据可依的

最终回答4.1.2连接器实现方法:步骤一:安装依赖目标:安装所有必需的库,为后续开发做好准备。pipinstalllangchainlangchain-openailangchain-communitysentence-transformerschromadbpypdfdocx2txtpython-dotenvLangChain框架包含核心库与社区组件,构建应用的基石。Embedding模型sentence-transformers

提供强大的本地文本向量化能力。向量数据库ChromaDB

轻量级、易用的开源向量存储。文档加载器PyPDF&docx2txt

支持PDF和Word文档的内容读取。环境变量python-dotenv

安全管理OpenAI密钥等敏感信息。4.1.2连接器实现方法:步骤二:选择文档加载器核心目标:建立文件类型与对应加载器的映射关系,实现灵活的文档加载支持fromlangchain_community.document_loadersimportPyPDFLoader,Docx2txtLoader,TextLoaderLOADER_MAPPING={".pdf":(PyPDFLoader,{}),".docx":(Docx2txtLoader,{}),".txt":(TextLoader,{"encoding":"utf8"})}代码逻辑解析●字典结构设计:使用字典作为核心映射结构,键为文件扩展名,值为对应处理逻辑。●元组定义参数:值为元组,第一个元素是加载器类,第二个是初始化该类所需的关键字参数。●可扩展性:如需支持Markdown、Excel等新格式,只需在此字典中增加新的键值对即可。4.1.2连接器实现方法:步骤三:加载文档(核心逻辑)🎯核心目标:实现一个函数,能够递归地遍历目标目录下所有文件,并根据文件的扩展名,自动匹配并调用相应的加载器进行解析,最终将解析后的文档对象统一收集管理。01遍历目录使用os.walk方法递归遍历指定的目标目录及其所有子目录,扫描每一个文件。02获取扩展名对遍历到的每一个文件,提取其文件扩展名(如.md,.txt),作为匹配加载器的“钥匙”。03查找加载器依据扩展名,查找预设的LOADER_MAPPING映射表,找到对应的文件解析加载器。04加载文件如果成功匹配到加载器,调用该加载器对文件进行解析,将原始文本转换为结构化的文档对象。05收集文档将所有成功加载的文档对象收集并汇总到一个统一的列表中,为后续的索引和查询做准备。4.1.2连接器实现方法:步骤三:加载文档(代码实现)importosfromtypingimportListfromlangchain_core.documentsimportDocumentdefload_documents_from_directory(directory_path:str)->List[Document]:documents=[]forroot,_,filesinos.walk(directory_path):forfileinfiles:file_path=os.path.join(root,file)ext=os.path.splitext(file_path)[1].lower()ifextinLOADER_MAPPING:try:loader_class,loader_args=LOADER_MAPPING[ext]loader=loader_class(file_path,**loader_args)loaded_docs=loader.load()#核心加载方法documents.extend(loaded_docs)exceptExceptionase:print(f"加载文件{file_path}失败:{e}")returndocuments4.1.2连接器实现方法:步骤四:内容分割为什么需要分割?01.突破上下文窗口限制

LLM(大语言模型)受限于上下文窗口(ContextWindow),无法一次性处理过长的原始文档内容,会导致输入溢出或信息丢失。02.提升检索与向量化效率

将长文本切分为语义完整的小块(Chunks),既能保留文本的逻辑含义,又能显著提高后续向量化的计算效率,以及检索时的匹配精准度。代码实现(LangChain)#引入文本分割器

fromlangchain.text_splitterimportRecursiveCharacterTextSplitter#定义分割参数:块大小与重叠部分

CHUNK_SIZE=1000#字符数

CHUNK_OVERLAP=150#保持上下文连续splitter=RecursiveCharacterTextSplitter(

chunk_size=CHUNK_SIZE,chunk_overlap=CHUNK_OVERLAP

)

split_docs=splitter.split_documents(documents)4.1.2连接器实现方法:步骤五:自定义加载器适用场景当需要处理LangChain生态默认不支持的、业务定制化的私有文件格式时(例如自定义的.myformat格式),需开发专属的加载器以实现数据读取与结构化解析。核心实现步骤(Python)1.继承基类:继承`langchain.document_loaders.base.BaseLoader`抽象基类。

2.构造方法:实现`__init__`方法,定义并接收文件路径等关键初始化参数。

3.核心逻辑:实现`load`方法,编写读取、解析逻辑,最后返回`Document`对象列表。fromlangchain.document_loaders.baseimportBaseLoader

fromlangchain.docstore.documentimportDocument

classMyCustomFormatLoader(BaseLoader):

def__init__(self,file_path:str):

self.file_path=file_path

defload(self):

#自定义解析逻辑:读取文件内容并构造元数据

withopen(self.file_path,'r')asf:

content=f.read()

metadata={"source":self.file_path,"format":"myformat"}

return[Document(page_content=content,metadata=metadata)]4.1.2连接器实现方法:步骤六:处理网络/API数据源适用场景当需要从外部网站、在线文档或公开的WebAPI接口加载文本内容时使用。可高效抓取并解析多种格式的网页内容。核心工具LangChain内置组件:WebBaseLoader•底层依赖:使用requests库发送HTTP请求获取页面。

•内容解析:利用BeautifulSoup解析HTML,去除冗余标签。

•结果封装:将清洗后的文本内容标准化为Document对象。💻代码示例(Python)#1.安装必要依赖$pipinstallbeautifulsoup4langchain-community#2.加载单页或多页网页内容fromlangchain_community.document_loadersimportWebBaseLoader#加载单个URLloader=WebBaseLoader("/article")docs=loader.load()#返回Document对象列表#加载多个URL列表loader=WebBaseLoader(["url1","url2"])4.1.3应用案例分析:企业知识库问答系统案例目标:构建一个能深度理解企业内部各类文档(如PDF、DOCX、TXT等)并基于内容准确回答员工业务与知识类问题的智能系统,以提升企业内部信息流转效率与知识复用率。01配置在系统后台完成基础参数设定,包括API密钥认证、指定文档读取目录以及大模型关键参数配置。02加载利用文档连接器自动扫描并加载指定目录下的所有企业文档,支持多种主流格式的解析与识别。03处理将长文档进行语义化分割,并调用Embedding模型对分割后的文本片段进行向量化,转化为计算机可理解的数值形式。04存储将生成的文本向量批量存入高性能向量数据库中,建立索引以支持后续毫秒级的相似度检索。05问答用户通过自然语言提问,系统将问题向量化后检索匹配文档,结合大模型能力生成精准、可溯源的答案。案例分析:配置与文档加载环境配置与密钥管理最佳实践:使用.env文件和python-dotenv库来管理敏感信息(如API密钥),从环境变量读取而非硬编码在源码中,有效降低泄露风险。fromdotenvimportload_dotenvimportos#加载项目根目录下的.env文件load_dotenv()DEEPSEEK_API_KEY=os.getenv("DEEPSEEK_API_KEY")文档加载核心流程核心函数:load_documents_from_directory()这是整个知识库问答系统的数据起点。它负责将存储在本地的非结构化文件(如PDF、TXT、MD)解析并转化为系统可处理的Document对象。后续所有的文本分割、向量化处理、向量库存储和语义检索,都建立在这一步成功加载的数据之上,决定了回答的准确性和相关性。PART02文本向量化处理工具TextEmbedding4.2.1文本向量化概述什么是文本向量化?📌定义将文本(单词、句子、段落)转换为计算机可以理解的数值向量的过程。💡核心思想“语义相似的文本,其向量表示在多维空间中的距离也相近”。👀示例“猫”和“狗”的向量距离,比“猫”和“书”的向量距离更

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论