自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(58)
  • 收藏
  • 关注

原创 [ToolNode在LangGraph中的运用-01]LangChain和LangGraph两种编程模式的同一性

LangGraph赋予我们根据推理任务自由构建流程图的能力,所以我们完全可以不使用工具,而将每个工具的功能实现在某个节点中,这样对于流程的每个步骤都具有精准的控制。但是任何事都有利弊,这样的编程模式让我们摒弃了`ToolNode`具有的很多能力,在利用LangGraph开发Agent过程中有效地使用`ToolNode`,有时可以起到事半功倍的作用。

2026-04-04 08:42:34 287

原创 [RAG在LangChain中的实现-08]采用GraphRAG将孤立的信息点关联起来

RAG技术在帮助LLM推理私有数据集方面展现出潜力,例如企业的专有研究、业务文档或通信记录。传统的RAG利用向量相似度有效地解决这个问题,我们一般将其称为`Baseline-RAG`,它在某些情况下表现非常糟糕。为了解决这个问题,技术界正在努力开发扩展和增强RAG的方法。微软研究院的新方法`GraphRAG`基于输入语料库创建知识图谱。该图谱与社区摘要和图机器学习输出一起,用于在查询时增强提示信息。

2026-04-03 09:49:38 514

原创 [RAG在LangChain中的实现-07]利用重排序选择相关性最高的检索内容构建上下文

重排序(Re-ranking)是一种关键的RAG优化技术。它通过在“初始检索”与“最终生成”之间,通过对初步检索出的文档进行二次评估,筛选出与用户查询语义最相关的结果,从而提高生成内容的准确性。在典型的检索流程中,第一步通常使用向量相似度搜索,虽然速度极快,但由于只对比向量间的距离,往往难以捕捉深层的语义关系。重排序模型(Reranker)接收用户查询和一组初步检索到的文档,输出每个文档的相关性分数。

2026-04-02 08:47:16 524

原创 [RAG在LangChain中的实现-06]利用LangGraph实现基于“交谈历史”的RAG应用

“利用LangGraph编写RAG应用”提供的解决方案有一个问题:它将LLM完全视为一个完全无状态的函数在用,因为调用的输入都只有一条单一的消息,并没有之前交谈的历史,这样的好处是减少输入,降低成本。但这将导致LLM因缺乏上下文不能从之前的“失败”中学习,我们可以将create_agent默认采用的“面向交谈历史”的实现方式应用到LangGraph的编程模式上。

2026-04-01 08:50:47 535

原创 [RAG在LangChain中的实现-05]利用LangGraph编写RAG应用

在让“LLM在指定的上下文范围内回答问题”一文中,我们利用LangChain(`create_agent`工厂函数)编写了一个简单RAG应用,这是一个将指定博文内容作为上下文的QA应用。现在我们使用LangGraph的编程模式重现实现它,并额外添加检索内容相关度评估和查询重写的功能。

2026-03-31 09:25:06 711

原创 [RAG在LangChain中的实现-04]常用的向量存储和基于向量存储的检索器

向量存储是RAG解决方案的核心,目前市面上由很多向量存储产品,由免费开源的,也有商业闭源的;有本地部署的,也有完全云托管的;有传统数据库产品推出的针对向量存储的扩展,也有新势力专门针对向量存储设计的新产品。基于所有的VectorStore都提供了对应的检索器,后者可以以一个Runnable对象的形式作为LCEL链上的一环。

2026-03-30 08:46:18 583

原创 [RAG在LangChain中的实现-03]利用向量存储实现基于自然语言的相似度检索

被分割的文本切片需要转换成向量保存在`VertorStore`中,才能实现基于自然语言的相似度检索。`VectorStore`是RAG架构的核心组件。它的主要作用是存储和检索非结构化数据的“语义特征”。

2026-03-29 08:25:48 671

原创 [RAG在LangChain中的实现-02]根据数据格式选择文档加载器和文本分割器

在RAG(检索增强生成)系统中,文档加载器和文本分割器是数据预处理阶段的两个核心组件,决定了系统最终能检索到什么质量的内容。文档加载器的主要任务是“数据摄取”,将各种格式的外部非结构化数据导入RAG管道,并转换为统一的文档格式。由于大语言模型有上下文窗口限制,且过长的文本会降低检索精度,分割器负责将加载好的长文档“切片”成更小的块。

2026-03-28 09:02:43 499

原创 [RAG在LangChain中的实现-01]让LLM在指定的上下文范围内回答问题

大模型(LLM)具有两大的局限:一是它不知道自己不知道,所以我们发现它经常天马行空、一本正经地胡说八道,这就是所谓的“幻觉”;二是模型具有的知识在训练生成的那一刻就已经冻结,知识体系不会继续更替。RAG是目前针对这两个问题的主要解决方案。RAG(Retrieval-Augmented Generation,检索增强生成)是一种结合了信息检索和文本生成的AI技术架构。它通过为大型语言模型(LLM)外挂一个“知识库”,让模型在回答问题前先去查询相关资料,从而有效解决了模型回答“胡编乱造”和知识滞后的问题。

2026-03-27 09:02:29 571

原创 [LangGraph编译原理-05]从“状态图(StateGraph)”到“Actor模型(Pregel)”的转变

我们通过添加节点和边创建`StateGraph`对象,其`compile`方法将其编译生成`CompiledStateGraph`,整个编译过程就是将`StateGraph`的节点和边转换成`Pregel`的节点和通道的过程。整个编译流程主要划分为三个步骤。

2026-03-26 08:37:08 660

原创 [LangGraph编译原理-04]状态图的“边”如何转换成针对“通道”的写入?

边(Edge)建立起两个节点之间基于执行顺序的依赖关系,后续节点必需在前序节点执行后才能执行。如果节点A和B之间有一条边,并且A是B唯一的前序节点,还进一步保证两个节点会在相邻的两个Superstep中执行。如果某个节点具有多个前序节点,这种场景被称为Fan-in,隐含的是该节点针对所有前序节点的依赖,意味着当前节点只有在确保所有前序节点全部执行后才能执行。具体的边又分为“(无条件)静态边(简称为边)”和“条件边(Conditional Edge)”

2026-03-25 08:43:59 589

原创 [LangGraph编译原理-03]深入系统地了解一下状态图的“节点”

`StateGraph`通过两个核心操作,即添加节点和边,来构建具有期望结构的图。节点在LangGraph中如何描述?为什么我们可以将节点定义成签名自由的函数?什么样的对象可以直接注入节点函数?节点函数返回字典和Command有什么不同?如何控制节点执行采用的重试策略和缓存策略?工具存在一个怎样的节点中?这些问题都可以在本篇文章中找到答案。

2026-03-24 08:40:39 682

原创 [LangGraph编译原理-02]面向通道定义Agent的状态

LangGraph编程基本围绕`StateGraph`进行,所以我们有必要对这个类型具有一个深刻的认识。这是一个泛型类型,四个泛型参数`StateT`、`ContextT`、`InputT`和`OutputT`分别表示状态、静态上下文、输入和输出类型,而且它们的类型都是一个`StateLike`类型。针对`StateLike`的定义,我们一般会使用`TypedDict`、`DataClass`和Pydantic模型。

2026-03-23 09:04:55 756

原创 [LangGraph编译原理-01]写一个Agent将英文诗歌翻译成古典诗词

复杂的任务要求Agent具有复杂的处理流程。加上图的“可组合”特性,Agent自身又可以作为图的一个节点,所以从原则上讲,具有任意复杂度处理流程的Agent都可以由相应的图转变而成。`StateGraph`对象体现的“图”经过编译会称为一个`CompiledStateGraph`对象,这是一个体现为Actor模型的`Pregel`对象,那么实现两者转换的编译是如何实现的呢?

2026-03-22 09:23:24 558

原创 [LangChain智能体本质论-09]中间件装饰器是如何将函数转换成AgentMiddleware的?

中间件除了可以通过定义继承自`AgentMiddleware`的类型来定义,还可以在某个满足签名条件的函数上应用相应的装饰器将其转换成`AgentMiddlewre`对象,那么背后的逻辑是怎样的呢?

2026-03-21 08:30:58 793

原创 [LangChain智能体本质论-08]中间件是如何参与Agent、Model和Tool三者交互的?

LangChain的中间件(Middleware)是围绕Agent执行流程构建的“可插拔钩子系统”。它允许开发者在不修改核心逻辑的情况下,在执行的关键节点(如输入处理、模型调用前后、输出解析等)对数据流进行拦截、修改或验证。中间件类型以`AgentMiddleware`为基类。

2026-03-20 08:45:49 1067

原创 [LangChain智能体本质论-07]如何在工具函数中注入各种运行时对象?

工具参数有两种来源,一种必需由外部提供,另一种则是由执行引擎根据约定自动注入,比如表示工具运行时的`ToolRuntime`。那么究竟什么样的对象可以注入到工具函数中,执行引擎又是如何识别和提供它们的呢?

2026-03-19 08:45:11 722

原创 [LangChain智能体本质论-06]赋予Agent执行力的工具是个什么东西?

在 LangChain框架中,工具是连接大语言模型与外部世界的桥梁。它们赋予了模型“行动”的能力,使其能够超越文本生成的范畴,去执行搜索、计算、运行代码或调用API等实际任务。工具本质上是带有名称 、描述 和Shema的函数。LLM并不直接运行工具(服务单工具除外),而是根据用户的查询,参考工具的描述来决定是否需要调用某个工具,并输出该工具所需的结构化参数。Agent接收到模型生成的参数后,在本地或服务器端执行该工具,并将结果返回给LLM,供其进行后续推理或总结。

2026-03-18 08:41:15 602

原创 [拆解LangChain执行引擎-17]Agent状态是如何从通道读取的?

在“Agent状态是如何被写入通道的?”中,我们探讨了组成的Agent的节点在完成了自身操作后,如何将执行结果通过写入相应的通道,进而更新Agent的状态。本篇文章则讨论这个问题的另一面:Agent的节点如何通过读取通道得到Agent的状态的。

2026-03-17 08:27:55 659

原创 [拆解LangChain执行引擎-16]Agent状态是如何被写入通道的?

根据"梳理Agent的执行流程"中针对Pregel执行流程的介绍,我们知道在每个Superstep的最后阶段,引擎会根据节点针对通道的订阅以及“__pregel_tasks”这个通道存储的`Send`对象,确定下一步应该执行的节点,并为它们创建代表执行任务的`PregelExecutableTask`。节点在执行过程中不能直接更新通道,它只能创建如下三种类型的对象来表示针对通道的写入意图。在默认情况下,这些对象承载的通道写入意图由`ChannelWrite`对象提交给引擎,后者在Superstep进入同步屏

2026-03-16 08:34:20 598

原创 [LangChain之链-07]RunnableCallable——将“自由定义”的函数变成标准组件

在众多针对`Runnable`的继承类型中,个人认为最重要的莫过于`RunnableCallable`。有过LangChain开发经验的人都知道,LangChain的很多组件都可以写成函数的形式,比如工具、中间件、LangGraph的节点等,而且它们的签名相对“自由”,其参数不仅仅用于提供外部输入,还可以用来注入一些运行时对象,比如`Runtime`、`BaseStore`、`StreamWriter`和`RunnableConfig`等。它们很多都会转换成`RunnableCallable`对象来使用。

2026-03-15 08:43:33 574

原创 [LangChain智能体本质论-05]结构化输出的两种实现方式

数据只有具有希望的结构才可能被有效地处理,我们在调用`create_agent`函数创建Agent的时候,可以利用`response_format`控制输出的格式。我们可以定义一个Pydantic模型类表表示期望输出的结构,如果将此类型表示成`ResponseT`,我们可以直接将此类型作为`response_format`参数的值,也可以将此参数赋值为`ResponseFormat[ResponseT]`。

2026-03-14 08:50:30 751

原创 [LangChain智能体本质论-04]Agent的状态即通道(Channel)

我们不断在强调Agent本质上是一个Pregel对象,其状态完全利用通道来维护,所以作为状态的`AgentState`对象的数据成员会转换成对应的通道。当我们看到`AgentState`的三个字段定义的时候,是不是感到很熟悉:前面演示实例输出的通道就有三个与它们同名。

2026-03-13 08:36:22 693

原创 [LangChain智能体本质论-03]三种等效的Agent构建方式

对于最新版本的LangChain,我们可以利用LangGraph以“图”的形式编排一个具有复杂交互流程的Agent。`create_agent`工厂函数内部本质上也是利用的这种方式。由于Agent从执行层面来看就是一个Pregel对象,一个由节点和通道构建而成的Actor模型。综上所述,利用`create_agent`构建的Agent,其实也可以利用其他两种方式来创建。接下来我们就使用三种不同的编程模式构建一个等效的Agent。

2026-03-12 08:45:25 852

原创 [LangChain智能体本质论-02]从消息交互角度审视模型组件在Agent中的作用

单纯从消息交互的角度来看待Agent中的model节点,可以看出它旨在利用`AIMessage`提供两种类型的响应: 在需要调用一个或者多个工具情况下,利用`ToolCall`返回针对工具调用意图的描述;做出最终的答复。我们可以利用一个假的模型组件来验证这一点

2026-03-11 09:41:13 174

原创 [LangChain智能体本质论-01]两种视角看待Agent和ReAct循环

作为LangChain智能体的Agent采用一种被称为ReAct循环的执行流程(如下图所示),这是一种结合了“推理”(Reasoning)与“行动”(Acting)的交互模式,旨在让Agent能像人类一样通过逻辑思考来解决复杂问题。但是从底层的执行方式来看,Agent本质上是一个Pregel对象(我的系列文章“[拆解LangChain执行引擎](https://blog.csdn.net/jaydenai/category_13127051.html)”对Pregel具有系统的介绍),是一个通过节点和通道构

2026-03-10 08:25:35 659

原创 [LangChain语言模型组件的设计与实现-10]针对模型输出的解析(下篇)

到目前为止,我们已经介绍LangChain的语言模型和提示词模板,它们都是一个Runnable对象,而且提示词模板的输出正是模型的输入,所以两者正好可以拼接在一起组成一条LCEL链。这条链还缺一环,那就是将模型输出转换成结构化数据,以方便应用处理,我们可以借助通过`BaseOutputParser`类型表示的输出解析器来完成此功能。提示词模板、语言模型和输出解析器组成了模型调用“三件套”。

2026-03-09 09:14:35 742

原创 [LangChain语言模型组件的设计与实现-09]针对模型输出的解析(上篇)

到目前为止,我们已经介绍LangChain的语言模型和提示词模板,它们都是一个Runnable对象,而且提示词模板的输出正是模型的输入,所以两者正好可以拼接在一起组成一条LCEL链。这条链还缺一环,那就是将模型输出转换成结构化数据,以方便应用处理,我们可以借助通过`BaseOutputParser`类型表示的输出解析器来完成此功能。提示词模板、语言模型和输出解析器组成了模型调用“三件套”。

2026-03-08 09:26:59 785

原创 [LangChain语言模型组件的设计与实现-08]少样本提示词模板

少样本学习(Few-Shot Learning)是一种机器学习范式,旨在让模型在仅有极少量标注样本(通常为 1-5 个)的情况下,能够快速理解新任务并做出准确预测。少样本提示词就是少样本学习在大模型领域的具体落地手段。如果说“少样本学习”是让模型具备举一反三的能力,那么“少样本提示词”就是你实现这种能力的“说明书”。LangChain提供了一组针对性的少样本提示词模板。

2026-03-07 09:26:54 753

原创 [LangChain语言模型组件的设计与实现-07]基于Chat模型的提示词模板

我们知道提示词 是调用语言模型最为核心的输入,提示词的质量直接影响答案的质量,所以我们不论抬高提示词的重要性都不过分。提示词在LangChain中通过PromptValue类型表示,我们一般利用预定义的提示词模板来生成它。提示词模板也以一个Runnable对象的形式存在,由于提示词模板生成的PromptValue正好使模型的输入,所有两者正好组合成一个LCEL链。这一篇将会介绍Chat模型的提示词模板。

2026-03-06 09:19:21 776

原创 [LangChain语言模型组件的设计与实现-06]基于Completion模型的提示词模板

我们知道提示词是调用语言模型最为核心的输入,提示词的质量直接影响答案的质量,所以我们不论抬高提示词的重要性都不过分。提示词在LangChain中通过`PromptValue`类型表示,我们一般利用预定义的提示词模板来生成它。提示词模板也以一个`Runnable`对象的形式存在,由于提示词模板生成的`PromptValue`正好使模型的输入,所有两者正好组合成一个LCEL链。

2026-03-05 09:01:02 688

原创 [LangChain语言模型组件的设计与实现-05]OpenAI Chat模型的设计与实现

LangChain中的语言模型是一个`Runnable`对象。所有的语言模型类型(包括基于文本补齐的Completion模型和基于多角色参与的Chat模型)都继承自抽象类`BaseLanguageModel`,`BaseChatModel`是所有Chat模型的基类。`ChatOpenAI`的基类`BaseChatOpenAI`就继承自`BaseChatModel`。上篇文`章着重介绍BaseLanguageModel`和`BaseChatModel`这两个基类的设计,这文章将会介绍ChatOpenAI。

2026-03-04 10:24:44 570

原创 [LangChain语言模型组件的设计与实现-04]Completion模型和Chat模型

LangChain中的语言模型是一个`Runnable`对象。所有的语言模型类型(包括基于文本补齐的Completion模型和基于多角色参与的Chat模型)都继承自抽象类`BaseLanguageModel`,`BaseChatModel`是所有Chat模型的基类。`ChatOpenAI`的基类`BaseChatOpenAI`就继承自`BaseChatModel`。这篇文章着重介绍BaseLanguageModel和BaseChatModel这两个基类的设计,下篇文章将会介绍ChatOpenAI。

2026-03-03 09:22:10 1009

原创 [LangChain语言模型组件的设计与实现-03]PromptValue——作为模型核心输入的提示词

在 LangChain 框架中,`PromptValue`是连接提示词模板与语言模型的中间数据层。提示词可以是单纯的字符串文本,还可以是一张图片,它们对应的类型分别为`StringPromptValue`和`ImagePromptValue`。Chat模型的提示词类型继承自`ChatPromptValue`,`ChatPromptValueConcrete`是它的一个子类。ImagePromptValue仅仅是对单一图片的封装,对于真正多模态解决方案应该利用ChatPromptValue生成具有多媒体内容的

2026-03-02 08:46:35 896

原创 [LangChain语言模型组件的设计与实现-02]多形态的消息内容——多模态AI解决方案的基础

作为消息的基类,`BaseMessage`利用其`content`字段存储原始的内容,它可以是一个字符串或者字典列表。原始的内容会转换成一个`ContentBlock`列表通过`content_blocks`的属性返回。作为消息的主体内容,它们可以是一段单纯的字符串文本,也可以一段多媒体内容(比如图片、音频和视频)或者一个二进制文件,不同的内容形态对应着相应的ContentBlock类型

2026-03-01 08:22:52 1277

原创 [LangChain语言模型组件的设计与实现-01]消息——Agent与模型交互的媒介

Agent开发语境下的模型大体分两种,即传统的文本补齐`Completions模型`和基于多方交谈的`Chat模型`,在LangChain中,它们都继承自如下这个`BaseLanguageModel`抽象类。它继承自`RunnableSerializable`,所以能成为LCEL链上的一环。

2026-02-28 11:59:30 1123

原创 [LangChain之链-06]使用Runnable实现配置绑定、失败重试、降级以及数据成员过滤

接下来介绍三个以`代理形式`存在的Runnable类型,其中`RunnableBinding`使Runnable对象可以绑定配置和参数,`RunnableRetry`则实现了针对失败重试策略的绑定。`RunnableWithFallbacks`可以在被代理Runnable对象执行失败后,利用一组Runnable对象作为后备。`RunnablePick`虽然不属于代理,但是使用起来类似于代理,因为它从被`代理`的Runnable的输出中摘取指定的成员。

2026-02-27 08:25:04 732

原创 [LangChain之链-05]四种逻辑控制Runnable类型

接下来介绍的几个Runnable类型会整合其他的`Runnable`,使它们按照指定的流程执行。`RunnableSequence`和`RunnableParallel`分布实现了多Runnable对象的 “串行” 和 “并行” 执行,`RunnableBranch`根据计算条件划分了逻辑分支,而`RunnablePassthrough`则简单实现了数据透传,并再此基础上完成数据成员的添加和覆盖。

2026-02-26 07:37:57 949

原创 [LangChain之链-04]将可执行对象和生成器转换成标准组件

在 LangChain 的 LCEL (LangChain Expression Language) 设计体系中,这两个组件是实现`自定义逻辑`与`流式传输`的核心桥梁。它们允许你将普通的 Python 函数包装成具备`invoke`、`batch`和`stream`能力的标准Runnable节点。

2026-02-25 08:28:11 455

原创 [LangChain之链-03]Runnable,不仅要可执行,还要可存储、可传输、可重建、可配置和可替换

在 LangChain 架构中,`RunnableSerializable`是一个至关重要的中间层基类。它继承自`Runnable`并混入了`Serializable`协议。在复杂的 AI 系统中,仅仅能“运行”是不够的,RunnableSerializable 使组件`可保存、可传输、可重建`。大多数常用的 LangChain 组件对应的类型都是它的派生类。

2026-02-24 07:58:13 839

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除