LLM——langchain 与阿里 DashScop (通义千问大模型) 和 DashVector(向量数据库) 结合使用总结

文章目录

  • 前言
  • 预览
    • 直接调用大模型
    • 使用 prompt template
    • 格式化输出
    • 使用上下文 RAG 增强检索
  • 自定义 langchain Agent
  • PromptTemplate 和 ChatPromptTemplate
  • 使用少量示例创建ChatPromptTemplate

前言

langchain 是一个面向大模型开发的框架,其中封装了很多核心组件,包括对文本等非结构化数据的 chunk,向量数据库的嵌入和查询等,并且对许多大模型的调用进行了封装, 如果说我们需要基于多个 LLM 开发 APP, 使用 Langchain 可以极大的简化我们的程序代码,很多操作可以直接通过 Langchain API 进行操作。
langchain 还有最重要的一个功能就是社区提供了很多 Agent 工具,比如说:

  • 视频做编辑的工具

  • 视频转换成动画的工具

  • 生成图片的工具

  • 生成动画视频的工具

  • TTS的工具

  • GPT的工具(输入,输出)

  • 编程的工具(输入,输出)

  • 脚本分镜的工具(输入,输出)

  • 我们就可以使用这些工具让 LLM 完成一个复杂的任务:自动拍摄一个动画类短视频,我们就可以使用下边的 Agent 去构建 APP:

  1. GPT的工具:生成脚本(输入,输出)
  2. 脚本分镜:很长的脚本分成不同的镜头
  3. 每个分镜生成图片:生成图片的工具
  4. 图片转换成视频

接下来我将首先 overview langchain 的核心功能,然后说明如何使用 langchain 和阿里的通义千问大模型以及向量检索服务(DashVector)结合使用。

预览

langchain 封装了各类模型,这里我将使用阿里云的通义千问模型(便宜,而且现在 OpenAI API 已经禁止国内访问,支持国产),演示如何使用 langchain 来操作。
前置条件

  • 安装通义千问访问依赖 pip install --upgrade --quiet dashscope
  • 确保开通了通义千问 API key 和 向量检索服务 API KEY
  • 安装 langchain pip install langchain
  • 安装阿里云的向量检索服务依赖:pip install dashvector

直接调用大模型

import osfrom langchain_community.chat_models.tongyi import ChatTongyi# 这里需要将 DASHSCOPE_API_KEY 替换为你在阿里云控制台开通的 API KEY
os.environ["DASHSCOPE_API_KEY"] = ""# 可以通过 model 指定模型
llm = ChatTongyi(model='qwen-vl-max')# 直接调用
res = llm.invoke("What is the Sora model?")print(res)

使用 prompt template

import osfrom langchain.prompts import ChatPromptTemplate
from langchain_community.chat_models.tongyi import ChatTongyi# 这里需要将 DASHSCOPE_API_KEY 替换为你在阿里云控制台开通的 API KEY
os.environ["DASHSCOPE_API_KEY"] = ""# 可以通过 model 指定模型
llm = ChatTongyi(model='qwen-vl-max')# 需要注意的一点是,这里需要指明具体的role,在这里是system和用户
prompt = ChatPromptTemplate.from_messages([("system", "You are the technical writer"),("user", "{input}")  # {input}为变量
])# 我们可以把prompt和具体llm的调用和在一起(通过chain,chain可以理解为sequence of calls to take)
chain = prompt | llm
res = chain.invoke({"input": "What is the Sora model?"})print(res)

返回内容如下:

content=[{'text': 'I\'m sorry, but I do not have any information on a specific "Sora model." Could you provide more context or detail about what you are asking?'}] 
response_metadata={'model_name': 'qwen-vl-max', 'finish_reason': 'stop', 'request_id': '8ec70fd8-a968-9a92-83aa-466d573ebe64', 'token_usage': {'input_tokens': 25, 'output_tokens': 33}} 
id='run-9b371b24-d34a-4b04-a565-9dbef773eb99-0'

可以看到目前该大模型暂时无法理解我们的问题,这个时候就需要使用 RAG,基于外部知识增强大模型的回复。

格式化输出

from langchain_core.output_parsers import StrOutputParseroutput_parser = StrOutputParser()  # 输出string
chain = prompt | llm | output_parser
chain.invoke({"input": "What is the Sora model?"})

使用上下文 RAG 增强检索

结合关于Sora的technical report来生成更好地答案,分下边几步:

  1. 寻找关于 Sora 的一些文库,并中抓取内容
  2. 把文库切块(Trunks)并存放到向量数据库
  3. 对于新的问题,我们首先从 vector store 中提取 chunks, 并融合到 prompt 中

这里我们使用的阿里云的通用文本向量和向量检索服务,不熟悉这两个云服务的可以参考我之前写的这篇文章:LLM-文本分块(langchain)与向量化(阿里云DashVector)存储,嵌入LLM实践。

import osimport dashvector
from langchain.prompts import ChatPromptTemplate
from langchain_community.chat_models.tongyi import ChatTongyi
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.embeddings.dashscope import DashScopeEmbeddings
from langchain_community.vectorstores.dashvector import DashVector
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain.chains import create_retrieval_chain# 我们需要同时开通 DASHSCOPE_API_KEY 和 DASHVECTOR_API_KEY
os.environ["DASHSCOPE_API_KEY"] = ""
os.environ["DASHVECTOR_API_KEY"] = ""
# DASHVECTOR_ENDPOINT 在向量检索服务控制台可以查看:
os.environ["DASHVECTOR_ENDPOINT"] = ""# 使用阿里的通义千问 LLM
llm = ChatTongyi()# 抓取 sora 相关数据
loader = WebBaseLoader("https://pixso.cn/designskills/what-is-sora/")
docs = loader.load()# 使用阿里云的 DashScopeEmbeddings
# langchain 结合 DashScopeEmbeddings 官方文档 https://python.langchain.com/v0.2/docs/integrations/text_embedding/dashscope/
embeddings = DashScopeEmbeddings(model="text-embedding-v1",
)# 拆分 chunks, 这里使用的是递归拆分, 需要注意这里 chunk_size 不能大于 2048,
# 因为阿里云的文本向量单行最大输入字符长度不能超过 2048
text_splitter = RecursiveCharacterTextSplitter(chunk_size=2048,chunk_overlap=200
)
documents = text_splitter.split_documents(docs)# 使用阿里云的 DashVecotr
# langchain 结合 DashVector 官方文档 https://python.langchain.com/v0.2/docs/integrations/vectorstores/dashvector/
vector = DashVector.from_documents(documents, embeddings)# 填充 prompt template
prompt = ChatPromptTemplate.from_template("""Answer the following question based only on the provided context:<context>
{context}
</context>Question: {input}""")
document_chain = create_stuff_documents_chain(llm, prompt)# 从向量数据库召回和 Sora 相关数据
retriever = vector.as_retriever()
retrieval_chain = create_retrieval_chain(retriever, document_chain)# 调用执行
response = retrieval_chain.invoke({"input": "What is the Sora model?"})
print(response["answer"])
  • 需要先开通义千问和向量检索服务的 API key, 然后设置对应的环境变量
  • 在使用 WebBaseLoader加载爬取网站数据的时候,需要注意有的网站是需要登录的,docs 可能会返回错误,而不是网站信息,这一点需要注意,最好是判断下 docs 中的内容是否存在网站上的数据,这是爬取的网站链接地址。
  • 在拆分 chunks 的时候需要注意chunk_size 不能超过 2048,因为阿里云的文本向量单行最大输入字符长度不能超过 2048:
    image.png
  • 执行完向量数据库写入后,可以在控制台查看写入的向量数据:
    image.png
  • 通过 RAG,llm 给出了我们回复如下,看起来生效了:
Sora is a video generation model developed by OpenAI, which is the first of its kind to create 60-second videos based on text prompts. It uses diffusion models and a transformer architecture to generate videos that are highly detailed, with complex scenes, realistic character expressions, and smooth camera movements. Sora's core capabilities include text-to-video generation, creation of complex scenes and characters, multi-shot generation, and the ability to work with static images or extend existing videos. Its release signifies a significant advancement in AI-generated content and hints at the possibility of more advanced forms of artificial general intelligence (AGI). However, it is currently not publicly available for general use.

自定义 langchain Agent

有时候当我们询问大模型一些私人问题的时候,大模型并不知道这些答案,比如说问:我同桌是小明,帮我说明小明的兴趣爱好。
这个时候我们就可以自定义 langchain 的 Agent, 当大模型找不到答案的时候,就会匹配相关 Agent, 匹配到的话,就会执行该 Agent。
安装依赖 pip install langchainhub,langchainhub 类似于 DockerHub, 是对各个 prompt template 的管理。

import osfrom langchain import hub
from langchain.agents import AgentExecutor
from langchain.agents import create_react_agent
from langchain_community.llms import Tongyi
from langchain_core.tools import BaseTool# 我们需要开通 DASHSCOPE_API_KEY
os.environ["DASHSCOPE_API_KEY"] = "sk-d35c623d2575460b8a296e4ff0db5f7c"model = Tongyi()
model.model_name = 'qwen-max'class SearchStudentInfoTool(BaseTool):"""查询同学信息工具"""name: str = "查询学生"description: str = ("当用户询问学生相关信息时,才使用此工具。")def _run(self, name: str) -> str:if name == '小明':return '''小明性别男,身高175,成绩良好!'''elif name == '小红':return '''小明性别女,身高163,成绩优秀,语文组长!'''return name + '抱歉,没有查到相关信息。'tools = [SearchStudentInfoTool()]prompt = hub.pull("hwchase17/react")agent = create_react_agent(model, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)result = agent_executor.invoke({'input': '学生小红的个人信息'})
print(result['output'])
  • 自定义 Agent tool 中的 description 很重要,langchain 将通过 description 判断是否应该调用此 Agent。
  • 执行结果如下:

image.png

PromptTemplate 和 ChatPromptTemplate

PromptTemplate只有补全功能,无对话功能,ChatPromptTemplate可以和用户对话,下边通过案例说明,在使用 ChatPromptTemplate 时需要定义rolecontent.

from langchain.prompts import PromptTemplateprompt_template = PromptTemplate.from_template("编写一段关于{主题}的小红书宣传文案,需要采用{风格}语气"
)
prompt_template.format(主题="美国留学", 风格="幽默")#### 输出如下
# '编写一段关于美国留学的小红书宣传文案,需要采用幽默语气'
from langchain_core.prompts import ChatPromptTemplate# 这里的 system, human,ai 就是角色
chat_template = ChatPromptTemplate.from_messages([("system", "你是AI助教,你的名字是{name}."),("human", "你好"),("ai", "你好,有什么可以帮到您?"),("human", "{user_input}"),]
)messages = chat_template.format_messages(name="张三", user_input="你的名字是什么?")llm.invoke(messages)##### 输出如下
# AIMessage(content='你好,我的名字是张三,我是你的AI助教。有什么可以帮助你的吗?')

使用 chain 调用:

chain = chat_template | llm
chain.invoke({"name":"张三", "user_input":"你的名字是什么?"})### 输出如下
# AIMessage(content='我的名字是张三。有什么问题我可以帮您解答呢?')

流式生成
基于 Transformer 架构的大模型是根据当前 token 预测下一个 token, 不断生成答案的,我们在调用 llm 获取答案时,有两种方式:

  • 使用 llm.invoke()等待大模型生成完毕,如果输出的 token 数量比较多,需要等待一会儿。
  • 使用 llm.stream()让大模型在预测下一个 token 的时候,输出当前已经生成的 token。
chain = messages | llm
chain.invoke({"name":"张三", "user_input":"你的名字是什么?"})
for chunk in llm.stream(messages):print(chunk.content, end="", flush=True)

使用少量示例创建ChatPromptTemplate

few-shot prompting(少样本提示)的目的是根据输入动态选择相关的样本,并将这些样本格式化成提示给模型,使用 FewShotChatMessagePromptTemplate可以实现这一点。

固定构建 template

from langchain.prompts import ChatPromptTemplate,FewShotChatMessagePromptTemplateexamples = [{"input": "2+2", "output": "4"},{"input": "2+3", "output": "5"},
]
# This is a prompt template used to format each individual example.
example_prompt = ChatPromptTemplate.from_messages([("human", "{input}"),("ai", "{output}"),]
)
few_shot_prompt = FewShotChatMessagePromptTemplate(example_prompt=example_prompt,examples=examples,
)print(few_shot_prompt.format())##### 输出内容如下
# Human: 2+2
# AI: 4
# Human: 2+3
# AI: 5

调用创建好的FewShotChatMessagePromptTemplate:

from langchain_community.chat_models.tongyi import ChatTongyifinal_prompt = ChatPromptTemplate.from_messages([("system", "You are a wondrous wizard of math."),few_shot_prompt,("human", "{input}"),]
)chain = final_prompt | ChatTongyi(temperature=0.0)
chain.invoke({"input": "What's the square of a triangle?"})##### 输出如下
# AIMessage(content=' Triangles do not have a "square". A square refers to a shape with 4 equal sides and 4 right angles. Triangles have 3 sides and 3 angles.\n\nThe area of a triangle can be calculated using the formula:\n\nA = 1/2 * b * h\n\nWhere:\n\nA is the area \nb is the base (the length of one of the sides)\nh is the height (the length from the base to the opposite vertex)\n\nSo the area depends on the specific dimensions of the triangle. There is no single "square of a triangle". The area can vary greatly depending on the base and height measurements.', additional_kwargs={}, example=False)

在构建最终推理prompt时,首先设置系统角色,然后提供少样本示例,最后传入用户的输入,让模型进行推理。final_prompt同时为模型提供上下文、示例和输入的作用,使其能够有针对性地生成响应。

使用示例选择器
有时候我们的 examples 包含大量的不同种类的样例,我们希望可以根据用户输入的问题,动态给出提示词,然后使用 chain 调用执行 llm.

import osfrom langchain_community.embeddings.dashscope import DashScopeEmbeddings
from langchain_community.vectorstores.dashvector import DashVector
from langchain.prompts import SemanticSimilarityExampleSelector
from langchain.prompts import ChatPromptTemplate,FewShotChatMessagePromptTemplate
from langchain_community.chat_models.tongyi import ChatTongyi
from langchain_core.output_parsers import StrOutputParser# 我们需要同时开通 DASHSCOPE_API_KEY 和 DASHVECTOR_API_KEY
os.environ["DASHSCOPE_API_KEY"] = ""
os.environ["DASHVECTOR_API_KEY"] = ""
# DASHVECTOR_ENDPOINT 在向量检索服务控制台可以查看:
os.environ["DASHVECTOR_ENDPOINT"] = ""examples = [{"input": "2+2", "output": "4"},{"input": "2+3", "output": "5"},{"input": "2+4", "output": "6"},{"input": "What did the cow say to the moon?", "output": "nothing at all"},{"input": "Write me a poem about the moon","output": "One for the moon, and one for me, who are we to talk about the moon?",},
]# 需要将提示信息写入向量数据库
to_vectorize = [" ".join(example.values()) for example in examples]
embeddings = DashScopeEmbeddings()
vectorstore = DashVector.from_texts(to_vectorize, embeddings, metadatas=examples)# 从向量数据库中查询出最相似的提示词
example_selector = SemanticSimilarityExampleSelector(vectorstore=vectorstore,# k 表示选择前 2 个最相似的提示k=2,
)
example_selector.select_examples({"input": "horse"})# 创建FewShotChatMessagePromptTemplate
few_shot_prompt = FewShotChatMessagePromptTemplate(# input variables选择要传递给示例选择器的值input_variables=["input"],example_selector=example_selector,# 定义每个示例的格式。在这种情况下,每个示例将变成 2 条消息:# 1 条来自人类,1 条来自 AIexample_prompt=ChatPromptTemplate.from_messages([("human", "{input}"), ("ai", "{output}")]),
)# 创建最终模板
final_prompt = ChatPromptTemplate.from_messages([("system", "You are a wondrous wizard of math."),few_shot_prompt,("human", "{input}"),]
)print(few_shot_prompt.format(input="What's 3+3?"))# 输出内容如下
# Human: 2+3
# AI: 5
# Human: 2+2
# AI: 4# 使用 chain 调用
output_parser = StrOutputParser()
chain = final_prompt | ChatTongyi(temperature=0.0) | output_parser
res = chain.invoke({"input": "What's 3+3?"})
print(res)# 输出内容如下
# 6

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

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

相关文章

基于lstm的股票Volume预测

LSTM&#xff08;Long Short-Term Memory&#xff09;神经网络模型是一种特殊的循环神经网络&#xff08;RNN&#xff09;&#xff0c;它在处理长期依赖关系方面表现出色&#xff0c;尤其适用于时间序列预测、自然语言处理&#xff08;NLP&#xff09;和语音识别等领域。以下是…

【算法】平衡二叉树

难度&#xff1a;简单 题目 给定一个二叉树&#xff0c;判断它是否是 平衡二叉树 示例&#xff1a; 示例1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;true 示例2&#xff1a; 输入&#xff1a;root [1,2,2,3,3,null,null,4,4] 输出&…

html表格账号密码备忘录:表格内容将通过JavaScript动态生成。点击查看密码10秒关闭

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><title>账号密码备忘录</title><style>body {background: #2c3e50;text-shadow: 1px 1px 1px #100000;}/* 首页样式开始 */.home_page {color: …

Excel第31享:基于left函数的截取式数据裂变

1、需求描述 如下图所示&#xff0c;在“Excel第30享”中统计2022年YTD各个人员的“上班工时&#xff08;a2&#xff09;”&#xff0c;需要基于工时明细表里的“日期”字段建立辅助列&#xff0c;生成“年份”字段&#xff0c;本文说明“年份”字段是怎么裂变而来的。 下图为…

AI时代:探索个人潜能的新视角

文章目录 Al时代的个人发展1 AI的高速发展意味着什么1.1 生产力大幅提升1.2 生产关系的改变1.3 产品范式1.4 产业革命1.5 Al的局限性1.5.1局限一:大模型的幻觉 1.5.2 局限二&#xff1a;Token 2 个体如何应对这种改变?2.1 职场人2.2 K12家长2.3 大学生2.4 创业者 3 人工智能发…

单相整流-TI视频课笔记

目录 1、单相半波整流 1.1、单相半波----电容滤波---超轻负载 1.2、单相半波----电容滤波---轻负载 1.3、单相半波----电容滤波---重负载 2、全波整流 2.1、全波整流的仿真 2.2、半波与全波滤波的对比 3、全桥整流电路 3.1、全波和全桥整流对比 3.2、半波全波和全桥…

高职计算机网络实训室

一、高职计算机网络实训室建设的背景 如今&#xff0c;数字化发展已成为国家发展的战略方向&#xff0c;是推动社会进步和经济发展的重要动力。在这一时代背景下&#xff0c;计算机网络技术作为数字化发展的基础设施&#xff0c;其地位和作用愈发凸显。因此&#xff0c;高职院…

数据结构(空间复杂度介绍)超详细!!!

1. 数据结构前言 1.1 数据结构 数据结构是计算机存储、组织数据的形式&#xff0c;指相互之间存在一种或多种特定关系的数据元素的集合 1.2 算法 算法&#xff1a;良好的计算过程&#xff0c;它取一个或一组的值为输入&#xff0c;并产生出一个或一组的值作为输出。即算法经…

UART编程

Q:为什么使用串口前要先在电脑上安装CH340驱动&#xff1f; 中断的作用&#xff1f; 环形buffer的作用&#xff1f; static和valitate的作用 三种编程方式简介 也可以通过DMA方式减小CPU资源的消耗 直接把数据在SRAM内存和UART模块进行传输 &#xff0c;流程&#xff1a; …

css文字自适应宽度动态出现省略号...

前言 在列表排行榜中通常会出现的一个需求&#xff1a;从左到右依次是名次、头像、昵称、徽标、分数。徽标可能会有多个或者没有徽标&#xff0c;徽标长度是动态的&#xff0c;昵称如果过长要随着有无徽标进行动态截断出现省略号。如下图布局所示&#xff08;花里胡哨的底色是…

接口安全配置

问题点&#xff1a; 有员工在工位在某个接口下链接一个集线器&#xff0c;从而扩展上网接口&#xff0c;这种行为在某些公司是被禁止的&#xff0c;那么网络管理员如何控制呢&#xff1f;可以配置接口安全来限制链接的数量&#xff0c;切被加入安全的mac地址不会老化&#xff…

防火墙NAT智能选举综合实验

一、实验目的 1&#xff0c;办公区设备可以通过电信链路和移动链路上网(多对多的NAT&#xff0c;并且需要保留一个公网IP不能用来转换) 2&#xff0c;分公司设备可以通过总公司的移动链路和电信链路访问到Dmz区的http服务器 3&#xff0c;多出口环境基于带宽比例进行选路&…

Anaconda+Pycharm 项目运行保姆级教程(附带视频)

最近很多小白在问如何用anacondapycharm运行一个深度学习项目&#xff0c;进行代码复现呢&#xff1f;于是写下这篇文章希望能浅浅起到一个指导作用。 附视频讲解地址&#xff1a;AnacondaPycharm项目运行实例_哔哩哔哩_bilibili 一、项目运行前的准备&#xff08;软件安装&…

护网HW面试常问——组件中间件框架漏洞(包含流量特征)

apache&iis&nginx中间件解析漏洞 参考我之前的文章&#xff1a;护网HW面试—apache&iis&nginx中间件解析漏洞篇-CSDN博客 log4j2 漏洞原理&#xff1a; 该漏洞主要是由于日志在打印时当遇到${后&#xff0c;以:号作为分割&#xff0c;将表达式内容分割成两部…

Linux的世界 -- 初次接触和一些常见的基本指令

一、Linux的介绍和准备 1、简单介绍下Linux的发展史 1991年10月5日&#xff0c;赫尔辛基大学的一名研究生Linus Benedict Torvalds在一个Usenet新闻组(comp.os.minix&#xff09;中宣布他编制出了一种类似UNIX的小操作系统&#xff0c;叫Linux。新的操作系统是受到另一个UNIX的…

WGCLOUD的ping设备监测可以导入excel数据吗

可以的 WGCLOUD的v3.5.3版本&#xff0c;已经支持导入excel数据&#xff0c;如下说明 数通设备PING监测使用说明 - WGCLOUD

FreeRTOS学习(1)STM32单片机移植FreeRTOS

一、FreeRTOS源码的下载 1、官网下载 FreeRTOS官方链接 官方下载速度慢&#xff0c;需要翻墙&#xff0c;一般选择第一个 2、直接通过仓库下载 仓库地址链接 同样很慢&#xff0c;甚至打不开网页&#xff0c;也不建议使用这种方法。 3、百度网盘 链接&#xff1a;https:…

Java | Leetcode Java题解之第234题回文链表

题目&#xff1a; 题解&#xff1a; class Solution {public boolean isPalindrome(ListNode head) {if (head null) {return true;}// 找到前半部分链表的尾节点并反转后半部分链表ListNode firstHalfEnd endOfFirstHalf(head);ListNode secondHalfStart reverseList(firs…

百度智能云将大模型引入网络故障定位的智能运维实践

物理网络中&#xff0c;某个设备发生故障&#xff0c;可能会引起一系列指标异常的告警。如何在短时间内从这些告警信息中找到真正的故障原因&#xff0c;犹如大海捞针&#xff0c;对于运维团队是一件很有挑战的事情。 在长期的物理网络运维工作建设中&#xff0c;百度智能云通…

OpenCV距离变换函数distanceTransform的使用

操作系统&#xff1a;ubuntu22.04OpenCV版本&#xff1a;OpenCV4.9IDE:Visual Studio Code编程语言&#xff1a;C11 功能描述 distanceTransform是OpenCV库中的一个非常有用的函数&#xff0c;主要用于计算图像中每个像素到最近的背景&#xff08;通常是非零像素到零像素&…