大模型应用开发与私有化部署

大模型应用开发与私有化部署必须有以下知识储备 Linux 基础 Docker amp Git Python 基础 Http 网络通信 amp Restful API 接口规范 web 前端基础 amp 前后端分离 amp FastAPI 大型语言模型 基于海量的数据进行学习得到的模型 在线大模型 OpenAI GPT Google Gemini Authropic Claude 智谱 AI GLM 百度 文心一言 优缺点

大家好,我是讯享网,很高兴认识大家。这里提供最前沿的Ai技术和互联网信息。



必须有以下知识储备:

  • Linux基础
  • Docker&Git
  • Python基础
  • Http网络通信&Restful API接口规范
  • web前端基础&前后端分离&FastAPI

大型语言模型,基于海量的数据进行学习得到的模型。

在线大模型:

OpenAI GPT

Google Gemini

Authropic Claude

智谱AI GLM

百度 文心一言

优缺点:

模型性能优越、研发成本低(0.005-0.008元/1000个token)、可以站在巨人的肩膀上快速探索前沿技术应用,稳定性和使用安全性高,但数据安全存在隐患,业务受制于人,上车容易下车难。

开源大模型:

Meta Llama(3.1 405B)

Mistral AI

X AI Grok

阿里 通义千问 Qwen

Baichuan

360 zhinao

优缺点:( 7B大模型->70亿->4张4090 ->语料->上十亿 -> )

完全自主可控,扩展性强,定制型强,数据安全有保障,但需要投入大量算力和开发成本,依赖开源,不好转身。

Llama系列

LLaMA系列大模型是Meta公司在2023年2月开源的基于 transformer 架构的大型语言模型, 包括四种尺寸(7B 、13B 、30B 和 65B),并在2024年进一步发展,推出了‌Llama 3版本。Llama3在多种行业基准测试中展现了最先进的性能,提供了包括改进的推理能力在内的新功能,是目前市场上最好的开源大模型之一。

img

Qwen系列

文档:https://qwen.readthedocs.io/zh-cn/latest/getting_started/quickstart.html

随着GLM的闭源,阿里的通义千问已经成为了国内开源大模型的领袖。

Qwen平均1个季度发布一个版本,性能始终处于开源大模型的第一梯队水平。目前最新发布版本:Qwen2.5。

img

阿里的魔塔社区(https://modelscope.cn/models)也随着技术迭代更新,成为了国内第一AI模型社区,号称“中文版HuggingFace(https://huggingface.co/)”,吸引了大批优质的大模型开发者参与进来,同时魔塔社区不仅提供免费在线开发环境(类似谷歌的Colab)和限时GPU算力(100小时32GB显存),助力开发者在线训练微调大模型,还与阿里云灵积平台(DashScope)深度绑定,让开发者训练微调完成的模型可以快速落地实施到阿里云架构服务器上(按量收费),形成了一整套混合模型在线服务的生态模式。

阿里还提供了高度适配的SWIFT轻量级微调框架和Qwen-Agent开发框架,其中SWIFT提供了代码环境和脚本微调两种模式,配套海量开源微调数据集,可以执行包括知识灌注、模型自我意识微调、Agent能力微调和领域能力微调等功能,还提供一键微调等功能。Qwen-Agent则支持高效稳定Multi Function calling、ReAct功能,支持调用开源大模型以及灵积平台的在线模型。

提示工程(Prompt Engineering)是一项通过优化提示词(Prompt)和生成策略,从而获得更好的模型返回结果的工程技术。

其基本实现逻辑如下:

img

简单而言,大模型的运行机制是“下一个字词预测”。用户输入的prompt即为大模型所获得上下文,大模型将根据用户的输入进行续写,返回结果。因此,输入的prompt的质量将极大地影响模型的返回结果的质量和对用户需求的满足程度,总的原则是“用户表达的需求越清晰,模型更有可能返回更高质量的结果”。

image-20240920225029776

image-20240920225039175

prompt工程这种微调手段对于大模型本身的推理能力的提升的范围大概也就10%左右。大模型训练工程师,prompt工程多数用在在线大模型,而不是开源大模型。

Prompt经验总结:清晰易懂、提供例子和锁定上下文、明确步骤、准确表达意图。

去玩一下吧:https://modelscope.cn/studios/LLMRiddles/LLMRiddles/summary

通常情况下,每条信息都会有一个角色(role)和内容(content):

  • 系统角色(system)用来向语言模型传达开发者定义好的核心指令,优先级是最高的。
  • 用户角色(user)则代表着用户自己输入或者产生出来的信息。
  • 助手角色(assistant)则是由语言模型自动生成并回复出来。

系统指令(system)

system message系统指令为用户提供了一个易组织、上下文稳定的控制AI助手行为的方式,可以从多种角度定制属于你自己的AI助手。系统指令允许用户在一定范围内规定LLM的风格和任务,使其更具可定性和适应各种用例。大部分LLM模型的系统指令System message的权重强化高于人工输入的prompt,并在多轮对话中保持稳定,您可以使用系统消息来描述助手的个性,定义模型应该回答和不应该回答的内容,以及定义模型响应的格式。

默认的System message:You are a helpful assistant.

下面是一些system message的使用示例:

行业 角色 system message 教育 数学老师 你是一名优秀的数学老师,教导学生学习数学,经常使用简单通俗的生活例子使复杂的数学概念变得更容易理解。 工作 python工程师 你是一名行业顶尖的Python开发工程师,会使用详细步骤和代码帮助公司和同事解决项目开发过程中的问题。 创作 小红书文案 你是一名优秀的小红书文案创作者,擅长使用诙谐风格来创作,经常会在创作中分享生活经验和工作经验。

System message可以被广泛应用在:角色扮演、语言风格、任务设定、限定回答范围。

用户指令(user)

用户指令是最常用的提示组件,主要功能是向模型说明要执行的操作。以下举例:

指令类型 prompt 简单指令 简要介绍一下xx公司。 详细指令 简要介绍一下xx公司,并介绍它的公司创始人,主营业务,使命和愿景。

Ollama 是一个开源的大型语言模型服务工具,专为在服务器上便捷部署和运行大型语言模型(LLMs)而设计,它提供了一个简洁且用户友好的命令行界面,通过这一界面,用户可以轻松地部署和管理各类开源的 LLM。具有以下特点和优势:

  • 开源免费:Ollama 以及其支持的模型完全开源免费,任何人都可以自由使用、修改和分发
  • 简化部署:Ollama 目标在于简化在 Docker 容器中部署大型语言模型的过程,使得非专业用户也能方便地管理和运行这些复杂的模型,无需复杂的配置和安装过程,只需几条命令即可启动和运行Ollama
  • 轻量级与可扩展:作为轻量级框架,Ollama 保持了较小的资源占用,同时具备良好的可扩展性,允许用户根据需要调整配置以适应不同规模的项目和硬件条件,即使在普通笔记本电脑上也能流畅运行。
  • API支持:提供了一个简洁的 API,使得开发者能够轻松创建、运行和管理大型语言模型实例,降低了与模型交互的技术门槛。
  • 预构建模型库:包含一系列预先训练好的大型语言模型,用户可以直接选用这些模型应用于自己的应用程序,无需从头训练或自行寻找模型源。

官方站点:https://ollama.com/

Github:https://github.com/ollama/ollama

下载地址:https://ollama.com/download,根据系统类型进行安装,这里演示的是window系统安装过程。

注意,在windows下安装ollama是不允许自定义位置的,会默认安装在系统盘,而后续使用的大模型可以选择自定义保存路径。

image-20240903071749775

安装过程,非常简单:

image-20240903072301064

安装完成以后,新开一个命令终端并输入命令,如果效果如下则表示安装成功:

image-20240903072513199

拉取并运行一个大模型:

 
  

这里的命令,全系统通用的。

命令 描述 ollama list 列出本地拉取的模型镜像列表 ollama pull 从远程仓库中拉取模型镜像文件 ollama run 运行模型,如果本地没有则先默认执行pull命令进行拉取 ollama ps 展示当前加载的模型、它们所占的内存大小以及使用的处理器类型(GPU 或 CPU) ollama serve 启动ollama的http网络服务 ollama rm 删除模型 ollama cp 复制模型 ollama push 推送模型到远程仓库,需要在ollama官网上面注册账号。 ollama create 从模型文件Modelfile创建自定义模型 help 帮助提示

ollama仓库地址:https://ollama.com/library

hugging face仓库地址:https://huggingface.co/models 【镜像】https://hf-mirror.com/models

魔塔社区:https://modelscope.cn/models

image-20240919164309924

魔塔下载大模型说明文档:https://www.modelscope.cn/docs/模型的下载

使用魔塔下载大模型文件,安装魔塔工具(python3.10^):

 
  

基于python脚本调用魔塔拉取模型文件,modelscope_download.py,代码:

 
  

执行效果如下:

image-20240919233450486

Modelfile

Ollama自定义大模型需要通过Modelfile定义和配置模型的行为和特性,在使用 Ollama 进行本地部署和运行大型语言模型时,Modelfile 扮演着至关重要的角色。

是使用 Ollama 创建和共享模型的方案。它包含了构建模型所需的所有指令和参数,使得模型的创建和部署变得简单而直接。

常用指令

Modelfile中不区分大小写,但是强烈要求一定大写!!

操作说明 描述 (必须) 定义要使用的基础模型,如果值是一个路径表示镜像文件在本地,如果是模型名称则默认到官方仓库中拉取。 指定将在模板中设置的系统消息. 设置 Ollama 如何运行模型的参数 要发送给模型的完整提示模板. 定义适用于模型的 适配器. 指定合法的许可证。 指定消息历史记录。
PARAMETER的有效参数和值
参数 描述 值类型 示例用法 mirostat 启用 Mirostat 采样来控制困惑度。(默认值:0,0 = 禁用,1 = Mirostat,2 = Mirostat 2.0) int mirostat 0 mirostat_eta 影响算法对生成文本反馈的响应速度。较低的学习率会导致调整速度较慢,而较高的学习率会使算法响应更快。(默认值:0.1) float mirostat_eta 0.1 mirostat_tau 控制输出的连贯性和多样性之间的平衡。值越低,文本越集中、越连贯。(默认值:5.0) float mirostat_tau 5.0 num_ctx 设置用于生成下一个标记的上下文窗口的大小。(默认值:2048) int num_ctx 4096 repeat_last_n 设置模型回溯多远以防止重复。(默认值:64,0 = 禁用,-1 = num_ctx) int repeat_last_n 64 repeat_penalty 设置对重复的惩罚力度。较高的值(例如 1.5)将对重复的惩罚力度更大,而较低的值(例如 0.9)将更宽松。(默认值:1.1) float repeat_penalty 1.1 temperature 模型的温度。增加温度将使模型的回答更具创意。(默认值:0.8) float temperature 0.7 seed 设置用于生成的随机数种子。将其设置为特定数字将使模型针对同一提示生成相同的文本。(默认值:0) int seed 42 stop 设置要使用的停止序列。遇到此模式时,LLM 将停止生成文本并返回。可以通过在模型文件中指定多个单独的参数来设置多个停止模式。 string stop “AI assistant:” tfs_z 尾部自由采样用于减少输出中可能性较小的标记的影响。较高的值(例如 2.0)将进一步减少影响,而值 1.0 则禁用此设置。(默认值:1) float tfs_z 1 num_predict 生成文本时要预测的最大标记数。(默认值:128,-1 = 无限生成,-2 = 填充上下文) int num_predict 42 top_k 降低产生无意义答案的概率。值越高(例如 100)答案就越多样化,值越低(例如 10)答案就越保守。(默认值:40) int top_k 40 top_p 与 top-k 配合使用。较高的值(例如 0.95)将产生更加多样化的文本,而较低的值(例如 0.5)将产生更加集中和保守的文本。(默认值:0.9) float top_p 0.9
TEMPLATE的模板变量
变量 描述 用于指定自定义行为的系统消息。 用户提示消息。 来自模型的响应。生成响应时,此变量后的文本将被省略。
MESSAGE的有效角色
角色 描述 system 为模型提供系统消息的另一种方法。 user 用户可能询问的示例消息。 assistant 模型应如何响应的示例消息。

创建模型描述文件Modelfile,编写内容如下:

 
  

文档:https://qwen.readthedocs.io/en/latest/run_locally/ollama.html#

通过运行以下命令来创建ollama模型

 
  

运行新建的ollama模型:

 
  

大语言模型(Large Language Model): 通常是具有大规模参数和计算能力的自然语言处理模型,例如 OpenAI 的 GPT-3 模型。这些模型可以通过大量的数据和参数进行训练,以生成人类类似的文本或回答自然语言的问题。大型语言模型在自然语言处理、文本生成和智能对话等领域有广泛应用。

按照输入数据类型的不同,大模型的分类:

  • 语言大模型(NLP):是指在自然语言处理(Natural Language Processing,NLP)领域中的一类大模型,通常用于处理文本数据和理解自然语言。这类大模型的主要特点是它们在大规模语料库上进行了训练,以学习自然语言的各种语法、语义和语境规则。例如:GPT 系列(OpenAI)、Bard(Google)、文心一言(百度)。
  • 视觉大模型(CV):是指在计算机视觉(Computer Vision,CV)领域中使用的大模型,通常用于图像处理和分析。这类模型通过在大规模图像数据上进行训练,可以实现各种视觉任务,如图像分类、目标检测、图像分割、姿态估计、人脸识别等。例如:VIT 系列(Google)、文心UFO、华为盘古 CV、INTERN(商汤)。
  • 多模态大模型: 是指能够处理多种不同类型数据的大模型,例如文本、图像、音频等多模态数据。这类模型结合了 NLP 和 CV 的能力,以实现对多模态信息的综合理解和分析,从而能够更全面地理解和处理复杂的数据。例如:DingoDB 多模向量数据库(九章云极 DataCanvas)、DALL-E(OpenAI)、悟空画画(华为)、midjourney。

按照应用领域的不同,大模型主要可以分为 L0、L1、L2 三个层级:

  • 通用大模型 L0:是指可以在多个领域和任务上通用的大模型。它们利用大算力、使用海量的开放数据与具有巨量参数的深度学习算法,在大规模无标注数据上进行训练,以寻找特征并发现规律,进而形成可“举一反三”的强大泛化能力,可在不进行微调或少量微调的情况下完成多场景任务,相当于 AI 完成了“通识教育”。
  • 行业大模型 L1:是指那些针对特定行业或领域的大模型。它们通常使用行业相关的数据进行预训练或微调,以提高在该领域的性能和准确度,相当于 AI 成为“行业专家”。
  • 垂直大模型 L2:是指那些针对特定任务或场景的大模型。它们通常使用任务相关的数据进行预训练或微调,以提高在该任务上的性能和效果。

开发以大语言模型为功能核心、通过大语言模型的强大理解能力和生成能力、结合特殊的数据或业务逻辑来提供独特功能的应用称为大模型开发。

开发大模型相关应用,其技术核心点虽然在大语言模型上,但一般通过调用 API 或开源模型来实现核心的理解与生成,通过 Prompt Enginnering 来实现大语言模型的控制,因此,大模型虽然是深度学习领域的集大成之作,大模型开发却更多是一个工程问题。

在大模型开发中,我们一般不会去大幅度改动模型,而是将大模型作为一个调用工具,通过 Prompt Engineering、数据工程、业务逻辑分解等手段来充分发挥大模型能力,适配应用任务,而不会将精力聚焦在优化模型本身上。

大模型开发与传统的AI 开发在整体思路上有着较大的不同:

  • 传统AI 开发:首先需要将复杂的业务逻辑依次拆解,对于每个子业务构造训练数据与验证数据,对于每个子业务训练优化模型,最后形成完整的模型链路来解决整个业务逻辑。

    img

  • 大模型开发:用 Prompt Engineering 来替代子模型的训练调优,通过 Prompt 链路组合来实现业务逻辑,用一个通用大模型 + 若干业务 Prompt 来解决任务,从而将传统的模型训练调优转变成了更简单、轻松、低成本的 Prompt 设计调优。

    img

目前大部分企业都是基于 LangChain 、qwen-Agent、lammaIndex框架进行大模型应用开发。LangChain 提供了 Chain、Tool 、RAG等架构的实现,可以基于 LangChain 进行个性化定制,实现从用户输入到数据库再到大模型最后输出的整体架构连接。

img

向量是多维数学空间中的一个坐标点,指具有大小和方向的量,它在直角坐标系里通常表现为一段带箭头的线段。

img

由于向量可以高度抽象地表示事物的特征和属性,世界上几乎所有类型的数据——视频、图像、声音、文本……统统都可以通过数据处理转换成向量数据。因而,在AI领域流传着一句话,万物皆可Embedding。

img

所谓的向量数据,通常指的是将实体(如文本、图像、音频等)转换为数值形式的高维向量。这些向量能够捕捉实体的关键特征,并在向量空间中进行各种计算和比较。向量数据在AI中的应用非常广泛,包括但不限于自然语言处理(NLP)、计算机视觉、语音识别、推荐系统等。通过向量化,AI系统能够更好地理解和处理复杂的数据类型,从而提供更加智能和个性化的服务。

将其他类型的信息转换为向量数据的过程就是向量化。

在传统AI领域中(机器学习和自然语言处理(NLP),(嵌入,向量化)是一种将类别数据,如单词、句子或者整个文档,转化为实数向量的技术,这些实数向量可以被计算机更好地理解和处理。嵌入背后的主要想法是,相似或相关的对象在嵌入空间中的距离应该很近

我喜欢吃苹果。 -> [1, 0, 0, 5, 2, 1]

我喜欢苹果手机。-> [1, 2, 5, 0, 3, 2.8]

我喜欢吃香蕉。 -> [1, 0, 0, 5, 2, 3]

举个例子,可以使用词嵌入(word embeddings)来表示文本数据,在词嵌入中,每个单词被转换为一个向量,这个向量捕获了这个单词的语义信息。例如,"king" 和 "queen" 这两个单词在嵌入空间中的位置将会非常接近,因为它们的词性与含义相似;而 "apple" 和 "orange" 也会很接近,因为它们都是水果;而 "king" 和 "apple" 这两个单词在嵌入空间中的距离就会比较远,因为它们的含义不同。

img

向量数据库(Vector Database)也叫矢量数据库,是专为存储、处理、分析「向量数据」而生的,能够基于目标向量快速进行相似度搜索,并返回最相近的数据。总而言之,就是用来存储和处理向量数据的数据库。

随着大型AI语言模型的崛起,向量数据库成为了解决模型“幻觉”问题的关键。它号称是LLM记忆的海马体,是大模型的记忆和存储核心,通过注入实时&私域数据的形式,可以使得LLM能够在更多通用场景中落地应用,缓解模型”幻觉“的问题。

常见的向量数据库:MilvusChromaWeaviateFaiss、Elasticsearch、PGVector、opensearch、腾讯VectorDB,ClickHouse

VectorStore 介绍 AnalyticDB 阿里云自主研发的云原生数据仓库 Annoy 一个带有Python bindings的C ++库,用于搜索空间中给定查询点的近邻点。 AtlasDB 一个非结构化数据集平台 Chroma 一个开源嵌入式数据库 Deep Lake 多模向量存储,可以存储嵌入及其元数据,包括文本、jsons、图像、音频、视频等。 DocArrayHnswSearch 一个轻量级的文档索引实现 DocArrayInMemorySearch 一个由Docarray提供的文档索引,将文档存储在内存中 ElasticSearch ElasticSearch FAISS Facebook AI相似性搜索服务 LanceDB 一个用于向量搜索的开源数据库,它采用持久性存储 Milvus 用于存储、索引和管理由深度神经网络和其他机器学习(ML)模型产生的大量嵌入向量的数据库 MyScale 一个基于云的数据库,为人工智能应用和解决方案而优化 OpenSearch 一个可扩展的、灵活的、可延伸的开源软件套件,用于搜索、分析和可观察性应用 PGVector 一个用于Postgres的开源向量相似性搜索服务 Pinecone 一个具有广泛功能的向量数据库 Qdrant 一个向量相似性搜索引擎 Redis 基于redis的检索器 SupabaseVectorStore 一个开源的Firebase 替代品,提供一系列后端功能 Tair 一个Key/Value结构数据的解决方案 Weaviate 一个开源的向量搜索引擎 Zilliz 数据处理和分析平台

向量数据库的特点:

img

LangChain是一个强大的大模型开发框架,旨在帮助开发人员使用语言模型构建端到端的应用程序。其作者是Harrison Chase(哈里森·蔡斯),最初是于 2022 年 10 月开源的一个项目,在 GitHub 上获得大量关注之后迅速转变为一家人工智能初创公司。

LangChain提供了一套工具、组件和接口,可简化创建由大型语言模型 (LLM) 和聊天模型提供支持的应用程序的过程。LangChain 可以轻松管理与语言模型的交互,将多个组件链接在一起,并集成额外的资源,例如 API 和数据库。目前最新版本:v0.3版本。

Github:https://github.com/langchain-ai/langchain

image-20240920113410177

LLM大模型与AI应用的粘合剂

LangChain本身并不开发LLMs,它的核心理念是为各种LLMs提供通用的接口,降低开发者的学习成本,方便开发者快速地开发复杂的LLMs应用

官方的定义:LangChain是一个基于大语言模型开发应用程序的框架。它可以实现以下应用程序:

  • 数据感知:将语言模型连接到其他数据源
  • 自主性:允许语言模型与其环境进行交互

LangChain的主要价值在于:

  • 组件化:为使用语言模型提供抽象层,以及每个抽象层的一组实现。组件是模块化且易于使用的,无论您是否使用LangChain框架的其余部分。
  • 现成的链:结构化的组件集合,用于完成特定的高级任务。

应用场景

LangChain为构建基于大型语言模型的应用提供了一个强大的框架,将逐步的运用到各个领域中,如,智能客服、文本生成、知识图谱构建等。随着更多的工具和资源与LangChain进行集成,大语言模型对人的生产力将会有更大的提升。

常用的业务场景:

智能客服:结合聊天模型、自主智能代理和问答功能,开发智能客服系统,帮助用户解决问题,提高客户满意度。

个性化推荐:利用智能代理与文本嵌入模型,分析用户的兴趣和行为,为用户提供个性化的内容推荐。

知识图谱构建:通过结合问答、文本摘要和实体抽取等功能,自动从文档中提取知识,构建知识图谱。

自动文摘和关键信息提取:利用LangChain的文本摘要和抽取功能,从大量文本中提取关键信息,生成简洁易懂的摘要。

代码审查助手:通过代码理解和智能代理功能,分析代码质量,为开发者提供自动化代码审查建议。

搜索引擎优化:结合文本嵌入模型和智能代理,分析网页内容与用户查询的相关性,提高搜索引擎排名。

数据分析与可视化:通过与API交互和查询表格数据功能,自动分析数据,生成可视化报告,帮助用户了解数据中的洞察信息。

智能编程助手:结合代码理解和智能代理功能,根据用户输入的需求自动生成代码片段,提高开发者的工作效率。

在线教育平台:利用问答和聊天模型功能,为学生提供实时的学术支持,帮助他们解决学习中遇到的问题。

自动化测试:结合智能代理和代理模拟功能,开发自动化测试场景,提高软件测试的效率和覆盖率。

要使用 LangChain,开发人员首先要导入必要的组件和工具,例如 LLMs, chat models, agents, chains, 内存功能。这些组件组合起来创建一个可以理解、处理和响应用户输入的应用程序。

  • Model I/O:管理语言模型(Models),及其输入(Prompts)和格式化输出(Output Parsers)。
  • data connection:与特定任务的数据接口,管理主要用于建设私域知识(库)的向量数据存储(Vector Stores)、内容数据获取(Document Loaders)和转化(Transformers),以及向量数据查询(Retrievers)
  • memory:在一个链的运行之间保持应用状态,用于存储和获取 对话历史记录 的功能模块
  • chains:构建调用序列,用于串联 Memory ↔ Model I/O ↔ Data Connection,以实现 串行化 的连续对话、推测流程
  • agents:给定高级指令,让链选择使用哪些工具,基于 Chains 进一步串联工具(Tools),从而将大语言模型的能力和本地、云服务能力结合
  • callbacks:记录并流式传输任何链的中间步骤,可连接到 LLM 申请的各个阶段,便于进行日志记录、追踪等数据导流
 
  

图片

Models

说到模型,在LangChain中 model 是一种抽象,表示框架中使用的不同类型的模型。单纯的大模型只能生成文本内容。

LangChain的一个核心价值就是它提供了标准的模型接口,然后我们可以自由的切换不同的模型,当前主要有两种类型的模型,但是考虑到使用场景,对我们一般用户来说就是使用一种模型即文本生成模型

LangChain 中的模型有语言模型、文本嵌入模型等多种分类。

语言模型(Language Models)

语言模型(Language Models),用于文本生成,文字作为输入,输出也是文字。

  1. 普通LLM(llms):接收文本字符串作为输入,并返回文本字符串作为输出。
  2. 聊天模型(Chat Model):将聊天消息列表作为输入,并返回一个聊天消息对象。

    聊天模型是语言模型的一个变体,聊天模型以语言模型为基础,其内部使用语言模型,不再以文本字符串为输入和输出,而是将聊天信息列表为输入和输出,他们提供更加结构化的 API。通过聊天模型可以传递一个或多个消息。LangChain 目前支持四类消息类型:分别是 AIMessage(AI助手回复消息)、HumanMessage(用户发送消息)、SystemMessage(系统角色信息) 。

 
  

案例1,代码:

 
  

代码效果:

image-20241020180023625

案例2,代码:

 
  

案例3,langchain基于LLMs语言模型调用Tongyi(通义千问)。

通义API-KEY:https://bailian.console.aliyun.com/?apiKey=1

安装灵积模块:

 
  

代码:

 
  

image-20241027145835645

注意:普通llms的写法在langchain==0.3版本以后openAI不再支持,代码:

 
  

案例4,基于langchain调用Ollama本地运行的大模型服务。

 
  

代码:

 
  

如果不希望每次在脚本中都设置OPENAI_API_KEY和代理,可以把它设置到环境变量中:

image-20241027152133177

文本嵌入模型(Text Embedding Models)

把文字转换为浮点数形式的描述,表示这些模型接收文本作为输入并返回一组浮点数(向量)。这些浮点数通常用于表示文本的语义信息,以便进行文本相似性计算、聚类分析等任务。文本嵌入模型可以帮助开发者在文本之间建立更丰富的联系,提高基于大型语言模型的应用的性能。

LangChain中的基础Embeddings类提供了两种方法:一种用于嵌入文档,另一种用于嵌入查询。嵌入文档接受多个文本作为输入,而嵌入查询则接受单个文本。之所以将这两种方法分开,是因为一些嵌入提供商对文档(要搜索的内容)与查询(搜索查询本身)使用不同的嵌入方法。

langchain集成支持的模型列表:https://python.langchain.com/docs/integrations/text_embedding/

初始化:

 
  

嵌入文本列表,代码:

 
  

查询检索单个文本嵌入,代码:

 
  
langchain调用Milvus

langchain作为大模型开发框架,内部集成了市面上较多常用的向量数据库。

langchain支持的向量库列表:https://python.langchain.com/docs/integrations/vectorstores/

安装langchain的Milvus数据库模块:

 
  

接下来,我们就需要使用langchain调用我们本地安装的向量库,所以需要确保自己的机子中已经正常运行了Milvus。代码:

 
  

Prompt

prompt(提示词)是我们与模型交互的方式,或者是模型的输入,通过提示词可以让模型返回我们期望的内容,比如让模型按照一定的格式返回数据给我们。LangChain提供了一些工具,可以方便我们更容易的构建出我们想要的提示词,主要工具如下:

Prompt**实践

  1. 明确目标:“请帮助我撰写一篇关于气候变化影响的文章,重点讨论其对农业和生态系统的影响。”
  2. 提供上下文:“在过去的十年中,全球气温上升了约1.2摄氏度。请解释这一变化对极地冰盖融化的影响。”
  3. 使用具体的指示:“列出五种可以有效减少碳足迹的方法,并简要说明每种方法的作用。”
  4. 提供可参考的示例:“请根据以下例子撰写一个相似的故事:‘小猫咪在阳光下懒洋洋地睡觉,偶尔伸个懒腰,似乎在享受这个美好的午后。’”
  5. 使用分步提示:“首先,请定义什么是人工智能;然后,描述其在医疗领域的应用;最后,讨论可能面临的伦理问题。”
  6. 控制输出长度:“请简要总结人工智能的历史,控制在100字以内。”
  7. 使用占位符和模板:“请用以下模板生成一段介绍:‘今天我想介绍{主题}。首先,我会讲述{相关信息},然后讨论{重要性}。’”
  8. 反复试验和调整:“我正在撰写一篇关于社交媒体影响的文章。请给我一些不同角度的观点,帮我尝试不同的切入点。”
  9. 指定输出格式:“请以表格的形式列出2023年和2024年的主要科技趋势,包括趋势名称、描述和潜在影响。”
  10. 使用多轮对话:“我想讨论气候变化。首先,你能告诉我气候变化的主要原因吗?然后我们可以讨论其影响。”
  11. 使用反思和迭代:“根据我之前的请求,你给出的总结让我觉得有些太简略。请再细化一下,添加更多背景信息和细节。”
PromptTemplates

PromptTemplates(语言模型提示词模板),提示模板可以让我们重复的生成提示,复用我们的提示。它包含一个文本字符串(“模板”),从用户那里获取一组参数并生成提示,包含:

  1. 对语言模型的说明,应该扮演什么角色
  2. 一组少量示例,以帮助LLM生成更好的响应,
  3. 具体的问题

示例1,低版本写法,代码:

 
  

示例2,新版本写法,代码:

 
  

示例3,在线大模型调用模板提示词,代码:

 
  
 
  

示例4,Ollama部署的本地大模型调用模板提示词,代码:

 
  

以下提示词如果使用在线大模型,成本很高,钱包估计要尖叫,但是使用本地大模型就无所谓了。代码:

 
  
ChatPrompt Templates

ChatPrompt Templates(聊天模型提示词模板), ChatModels接受聊天消息列表作为输入。列表一般是不同的角色提示,并且每个列表消息一般都会有一个角色。

示例1,代码:

 
  

示例2,低版本写法,代码:

 
  
Example Selectors

在提示工程(Prompt Engineering)中,选择合适的示例对于生成高质量的输出至关重要。LangChain框架提供了一种强大的机制——Example Selectors(示例选择器),允许用户为模型提供输入和输出示例,Example Selectors可以根据用户的需求,动态地向模型发送输入输出示例。在Langchain中一共有如下几种方式,供开发者使用示例选择器:

  1. 自定义示例选择器,继承于BaseExampleSelector,并实现了BaseExampleSelector的必要抽象方法。
  2. 内置示例选择器:
    • LengthBaseExampleSelector,基于输入内容长度匹配示例的选择器,输入内容多的时候示例会少一点,输入内容少的时候,示例会多一些。
    • SemanticSimilarityExampleSelector,根据相似度进行匹配示例的选择器,选择一个和输入最相似的示例。

示例1,基于自定义的示例选择器,基本代码:

 
  

结合少样本示例动态提示模板(FewShotPromptTemplate)使用,补充代码:

 
  

最后结合LLM,完整代码:

 
  

实例2,基于输入内容长度匹配示例选择器,基本代码:

 
  

结合少样本示例动态提示模板(FewShotPromptTemplate)使用,补充代码:

 
  

最后结合LLM,完整代码:

 
  

示例3,基于输入内容的余弦相似度匹配示例的选择器,代码:

 
  

结合LLM,完整代码:

 
  

Output Parsers

Output Parsers(输出解析器),是langchain中提供给我们对模型响应内容进行格式化输出的。LLM的输出为文本,但在程序中除了显示文本,如果希望获得更多不同的结构化数据时,就可以使用langchain提供的输出解析器(Output Parsers)来完成了。输出解析器(Output Parsers)实际上就是结构化语言模型提供的响应处理工具类,其提供了如下两个方法给开发者使用,也是这些响应类必须实现的两个方法:

get_format_instructions() -> str :返回一个包含语言模型如何格式化输出的指令字符串。

invoke()-> Any:接受一个结构化言模型的响应对象,并将其解析为指定

Str输出解析器

代码:

 
  
列表输出解析器
 
  
JSON输出解析器

代码:

 
  
stream输出解析器

代码:

 
  
自定义输出解析器

这里我们实现一个markdown格式输出解析器。

 
  

代码:

 
  

Cache

我们还基于langchain提供的输出缓存,让LLM在遇到同一prompt时,直接调用缓存中的结果,以此加速。

 
  

langsmith

LangSmith是一个用于构建生产级LLM应用程序的在线监控平台。它允许开发者密切监控和评估自己的大模型应用程序,以便开发者可以快速了解开发过程中的LLM调用细节。LangSmith是独立于LangChain框架的,并不一定需要使用 LangChain框架。

文档:https://docs.smith.langchain.com/

代码:

 
  

image-20241103153126417

链(Chain),也叫链式语言表达式(LCEL),是 LangChain 的核心组件。如果把用 LangChain 构建 AI 大模型应用的过程比作“积木模型”的搭建与拼接,那么 Chain 就是是该模型搭建过程中的骨骼部分,通过它将各模块快速组合在一起就可以快速搭建一个应用。langchain提供的chains使用声明式方法将多个操作链接在一起,形成一个完整的处理流程。常见链的类型有3种:LLMChain,SequentialChain、LLMRouteChain。

文档:https://python.langchain.com/docs/concepts/lcel/

LLMChain

通过 LLMChain(大模型链) 可以直接将数据、Prompt、以及想要应用的大模型串到一起连贯调用。

旧版本,代码:

 
  

新版本,代码:

 
  

Sequential Chains

不同于基本的 LLMChain,Sequential Chain(序列链)是由一系列的链组合而成的,许将多个链按顺序链接在一起,前一个链的输出作为下一个链的输入。序列链有两种类型,一种是单个输入输出,另一个则是多个输入输出。代码:

 
  

LLMRouteChain

路由链,主要是基于分支判断实现chains的分发调用,代码:

 
  

langchain提供的文档加载器(Document loaders)主要基于 包, 是一个python包,可以把各种类型的文件转换成文本。LangChain支持的文档加载器包括了csv(CSVLoader),html(UnstructuredHTMLLoader),json(JSONLoader),markdown(UnstructuredMarkdownLoader)以及pdf(因为pdf的格式比较复杂,提供了PyPDFLoader、MathpixPDFLoader、UnstructuredPDFLoader,PyMuPDF等多种形式的PDF加载引擎)几种常用格式的内容解析,但是在实际的项目中,数据来源一般比较多样,格式也比较复杂

TextLoader

txt文档加载器,代码:

 
  

其他检索类型:

 
  

使用内存型向量库Chroma来完成向量存储,

 
  

代码:

 
  

采用HuggingFace/魔塔平台上下载的Embeddings,确保自己的开发机子上已经安装好了适配系统的pytorch以后,还需要安装以下依赖:

 
  

需要到huggingface官网上进行注册一个账号,并登陆获取huggingface的访问Token,官网:https://huggingface.co/.

image-20241117104120962

image-20241117104822981

有部分模型实际上是需要token认证以后才能拉取。

 
  

代码:

 
  

集合本地大模型实现基本检索增强(RAG),代码:

 
  

PDFLoader

PyPDFLoader
 
  

代码:

 
  

采用递归文本分割器,代码:

 
  

惰性加载大型文档,可以使用惰性加载来逐页处理文档,代码:

 
  

加载多份PDF文档,代码:

 
  
PyMuPDFLoader

PyMuPDFLoader这个加载比langchain默认内置pyPDFLoader加载速度更快。

 
  

代码:

 
  
OnlinePDFLoader

加载线上的pdf文档,安装:

 
  

代码:

 
  

MarkdownLoader

 
  

DirectoryLoader

按目录加载文档,支持多个格式文档的模糊匹配

 
  

代码:

 
  

WebBaseLoader

加载html网页,代码:

 
  
文档加载器 介绍 Airbyte JSON 从Airbyte加载JSON,Airbyte是一个数据集成平台 Apify Dataset Apify Dataset是一个可扩展的纯应用存储,具有顺序访问功能,用于存储结构化的网络抓取结果 Arxiv arXiv是一个开放性的档案库,收录了物理学、数学、计算机科学、定量生物学、定量金融、统计学、电气工程和系统科学以及经济学等领域的200万篇学术文章。 AWS S3 Directory AWS S3是Amazon的对象存储服务,加载目录 AWS S3 File 加载文件 AZLyrics AZLyrics是一个大型的、合法的、每天都在增长的歌词集。https://www.azlyrics.com/ Azure Blob Storage Container 微软的对象存储服务 Azure Blob Storage File 加载文件 Bilibili 加载B站视频 Blackboard 一个虚拟学习环境和学习管理系统 Blockchain 基于alchemy 加载区块链数据 ChatGPT Data chatGPT消息加载器 College Confidential 提供全世界的大学信息 Confluence 一个专业的企业知识管理与协同平台 CoNLL-U CoNLL-U是一种文件格式 Copy Paste 普通文本 CSV CSV文件 Diffbot 一个将网站转化为结构化数据的平台 Discord 最初为游戏玩家提供服务的游戏社区论坛,先发展为多领域的社区论坛。 DuckDB 一个分析数据库系统 Email 邮件,支持.eml和.msg格式 EPub epub电子书 EverNote EverNote文档 Facebook Chat Facebook消息 Figma 一个web设计工具 File Directory 加载目录下所有文件 Git GIt GitBook GItBook Google BigQuery 谷歌云服务 Google Cloud Storage Directory 谷歌云服务 Google Cloud Storage File 谷歌云服务 Google Drive 谷歌云服务 Gutenberg 一个在线电子书平台 Hacker News 一个计算机信息网站 HTML 网页 HuggingFace dataset HuggingFace数据集 iFixit 一个维修为主题的社区 Images 加载图片 Image captions 根据图片生成图片说明 IMSDb 电影数据库 JSON Files 加载JSON文件 Jupyter Notebook 加载notebook文件 Markdown 加载markdown文件 MediaWikiDump wiki xml数据 Microsoft OneDrive 加载微软OneDrive文档 Microsoft PowerPoint 加载ppt文件 Microsoft Word 加载word文件 Modern Treasury 一家支付运营软件提供商 Notion DB 加载Notion文件 Obsidian 一个笔记软件 Unstructured ODT Loader 加载OpenOffice文件 Pandas DataFrame Pandas表格型数据结构 PDF 加载pdf文件 ReadTheDocs Documentation 一个在线文档平台 Reddit 一个社交新闻网站 Roam 一个个人笔记产品 Sitemap 网站地图 Slack 一个聊天群组产品 Spreedly 一个支付平台 Stripe 一个支付平台 Subtitle 一个字幕制作平台 Telegram 聊天软件 TOML 一种配置文件 Twitter Unstructured File Unstructured文件 URL 通过url加载内容 WebBaseLoader 基础的web加载器 WhatsApp Chat WhatsApp聊天 Wikipedia 加载Wikipedia内容 YouTube transcripts 加载YouTube视频
文本分割器 LatexTextSplitter 沿着Latex标题、标题、枚举等分割文本。 MarkdownTextSplitter 沿着Markdown的标题、代码块或水平规则来分割文本。 NLTKTextSplitter 使用NLTK的分割器 PythonCodeTextSplitter 沿着Python类和方法的定义分割文本。 RecursiveCharacterTextSplitter 用于通用文本的分割器。它以一个字符列表为参数,尽可能地把所有的段落(然后是句子,然后是单词)放在一起 SpacyTextSplitter 使用Spacy的分割器 TokenTextSplitter 根据openAI的token数进行分割

LLM 本身是没有记忆的,每一次LLM的API调用都是一个全新的会话。但在某些应用程序中,如:聊天机器人,让LLM记住以前的历史交互是非常重要,无论是在短期的还是长期的。langchain中的“Memory”即对话历史(message history)就是为了实现这一点。

注意:LangChain中大多数与memory相关的功能都标记为测试版,原因如下:

  1. 大部分功能并没有完善就已经产生了新的替代技术,导致部分功能一直在不断升级维护。
  2. 频繁的版本升级,导致产生了大量的历史版本,导致每个版本的模块代码提供的方式和使用规则都不一样。

代码:

 
  

如果我们想要让模型有记忆(Memory),利用的实际上是提示词工程,前面的代码例子中就可以看到提示词中告知LLM充当江小白,所以在后续的多次对话中,尽管LLM没有进行上下文管理记录对话历史,但是LLM在回答时始终会告诉用户,它是江小白。因此我们如果要实现会话历史管理,可以借鉴这种方式。

image-20241120041915001

对话消息历史

接下来我们采用提示词的占位符MessagePlaceholder去作为用户输入的占位符,并在使用chain的invoke方法进行提问前,手动把历史信息放在一个history的列表里面,然后去获取最后结果。代码:

 
  

上面的方式就是对LLM与用户的对话历史信息进行手动记录管理的流程。如果要实现多人会话消息历史管理,我们只需要根据给不同用户设置一个唯一的session_id即可,代码:

 
  

ChatMessageHistory-对话消息历史管理

实际上langchain已经提供了一个ChatMessageHistory(对话消息历史)对象给开发者在内存中管理对话消息历史数据。

文档:https://python.langchain.com/api_reference/core/chat_history.html

就是的别名。

代码:

 
  

ChatMessageHistory的常用方法:

方法名 描述 add_message(self, message: BaseMessage) 添加一条消息到对话历史对象中 add_messages(self, messages: Sequence[BaseMessage]) 批量添加消息到对话历史对象中 add_user_message(message: Union[HumanMessage, str]) 添加用户类型消息到对话历史对象中 add_ai_message(self, message: Union[AIMessage, str]) 添加AI类型消息到对话历史对象中 clear(self) 清除消息历史

有了对话消息历史管理对象,不仅可以管理和存储单个用户和LLM的历史对话信息以此来维持会话状态,还可以实现管理多用户与LLM的独立历史对话信息。代码:

 
  

实际上langchain中提供的ChatMessageHistory工具类已经内置了类似get_session_history的方法,所以我们根本不需要自己声明这个方法,直接通过ChatMessageHistory实例化时指定session_id即可,代码:

 
  

RunnableWithMessageHistory-可运行的消息历史记录对象

上面虽然使用了ChatMessageHistory保存对话历史数据,但是与Chains/Agents的操作是独立的,并且每次产生新的对话消息都要手动记录,所以为了方便使用,langchain还提供了RunnableWithMessageHistory可以自动为Chains/Agents添加对话历史记录。

文档:https://python.langchain.com/api_reference/core/runnables/langchain_core.runnables.history.RunnableWithMessageHistory.html

代码:

 
  

langchain中除了可以使用ChatMessageHistory在内存中保存对话历史数据,还提供了如下工具类方便开发者使用各种设备保存对话历史数据。

文档地址:https://python.langchain.com/api_reference/community/chat_message_histories.html

 
  
工具类 描述 InMemoryChatMessageHistory 内存存储对话历史 FileChatMessageHistory 文件存储对话历史 MongoDBChatMessageHistory MongoDB数据库存储对话历史 PostgresChatMessageHistory Postgresql数据库存储对话历史 RedisChatMessageHistory redis数据库存储对话历史 ElasticsearchChatMessageHistory Elasticsearch数据库存储对话历史 KafkaChatMessageHistory Kafka消息队列存储对话历史 SQLChatMessageHistory SQL数据库存储对话历史

以Redis为例,代码:

 
  

RunnableWithMessageHistory在使用过程中,除了支持自动管理多人对话历史消息以外,还支持同一人多次不同会话历史的独立保存。代码:

 
  
Runnable-可运行对象

在前面的学习中,我们曾经学习过LangChain的核心是Chains(链),即使用声明式方法将多个操作链接在一起进行调用。之前所说的操作实际上就是Runnable对象包含的操作。

Runnable,表示可运行对象,可以理解为“链式可运行对象”或“链对象”,也就是langchain中所谓的“Chain”。

多个Chain(链)使用组合操作,就是一个链条。

LangChain为了让其内部提供的所有组件类都能以LCEL的方式快速简洁的调用,计划将所有组件类都实现Runnable接口。比如我们常用的 、 、 等。

官方文档:https://python.langchain.com/docs/concepts/lcel/

LCEL语法中竖杠写法的简单实现原理,代码:

注意:

这里模拟的仅仅是LCEL语法中使用竖杠的伪代码,实际核心代码中Runnable是一个抽象接口类,在实际的LCEL语法使用中,我们使用的都是Runnable的子类,例如:RunnableSequence(可运行序列容器链)和RunnableParallel(可运行的并行容器链)才是最常被调用的链对象。

 
  

在 langchain 中,Runnable 接口的实现可以用于多种业务场景,包括但不限于:

  • 文本预处理:如去除停用词、文本规范化等。
  • 模型推理:调用预训练的语言模型进行推理。
  • 结果后处理:对模型的输出结果进行进一步处理,如抽取信息或格式转换。
  • 管道集成:将多个 Runnable 组件(例如:prompt、llm、StrOutPuter等等)串联成一个处理管道,实现复杂的处理逻辑。
常用的Runnable接口实现对象的定义和应用场景
RunnableLambda

RunnableLambda可以将Python 可调用对象(例如:回调函数)转换为 Runnable对象,这种转换使得任何函数都可以被看作 LCEL 链的一部分,有了它,我们就可以把自己需要的功能通过自定义函数 + RunnableLambda的方式包装一下成 一个Runnable对象集成到 LCEL 链中,完成一些额外的业务操作流程,但是注意这种类型的Runnable无法处理流式数据。代码:

 
  
RunnableGenerator[了解]

RunnableGenerator的作用与上面的RunnableLambda类似,RunnableGenerator将Python中的生成器格式转换成Runnable可运行对象,这种方式转换得到的Runnable对象可以支持处理流式数据。代码:

 
  
RunnableParallel

RunnableParallel用于并行执行多个Runnable,使用RunnableParallel可以实现部分Runnable或所有Runnable并发执行的业务流程,提高执行效率,也会额外消耗系统性能。

 
  
RunnablePassthrough

RunnablePassthrough 主要用在链条中传递数据,可用于格式化上一个子链的输出结果,从而匹配下一个输入子链的需要的格式,一般写用在链的第一个位置,用于接收用户的输入。如果处在中间位置,则用于接收上一步子链的输出,通常与RunnableParallel配合使用。代码:

 
  
RunnableBranch

RunnableBranch主要用于多分支子链的场景,为链的调用提供了路由功能,有点类似于之前的LLMRouteChain(路由链)。使用RunnableBranch可以创建多个子链,然后根据条件判断选择执行某一个子链。代码:

 
  

旧版本Momery工具类[了解]

以下内容已经在langchain0.2版本以后声明废弃了,但是市场上任然有基于langchain0.1版本开发的项目,所以大家可以了解即可。

langchain提供的Memory组件本质上就是将对话历史存到内存或第三方设备中,然后每次向LLM提问前先在提示词中带上了所有的上下文对话,从而让 LLM 调用的时候可以得知上下文信息,从而回答新的问题。但这种方法会随着你的对话次数增加,导致历史对话信息占据提示词的内容长度越来越长,模型预测的时间越来越慢,如果是使用了线上LLM大模型,Token会不断增加,价格自然越来越贵,最终超出Token 限制。而 LangChain 在这方面提供了几种不同的 Memory 组件类来以不同方式存储历史内容,这些类本质上都是对ChatMessageHistory的高度封装。

组件类 特点 适用场景 ConversationBufferMemory 无限制 保存全部的上下文历史对话信息 ConversationBufferWindowMemory 频率高,句式短小,明确次数 能确定对话的轮次 ConversationTokenBufferMemory 限制Token的消费 限制Token的消费 ConversationSummaryBufferMemory 摘要 节省token的同时,尽量实现需求
ConversationBufferMemory-简单实现对话

ConversationBufferMemory 用于实现基本的对话功能,没有什么使用上的限制,而且可以轻松获取到历史对话的上下文。通过ConversationBufferMemory ,直接将存储的所有内容给LLM,因此LLM能够理解之前的对话内容,但是也因为大量信息意味着新输入提示词中包含更多的Token,导致响应时间变慢和成本增加。此外,当达到LLM的Token上限时,太长的对话无法被记住。代码:

 
  
ConversationEntityMemory-实体记忆

ConversationEntityMemory是实体记忆,它可以跟踪对话中提到的实体,在对话中记住关于特定实体的给定事实。它提取关于实体的信息(使用LLM),并随着时间的推移建立对该实体的知识(使用LLM)。使用它来存储和查询对话中引用的各种信息,比如人物、地点、事件等,代码:

 
  
ConversationKGMemory-知识图谱记忆

ConversationKGMemory是知识图谱对话记忆,用于在对话过程中存储和检索知识图谱(Knowledge Graph)数据。这种记忆类型使用知识图谱来重现记忆。

 
  

在历史对话中设置出现某些信息,然后使用知识图谱记忆构建这些信息成一个完整全面的知识图谱,代码:

 
  
ConversationBufferWindowMemory-缓冲窗口记忆

ConversationBufferWindowMemory是一种缓冲窗口记忆,它只保存最新最近的几次人类和AI的互动。它基于之前的缓冲记忆思想,增加了一个窗口值k。这意味着只保留一定数量的过去互动,然后“忘记”之前的互动。缓冲窗口记忆不适合记住遥远的互动,但它在限制使用的Token数量方面表现优异。如果只需记住最近的互动,缓冲窗口记忆是一个不错的选择。代码:

 
  
ConversationSummaryMemory-摘要总结记忆

ConversationSummaryMemory这种类型的记忆随着时间的推移创建对话的摘要。对话摘要记忆随着对话的发生而总结对话,并在记忆中存储当前的摘要。

ConversationSummaryMemory这种记忆对于较长的对话最有用,可以避免过度使用Token,因为将过去的信息历史以原文形式保留在提示中会占用太多的Token。ConversationSummaryMemory可以减少长对话中使用的Token数量,记录更多轮的对话信息,易于理解。 对于较短的对话可能会增加Token使用量。同时,对话历史的记忆完全依赖于中间摘要LLM的能力,需要为摘要LLM分配Token,增加成本且未限制对话长度。

代码:

 
  
ConversationSummaryBufferMemory-摘要缓冲混合记忆

ConversationSummaryBufferMemory对话摘要缓冲记忆是一种混合记忆模型,结合了ConversationSummaryMemory和ConversationBufferWindowMemory的特点。它旨在对对话进行摘要总结,同时保留最近互动中的原始内容,但不是简单地清除旧的交互,而是将它们编译成摘要并同时使用。它使用标记长度而不是交互数量来确定何时清除交互。但是ConversationSummaryBufferMemory的Token分词实现依赖于GPT-2模型,所以需要提前安装transformers。使用参数,让它在对话长度在200字内时记忆原始内容,在超出长度时对内容进行总结以节省Token数量。代码:

 
  
ConversationTokenBufferMemory-令牌缓冲记忆

ConversationTokenBufferMemory 在内存中保持最近交互的缓冲区,并使用标记长度而不是交互数量来确定何时清除交互。

代码:

 
  
VectorStoreRetrieverMemory-向量存储库记忆

VectorStoreRetrieverMemory 将记忆存储在向量存储中,并在每次调用时查询前 K 个最匹配的文档。

代码:

 
  

代理(Agent)是使用LLM作为思考工具,决定当前要做什么。我们会给代理一系列的工具,代理根据我们的输入判断用哪些工具可以完成这个目标,然后不断的运行工具,来完成目标。代理(Agent)可以看做是增强版的Chain,不仅绑定模板、LLM,还可以给代理添加一些外部工具。

代理(Agent)还是构建智能体的基础,它负责根据用户输入和应用场景,在一系列可用工具中选择合适的工具进行操作。Agent可以根据任务的复杂性,采用不同的策略来决定如何执行操作。

langchain中主要提供了有两种类型的Agent:

  • 动作代理(Action Agents):这种代理一次执行一个动作,然后根据结果决定下一步的操作。
  • 计划-执行代理(Plan-and-Execute Agents):这种代理首先决定一系列要执行的操作,然后根据上面判断的列表逐个执行这些操作。

对于简单的任务,动作代理(Action Agents)更为常见且易于实现。对于更复杂或长期运行的任务,计划-执行代理的初始规划步骤有助于维持长期目标并保持关注。但这会以更多调用和较高延迟为代价。这两种代理并非互斥,可以让动作代理负责执行计划-执行代理的计划。

LangChain 中内置了一系列常用的 Agent工具,这些工具提供的Agent都属于Action Agent

Agent内部涉及的核心概念如下:

  • 代理(Agent):这是应用程序主要逻辑。代理暴露一个接口,接受用户输入和代理已执行的操作列表,并返回AgentAction或AgentFinish。
  • 工具(Tools):这是代理可以采取的动作。比如发起HTTP请求,发邮件,执行命令。
  • 工具包(Toolkits):这些是为特定用例设计的一组工具。例如,为了让代理以**方式与SQL数据库交互,它可能需要一个执行查询的工具和另一个查看表格的工具。可以看做是工具的集合。
  • 代理执行器(Agent Executor):将代理与一系列工具包装在一起。它负责迭代运行代理,直到满足停止条件。

在LangChain框架中,智能代理(Agent)通常按照观察(Observation)- 思考(Thought)- 行动(Action)的模式来处理任务,这个模式叫ReAct思考框架。Agent的执行流程:

图片

在LangChain中,ReAct框架的实现流程如下:

  • 任务:Agent的起点是一个任务,如一个用户查询、一个目标或一个需要解决的特定问题。
  • 大模型:任务被输入大模型中。大模型使用训练好的模型进行推理。
  • 工具:大模型可能会决定使用一系列的工具来辅助完成任务。
  • 行动:Agent根据大模型的推理结果采取行动。
  • 环境:行动会影响环境,而环境将以某种形式响应这些行动。
  • 结果:将行动导致的结果反馈给Agent。

快速使用langchain提供的维基百科工具实现Agent智能体,代码:

 
  

内置Agent工具

常用Agent内置工具包:

https://python.langchain.com/docs/how_to/#tools

https://python.langchain.com/docs/integrations/tools/

获取目前langchain内置的所有agent工具包,代码:

 
  

搜索工具的基本使用,代码:

 
  

搜索工具的账号注册:https://serpapi.com/search-api

谷歌搜索的站好注册:https://serper.dev/

案例,python解释器,安装基本模块:

 
  

python编辑器的基本使用,代码:

 
  

结合前面的搜索工具,实现一个代码AI助手的Agent,代码:

 
  
创建Agent的工具函数 create_react_agent 构建一个基于ReAct思考框架的智能体,只允许有1个参数 create_structured_chat_agent 构建一个支持多个任务对话处理的智能体,允许有多个参数 create_json_agent 构建一个支持返回json数据结构的智能体,不管返回得到内容或者接受的参数都支持json结构 create_sql_agent 构建一个能与SQL数据库交互的智能体,可用于创建一个能够处理SQL任务、自动化数据库操作或提供数据库连接管理的服务或组件 create_openai_functions_agent 构建一个基于OpenAI functions风格的智能体,能够与OpenAI提供的API函数进行交互 create_tool_calling_agent 构建一个基于大模型API接口的智能体,能够与OpenAI以外的其他本地或在线大模型的API进行交互【部分本地大模型无法兼容】

上面搜索工具的案例代码改成基于create_react_agent框架,代码:

 
  

案例2,基于对话提示词来完成AI问答,代码:

 
  

案例3,结合ChatMessageHistory对话历史管理使用Agent,代码:

 
  

案例4,基于Tavily实现一个在线搜索Agent,代码:

 
  

案例5,基于create_structured_chat_agent构建多任务智能体,代码:

 
  

自定义Agent工具

基于函数自定义Agent工具

代码:

 
  
基于BaseTool基础类创建Agent工具

代码:

 
  
LangGraph

LangGraph 是在 LLM 和 LangChain 的基础之上构建的一个扩展库,可以与 LangChain 现有的链(Chain)等无缝协作,它能够协调多个 Chain、Agent、Tool 等共同协作,实现依赖外部工具、外部数据库且带有反馈的问答任务,目的是为了实现更加强大的RAG程序。

官网:https://www.langchain.com/agents

安装:

 
  
 
  

检索增强生成(Retrieval Augmented Generation,RAG)技术,顾名思义,就是去(本地或线上)知识库检索用户查询相关的各种信息,把检索出来的信息,融合到 prompt(提示词) 中,增强输入信息,最后让大模型生成更符合更准确的回答(用户更希望的答案)。RAG通过整合内部知识库的丰富信息赋能大语言模型(Large Language Model,简称 LLM),为生成式 AI 带来了革命性的改进。在生成答案或内容时,RAG 技术能够参照精确的知识源,为用户提供高度合理和准确的响应。RAG本质上就是一种给大模型外挂知识的手段,可以有效增强大模型推理的能力、准确性,能够更加符合客观事实,同时这种外挂知识的方式在知识库进行增删更新时,用户是没有感知的,比传统SFT微调技术更加节约资源和时间。RAG 技术与 LLM 模型相结合的应用方式,成功弥补了 LLM 模型在处理特定领域请求时存在幻觉、知识泛化、可解释性差等问题。常用的TAG开发框架如下:

框架 描述 LangChain 目前比较流行和常用的大模型应用开发框架,内置RAG实现流程,但并没有提供UI界面效果,需要结合Gradio或者FastGPTy或者open-webUI等框架手动实现客户端界面UI。 Langchain-Chatchat 基于langchain结合国内外大模型开发的一款RAG开发框架,内置了UI界面效果,开源、可离线部署 RAGFlow 一款基于深度文档理解构建的开源 RAG框架,提供一套精简的 RAG 工作流程,结合大语言模型(LLM)针对用户各类不同的复杂格式数据提供可靠的问答以及有理有据的引用,开源免费。 FastGPT FastGPT 是一个基于 LLM 大语言模型的知识库问答系统,提供开箱即用的数据处理、模型调用等能力。同时可以通过 Flow 可视化进行工作流编排,从而实现复杂的问答场景! open-webui 一个可扩展、功能丰富且用户友好的自托管 WebUI,旨在完全离线运行。它支持各种 LLM 运行器,包括 Ollama 和与 OpenAI 兼容的 API。 QAnything 网易有道开源的一个本地知识库问答系统,旨在支持广泛的文件格式和数据库,允许离线安装和使用。使用 可以简单地丢弃任何格式的本地存储文件,并接收准确、快速和可靠的答案。 MaxKB 一款基于大语言模型和 RAG 的开源知识库问答系统,广泛应用于智能客服、企业内部知识库、学术研究与教育等场景。

image-20241208201650536

新建 文件,代码:

 
  

,代码:

 
  

小讯
上一篇 2026-04-04 20:08
下一篇 2026-04-04 20:06

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/222937.html