LangGraph 插件开发教程:打造专属多智能体工具的全流程
LangGraph 插件开发教程:打造专属多智能体工具的全流程
关键词:LangGraph、多智能体系统、LangChain插件、智能工具编排、状态管理、LLM驱动应用、Python插件开发
摘要:想象一下你有一个由不同技能“小精灵助手”组成的团队——有的会画图,有的会查天气,有的会算数学题,有的会写代码,但它们之前各干各的,没法好好配合。LangGraph就是把这些小精灵组织起来当指挥官的“超级魔法指挥棒”,而插件则是给指挥棒准备的“专属武器库”——你想要小精灵们用什么新工具?自己造!这篇教程会像搭乐高一样,一步一步教你从零开始理解LangGraph、掌握它的插件体系、亲手打造第一个专属插件(比如帮你写带配图的小红书美食分享的“美食小红书生成器插件”)、再把它集成到真正的多智能体应用里,最后还有进阶的插件开发技巧和未来展望。全文没有晦涩的术语堆砌,全是小学生都能懂的故事比喻,还有完整可运行的Python代码,保证你看完就能动手做出属于自己的AI小工具!
1. 背景介绍:从“孤独的AI小精灵”到“超级团队指挥官”
1.1 目的和范围
1.1.1 我们要解决什么问题?
先给大家讲个我朋友上周的真实故事,就像给孤独的小精灵找团队那样,有共鸣感——
我朋友小李是个美食博主,最近她想写一篇“周末在家做芒果班戟”的小红书。她需要做什么呢?
- 先问AI“帮我写一篇带表情符号、分步骤、适合新手的小红书芒果班戟食谱文案”;
- 再查本地的芒果价格和超市位置,确定配图里要不要突出水果摊的实拍灵感;
- 接着用AI画图工具生成3张高质量的小红书风格配图:食材大合照、制作过程的煎班戟皮图、成品装盘撒糖粉图;
- 最后把文案和图片的提示词整理一下,方便下次用。
结果呢?她开了4个网页窗口:ChatGPT写文案、高德地图查价格/位置、Stable Diffusion画图、Notion存提示词,来回切换复制粘贴,折腾了快2小时才弄好!要是有个“美食小红书生成器小助手”,能自己串起这些事,2分钟搞定该多好?
没错!小李遇到的问题,就是现在很多人用AI工具的通病:工具是分散的,没法自动串联,每次用都要手动当“传声筒”和“搬运工”。之前的LangChain虽然也能把工具连起来,但它是“线性的链条”——就像让小精灵们排成一队,必须前一个做完才能下一个,万一中间需要“商量”或者“修改”前一个的结果(比如小李觉得文案太长,要让写文案的小精灵先缩一下再给画图的生成配图),线性链条就完全做不到了!
那怎么办?这时候就需要超级魔法指挥棒——LangGraph登场了!它不是线性的链条,而是像思维导图那样的“状态图”——你可以让小精灵们在图里随便走,随便商量,随便修改,最后给你想要的结果!而插件呢?就是给这个超级指挥棒准备的“专属武器库”——LangGraph自带一些基础武器(比如搜索、计算器),但如果你想要“芒果班戟小红书生成器”这种定制化武器,就得自己造插件!
1.1.2 这篇教程会教你什么?
这篇教程是LangGraph插件开发的“保姆级全流程指南”,从0基础的小白,到想进阶的开发者,都能有所收获。我们会覆盖以下内容:
- LangGraph核心概念扫盲:用乐高、小精灵、魔法指挥棒这些比喻,讲清楚什么是状态、节点、边、条件边这些最核心的东西;
- LangChain插件体系入门:因为LangGraph的插件是基于LangChain的,所以我们先搞懂LangChain的插件是啥、怎么用;
- 从零打造第一个专属LangGraph插件:我们会一起做“美食小红书生成器插件”——这个插件会整合“小红书文案生成”“高德API查本地芒果价格/位置”“Stable Diffusion WebUI API生成配图”“Notion存提示词”4个工具;
- 把插件集成到真正的多智能体应用里:我们会用LangGraph搭一个“美食助手多智能体团队”——团队里有“文案策划小精灵”“食材调研小精灵”“配图设计小精灵”“资料整理小精灵”4个角色,它们会用我们做的插件互相配合,自动完成小李的任务;
- 插件开发进阶技巧:比如插件的状态传递、错误处理、权限控制、性能优化、多工具组合插件、异步插件开发;
- 插件的测试与部署:比如怎么用LangSmith测试插件的效果,怎么把插件部署到LangChain Hub或者本地的仓库里;
- 未来发展趋势与挑战:比如LangGraph插件的标准化、跨平台部署、多模态插件、实时协作插件;
- 最佳实践和避坑指南:比如我在开发插件时踩过的那些坑,怎么避免;
- 常见问题与解答:比如“LangGraph和AutoGen有啥区别?”“插件开发用不用LangChain?”这些问题的答案。
1.1.3 这篇教程不会教你什么?
为了保证教程的聚焦和通俗易懂,我们不会讲以下内容:
- Python语法的基础入门:你需要至少会一点Python——比如变量、函数、类、if-else、for循环这些;
- LangChain的所有功能:我们只会讲和LangGraph插件开发相关的LangChain内容;
- Stable Diffusion WebUI的部署:我们会假设你已经有一个可用的Stable Diffusion WebUI API(或者你可以用我们提供的免费演示API密钥,不过有调用次数限制);
- 高德地图API的详细配置:我们会告诉你怎么申请API密钥,但不会讲高德地图API的所有功能;
- Notion API的详细配置:同理,我们会告诉你怎么申请API密钥,但不会讲Notion API的所有功能;
- 非常复杂的多智能体系统设计:比如多智能体的博弈论、共识机制这些,我们只会讲最基础、最实用的多智能体编排;
- 其他编程语言的LangGraph插件开发:目前LangGraph的官方支持语言是Python和TypeScript,但这篇教程只会讲Python,因为Python对小白更友好。
1.2 预期读者
这篇教程的预期读者是:
- 对AI驱动应用感兴趣的小白:只要会一点Python,就能跟着教程一步步做;
- LangChain的老用户:想从“线性链条”升级到“状态图”,并掌握插件开发;
- 多智能体系统的开发者:想快速打造定制化的多智能体工具;
- 产品经理和设计师:想了解多智能体工具的开发流程,为产品设计提供思路;
- 学生和研究者:想学习LangGraph和多智能体系统的基础知识。
1.3 文档结构概述
为了让大家像搭乐高一样,一步一步跟着教程走,我们把文档分成了以下几个部分:
- 背景介绍:就是现在你正在看的这部分,讲了我们要解决的问题、教程的目的和范围、预期读者、文档结构、术语表;
- 核心概念与联系:用乐高、小精灵、魔法指挥棒这些比喻,讲清楚LangGraph和LangChain插件的核心概念,还有它们之间的关系;
- 准备工作:环境搭建和工具申请:这部分我们会一起搭建开发环境,申请需要的API密钥(OpenAI、高德地图、Notion、Stable Diffusion WebUI);
- LangChain插件体系入门:打造基础的单工具插件:这部分我们先搞懂LangChain的插件体系,一起做几个基础的单工具插件——比如“天气查询插件”“计算器插件”;
- 从零打造第一个专属LangGraph多工具插件:美食小红书生成器插件:这部分是教程的核心,我们会一起整合4个工具,做一个真正有用的定制化插件;
- 把插件集成到LangGraph多智能体应用里:这部分我们会用LangGraph搭一个“美食助手多智能体团队”,让它们用我们做的插件互相配合;
- 插件开发进阶技巧:这部分我们会讲一些进阶的插件开发技巧,让你的插件更强大、更稳定;
- 插件的测试与部署:这部分我们会讲怎么测试和部署你的插件;
- 最佳实践和避坑指南:这部分我会分享我在开发插件时踩过的那些坑,还有一些最佳实践;
- 未来发展趋势与挑战:这部分我们会聊一聊LangGraph插件的未来;
- 总结:学到了什么?:这部分我们会回顾一下教程的主要内容;
- 思考题:动动小脑筋:这部分我们会给大家留一些思考题,鼓励大家进一步思考和应用所学知识;
- 附录:常见问题与解答:这部分我们会解答一些常见的问题;
- 扩展阅读 & 参考资料:这部分我们会给大家推荐一些扩展阅读和参考资料。
1.4 术语表
为了避免大家在看教程的时候遇到陌生的术语,我们先在这里把所有核心术语解释一遍——用的都是小学生能懂的比喻哦!
1.4.1 核心术语定义
| 核心术语 | 专业定义(简要) | 小学生能懂的比喻 |
|---|---|---|
| LLM | 大语言模型(Large Language Model),一种能理解和生成人类语言的AI模型 | 一个超级聪明的“语言小精灵”,会讲故事、写作文、算数学题、翻译,几乎无所不能,但有时候会“胡说八道”(幻觉) |
| LangChain | 一个用于开发LLM驱动应用的Python/TypeScript框架,提供了很多现成的工具、组件和模板 | 一个“AI工具箱”,里面有很多现成的零件(比如LLM接口、工具接口、文档加载器),你可以用这些零件快速搭出AI小应用 |
| LangGraph | LangChain团队开发的一个用于开发状态驱动、多智能体LLM应用的Python/TypeScript框架,是LangChain的“升级指挥官” | 一个“超级魔法指挥棒”,不是让AI小精灵排成一队干活,而是让它们在“状态图”里随便走、随便商量、随便修改,最后给你想要的结果 |
| 状态(State) | LangGraph应用的“记忆库”,存储了所有小精灵在工作过程中产生的信息,所有小精灵都可以读取和修改这个记忆库 | 一个“共享笔记本”,所有小精灵都可以在上面写字、画画、修改,大家都能看到别人写的内容 |
| 节点(Node) | LangGraph应用的“工作单元”,每个节点对应一个具体的任务,可以是调用LLM、调用工具、修改状态、判断条件等等 | 一个“AI小精灵”或者“AI小精灵的任务组”,负责完成一个具体的工作 |
| 边(Edge) | LangGraph应用的“连接线”,告诉小精灵们做完一个任务之后,接下来要做什么 | 一个“箭头”,画在共享笔记本的旁边,告诉小精灵们写完这一页之后,接下来要写哪一页 |
| 条件边(Conditional Edge) | 一种特殊的边,不是固定的箭头,而是根据状态里的内容,决定接下来要写哪一页 | 一个“选择题”,写在共享笔记本的旁边,比如“如果文案太长,就回到文案策划小精灵那里修改;如果文案刚好,就去配图设计小精灵那里” |
| 入口(Entry Point) | LangGraph应用的“起点”,告诉小精灵们从哪一页开始写 | 一个“红色的起点标记”,画在共享笔记本的第一页 |
| 出口(Exit Point) | LangGraph应用的“终点”,告诉小精灵们什么时候可以结束工作 | 一个“绿色的终点标记”,画在共享笔记本的最后一页 |
| 工具(Tool) | LLM可以调用的外部能力,比如搜索、计算器、画图、查天气等等 | 一个“小精灵的武器”,比如“搜索枪”“计算器刀”“画图魔法棒”,有了这些武器,小精灵就能做更多的事了 |
| LangChain插件(LangChain Plugin) | 一种特殊的工具包,把一个或多个工具打包在一起,提供统一的接口,方便LLM调用 | 一个“小精灵的武器套装”,比如“美食武器套装”里有“文案生成枪”“食材调研刀”“画图魔法棒”“资料整理本” |
| LangGraph插件(LangGraph Plugin) | 其实LangGraph没有专门的“插件类型”,我们通常说的LangGraph插件,是指专门为LangGraph设计的、可以很好地处理状态传递的LangChain插件,或者是直接封装了节点和边的LangGraph组件 | 一个“超级魔法指挥棒的专属武器库组件”,不仅有武器,还有“使用说明书”——告诉你什么时候用这个武器,用了之后接下来要做什么 |
| 幻觉(Hallucination) | LLM生成的看起来合理但实际上是错误的信息 | 小精灵“胡说八道”,比如告诉你“芒果班戟的原料是苹果和面粉” |
| 异步(Asynchronous) | 一种编程方式,可以让多个任务同时进行,不需要等前一个任务做完 | 多个小精灵同时干活,比如文案策划小精灵在写文案的时候,食材调研小精灵已经在查价格了 |
1.4.2 相关概念解释
| 相关概念 | 简要解释 |
|---|---|
| API | 应用程序编程接口(Application Programming Interface),是两个软件之间通信的“桥梁” |
| API密钥(API Key) | 一种用于验证API调用者身份的“密码” |
| JSON | 一种轻量级的数据交换格式,易于人类阅读和编写,也易于机器解析和生成 |
| 环境变量(Environment Variable) | 一种存储在操作系统环境中的变量,用于存储敏感信息(比如API密钥)或者配置信息 |
1.4.3 缩略词列表
| 缩略词 | 全称 | 中文翻译 |
|---|---|---|
| LLM | Large Language Model | 大语言模型 |
| API | Application Programming Interface | 应用程序编程接口 |
| JSON | JavaScript Object Notation | JavaScript对象表示法 |
| SDK | Software Development Kit | 软件开发工具包 |
| UI | User Interface | 用户界面 |
| CLI | Command Line Interface | 命令行界面 |
| OS | Operating System | 操作系统 |
| IDE | Integrated Development Environment | 集成开发环境 |
| GPU | Graphics Processing Unit | 图形处理器 |
| CPU | Central Processing Unit | 中央处理器 |
2. 核心概念与联系:用乐高、小精灵和魔法指挥棒讲明白
2.1 故事引入:小李的“美食助手多智能体团队”梦想
上一章我们讲了小李的烦恼——开4个网页窗口来回切换,折腾2小时才写好一篇小红书。那小李的梦想是什么呢?她的梦想是有一个**“美食助手多智能体团队”**,这个团队里有4个不同技能的AI小精灵:
- 文案策划小精灵(小艺):专门负责写小红书美食文案,会加表情符号,会分步骤,会控制字数,还会根据食材调研的结果调整文案;
- 食材调研小精灵(小食):专门负责查本地的食材价格和超市位置,会用高德地图API,还会把结果整理成结构化的信息传给小艺;
- 配图设计小精灵(小图):专门负责生成小红书风格的配图,会用Stable Diffusion WebUI API,还会根据小艺的文案生成合适的提示词;
- 资料整理小精灵(小理):专门负责把文案、提示词、调研结果整理好,存入Notion,方便下次用。
这个团队是怎么工作的呢?小李只需要说一句“帮我写一篇周末在家做芒果班戟的小红书”,然后:
- 团队从共享笔记本的第一页(起点)开始;
- 小艺先写一个初步的文案,写在共享笔记本上;
- 小理(不对,应该是小食)看了共享笔记本上的文案,知道需要芒果、面粉、鸡蛋这些食材,然后用高德地图API查本地的价格和位置,把结果写在共享笔记本上;
- 小艺看了共享笔记本上的调研结果,调整了文案(比如加上“今天楼下永辉超市的芒果只要9.9元一斤哦!”),再写在共享笔记本上;
- 小图看了共享笔记本上的最终文案,生成3张小红书风格的配图提示词,再用Stable Diffusion WebUI API生成配图,把提示词和配图的URL写在共享笔记本上;
- 小理看了共享笔记本上的所有内容,整理好存入Notion,把Notion的页面链接写在共享笔记本上;
- 团队到共享笔记本的最后一页(终点),把所有内容(文案、配图URL、Notion链接)一起给小李。
哇!这是不是太完美了?那怎么才能实现这个梦想呢?没错!就是用超级魔法指挥棒——LangGraph,还有我们自己造的专属武器库——美食小红书生成器插件!
2.2 核心概念解释(像给小学生讲故事一样)
好了,故事讲完了,现在我们来正式解释LangGraph和LangChain插件的核心概念——用的都是刚才故事里的比喻哦!
2.2.1 核心概念一:什么是LangGraph?
上一章我们说过,LangChain是一个“AI工具箱”,但它是“线性的链条”——就像让小精灵们排成一队,必须前一个做完才能下一个,万一中间需要“商量”或者“修改”前一个的结果,线性链条就完全做不到了!
那LangGraph是什么呢?LangGraph是LangChain团队在2024年初发布的一个升级框架,它的全称是“LangChain Graph State Machine”——翻译成中文就是“LangChain图状态机”。不过我们不用管这个专业的名字,我们只需要记住:
LangGraph就是一个超级魔法指挥棒,它不是让AI小精灵排成一队干活,而是让它们在一张“状态图”(也就是共享笔记本的每一页之间的箭头和选择题)里随便走、随便商量、随便修改,最后给你想要的结果!
更具体一点说,LangGraph有以下几个特点:
- 状态驱动:所有小精灵的工作都是围绕着“共享笔记本(状态)”展开的——每个小精灵都可以读取和修改共享笔记本的内容,大家的信息是完全同步的;
- 图结构:不是线性的链条,而是像思维导图那样的图结构——有起点、终点、节点(小精灵)、边(箭头)、条件边(选择题);
- 循环支持:可以让小精灵们重复做某个任务,直到满足条件——比如小艺写文案,小图觉得不合适,让小艺回去修改,改到小图满意为止;
- 多智能体支持:可以轻松地把多个不同技能的小精灵组织起来,让它们互相配合;
- 可视化支持:可以把状态图画出来,方便调试和理解;
- LangChain兼容:完全兼容LangChain的所有组件——工具、LLM、文档加载器、提示词模板等等,你之前用LangChain做的东西,都可以直接用到LangGraph里!
2.2.2 核心概念二:什么是状态(State)?
状态是LangGraph应用的灵魂,没有状态,LangGraph就和普通的线性链条没有区别了!那状态是什么呢?
状态就是一个共享笔记本,所有AI小精灵都可以在上面写字、画画、修改,大家都能看到别人写的内容,而且大家的修改都是实时同步的!
更专业一点说,状态是一个Python字典(或者Pydantic模型,Pydantic模型我们后面会讲),里面存储了所有小精灵在工作过程中产生的信息——比如文案、调研结果、配图提示词、配图URL、Notion链接等等。
那为什么要用状态呢?因为:
- 信息同步:所有小精灵都能看到同一个共享笔记本,不需要手动复制粘贴;
- 修改方便:小精灵可以随时修改共享笔记本的内容,比如小艺可以根据小食的调研结果调整文案;
- 循环支持:可以把“是否需要修改”的信息写在共享笔记本上,然后用条件边决定是否回到之前的节点;
- 结果输出:最后可以把共享笔记本里的所有内容(或者部分内容)作为结果输出给用户。
举个例子,我们的“美食助手多智能体团队”的状态可能是这样的(Python字典格式):
{
"user_query": "帮我写一篇周末在家做芒果班戟的小红书", # 用户的原始请求
"initial_script": "🍰周末在家做芒果班戟啦!超简单零失败!\n\n食材:...", # 小艺写的初步文案
"ingredient_research": { # 小食的调研结果
"mango_price": "9.9元/斤",
"supermarket": "永辉超市(XX路店)",
"address": "XX市XX区XX路123号"
},
"final_script": "🍰周末在家做芒果班戟啦!超简单零失败!今天楼下永辉超市的芒果只要9.9元一斤哦!\n\n食材:...", # 小艺调整后的最终文案
"image_prompts": [ # 小图生成的配图提示词
"小红书风格,食材大合照:芒果2个,低筋面粉100克,鸡蛋2个,纯牛奶200毫升,糖粉适量,淡奶油200毫升,白砂糖30克,自然光,温暖色调,特写,无文字,4K",
"小红书风格,制作过程:煎班戟皮,平底锅,小火,淡黄色的班戟皮,特写,温暖色调,自然光,无文字,4K",
"小红书风格,成品装盘:芒果班戟,撒上糖粉,白色陶瓷盘,绿色薄荷叶装饰,温暖色调,自然光,俯视角度,无文字,4K"
],
"image_urls": [ # 小图生成的配图URL
"https://example.com/image1.jpg",
"https://example.com/image2.jpg",
"https://example.com/image3.jpg"
],
"notion_page_url": "https://www.notion.so/xxx/Mango-Pancake-xxx", # 小理存的Notion页面链接
"needs_revision": False # 是否需要修改的标记
}
2.2.3 核心概念三:什么是节点(Node)?
节点是LangGraph应用的工作单元,每个节点对应一个具体的任务——可以是调用LLM、调用工具、修改状态、判断条件等等。那节点是什么呢?
节点就是一个AI小精灵或者AI小精灵的任务组,负责完成一个具体的工作!
更专业一点说,节点是一个Python函数,这个函数接收当前的状态作为输入,然后返回一个**新的状态(或者状态的一部分)**作为输出——注意哦,节点通常不会直接修改输入的状态,而是返回一个新的状态或者状态的增量,LangGraph会自动把这个增量合并到当前的状态里!
举个例子,我们的“美食助手多智能体团队”里的小艺(文案策划小精灵)对应的节点函数可能是这样的(简化版):
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
# 初始化LLM
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.7)
# 初始化提示词模板
prompt_template = ChatPromptTemplate.from_messages([
("system", "你是一个专业的小红书美食博主,专门负责写带表情符号、分步骤、适合新手、字数在300-500字之间的美食文案。如果有食材调研结果,请把调研结果自然地融入文案里。"),
("user", "用户的原始请求:{user_query}\n初步文案:{initial_script}\n食材调研结果:{ingredient_research}")
])
# 把提示词模板和LLM组合成一个链
script_chain = prompt_template | llm
# 定义小艺的节点函数
def script_planner_node(state):
# 从状态里读取需要的信息
user_query = state["user_query"]
initial_script = state.get("initial_script", "")
ingredient_research = state.get("ingredient_research", {})
# 调用链生成文案
response = script_chain.invoke({
"user_query": user_query,
"initial_script": initial_script,
"ingredient_research": ingredient_research
})
final_script = response.content.strip()
# 返回状态的增量——注意哦,我们只返回需要修改的部分,LangGraph会自动合并到当前的状态里
return {
"final_script": final_script,
"needs_revision": False # 先假设不需要修改,后面可以让小图修改这个标记
}
看!这个节点函数是不是很简单?它接收当前的状态作为输入,调用LLM生成文案,然后返回状态的增量——final_script和needs_revision。
2.2.4 核心概念四:什么是边(Edge)和条件边(Conditional Edge)?
边和条件边是LangGraph应用的**“连接线”和“选择题”**,告诉小精灵们做完一个任务之后,接下来要做什么。那边和条件边是什么呢?
边就是一个固定的箭头,画在共享笔记本的旁边,告诉小精灵们写完这一页之后,接下来一定要写哪一页!
条件边就是一个选择题,画在共享笔记本的旁边,告诉小精灵们写完这一页之后,接下来要写哪一页,取决于共享笔记本上的某个内容!
更专业一点说,边是从一个节点到另一个节点的固定连接,而条件边是从一个节点到一个“路由函数”的连接,路由函数接收当前的状态作为输入,然后返回下一个节点的名字(或者END,表示结束)。
举个例子,我们的“美食助手多智能体团队”的状态图里可能有以下几条边和条件边:
- 起点 → 小艺(初步文案):固定边,告诉小精灵们从起点开始,先去小艺那里写初步文案;
- 小艺(初步文案) → 小食(食材调研):固定边,告诉小精灵们写完初步文案之后,去小食那里查食材;
- 小食(食材调研) → 小艺(最终文案):固定边,告诉小精灵们查完食材之后,回到小艺那里调整文案;
- 小艺(最终文案) → 小图(配图生成):固定边,告诉小精灵们调整完文案之后,去小图那里生成配图;
- 小图(配图生成) → 路由函数(是否需要修改):条件边,告诉小精灵们生成完配图之后,去路由函数那里做选择题;
- 路由函数(是否需要修改) → 小艺(最终文案):如果
needs_revision是True,就回到小艺那里修改文案; - 路由函数(是否需要修改) → 小理(资料整理):如果
needs_revision是False,就去小理那里整理资料; - 小理(资料整理) → 终点:固定边,告诉小精灵们整理完资料之后,就结束工作。
那路由函数是什么样的呢?举个简化版的例子:
from langgraph.graph import END
# 定义路由函数
def revision_router(state):
# 从状态里读取是否需要修改的标记
needs_revision = state.get("needs_revision", False)
# 做选择题
if needs_revision:
return "script_planner_final" # 回到小艺(最终文案)的节点
else:
return "note_organizer" # 去小理(资料整理)的节点
看!这个路由函数是不是很简单?它接收当前的状态作为输入,读取needs_revision的标记,然后返回下一个节点的名字。
2.2.5 核心概念五:什么是工具(Tool)和LangChain插件(LangChain Plugin)?
工具和LangChain插件是LLM的**“武器”和“武器套装”**,有了它们,LLM就能做更多的事了——比如查天气、画图、算数学题、搜索资料等等。那工具和LangChain插件是什么呢?
工具就是一个AI小精灵的武器,比如“搜索枪”“计算器刀”“画图魔法棒”,有了这个武器,小精灵就能做一件具体的事!
LangChain插件就是一个AI小精灵的武器套装,比如“美食武器套装”里有“文案生成枪”“食材调研刀”“画图魔法棒”“资料整理本”,有了这个套装,小精灵就能做一组相关的事!
更专业一点说,工具是一个Python类,继承自langchain_core.tools.BaseTool,它有以下几个核心属性和方法:
- name:工具的名字,LLM通过这个名字来调用工具;
- description:工具的描述,告诉LLM这个工具是做什么的、什么时候用、怎么用;
- args_schema:工具的参数 schema,告诉LLM这个工具需要什么参数、参数的类型是什么、参数的描述是什么;
- _run:工具的同步执行方法,接收参数作为输入,返回结果作为输出;
- _arun:工具的异步执行方法,和
_run类似,但支持异步操作(可以同时执行多个任务)。
举个例子,我们的“美食助手多智能体团队”里的“高德地图查芒果价格”的工具(简化版)可能是这样的:
from langchain_core.tools import BaseTool
from pydantic import BaseModel, Field
from typing import Type
import requests
# 定义工具的参数 schema
class MangoPriceToolInput(BaseModel):
city: str = Field(description="要查询的城市名称,比如北京、上海、广州")
address: str = Field(description="要查询的具体地址,比如XX区XX路,或者留空查询全市")
# 定义工具类
class MangoPriceTool(BaseTool):
name: str = "mango_price_tool"
description: str = "这是一个专门用于查询本地芒果价格和附近超市位置的工具,当用户需要写美食文案或者购买食材时,可以调用这个工具。参数:city(必填,城市名称)、address(可选,具体地址)。返回:JSON格式的结果,包含芒果价格、超市名称、超市地址。"
args_schema: Type[BaseModel] = MangoPriceToolInput
def _run(self, city: str, address: str = "") -> str:
# 这里我们用一个模拟的API,实际上你需要用真实的高德地图API或者其他电商API
mock_api_url = "https://api.example.com/mango-price"
params = {
"city": city,
"address": address,
"api_key": "your_mock_api_key" # 这里需要换成真实的API密钥
}
try:
response = requests.get(mock_api_url, params=params, timeout=10)
response.raise_for_status() # 如果API调用失败,抛出异常
return response.text # 返回JSON格式的字符串
except Exception as e:
return f"查询失败:{str(e)}"
# 异步执行方法,我们后面会讲
async def _arun(self, city: str, address: str = "") -> str:
pass
看!这个工具类是不是很简单?它继承自BaseTool,定义了名字、描述、参数 schema,还有同步执行方法_run。
那LangChain插件是什么呢?LangChain插件其实就是一个包含多个工具的Python包,或者是一个通过HTTP协议暴露的工具服务。LangChain官方提供了一个插件的注册平台——LangChain Hub,你可以把自己做的插件上传到LangChain Hub,也可以从LangChain Hub下载别人做的插件。
不过,对于我们的“美食小红书生成器插件”来说,我们不需要上传到LangChain Hub,我们只需要把它做成一个本地的Python包或者一个包含多个工具的列表,然后直接在LangGraph里使用就可以了!
2.2.6 核心概念六:什么是LangGraph插件?
其实,LangGraph并没有专门的“插件类型”,我们通常说的LangGraph插件,是指专门为LangGraph设计的、可以很好地处理状态传递的LangChain插件,或者是直接封装了节点和边的LangGraph组件。
为什么需要专门为LangGraph设计插件呢?因为普通的LangChain工具只能接收参数作为输入,返回结果作为输出,而LangGraph的节点是接收状态作为输入,返回状态的增量作为输出的。所以,为了让普通的LangChain工具更好地在LangGraph里使用,我们通常会把工具封装成一个节点函数——这个节点函数从状态里读取工具需要的参数,调用工具,然后把工具的返回结果合并到状态里。
不过,更高级的LangGraph插件会直接封装多个节点和边,甚至会封装一个子图(Subgraph)——子图就是一个小的状态图,可以作为一个大的状态图的节点使用。这样的话,你只需要把这个子图插件添加到你的大状态图里,就可以直接使用它的所有功能了,非常方便!
举个例子,我们的“美食小红书生成器插件”如果做成一个子图插件的话,它可能会封装“小艺(初步文案)”“小食(食材调研)”“小艺(最终文案)”“小图(配图生成)”“小理(资料整理)”这几个节点,还有它们之间的边和条件边——你只需要把这个子图插件添加到你的大状态图里,就可以直接使用它生成美食小红书了!
2.3 核心概念之间的关系(用小学生能理解的比喻)
好了,核心概念解释完了,现在我们来聊一聊这些核心概念之间的关系——用的还是刚才故事里的比喻哦!
2.3.1 概念一和概念二的关系:LangGraph和状态的关系
LangGraph和状态的关系,就像超级魔法指挥棒和共享笔记本的关系——没有共享笔记本,超级魔法指挥棒就没法指挥小精灵们互相配合;没有超级魔法指挥棒,共享笔记本就只是一本普通的笔记本,没法让小精灵们按照一定的顺序工作!
更专业一点说,状态是LangGraph应用的“记忆库”和“信息中心”,LangGraph的所有节点、边、条件边都是围绕着状态展开的——节点读取状态的信息,修改状态的信息;边和条件边根据状态的信息决定接下来要做什么。
2.3.2 概念二和概念三的关系:状态和节点的关系
状态和节点的关系,就像共享笔记本和AI小精灵的关系——AI小精灵从共享笔记本里读取需要的信息,然后把自己的工作成果写在共享笔记本上;所有AI小精灵都能看到共享笔记本上的内容,大家的信息是完全同步的!
更专业一点说,节点是LangGraph应用的“工作单元”,状态是节点的“输入”和“输出”——节点接收当前的状态作为输入,返回一个新的状态或者状态的增量作为输出;LangGraph会自动把这个增量合并到当前的状态里,生成一个新的状态,然后传递给下一个节点。
2.3.3 概念三和概念四的关系:节点和边/条件边的关系
节点和边/条件边的关系,就像AI小精灵和箭头/选择题的关系——箭头告诉AI小精灵做完这个任务之后,接下来一定要做什么;选择题告诉AI小精灵做完这个任务之后,接下来要做什么,取决于共享笔记本上的某个内容!
更专业一点说,边和条件边是LangGraph应用的“控制流”——它们决定了节点的执行顺序;固定边的执行顺序是固定的,条件边的执行顺序是动态的,取决于当前的状态。
2.3.4 概念三和概念五的关系:节点和工具/LangChain插件的关系
节点和工具/LangChain插件的关系,就像AI小精灵和武器/武器套装的关系——AI小精灵没有武器,只能做一些简单的事(比如写作文、算数学题);有了武器,AI小精灵就能做更多的事(比如查天气、画图、搜索资料);有了武器套装,AI小精灵就能做一组相关的事(比如生成美食小红书)!
更专业一点说,工具和LangChain插件是节点的“外部能力扩展”——节点可以调用工具和LangChain插件来完成一些LLM本身无法完成的任务;普通的LangChain工具需要封装成节点函数才能在LangGraph里使用,而高级的LangGraph插件可以直接封装成子图,作为一个大的状态图的节点使用。
2.3.5 概念五和概念六的关系:LangChain插件和LangGraph插件的关系
LangChain插件和LangGraph插件的关系,就像普通武器套装和超级魔法指挥棒专属武器套装的关系——普通武器套装任何AI小精灵都能用,但用的时候需要手动给小精灵递武器、收武器;超级魔法指挥棒专属武器套装不仅有武器,还有“使用说明书”——告诉你什么时候用这个武器,用了之后接下来要做什么,甚至还会自动给小精灵递武器、收武器!
更专业一点说,LangChain插件是通用的,可以在任何LangChain应用里使用,但用的时候需要手动处理参数和结果;LangGraph插件是专门为LangGraph设计的,可以很好地处理状态传递,甚至可以直接封装成子图,使用起来非常方便。
2.4 核心概念原理和架构的文本示意图(专业定义)
为了让大家更直观地理解LangGraph的核心概念和架构,我们来看一个文本示意图:
┌─────────────────────────────────────────────────────────────────────────────────────────┐
│ LangGraph 应用架构示意图 │
├─────────────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────────────────────────────────────────────┐ │
│ │ 状态(State):Pydantic 模型 / Python 字典 │ │
│ │ ┌─────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ user_query │ │ final_script │ │ image_urls │ │ notion_url │ ... │ │
│ │ └─────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────────────────────┘ │
│ ↑↓ 读取和修改状态 │
│ ┌───────────────────────────────────────────────────────────────────────────────────┐ │
│ │ 图(Graph):节点 + 边 + 条件边 + 起点 + 终点 │ │
│ │ │ │
│ │ ┌─────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ │
│ │ │ 起点 │────▶│ 节点1 │────▶│ 节点2 │───┬─▶│ 节点3 │────▶│ 终点 │ │
│ │ └─────────┘ └──────────┘ └──────────┘ │ └──────────┘ └─────────┘ │
│ │ ▲ │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────┘ 条件边(路由函数) │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────────────────────────┘ │
│ ↑↓ 调用外部能力 │
│ ┌───────────────────────────────────────────────────────────────────────────────────┐ │
│ │ 外部能力:工具 + LangChain插件 + LangGraph插件 + 子图 │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ 工具1 │ │ 工具2 │ │ 插件1 │ │ 子图1 │ ... │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ └───────────────────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────────────┘
这个文本示意图是不是很直观?它展示了LangGraph应用的三大核心部分:
- 状态(State):存储所有信息的“记忆库”;
- 图(Graph):包含节点、边、条件边、起点、终点的“控制流”;
- 外部能力:包含工具、LangChain插件、LangGraph插件、子图的“能力扩展”。
2.5 Mermaid 流程图(核心概念交互关系图)
为了让大家更直观地理解核心概念之间的交互关系,我们来看一个Mermaid流程图:
更多推荐



所有评论(0)