Langchain实战

感谢阅读

  • LangChain介绍
  • 百度文心API申请
    • 申请百度智能云
    • 创建应用
  • LLMChain demo以及伪幻觉问题
  • 多轮对话的实现
  • Sequential Chains
    • SimpleSequentialChain
    • SequentialChain
    • Router Chain
  • Documents Chain
    • StuffDocumentsChain
    • RefineDocumentsChain
    • MapReduceDocumentsChain
    • MapRerankDocumentsChain
  • Document Loaders
  • Agent

LangChain介绍

LangChain是一个基于大语言模型(如ChatGPT)的Python框架,专为构建端到端语言模型应用而设计。它提供了一套全面的工具、组件和接口,旨在简化与大型语言模型(LLM)和聊天模型的交互过程,从而轻松创建出功能强大的应用程序。LangChain不仅方便管理语言模型的交互,还能将多个组件灵活链接,满足各种应用场景的需求。使用LangChain,您可以更加高效地构建出具有创新性和实用性的语言模型应用。(这个就是langchain配合文心生成的介绍)

百度文心API申请

申请百度智能云

点我申请

创建应用

点我创建

LLMChain demo以及伪幻觉问题

from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain_wenxin.chat_models import ChatWenxin
from langchain.schema import HumanMessageWENXIN_APP_Key = "你自己的KEY"
WENXIN_APP_SECRET = "你自己的SECRET"chat = ChatWenxin(temperature=0.9,model="ernie-bot-turbo",baidu_api_key=WENXIN_APP_Key,baidu_secret_key=WENXIN_APP_SECRET,verbose=True,
)def 基本调用(input):template = f"描述我的{input}一个最佳名字是什么?只返回一个答案,答案限定为3到5字"prompt = PromptTemplate(input_variables=["input"], template=template)llm_chain = LLMChain(prompt=prompt, llm=chat)res = llm_chain.run(product=input)print(res)def main():基本调用("狗狗")基本调用("宠物公司")return 0if __name__ == '__main__':main()

我们上面代码用的是LLMChain通过prompt+input给模型,然后接受返回模型返回。结果如下图:
在这里插入图片描述
那么真的就这么简单吗?其实我们只需要改一下prompt就可以让模型出现伪幻觉,为什么是伪幻觉?因为这并不是真正的幻觉,而是模型推理的时候由于升维目标可能的维度太多导致模型要去考虑大多数情况而忽略了原本的束缚。我们修改如下:

def 基本调用(input):# template = f"描述我的{input}一个最佳名字是什么?只返回一个答案,答案限定为3到5字"template = f"给我的{input}起一个名字?只返回一个答案,答案限定为3到5字"prompt = PromptTemplate(input_variables=["input"], template=template)llm_chain = LLMChain(prompt=prompt, llm=chat)res = llm_chain.run(product=input)print(res)def main():基本调用("狗狗")基本调用("宠物公司")return 0

可以看到结果并不是要求的 “只会返回一个” 答案
在这里插入图片描述

多轮对话的实现

通过在prompt template里引入{chat_history}变量以及memory机制,Langchain可以实现多轮对话。我们做个示例,那么这个有没有问题呢?当然有,就和人一样,太久的东西会忘记(对于机器来说老早之前的文本历史被舍弃了)。还有就是人有的时候会不会胡乱联想,AI也会(这个才是幻觉问题的一种)。当然会很多。下面是正常的代码:

def 多轮对话():template = """You are a chatbot having a conversation with a human. Please answer as briefly as possible.{chat_history}Human: {human_input}Chatbot:"""prompt = PromptTemplate(input_variables=["chat_history", "human_input"], template=template)memory = ConversationBufferMemory(memory_key="chat_history")llm_chain = LLMChain(llm=chat,prompt=prompt,verbose=False,memory=memory,)res = llm_chain.run(human_input="诸葛亮是谁")print(res)res = llm_chain.run(human_input="他有没有老婆")print(res)def main():# 基本调用("狗狗")# 基本调用("宠物公司")多轮对话()return 0

运行结果如下:
在这里插入图片描述

Sequential Chains

SimpleSequentialChain

SimpleSequentialChain是最基本的一种Sequential Chains,因为它只有一个输入和一个输出,其中前一个chain的输出为后一个chain的输入。有啥意义?通用模型拿到常识结果,然后找擅长这个领域的专家模型进行解决。是不是可以加大模型的准确率。
假如我想让第一个模型得到三国演义的一个人物,第二个模型拿到该人物并进行分析。怎么操作呢?如下:

def 简单工作流(input):# prompt template 1first_prompt = ChatPromptTemplate.from_template("{input}中的一个杰出人物,要求男,军师。只要一个结果")# Chain 1chain_one = LLMChain(llm=chat, prompt=first_prompt, output_key="person")# prompt template 2second_prompt = ChatPromptTemplate.from_template("为该人物编写 20 个字的描述:{person}")# chain 2chain_two = LLMChain(llm=chat, prompt=second_prompt)# 将chain1和chain2组合在一起生成一个新的chain.overall_simple_chain = SimpleSequentialChain(chains=[chain_one, chain_two],verbose=True)# 执行新的chainres = overall_simple_chain.run(input)# print(res)def main():# 基本调用("狗狗")# 基本调用("宠物公司")# 多轮对话()简单工作流("三国演义")return 0

运行结果
在这里插入图片描述

SequentialChain

SequentialChain与SimpleSequentialChain的区别在于它可以有多个输入和输出,而SimpleSequentialChain只有一个输入和输出。
为啥要搞这个?比如你是跨境电商。那么将会面临两个痛点,第一就是不是所有语言我们都掌握。第二个就是由于时差,可能会导致回复消息或者查看评论不及时降低服务分。怎么办?AI来帮你搞定。那么需要AI完成这些事情:
1.将用户评论翻译成中文(机器翻译)
2.概括评论(可以参考文本摘要)
3.识别出用户评论使用的语言(机器翻译)
4.根据2 3的结果按原始评论语言生成回复(文本生成)
5.将回复翻译成中文(机器翻译)
为啥不一个AI,可以说专业的人干专业的事情。AI也一样。下面是以回复评论为列子的代码:

def 多输入单输出():# prompt template 1: 将评论翻译成中文first_prompt = ChatPromptTemplate.from_template("将下面的评论翻译成中文:""\n\n{Review}")# chain 1: input= Review and output= Chinese_Reviewchain_one = LLMChain(llm=chat, prompt=first_prompt,output_key="Chinese_Review")# 概括评论second_prompt = ChatPromptTemplate.from_template("你能用 1 句话概括以下评论吗:""\n\n{Chinese_Review}")# chain 2: input= Chinese_Review and output= summarychain_two = LLMChain(llm=chat, prompt=second_prompt,output_key="summary")# prompt template 3: 识别评论使用的语言third_prompt = ChatPromptTemplate.from_template("下面的评论使用的是什么语言?:\n\n{Review}")# chain 3: input= Review and output= languagechain_three = LLMChain(llm=chat, prompt=third_prompt,output_key="language")# prompt template 4: 生成回复信息fourth_prompt = ChatPromptTemplate.from_template("编写对以下摘要的后续回复:""\n\n摘要:{summary}")# chain 4: input= summary, language and output= followup_messagechain_four = LLMChain(llm=chat, prompt=fourth_prompt,output_key="followup_message")# prompt template 5: 将回复信息翻译成英文five_prompt = ChatPromptTemplate.from_template("将下面的评论翻译成英文:""\n\n{followup_message}")# chain 5: input= followup_message and output= Chinese_followup_messagechain_five = LLMChain(llm=chat, prompt=five_prompt,output_key="English_followup_message")overall_chain = SequentialChain(chains=[chain_one, chain_two, chain_three, chain_four, chain_five],input_variables=["Review"],output_variables=["language", "Chinese_Review", "summary","followup_message", "English_followup_message"],verbose=True)review = "this restaurant is very good, i strongly recommend it!"res = overall_chain(review)print(res)print(res["English_followup_message"])return 0def main():# 基本调用("狗狗")# 基本调用("宠物公司")# 多轮对话()# 简单工作流("三国演义")多输入单输出()return 0

在这里插入图片描述

Router Chain

根据信息的内容将其传送到不同的chain,而每个chain的职能是只擅长回答自己所属领域的问题,那么在这种场景下就需要一种具有"路由器"功能的chain来将信息传输到不同职能的chain。能不能实现呢?
刚才讲了多对一,有没有一对多来解决这个问题。
在正式代码之前,先看用大模型调用小模型而不进行解析会出现什么情况:
在这里插入图片描述
加了解析以后,我们就可以得到正确结果
在这里插入图片描述
加了解析的完整代码如下:

def 单输入多输出():physics_template = """你是一位非常聪明的物理学教授。\你擅长以简洁易懂的方式回答有关物理的问题。 \当你不知道某个问题的答案时,你就承认你不知道。这里有一个问题:{input}"""math_template = """你是一位非常优秀的数学家。\你很擅长回答数学问题。 \你之所以如此出色,是因为你能够将难题分解为各个组成部分,\回答各个组成部分,然后将它们组合起来回答更广泛的问题。这里有一个问题:{input}"""history_template = """你是一位非常优秀的历史学家。\你对各个历史时期的人物、事件和背景有深入的了解和理解。 \你有能力思考、反思、辩论、讨论和评价过去。 \你尊重历史证据,并有能力利用它来支持你的解释和判断。这里有一个问题:{input}"""computerscience_template = """你是一位成功的计算机科学家。\你有创造力,协作精神,前瞻性思维,自信,有很强的解决问题的能力,\对理论和算法的理解,以及出色的沟通能力。\你很擅长回答编程问题。你是如此优秀,因为你知道如何通过描述一个机器可以很容易理解的命令步骤来解决问题,\你知道如何选择一个解决方案,在时间复杂度和空间复杂度之间取得良好的平衡。这里有一个问题:{input}"""prompt_infos = [{"name": "physics","description": "擅长回答有关物理方面的问题","prompt_template": physics_template},{"name": "math","description": "擅长回答有关数学方面的问题","prompt_template": math_template},{"name": "history","description": "擅长回答有关历史方面的问题","prompt_template": history_template},{"name": "computer science","description": "擅长回答有关计算机科学方面的问题","prompt_template": computerscience_template}]# 创建目标chain {'name': chain}destination_chains = {}for p_info in prompt_infos:name = p_info["name"]prompt_template = p_info["prompt_template"]prompt = ChatPromptTemplate.from_template(template=prompt_template)chain = LLMChain(llm=chat, prompt=prompt)destination_chains[name] = chain# print(destination_chains)# 创建要写入prompt的chain stringdestinations = [f"{p['name']}: {p['description']}" for p in prompt_infos]# print("destinations: \n", destinations)destinations_str = "\n".join(destinations)# print(destinations_str)# default prompt,无法被route的input,用default LLM来处理default_prompt = ChatPromptTemplate.from_template("{input}")default_chain = LLMChain(llm=chat, prompt=default_prompt)MULTI_PROMPT_ROUTER_TEMPLATE = """给定一个原始文本输入到一个语言模型并且选择最适合输入的模型提示语。你会获得可用的提示语的名称以及该提示语最合适的描述。记住:任何情况下都要使用原始文本输入。<< FORMATTING >>返回一个 Markdown 代码片段,其中 JSON 对象的格式如下:```json{{{{"destination": string"next_inputs": string}}}}```记住: "destination"的值需要从下面"CANDIDATE PROMPTS"里挑选一个和原始文本输入内容最匹配的值。如果没有匹配的则把值设为"default"记住: "next_inputs"的值就是给定的原始文本输入<< CANDIDATE PROMPTS >>{destinations}<< INPUT >>{{input}}<< OUTPUT (must include ```json at the start of the response) >><< OUTPUT (must end with ```) >>"""router_template = MULTI_PROMPT_ROUTER_TEMPLATE.format(destinations=destinations_str)# print(router_template)router_prompt = PromptTemplate(template=router_template,input_variables=["input"],output_parser=RouterOutputParser(),)# print("\n router_prompt: \n", router_prompt)# 创建route chainrouter_chain = LLMRouterChain.from_llm(chat, router_prompt, verbose=True)chain = MultiPromptChain(router_chain=router_chain,destination_chains=destination_chains,default_chain=default_chain, verbose=True)response = chain.run("1+1等于几?")# response = chain.run("牛顿第一定律?")# response = chain.run("武则天是谁?")# response = chain.run("python编程语言有什么特点?")# response = chain.run("爱情是什么?")print("response: ", response)return 0def main():# 基本调用("狗狗")# 基本调用("宠物公司")# 多轮对话()# 简单工作流("三国演义")# 多输入单输出()单输入多输出()return 0

Documents Chain

这个主要适用于文档(建议doc,不建议其他格式。如果其他格式比如PDF可以用工具转doc)
下面的 4 种 Chain 主要用于 Document 的处理,在基于文档生成摘要、基于文档的问答等场景中经常会用到。

StuffDocumentsChain

这种链最简单直接,是将所有获取到的文档作为 context 放入到 Prompt 中,传递到 LLM 获取答案。

RefineDocumentsChain

通过迭代更新的方式获取答案。先处理第一个文档,作为 context 传递给 llm,获取中间结果 intermediate answer。然后将第一个文档的中间结果以及第二个文档发给 llm 进行处理,后续的文档类似处理。

MapReduceDocumentsChain

先通过 LLM 对每个 document 进行处理,然后将所有文档的答案在通过 LLM 进行合并处理,得到最终的结果。

MapRerankDocumentsChain

和MapReduceDocumentsChain 类似,先通过 LLM 对每个 document 进行处理,每个答案都会返回一个 score,最后选择 score 最高的答案。

Document Loaders

LangChain 通过 Loader 加载外部的文档,转化为标准的 Document 类型。langchain提供了很多文档加载的类,以便进行不同的文件加载,这些类都通过 langchain.document_loaders 引入。
例如加载文本:UnstructuredFileLoader(txt文件读取)、UnstructuredFileLoader(word文件读取)、MarkdownTextSplitter(markdown文件读取)、UnstructuredPDFLoader(PDF文件读取)

Agent

Agents可以看做是一个智能化的流程封装。它基于LLM的CoT能力,动态串联多个Tool或Chain,完成对复杂问题的自动推导和执行解决。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/9230.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言 变量的作用域

今天 我们来说变量的作用域和存储类型 每种事物 都有自己作用的范围限制 例如 汽车只能在路上跑 轮船只能在海洋 飞机只能通行于天空 函数的参数 也只有在函数被调用过程中分配内存资源 函数执行结束 空间也会被立即释放 这也说明了 行参变量只有在函数内才有效 离开了该函数 …

【Linux】项目自动化构建工具make/makefile的简单使用

使用步骤 1) 编写 创建 makefile 文件 vim makefile用 vim 打开名为 makefile 的文件,存在该文件则打开编辑,不存在则创建并打开.在 makefile 文件中编写需要编译的文件 test:test.cppg -o test test.cpp第一行: 冒号左侧为编译后的可执行文件名,可以随便取. 冒号右侧为依赖…

封装一个可以最小化和展开的弹窗组件

gl-dialog 大概思路&#xff1a; 在弹窗组件内部引入gl-dialog-collapse&#xff0c;这个组件主要用于存储已经被最小化的弹窗&#xff08;基础数据&#xff09; 弹窗内部的数据如何在父组件拿到是通过作用域插槽来实现的 gl-dialog接收一个tempData这个数据会在内部被记录下来…

salmon使用体验

文章目录 salmon转录本定量brief模式一&#xff1a;fastq作为输入文件需要特别注意得地方 模式二&#xff1a; bam文件作为输入 salmon转录本定量 brief 第一点是&#xff0c;通常说的转录组分析其中有一项是转录本定量&#xff0c;这是一个很trick的说话&#xff0c;说成定量…

代码随想录算法训练营第四十二天| 01背包问题(二维、一维)、416.分割等和子集

系列文章目录 目录 系列文章目录动态规划&#xff1a;01背包理论基础①二维数组②一维数组&#xff08;滚动数组&#xff09; 416. 分割等和子集①回溯法&#xff08;超时&#xff09;②动态规划&#xff08;01背包&#xff09;未剪枝版剪枝版 动态规划&#xff1a;01背包理论基…

基于Vue3与ElementUI Plus酷企秀可视化设计器中的创新应用

一、引言 随着科技的快速发展&#xff0c;前端技术已经从简单的网页呈现进化到了复杂的数据可视化、互动体验和跨平台应用的构建。酷企秀可视化设计器作为一个集成了多种前端技术的创新平台&#xff0c;不仅为企业提供了全方位的数字化展示解决方案&#xff0c;还在多个行业领…

SRC上分秘诀+实战挖掘+挖洞技巧+新手上路+详细讲解

SRC马上到来 可能有些好兄弟们还没有头绪 只会做一些靶场 并没有什么实战经验 所以这篇文章给大家分享一下我挖洞2个月的经验分享 适合新手上路 如何找站&#xff1f; 谷歌搜索 谷歌搜索 谷歌搜索 SQL注入XSS所有漏洞 inurl:.php?idxx 公司inurl:.asp?idxx 公司inurl:.jsp?…

Mysql基础篇(一)Mysql概述

目录 基本概念 数据库(DataBase,DB) 数据库的定义 数据库的分类 数据库管理系统(DataBase Management System,DBMS) SQL(Structured Query Language) Mysql Mysql数据模型 下载安装Mysql 基本概念 数据库(DataBase,DB) 数据库的定义 按照数据结构来组织、存储和管理数…

java报错:使用mybatis plus查询一个只返回一条数据的sql,却报错返回了1000多条

今天遇到一个问题 系统线上问题&#xff0c;经常出现这样的问题&#xff0c;刚重启系统时不报错了&#xff0c;可是运行一段时间又会出现。sql已经写了limit 1&#xff0c;mybatis的debug日志也返回total为1&#xff0c;可是却报错返回了1805条数据 乍一看&#xff0c;感觉太不…

汽车之家,如何在“以旧换新”浪潮中大展拳脚?

北京车展刚刚落幕&#xff0c;两重利好正主导汽车市场持续升温&#xff1a;新能源渗透率首破50%&#xff0c;以及以旧换新详细政策进入落地期。 图源&#xff1a;中国政府网 在政策的有力指引下&#xff0c;汽车产业链的各个环节正经历着一场深刻的“连锁反应”。在以旧换新的…

Python运维之多线程!!

一、多线程 二、多线程编程之threading模块 2.1、使用threading进行多线程操作有两种方法&#xff1a; 三、多线程同步之Lock&#xff08;互斥锁&#xff09; 四、多线程同步之Semaphore&#xff08;信号量&#xff09; 五、多线程同步之Condition 六、多线程同步之Event…

CSS和JavaScript

CSS 在html中引入CSS 我们需要先在该项目先建立css文件 html引入CSS,在<head></head>中添加<link>标签 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" co…

mac 本地使用docker 运行es,kibana

1.下载 m芯片一些版本不支持.踩过坑.翻看官网才知道只有部分镜像支持m芯片 https://hub.docker.com/添加链接描述 docker pull elasticsearch:7.17.21 docker pull kibana:7.17.21镜像已经下载下来了 2.创建文件映射-挂载 /Users/lin/dev/dockerMsg 其中lin是自己的用户名…

关于线程池,它的扩展问题你知道吗?(自己总结)

专门想一下为什么线程池不用Excutors&#xff0c;之前的印象是错的&#xff0c;居然还拿来面试里讲&#xff0c;惭愧&#xff0c;这里暂时整理俩小问题&#xff0c;其他的后续可能会更新。。 线程池是创建的越大越好嘛 #线程池创建的越大越好吗 Tip&#xff1a;2024-04-10 更…

本地搭建hydra服务用go以验证oidc流程

目录 1、docker搭建hydra&#xff0c;环境配置&#xff1a; 2、搭建完成后服务调用&#xff1a; 2.1保证服务正常启动&#xff1a; 2.2 通过postman调用&#xff0c;获取client_id&#xff1a; 2.3 通过client_id&#xff0c;实现oauth2/auth调用 3. 通过go语言实现oidc验…

【qt】容器的用法

容器目录 一.QVertor1.应用场景2.增加数据3.删除数据4.修改数据5.查询数据6.是否包含7.数据个数8.交换数据9.移动数据10.嵌套使用 二.QList1.应用场景2.QStringList 三.QLinkedList1.应用场景2.特殊点3.用迭代器来变量 四.QStack1.应用场景2.基本用法 五.QQueue1.应用场景2.基本…

OS复习笔记ch5-3

引言 上一节我们学习了关于信号量机制的一些内容&#xff0c;包括信号量的含义&#xff0c;对应的PV操作等。 如图所示&#xff0c;上一节主要是针对信号量的互斥&#xff0c;其实信号量机制还可以做很多事情&#xff0c;比如实现进程同步和前驱关系&#xff0c;这一节我们先复…

【Spring】JdbcTemplate

JdbcTemplate 是 Spring 提供的一个 JDBC 模板类&#xff0c;是对 JDBC 的封装&#xff0c;简化 JDBC 代码 也可以让 Spring 集成其它的 ORM 框架&#xff0c;例如&#xff1a;MyBatis、Hibernate 等 使用 JdbcTemplate 完成增删改查 一、环境准备 数据库&#xff1a; 准备…

Marin说PCB之如何快速打印输出整板的丝印位号图?

当小编我辛辛苦苦加班加点的把手上的板子做到投板评审状态的时候&#xff0c;坐在我旁边的日本同事龟田小郎君说让我把板子上的丝印也要调一下&#xff0c;我当时就急了&#xff0c;这么大的板子&#xff0c;将近1W多PIN 了都&#xff0c;光调丝印都要老半天啊&#xff0c;而且…

Docx文件误删除如何恢复?别再花冤枉钱了,4个高效恢复软件!

不管是工作还是学习&#xff0c;总是会与各种各样的文件打交道。文件量越多就越容易出现文件丢失、文件误删的情况。遇到这些情况&#xff0c;失去的文件还能找回来吗&#xff1f;只要掌握了一些数据恢复方法&#xff0c;是很有机会恢复回来的&#xff0c;下面我会将这些方法分…