2025-03-31 15:00:00
做一个有温度和有干货的技术分享作者 —— Qborfy
经过LangChain系列文章的学习, 实战一个有趣的小应用,通过Agent调用工具+大模型的推理能力开发一个 【低代码平台的 AI 小助手】,通过用户输入自然语言能实现 低代码平台页面生成。
如无意外,这篇应该是 LangChain最后一篇学习内容,将之前文章进行汇总,具体如下:
声明:本文部分材料是基于DeepSeek-R1模型生成。
2025-03-15 15:00:00
做一个有温度和有干货的技术分享作者 —— Qborfy
前面几篇学习LangChain,基本上完成对 LangChain从开发到上线有一个整体的了解,那么接下来我们就要开始实战了,我们将会使用LangChain开发一个问答机器人,这个问答机器人将会使用到RAG模型,那么接下来我们开始学习RAG。
RAG是一种用额外数据增强大模型知识的技术,俗称“RAG”(Retrieval-Augmented Generation),中文叫检索增强生成。
RAG是LangChain中一个重要的应用场景,它能够将检索和生成结合起来,从而生成更加精准的答案。
RAG模型由两个部分组成:Retriever和Generator。
Generator
生成索引向量,根据文档中问题和答案生成索引向量数据库。Retriever
检索对比类似,根据用户的问题,从生成的知识库中检索召回最相关的问题和答案。RAG技术是通过检索和生成相结合的方式找最相关的知识内容, 加入到大模型的提示语中,通过大模型推理得到用户问题在知识库中最合适的答案。
下面是我个人依据网上相关资料整理的通用RAG模型架构图:
生成向量索引有三个步骤,分别如下:
Embeddings
模型进行生成索引,然后存储到向量数据库VectorStore
。RAG模型使用Embeddings
模型将问题和答案进行编码,生成向量数据,这里我们必不可免需要对Embeddings
模型进行初步了解。
Embeddings模型,也叫嵌入模型,是一种将高维度的数据,如:自然语言、图片、视频等,转换成低维度的向量数据,如:多维矩阵数组等,方便后续进行相似度对比。
或者我们可以更加直观的理解,Embeddings
模型可以把我们人类能够理解的内容,转换成计算机能够计算理解的数据,从而实现更多的算法对比逻辑。
这两个步骤一般都是同时进行,一般也是 通过Embeddings嵌入模型去转换搜索内容为向量,然后通过检索到最后生成内容。
Ollama安装模型:
1 |
对话大模型 |
LangChain和 Streamlit安装
1 |
# python环境 3.12.4 |
requirements.txt
文件内容如下:
1 |
streamlit==1.39.0 |
streamlit是构建和共享数据应用程序的更快方法, 几分钟内将您的数据脚本转换为可共享的网络应用程序,全部采用纯 Python 编写,无需前端经验。
官方文档:https://docs.streamlit.io/get-started/installation
新建一个文件bot_chat.py
, 分步骤实现。
代码参考如下:
1 |
import streamlit as st |
执行效果如下:
1 |
|
上文件后, 执行效果如下:
聊天功能主要几点:
具体实现代码如下:
1 |
# step2 初始化聊天消息界面 |
这里实现一个Agent, 过程是 去调用一个检索工具,支持模板和用户输入,调用大模型进行检索,然后返回结果。
具体代码如下:
1 |
# step3 创建检索 agent |
这一步基本上就是解决用户输入显示与 Agent返回结果,同时通过 streamlit的 callbank函数去 展示 Agent的执行过程,具体如下:
1 |
# step5 用户输入查询与返回 |
1 |
streamlit run bot_chat.py |
执行效果如下:
对话中:
返回答案:
声明:本文部分材料是基于DeepSeek-R1模型生成。
2025-03-12 15:00:00
做一个有温度和有干货的技术分享作者 —— Qborfy
从 LangChain系列文章开始到现在,我们学习 LangChain的基础知识和实战撸代码,现在我们假设已经开发好一个 LangChain链式任务,那么如何部署以及如何与 web服务进行互相调用呢?
那么接下来我们应该就学习LangServer与LangSmith,如何让 LangChain进行企业级开发。
LangServer: 帮开发者将 LangChain 部署一个 Restful 服务。
LangSmith: 监控 LangChain调用链路服务和提供更加友好的可视化界面。
LangServer是集成了FastApi + Pydantic的Restful框架。它提供了一些特性:
/invoke
、 batch
和 /stream
接口服务,支持单个服务器多个并发请求/stream_log
接口,实现链式任务中间态步骤返回/stream_events
更加清晰任务事件状态信息安装langchain-cli
全局命令,方便快速启动 Lang Server项目
1 |
pip install -U langchain-cli |
安装poetry
管理项目的依赖,更好管理服务依赖 pip包。
poetry
Python packaging and dependency management made easy, 翻译过来就是更加轻松管理 python项目和依赖
1 |
安装 pipx |
1 |
初始化一个langserver的项目 |
1 |
mylangserver # 项目名 |
在根目录下运行如下命令:
1 |
langchain server |
就可以直接访问 http://localhost:8080
,效果具体如下图:
server.py
文件server.py
文件,具体如下:1 |
from fastapi import FastAPI |
DeepSeek-R1
模型的接口通过 add_routes
新增一个模型对象,会自动封装成对应的 Restful接口,具体如下:
1 |
from fastapi import FastAPI |
接下来我们访问 http://localhost:8000/
,就会出现和/deepseek
相关的文档,具体如下图:
接口测试我们可以通过ApiFox (一个和 Postman类似 API 测试工具)进行测试,具体如下.
/invoke
发起一个对话请求, 具体如下图:/stream
流式调用,具体如下图:在LangChain中是可以通过 LangServe提供的 RemoteRunable
进行远程调用,和原来的调用大模型的使用方式其实是一样的, 具体代码如下:
1 |
# 实现langchain调用远端调用 LangServer |
这样子我们不仅可以在本地调用大模型,还能调用其他人提供 LangChain服务,从而实现更加复杂的功能。
LangServer生产部署,按照 LangChain官方推荐是通过Dockerfile
打包进行部署,其中也比较简单,具体执行如下命令:
1 |
打包镜像 |
或者是通过 docker-compose启动 docker服务,具体如下:
1 |
version: '3' |
最终执行docker-compose up -d
启动服务后,就可以通过http://localhost:8080/docs
访问到服务了。
LangSmith是 LangChain官方提供的监控工具,可以监控模型运行情况,一个 SASS服务需要我们将服务相关信息注册到 LangSmith网站上,因此可以按个人或公司需要判断是否允许使用。
LangSmith是一个用于构建生产级应用的平台。它允许您密切监控和评估您的应用,以便您可以快速而自信地发布应用。
传统软件应用程序是通过编写代码来构建的,而 AI 应用程序则需要编写提示来指导应用程序执行哪些操作。
LangSmith 提供了一套旨在实现和促进提示工程的工具,以帮助您找到适合您的应用程序的完美提示。
PS:LangSmith这里提示未来编程开发者的思维转变,我们实现功能的思路不再是针对一些实现逻辑,而是面向不同的 AI 模型,优化提示语实现我们想要的功能。
在 LangServer 中使用 LangSmith,需要先注册一个账号,然后获取 api key 添加到 LangServer中,具体使用代码如下:
1 |
import os |
具体使用教程可以参考LangSmith官方文档
LangSmith主要作用是监控 链路任务节点调用和扭转情况,可以更加清晰的分析链的运行情况和日志,具体效果如下图所示:
如果我们不想把自己的服务相关的日志信息暴露给 LangSmith, 我们还可以通过设置set_verbose
设置详细日志开关, 从而实现我们调用 LangChain链路的完整日志,具体如下:
1 |
from langchain.globals import set_verbose |
打开开关后,我们再调用helloworld.py
大模型,可以看到关键的日志信息,但是verbose只会输出关键日志,下面我们还可以 debug
查看更加详细的日志信息。
我们可以通过debug
设置日志级别,从而查看更加详细的日志信息,具体如下:
1 |
from langchain.globals import set_debug |
打开开关后,我们再调用helloworld.py
大模型,可以看到更加详细的日志信息,具体如下图:
本文我们主要学习了LangServer的去部署一个 LangChain链,通过 LangServe对于第三方就能加友好的访问我们的提供 LangChain服务,从而实现更加复杂的功能。回顾一下,我们主要学习了以下内容:
langchain serve
运行项目add_routes
添加接口,可以直接把一个 LangChain添加到 LangServer中且自动生成 Swagger文档 set_verbose
或者set_debug
设置详细日志开关, 从而实现我们调用 LangChain链路的完整日志声明:本文部分材料是基于DeepSeek-R1模型生成。
2025-03-03 15:00:00
做一个有温度和有干货的技术分享作者 —— Qborfy
上一篇文章我们学习05篇 AI从零开始 - LangChain学习与实战(2) PromptTemplate降低AI幻觉,对 LangChain实际应用有了基本的了解,接下我们会进入 LangChain最重要的一次学习,就是 LangChain工作流编排原理与实战(LCEL), 学了本文基本上后续 LangChain实际开发都可以独立完成,本文内容较多,建议大家收藏,慢慢学习。
LCEL(LangChain Expression Language) 是 LangChain提出来一种强大的工作流编排模式,可以通过基础组件去构建复杂任务链条式,包括但不限于:
Pydantic
对象和 JSON
对象作为输入和输出,从而更好验证链路的正确性,并且LangServer的重要组成部分LCEL之所以有如此强大的功能,离不开它的设计理念 —— Runable Interface,LangChain一套标准且强大的接口设计规范,让所有的组件都按照这个去实现,从而实现 LCEL 工作流编排。
Runable Interface接口设计有以下几个方面“
同步调用方法:
结合await
实现异步调用的方法:
LangChain的输入和输出都是遵循schema
规范,从可运行对象结构自动生成对应的Pydantic
模型。
Pydantic
是用于数据建模/解析的Python库,它允许您定义一个数据模型,然后使用该模型验证输入和输出。
它可以帮助您确保输入和输出数据符合预期的格式和类型,从而提高代码的健壮性和可维护性。
同时Pydantic
内置了对JSON编码和解码的支持。
不过不同组件输入类型和输出类型是不同的,下面常用 LangChain组件输入和输出类型:
组件 | 输入类型 | 输出类型 |
---|---|---|
提示 Prompt | string | PromptTemplate提示值 |
聊天模型 | string、聊天信息列表、提示值 | string |
LLM | string、聊天信息列表、提示值 | string |
输出解析器 | LLM、 LLM的输出 | 取决于解析器的类型,如 jsonparser 输出的是 json格式 |
流式运行对于基于 LLM 开发的应用会对用户使用体验上有更好的体验,所以目前LangChain中重要的组件都实现 LangChain Runable Interface中的 stream
和astream
,如:PromptTemplate
、ChatModel
、LLM
、OutputParser
等。
上面弄清楚 LCEL的运行原理,我们还需要了解 Stream
这一概念,才能更好的理解 LCEL工作流编排。
Stream
指的是一个数据流,它表示一个连续的数据序列,可以是一个数据块、一个文件、一个数据库表、一个网络连接等。在计算机科学中,流通常用于表示实时数据传输,例如从网络连接中接收的数据、从文件中读取的数据等。流数据具有连续性、实时性和不可预测性等特点,因此处理流数据需要特殊的算法和数据结构。
在 LangChain中所有 Runable对象都实现了 stream(同步)
和 astream(异步)
接口,通过 stream
和 astream
接口,LangChain链式中的每个任务步骤都可以按照流式输入与输出。
从简单的任务,如发起一个 LLM调用,到复杂的任务,如:传输json数据等。
了解完 LCEL工作流编排原理,我们开始实战,下面我们通过几个的例子,来更好理解 LCEL工作流编排。
我们去调用一个 Ollama 大模型,然后调用 stream
方法,看看最终会输出什么?
1 |
# 实现langchain调用 ollama 大模型 |
最终输出效果,按照一块块输出,如下图:
进一步看看astream
调用和stream
调用有什么区别?
1 |
# 实现langchain调用 ollama 大模型 |
异步调用需要定义 async 方法,调用的话需要通过 asyncio.run() 方法,最终效果和stream
调用效果一样,不过在并行任务较多的情况下,astream
调用会利用更多的CPU资源,从而提高并行任务处理效率。
在实际应用中,我们很多场景其实 web服务通过 http协议传输,而且希望能被其他服务调用因此json
格式输出会更好,下面我们看看如何实现?
1 |
# 实现langchain调用 ollama 大模型 |
上文我们可以看到用到JsonOutputParser
,它保证每次输出都是json格式,所以最终输出效果如下:
我们先看调用一个 LLM模型会产生哪些事件?
1 |
# 实现langchain调用 ollama 大模型 |
输出如下图:
返回event
数据结构如下:
event
事件类型,如:stream_start
、stream_end
、stream_chunk
等data
事件数据,如:stream_chunk
事件数据为chunk
,stream_end
事件数据为end
等run_id
本次调用id,当多次任务并发的时候可以找到对应任务metadata
事件元数据,包括模型版本、模型名称、模型参数等tags
、name
、parent_ids
等完整的事件类型我们可以到 LangChain官方文档去查看,地址为如何使用 Stream Events
通过本文我们完整了解 LangChain LCEL流式调用和工作原理,从而为后续使用LangChain进入实际开发提供基础知识。 LCEL主要包含以下内容:
stream
、astream
astream_events
JsonOutputParser
等声明:本文部分材料是基于DeepSeek-R1模型生成。
2025-02-20 15:00:00
做一个有温度和有干货的技术分享作者 —— Qborfy
上一节学习了04篇 AI从零开始 - LangChain学习与实战(1) 基础知识,对Langchain有了基础的认知和简单应用,其中我们使用PromptTemplate
去实现一次大模型对话。
同时我们在03篇 AI从零开始 - Prompt提示语学习与应用也学习了提示语生成规范,但是在结合 LangChain中我们应该如何利用PromptTemplate
提示模板+提示语规范去降低 AI幻觉呢?
AI幻觉, 指人工智能(尤其是大语言模型)生成看似合理但实际错误、虚构或与现实不符的内容的现象。本质是模型在缺乏真实理解能力的情况下,基于统计模式生成的「自信错误」。
下面是 Langchain执行一次 LLM 调用的流程图:
提示词模板跟平时大家使用邮件模板、短信模板类型,本质上是一个字符串模板,模板里包含了模板参数,可以通过输入参数来生成最终的提示词。
一个提示词模板包括以下内容:
可以使用PromptTemplate
类来创建一个提示词模板,它接收一个prompt
参数,这个参数是一个字符串,用于指定提示词模板。
1 |
from langchain_core.prompts import ChatPromptTemplate |
这样子我们就可以得到一个正确的Message
了, 如上代码执行结果如下:
返回的内容如下说明:
LangChain还抽象了其他提示语模版,具体如下:
ChatPromptTemplate
对象,可以设定大模型角色和示例MessagesPlaceHolder
主要作用在特定位置添加消息列表(等于占位符), 可以集中管理消息列表,更好聊天过程注入上下文。
1 |
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder |
在之前03篇 AI从零开始 - Prompt提示语学习与应用中也提到过示例的重要性, 这里我们不在说示例对应大模型应用中的重要性了。
我们看看 在 LangChain中如何讲示例集 给到大模型中,其中FewShot
主要作用是给大模型提供示例,让大模型更好的理解用户输入,从而生成更符合用户预期的结果,从而降低 AI 幻觉。
这里可以理解成模型的微小型训练,让大模型能依据我们提供少量示例(有点类似小RAG知识库),从而更加更加准确的答案。
在 LangChain 创建一个示例集,如下:
1 |
from langchain.prompts.few_shot import FewShotPromptTemplate |
输出结果如下:
示例集合等同于一个知识库,在正式环境中我们不可能把完整的知识库都给到模型,因此我们需要去分析用户输入,从而选择合适的示例,LangChain 提供了ExampleSelector
类来帮助我们实现这个功能。
LangChain 提供了不同的ExampleSelector
,具体如下:
SemanticSimilarityExampleSelector
: 语义相似性示例选择, 会根据用户输入,然后通过嵌入模型计算输入与示例之间的相似性,然后使用向量数据库进行相似搜索,从示例集合中选择最相似的示例。MaxMarginalRelevanceExampleSelector
: 基于 最大边际相关性(MMR) 的示例选择器, 希望在从示例集中选择与输入 既相关又多样化 的示例, 通过平衡 相关性 与 多样性 来优化示例选择效果。通常情况下,我们使用SemanticSimilarityExampleSelector
, 根据上面示例集合,我们根据问题去选择示例,如下:
1 |
# ExapleSelector 示例筛选器 |
具体输出效果如下图:
本文我们完整学习了 LangChain 中如何使用 PromptTemplate去更好的创建一个提示语模板,从而降低 大模型的自我创新性(降低AI 幻觉)。
这里总结一下整个实现过程 约等于 后续 RAG知识库训练过程,如下图所示:
声明:本文部分材料是基于DeepSeek-R1模型生成。
2025-02-18 15:00:00
做一个有温度和有干货的技术分享作者 —— Qborfy
上一节学习了03篇 AI从零开始 - AI从零开始 - Prompt提示语学习与应用,但是我们发现,Prompt提示语虽然可以让我们得到想要的答案,但是它也有缺点,比如:
如果要开发一个完整 LLM应用,开发者需要手动处理:
接下来,我们学习一下LangChain,它是一个基于链式调用的LLM框架,可以让我们更加方便地使用大模型,实现多轮对话、多步骤推理等复杂功能。
Langchain是开发由大型语言模型(LLMS)提供支持的应用程序的框架。
从我理解的是, LangChain 是一个用于开发大语言模型(LLM)应用的框架,它的核心价值在于简化复杂语言模型应用的开发流程,并提供标准化的工具链。
Langchain 提供了以下基础功能:
Langchain 针对所有的LLM大模型的 API 进行抽象,统一了大模型访问API,同时也提供了 Prompt 模板管理机制。
可以把 Chain 理解为任务。一个 Chain 就是一个任务,当然也可以像链条一样,一个一个的执行多个链。
LCEL: LangChain Expression Language,通过表达式解决工作流编排问题,可以灵活自定义 AI任务处理流程,也就是自定义链。
RAG: Retrieval Augmented Generation,用于增强大模型的知识内容,录入新的信息到大模型中的一种模式。
Agent其实是大模型的一种应用设计模式,利用 LLM自然语言理解能力和推理能力,去实现用户输入需求自动调用外部系统、设置去共同完成任务。
常见的智能体:
LangChain提供一套内存机制,让LLM可以记住对话上下文内容,从而实现模型记忆。
Langchain接收大模型返回文本内容(原始数据基本上是 markdown格式)后,可以使用专门的输出解析器转换数据结果,比如转成 json, 或者转换为 python对象等。
将 Document 文档转换成向量存储,才能进行向量存储。因为大模型只能处理向量,所以需要将文本转换成向量。
转换成向量也很简单,只需要我们把数据存储到对应的向量数据库中即可完成向量的转换。
官方也提供了很多的向量数据库供我们使用。
https://python.langchain.com/en/latest/modules/indexes/vectorstores.html
Embedding(嵌入) 是将文本转化为数值向量(vector)的核心技术,用于捕捉语义信息并实现机器可理解的表示。
Langchain 提供了多种 Embedding 模型调用,具体可以到官网查看,Embedding models 嵌入模型。
更多概念可以到官方文档查看:LangChain官方概念指南。
LangChain(v0.3版本)的框架图如下:
更加详细说明
为了更好地使用 LangChain,我们先来写一个简单的例子,来了解下 LangChain 的使用流程。
1 |
新建目录 |
安装后续依赖pip 新建文件requirements.txt
,写入以下内容:
1 |
langchain==0.3.19 |
执行pip install -r requirements.txt
安装依赖。
新建一个demo1.py
文件,写入以下代码:
1 |
# 实现langchain调用 ollama 大模型 |
输出结果如下图所示:
Langchain让我们实现调用一个大模型API 变得更加简单,只需要几行代码就会实现一个简单对话。主要实现逻辑为:
记录问题: 如果我部署的大模型 Langchain 没有找到对应的模型,应该怎么做?
声明:本文部分材料是基于DeepSeek-R1模型生成。