自己做网站还能挣钱吗,石家庄建设企业网站,海南州公司网站建设,市场监督管理局官网查询简介
文章探讨了LangChain框架在大模型应用开发中的适用性。作者指出框架存在的意义在于封装重复劳动、沉淀最佳实践和统一代码风格#xff0c;但同时也指出盲目引入框架可能带来的问题。通过对LangChain的API设计分析#xff0c;作者认为其存在不一致且冗长的问题#xff…简介文章探讨了LangChain框架在大模型应用开发中的适用性。作者指出框架存在的意义在于封装重复劳动、沉淀最佳实践和统一代码风格但同时也指出盲目引入框架可能带来的问题。通过对LangChain的API设计分析作者认为其存在不一致且冗长的问题容易掩盖底层逻辑增加理解难度。文章建议开发者在简单场景下优先考虑原生SDK实现只有在需要复杂任务调度和编排时才考虑使用框架。需要提前说明存在广义和狭义两类对LangChain的定义。狭义上的LangChain即等同于在本章中我们使用到的LangChain框架而广义上的LangChain代指的是LangChain技术厂牌旗下包含 LangChain、LangSmith一个用于调试、测试、监控大模型应用的平台、LangGraph一款用于制作包含管理复杂工作流的大模型应用的框架 等多种产品。本小节所谈论到各种问题仅限于LangChain 框架本身而非代指所有与它有关的产品。为什么我们需要框架既然在第4章中我们已经借助OpenAI SDK完成了想要实现的功能为什么还需要引入额外的代码库在我看来框架以及类库存在最根本的意义是对重复劳动的封装。Loadsh是所有前端项目内必不可或缺的类库它之所以被广泛采用并非因为其中的某个高精尖的技术特性而是提供了许多常用开箱即用的功能例如对数组去重、合并对数据类型进行判断等等。去实现这类工具类函数并非什么难事那为什么我们选择直接使用一款第三方类库而非是亲自去实现它很简单因为这能够帮助你节省大量的时间精力——对于此类功能你我的代码实现乃至 Lodash 的代码实现不会有太大差异在最终效果一致的情况下考虑到专业的开源团队有足够的精力对代码提供稳定的持续保障选择它们自然也就是顺理成章的事情。另一方面绝大部分的开发者在实际工作中承担的是以业务向导开发任务能够编写工具代码的时间精力有限市面上开箱即用的现成工具也就成了我们的不二之选。这便是是大多数框架之所以存在的底层逻辑。除此之外框架的另一层价值在于它代表对经验的沉淀对模式的封装。平心而论在任何编程语言之下去实现一整套API服务并非难事但为什么倾向去选择既有的API服务框架例如Node.js里Express.js或者Python中的FastAPI一分部原因来自于上述所说对时间精力的节省更重要的是尊循框架本身也等同于尊循最佳实践。代码是有好坏之分的我们所常常听到的可读性、时间效率、可拓展性等等便是区分好与坏的重要指标。那些能够带来好结果的行为通常被人们逐渐整理为最佳实践而那些带来坏影响的行为则被称之为反模式或者坏味道。遗憾的是这类知识点的习得大部分来自于开发经验的积累可如果团队中不同的成员水平参差不齐怎么办那么很可能具有坏味道的代码便被不小心的注入代码库中——而框架则通过将开发者的代码限制在既定的约束内杜绝了部分该类问题的发生。MVCModel-View-Controller 框架便是一个再合适不过的例子你也许并不清楚 MVC 模式解决了什么样的问题但该知识盲点并不妨碍你可以将代码拆分为不同的Model、View和Controller组件。如果你好奇 MVC 是否真的相比其他开发方式更加优秀不妨尝试摒弃MVC框架并利用原生代码实现同样的一组功能并不断的优化它。我相信在几个迭代之后你摸索出来的最优解会与MVC不谋而合。为什么我们需要推崇最佳实践因为上面所说的种种关于代码“好”的指标都指向软件工程的最终目的**提升代码的可维护性。倘若你继续探究会发现它代表的不过是最朴素的降本增效思想通过使代码变得易于修改来降低维护的维护成本以及提升其交付速率。**而最佳实践是达成这个目标的重要途径。提升代码可维护性的另一个手段也同样是框架带来的第三类优势统一团队代码风格。如果你让十位来自不同背景不同经验的程序员来实现同一组功能你会得到十套不同类型的代码。虽然独一无二的代码对于个体来说代表着他颇具个性的一面但来对于由一个团队集体维护的项目来说却是噩梦因为这意味着其中的每一位团队成员为了理解他人所写的代码都要提前了解其他团队成员的代码风格和流派这会给项目的开发过程带来不小的负担。所以让团队站在同一起跑线上对尽可能能多的问题达成一致有助于将代码知识传递下去。最理想的情况便是由不同成员的产出的代码都犹如同一人所写。框架是解决此类问题的一个手段另一类常见实践便是在代码库甚至IDE中内置格式检查工具。综上所述节省开发成本、封装最佳实践、统一代码风格是我们优先选择框架的原因其旨在提升代码的可维护性。扩展到更广的层面这套逻辑同样适用于我们依赖的各类云服务。从无服务计算Serverless Computing再到低代码平台Low Code Platform——技术并非凭空被发明出来他们是经验的化身。何谓好的框架GitHub上的收藏数量、代码库的更新频率、版本的发布速度等等显性指标当然都可以成为判断的开源框架的好坏标准。而在数值之外还有什么是我们值得关注的这里给出两点我的建议。首先最好的框架理应是没有框架。许多项目在搭建之初出于惯性优先想要回答的问题是选择哪一款框架而不是我们是否需要框架这给项目带来了不必要的负担。许多人忽略了框架的引入是存在代价的学习成本便是其中之一。回想一下你第一次熟悉某个技术框架时的经历肯定充满坎坷去学习定义不同类型的组件学习如何进行组件间的通信在论坛上提问如何实现你想实现的功能等等。问题不在于代价本身而在于付出与收益是否等价。在我的工作经历中框架带来的负面影响的事例不在少数例如团队经理盲目选择了某个时髦框架却因为没有团队成员精通该框架的缘故导致开发中总是有代码被分配到了错误的职责或者采用了官方不推荐的反模式。又例如开发人员还需定期对框架进行升级。注意此类升级并非是对开发者无感的因为框架自身升级过程中难免会引入破坏性修改这会导致项目代码与框架的集成失效。因此由框架升级而引发的项目本身的代码改动和小范围的回归测试都在所难免。这些都应该计算在引入框架的成本中。其次好的框架应该容易让人们把事情做对难以把事情做错。如果你选择的框架团队内鲜有人能够理解它的概念更很少有人难把它按照最佳实践写对这并非是一个好兆头。无论它号称能够提升多少倍性能或者减少多少人天的成本显而易见至少在你的团队是可望不可及的。项目说到底是由一群人来维护我们应该尽可能的降低项目的门槛用于容纳不同层次的开发者。如果项目的绝大部分问题都依赖团队的某个明星程序员来解决亦或是项目质量完全依靠团队经理来把控你应该为对此感到警惕。前端领域中的Redux就是一个很好的反面例子如果你有兴趣将Redux文档与当下同样流行的 Flux 框架文档进行比较例如 MobxZustandAkita就会发现学习Redux需要掌握的概念相比其他竞品来说复杂的令人发指稍不小心便会踏入官方不推荐的反模式中。这也是Redux Toolkit诞生的原因它旨在解决原生Redux高度的抽象以及缺少最佳实践的问题通过丰富模板代码来帮助开发者迅速找到常规问题的解决方案。如今官方早已将Redux Toolkit作为学习和使用Redux的首选平替。你也许会疑惑为什么我们要花如此长的篇幅聊框架决策中的种种考量因为接下来你将看到我是如何运用这些原则来选择出我们心仪的大模型框架的。你也许不需要框架在回答选 A 还是选 B 之前,我还是想不厌其烦的提醒各位也许你并不需要框架。我们不妨回顾以一下第四章中借助OpenAI SDK实现与大模型进行对话的代码示例代码如下所示from openai import OpenAI from dotenv import load_dotenv load_dotenv() client OpenAI() completion client.chat.completions.create( modelgpt-4o-mini, messages[ {role: system, content: You are a helpful assistant.}, { role: user, content: Whats your name?, } ] )我们可以轻松的将这段代码使用其他框架进行改写使用 LangChain重写之后的代码如下所示from langchain.prompts \ import SystemMessagePromptTemplate, \ HumanMessagePromptTemplate, \ ChatPromptTemplate from langchain_openai import ChatOpenAI llm ChatOpenAI(model_namegpt-3.5-turbo, temperature0.5) prompt ChatPromptTemplate.from_messages([ SystemMessagePromptTemplate.from_template(You are a helpful assistant.), HumanMessagePromptTemplate.from_template(Whats your name?) ]) chain prompt | llm即使你从未学习过LangChain也不妨碍你理解这段代码的逻辑。与原版相比其最大的不同在于将传递给 大模型的消息使用模板组件进行了封装原代码中的 SystemMessage HumanMessage SystemMessagePromptTemplate和 HumanMessagePromptTemplate例如在实际的使用场景中”You are a helpful assistant” 这类用于指定角色的提示语通常是固定的我们便可以选择利用模板固化下来将用户的输入提取为变量。依据上述思路修改之后的代码如下所示prompt ChatPromptTemplate.from_messages([ SystemMessagePromptTemplate.from_template(You are a helpful assistant), HumanMessagePromptTemplate.from_template({user_input}) ])注意上述代码中用户的提问内容已经被替换为了变量 user_inputchain prompt | llm res chain.invoke({ user_input: Explain LLM like Im 5 })在这个例子里我展示了LangChain在提示语生成方面能够提供的能力但我想提出的问题是这个特性真的是你需要的吗所有OpenAPI中的概念被平移到了LangChain当中被再次定义以 |我的建议是如果你的应用针对的是单一场景无需灵活多变的提示语句便不必将提示语句封装为模板。即使你想将提示语句抽象为模板框架并非是唯一的方式。Python 原生自带的 f-string 语法据支持将表达式内嵌于子符串中如下所示人名被提取为变量。user_name Alice greeting fHello {user_name}, welcome to the data science tutorial!如果你不确定框架会给你带来何种优势盲目的将其引入便会产生我在上一小节中提到的那些弊端。在上述代码中你已经看到种种大模型概念在LangChain中被再次封装却看不到由此带来的额外收益。事实上OpenAI作为开放平台它本身就已经提供了足够多的接口来完成大部分常见需求。考虑到OpenAI SDK作为官方出品的类库它们更新频率和更新质量肯定会比由社区维护的开源类库更加稳定因此优先使用第一方类库也是项目质量的无形保障。我越来越多的在有关大模型应用开发的论坛中在Hacker News社区里看到开发者们在逐渐达成此类共识大多数时候你无需依赖框架来开发大模型应用。框架的优势体现原型的搭建、任务的调度与编排上。为什么不推荐 LangChain无论是OpenAI还是Google Gemini官方自身提供的能力始终存在着上限我们需要在社区中寻找突破点。毋庸置疑LangChain是时下风头最劲的框架之一我相信在你能够搜索到的有关大模型应用开发的教程中与LangChain有关的课程一定占据了相当大的比例。但你可能没有留意到的是近些年业内对于LangChain的批评声音却变得越来越多LangChain的颓势在愈发显现。最直观的便是Thoughtworks技术雷达(Technology Radar)对于 LangChain 态度的变化。技术雷达是科技领域咨询公司Thoughtworks每年两次定期发布的技术趋势指南。在每一期发布的指南中他们会对新兴技术的成熟度与潜力进行打分读者可以将技术所属的成熟度状态如试验、评估、采纳、淘汰来作为技术选型的参考之一。LangChain于2023年4月入选第28期技术雷达成熟度状态为“评估”在2024年4月第30期技术雷达中成熟度则被降至“暂缓”即不推荐在项目上引入在2024年10月第31期技术雷达中 LangChain被彻底移除。LangChain 被淘汰的理由在它的评级被降至“暂缓”时给出了充分的说明……然而我们还发现其存在 API 设计不一致且冗长的情况。因此它经常会掩盖底层实际发生的情况使得开发者难以理解和控制 LLMs 及其周围的各种模式在背后实际是如何工作的……这里所说的API并非是狭义上的HTTP API而是指广义上代码间的通信接口。考虑到API是代码与框架的主要沟通方式欠佳的 API 设计意味对开发者而言项目与框架集成之路将变得困难重重。这里的批评也并非空穴来风接下来我用一个例子来说明 LangChain API 存在的问题。在提示工程中有一类技巧叫做few shot即在编写的提示语句中有意包含一些范例便于大模型更好的推测我们的意图以给出更为精准的答案。例如在向模型询问“big”的反义词之前在提示语句中提前给出反义词的相关事例具体提示如下Give the antonym of every inputInput: happyOutput: sadInput: tallOutput: shortInput: energeticOutput: lethargicInput: sunnyOutput: gloomyInput: windyOutput: calmInput: bigOutput:大模型在读到诸多事例之后即刻就会领悟到我们想要简短直接的回答并且答案必须契合“Input/Output”这类格式。用原生的Python将上述的提示语抽象为代码实现也非难事实现代码如下所示def generate_few_shot_prompt(pairs): prompt Give the antonym of every input\n\n for pair in pairs: input_word pair[input] output_word pair[output] prompt fInput: {input_word}\nOutput: {output_word}\n\n return prompt在调用该方法时只需要将所有事例的input和ouput值组装成字典结构然后以成数组形式传入函数中即可代码如下所示pairs [ {input: happy, output: sad}, {input: tall, output: short}, {input: energetic, output: lethargic}, {input: sunny, output: gloomy}, {input: windy, output: calm}, {input: big, output: } ] few_shot_prompt generate_few_shot_prompt(pairs)那现在不妨看看在LangChain框架之下应该如何实现上述功能。LangChain few shot这类业务场景提供了名为 FewShotPromptTemplatefrom langchain_core.example_selectors \ import LengthBasedExampleSelector from langchain_core.prompts \ import FewShotPromptTemplate, PromptTemplate examples [ {input: happy, output: sad}, {input: tall, output: short}, {input: energetic, output: lethargic}, {input: sunny, output: gloomy}, {input: windy, output: calm}, ] example_prompt PromptTemplate( input_variables[input, output], templateInput: {input}\nOutput: {output}, ) prompt FewShotPromptTemplate( examplesexamples, example_promptexample_prompt, prefixGive the antonym of every input, suffixInput: {adjective}\nOutput:, input_variables[adjective], ) print(prompt.format(adjectivebig))我们对上述代码稍作分析来理解在 LangChain 中是如何实现上述功能的需要在代码库中同时引入PromptTemplate和FewShotPromptTemplate模板组件。PromptTemplate用于创建常规提示包含模板内容与变量定义它与few shot场景无关。FewShotPromptTemplate虽然从名称上同为“模板”但实际上它去更像是原模版的“封装”或者“改善”工具。因为从使用方式上看它不仅为原模版补充了前缀部分(prefix)和提问部分(suffix)还负责将诸多事例(examples)注入进提示语中。也就是说为了生成出一个带有特定模式的提示语句在LangChain中我们需要引入两个模板组件(PromptTemplate和FewShotPromptTemplate)定义三个模板变量(PromptTemplate中的input与outputFewShotPromptTemplate中的adjective)还需要保证事例中数据格式与模板的变量格式相匹配。很显然这么做过于复杂了别忘了我们只是想生成一个具有特定模式的字符串而已。在更早的代码中看到我已经展示了如何在无需学习额外知识的情况下用更短的代码达成同样的效果。将few shot固化在代码中的做法本来就有待商榷因为包括few shot、chain of thought、least to most 等等各类提示语技巧本质上是解决问题的种种思路它们为代码实现提供了无数种可能性。而将思路固化在框架中的做法似乎是反其道而行之反而给这个技巧的发挥套上了枷锁。更可怕的是 LangChain还提供了几乎一模一样的兄弟组件FewShotPromptWithTemplates仅仅是为了支持将模板作为参数传入例如我可以将原子符串类型的prefix和suffix变量替换为模板代码如下所示# 在这里 prefix 与suffix 不再是上段代码中简单的子符串 # 而是被定义为可以用于生成提示语的模板 prefix_template PromptTemplate( input_variables[say_hi], template{say_hi}, Give the antonym of every input\n\n ) suffix_template PromptTemplate( input_variables[adjective], templateInput: {adjective}\nOutput: ) few_shot_prompt_with_templates FewShotPromptWithTemplates( # ...... input_variables[adjective, say_hi], prefixprefix_template, suffixsuffix_template ) new_input { adjective: big, say_hi: Hello } prompt few_shot_prompt_with_templates.format(**new_input)在我看来这是一处明显的API设计失误正确的做法应该是让组件去兼容更多种可能性例如前端的DOM 选择器 querySelecor有几篇对 LangChain 批评的文章影响力颇大比如 why we no longer use LangChain for building our AI agents 以及 The Problem With LangChain前者在 Hacker News 上引起了广泛的讨论后者也被技术雷达所引用。如果大家有兴趣可以通过这些材料来更进一步的理解 LangChain 当前所存在的其他问题。读者福利如果大家对大模型感兴趣这套大模型学习资料一定对你有用对于0基础小白入门如果你是零基础小白想快速入门大模型是可以考虑的。一方面是学习时间相对较短学习内容更全面更集中。二方面是可以根据这些资料规划好学习计划和方向。包括大模型学习线路汇总、学习阶段大模型实战案例大模型学习视频人工智能、机器学习、大模型书籍PDF。带你从零基础系统性的学好大模型一直在更新更多的大模型学习和面试资料已经上传带到CSDN的官方了有需要的朋友可以扫描下方二维码免费领取【保证100%免费】AI大模型学习路线汇总大模型学习路线图整体分为7个大的阶段全套教程文末领取哈第一阶段从大模型系统设计入手讲解大模型的主要方法第二阶段在通过大模型提示词工程从Prompts角度入手更好发挥模型的作用第三阶段大模型平台应用开发借助阿里云PAI平台构建电商领域虚拟试衣系统第四阶段大模型知识库应用开发以LangChain框架为例构建物流行业咨询智能问答系统第五阶段大模型微调开发借助以大健康、新零售、新媒体领域构建适合当前领域大模型第六阶段以SD多模态大模型为主搭建了文生图小程序案例第七阶段以大模型平台应用与开发为主通过星火大模型文心大模型等成熟大模型构建大模型行业应用。大模型实战案例光学理论是没用的要学会跟着一起做要动手实操才能将自己的所学运用到实际当中去这时候可以搞点实战案例来学习。大模型视频和PDF合集观看零基础学习书籍和视频看书籍和视频学习是最快捷也是最有效果的方式跟着视频中老师的思路从基础到深入还是很容易入门的。学会后的收获• 基于大模型全栈工程实现前端、后端、产品经理、设计、数据分析等通过这门课可获得不同能力• 能够利用大模型解决相关实际项目需求大数据时代越来越多的企业和机构需要处理海量数据利用大模型技术可以更好地处理这些数据提高数据分析和决策的准确性。因此掌握大模型应用开发技能可以让程序员更好地应对实际项目需求• 基于大模型和企业数据AI应用开发实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能学会Fine-tuning垂直训练大模型数据准备、数据蒸馏、大模型部署一站式掌握• 能够完成时下热门大模型垂直领域模型训练能力提高程序员的编码能力大模型应用开发需要掌握机器学习算法、深度学习框架等技术这些技术的掌握可以提高程序员的编码能力和分析能力让程序员更加熟练地编写高质量的代码。获取方式一直在更新更多的大模型学习和面试资料已经上传带到CSDN的官方了有需要的朋友可以扫描下方二维码免费领取【保证100%免费】