LangGraph 插件开发教程:打造专属多智能体工具的全流程

关键词:LangGraph、多智能体系统、LangChain插件、智能工具编排、状态管理、LLM驱动应用、Python插件开发

摘要:想象一下你有一个由不同技能“小精灵助手”组成的团队——有的会画图,有的会查天气,有的会算数学题,有的会写代码,但它们之前各干各的,没法好好配合。LangGraph就是把这些小精灵组织起来当指挥官的“超级魔法指挥棒”,而插件则是给指挥棒准备的“专属武器库”——你想要小精灵们用什么新工具?自己造!这篇教程会像搭乐高一样,一步一步教你从零开始理解LangGraph、掌握它的插件体系、亲手打造第一个专属插件(比如帮你写带配图的小红书美食分享的“美食小红书生成器插件”)、再把它集成到真正的多智能体应用里,最后还有进阶的插件开发技巧和未来展望。全文没有晦涩的术语堆砌,全是小学生都能懂的故事比喻,还有完整可运行的Python代码,保证你看完就能动手做出属于自己的AI小工具!


1. 背景介绍:从“孤独的AI小精灵”到“超级团队指挥官”

1.1 目的和范围

1.1.1 我们要解决什么问题?

先给大家讲个我朋友上周的真实故事,就像给孤独的小精灵找团队那样,有共鸣感——

我朋友小李是个美食博主,最近她想写一篇“周末在家做芒果班戟”的小红书。她需要做什么呢?

  1. 先问AI“帮我写一篇带表情符号、分步骤、适合新手的小红书芒果班戟食谱文案”;
  2. 再查本地的芒果价格和超市位置,确定配图里要不要突出水果摊的实拍灵感;
  3. 接着用AI画图工具生成3张高质量的小红书风格配图:食材大合照、制作过程的煎班戟皮图、成品装盘撒糖粉图;
  4. 最后把文案和图片的提示词整理一下,方便下次用。

结果呢?她开了4个网页窗口:ChatGPT写文案、高德地图查价格/位置、Stable Diffusion画图、Notion存提示词,来回切换复制粘贴,折腾了快2小时才弄好!要是有个“美食小红书生成器小助手”,能自己串起这些事,2分钟搞定该多好?

没错!小李遇到的问题,就是现在很多人用AI工具的通病:工具是分散的,没法自动串联,每次用都要手动当“传声筒”和“搬运工”。之前的LangChain虽然也能把工具连起来,但它是“线性的链条”——就像让小精灵们排成一队,必须前一个做完才能下一个,万一中间需要“商量”或者“修改”前一个的结果(比如小李觉得文案太长,要让写文案的小精灵先缩一下再给画图的生成配图),线性链条就完全做不到了!

那怎么办?这时候就需要超级魔法指挥棒——LangGraph登场了!它不是线性的链条,而是像思维导图那样的“状态图”——你可以让小精灵们在图里随便走,随便商量,随便修改,最后给你想要的结果!而插件呢?就是给这个超级指挥棒准备的“专属武器库”——LangGraph自带一些基础武器(比如搜索、计算器),但如果你想要“芒果班戟小红书生成器”这种定制化武器,就得自己造插件!

1.1.2 这篇教程会教你什么?

这篇教程是LangGraph插件开发的“保姆级全流程指南”,从0基础的小白,到想进阶的开发者,都能有所收获。我们会覆盖以下内容:

  1. LangGraph核心概念扫盲:用乐高、小精灵、魔法指挥棒这些比喻,讲清楚什么是状态、节点、边、条件边这些最核心的东西;
  2. LangChain插件体系入门:因为LangGraph的插件是基于LangChain的,所以我们先搞懂LangChain的插件是啥、怎么用;
  3. 从零打造第一个专属LangGraph插件:我们会一起做“美食小红书生成器插件”——这个插件会整合“小红书文案生成”“高德API查本地芒果价格/位置”“Stable Diffusion WebUI API生成配图”“Notion存提示词”4个工具;
  4. 把插件集成到真正的多智能体应用里:我们会用LangGraph搭一个“美食助手多智能体团队”——团队里有“文案策划小精灵”“食材调研小精灵”“配图设计小精灵”“资料整理小精灵”4个角色,它们会用我们做的插件互相配合,自动完成小李的任务;
  5. 插件开发进阶技巧:比如插件的状态传递、错误处理、权限控制、性能优化、多工具组合插件、异步插件开发;
  6. 插件的测试与部署:比如怎么用LangSmith测试插件的效果,怎么把插件部署到LangChain Hub或者本地的仓库里;
  7. 未来发展趋势与挑战:比如LangGraph插件的标准化、跨平台部署、多模态插件、实时协作插件;
  8. 最佳实践和避坑指南:比如我在开发插件时踩过的那些坑,怎么避免;
  9. 常见问题与解答:比如“LangGraph和AutoGen有啥区别?”“插件开发用不用LangChain?”这些问题的答案。
1.1.3 这篇教程不会教你什么?

为了保证教程的聚焦和通俗易懂,我们不会讲以下内容:

  1. Python语法的基础入门:你需要至少会一点Python——比如变量、函数、类、if-else、for循环这些;
  2. LangChain的所有功能:我们只会讲和LangGraph插件开发相关的LangChain内容;
  3. Stable Diffusion WebUI的部署:我们会假设你已经有一个可用的Stable Diffusion WebUI API(或者你可以用我们提供的免费演示API密钥,不过有调用次数限制);
  4. 高德地图API的详细配置:我们会告诉你怎么申请API密钥,但不会讲高德地图API的所有功能;
  5. Notion API的详细配置:同理,我们会告诉你怎么申请API密钥,但不会讲Notion API的所有功能;
  6. 非常复杂的多智能体系统设计:比如多智能体的博弈论、共识机制这些,我们只会讲最基础、最实用的多智能体编排;
  7. 其他编程语言的LangGraph插件开发:目前LangGraph的官方支持语言是Python和TypeScript,但这篇教程只会讲Python,因为Python对小白更友好。

1.2 预期读者

这篇教程的预期读者是:

  1. 对AI驱动应用感兴趣的小白:只要会一点Python,就能跟着教程一步步做;
  2. LangChain的老用户:想从“线性链条”升级到“状态图”,并掌握插件开发;
  3. 多智能体系统的开发者:想快速打造定制化的多智能体工具;
  4. 产品经理和设计师:想了解多智能体工具的开发流程,为产品设计提供思路;
  5. 学生和研究者:想学习LangGraph和多智能体系统的基础知识。

1.3 文档结构概述

为了让大家像搭乐高一样,一步一步跟着教程走,我们把文档分成了以下几个部分:

  1. 背景介绍:就是现在你正在看的这部分,讲了我们要解决的问题、教程的目的和范围、预期读者、文档结构、术语表;
  2. 核心概念与联系:用乐高、小精灵、魔法指挥棒这些比喻,讲清楚LangGraph和LangChain插件的核心概念,还有它们之间的关系;
  3. 准备工作:环境搭建和工具申请:这部分我们会一起搭建开发环境,申请需要的API密钥(OpenAI、高德地图、Notion、Stable Diffusion WebUI);
  4. LangChain插件体系入门:打造基础的单工具插件:这部分我们先搞懂LangChain的插件体系,一起做几个基础的单工具插件——比如“天气查询插件”“计算器插件”;
  5. 从零打造第一个专属LangGraph多工具插件:美食小红书生成器插件:这部分是教程的核心,我们会一起整合4个工具,做一个真正有用的定制化插件;
  6. 把插件集成到LangGraph多智能体应用里:这部分我们会用LangGraph搭一个“美食助手多智能体团队”,让它们用我们做的插件互相配合;
  7. 插件开发进阶技巧:这部分我们会讲一些进阶的插件开发技巧,让你的插件更强大、更稳定;
  8. 插件的测试与部署:这部分我们会讲怎么测试和部署你的插件;
  9. 最佳实践和避坑指南:这部分我会分享我在开发插件时踩过的那些坑,还有一些最佳实践;
  10. 未来发展趋势与挑战:这部分我们会聊一聊LangGraph插件的未来;
  11. 总结:学到了什么?:这部分我们会回顾一下教程的主要内容;
  12. 思考题:动动小脑筋:这部分我们会给大家留一些思考题,鼓励大家进一步思考和应用所学知识;
  13. 附录:常见问题与解答:这部分我们会解答一些常见的问题;
  14. 扩展阅读 & 参考资料:这部分我们会给大家推荐一些扩展阅读和参考资料。

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小精灵:

  1. 文案策划小精灵(小艺):专门负责写小红书美食文案,会加表情符号,会分步骤,会控制字数,还会根据食材调研的结果调整文案;
  2. 食材调研小精灵(小食):专门负责查本地的食材价格和超市位置,会用高德地图API,还会把结果整理成结构化的信息传给小艺;
  3. 配图设计小精灵(小图):专门负责生成小红书风格的配图,会用Stable Diffusion WebUI API,还会根据小艺的文案生成合适的提示词;
  4. 资料整理小精灵(小理):专门负责把文案、提示词、调研结果整理好,存入Notion,方便下次用。

这个团队是怎么工作的呢?小李只需要说一句“帮我写一篇周末在家做芒果班戟的小红书”,然后:

  1. 团队从共享笔记本的第一页(起点)开始;
  2. 小艺先写一个初步的文案,写在共享笔记本上;
  3. 小理(不对,应该是小食)看了共享笔记本上的文案,知道需要芒果、面粉、鸡蛋这些食材,然后用高德地图API查本地的价格和位置,把结果写在共享笔记本上;
  4. 小艺看了共享笔记本上的调研结果,调整了文案(比如加上“今天楼下永辉超市的芒果只要9.9元一斤哦!”),再写在共享笔记本上;
  5. 小图看了共享笔记本上的最终文案,生成3张小红书风格的配图提示词,再用Stable Diffusion WebUI API生成配图,把提示词和配图的URL写在共享笔记本上;
  6. 小理看了共享笔记本上的所有内容,整理好存入Notion,把Notion的页面链接写在共享笔记本上;
  7. 团队到共享笔记本的最后一页(终点),把所有内容(文案、配图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有以下几个特点:

  1. 状态驱动:所有小精灵的工作都是围绕着“共享笔记本(状态)”展开的——每个小精灵都可以读取和修改共享笔记本的内容,大家的信息是完全同步的;
  2. 图结构:不是线性的链条,而是像思维导图那样的图结构——有起点、终点、节点(小精灵)、边(箭头)、条件边(选择题);
  3. 循环支持:可以让小精灵们重复做某个任务,直到满足条件——比如小艺写文案,小图觉得不合适,让小艺回去修改,改到小图满意为止;
  4. 多智能体支持:可以轻松地把多个不同技能的小精灵组织起来,让它们互相配合;
  5. 可视化支持:可以把状态图画出来,方便调试和理解;
  6. LangChain兼容:完全兼容LangChain的所有组件——工具、LLM、文档加载器、提示词模板等等,你之前用LangChain做的东西,都可以直接用到LangGraph里!
2.2.2 核心概念二:什么是状态(State)?

状态是LangGraph应用的灵魂,没有状态,LangGraph就和普通的线性链条没有区别了!那状态是什么呢?

状态就是一个共享笔记本,所有AI小精灵都可以在上面写字、画画、修改,大家都能看到别人写的内容,而且大家的修改都是实时同步的!

更专业一点说,状态是一个Python字典(或者Pydantic模型,Pydantic模型我们后面会讲),里面存储了所有小精灵在工作过程中产生的信息——比如文案、调研结果、配图提示词、配图URL、Notion链接等等。

那为什么要用状态呢?因为:

  1. 信息同步:所有小精灵都能看到同一个共享笔记本,不需要手动复制粘贴;
  2. 修改方便:小精灵可以随时修改共享笔记本的内容,比如小艺可以根据小食的调研结果调整文案;
  3. 循环支持:可以把“是否需要修改”的信息写在共享笔记本上,然后用条件边决定是否回到之前的节点;
  4. 结果输出:最后可以把共享笔记本里的所有内容(或者部分内容)作为结果输出给用户。

举个例子,我们的“美食助手多智能体团队”的状态可能是这样的(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_scriptneeds_revision

2.2.4 核心概念四:什么是边(Edge)和条件边(Conditional Edge)?

边和条件边是LangGraph应用的**“连接线”和“选择题”**,告诉小精灵们做完一个任务之后,接下来要做什么。那边和条件边是什么呢?

边就是一个固定的箭头,画在共享笔记本的旁边,告诉小精灵们写完这一页之后,接下来一定要写哪一页!
条件边就是一个选择题,画在共享笔记本的旁边,告诉小精灵们写完这一页之后,接下来要写哪一页,取决于共享笔记本上的某个内容!

更专业一点说,边是从一个节点到另一个节点的固定连接,而条件边是从一个节点到一个“路由函数”的连接,路由函数接收当前的状态作为输入,然后返回下一个节点的名字(或者END,表示结束)。

举个例子,我们的“美食助手多智能体团队”的状态图里可能有以下几条边和条件边:

  1. 起点 → 小艺(初步文案):固定边,告诉小精灵们从起点开始,先去小艺那里写初步文案;
  2. 小艺(初步文案) → 小食(食材调研):固定边,告诉小精灵们写完初步文案之后,去小食那里查食材;
  3. 小食(食材调研) → 小艺(最终文案):固定边,告诉小精灵们查完食材之后,回到小艺那里调整文案;
  4. 小艺(最终文案) → 小图(配图生成):固定边,告诉小精灵们调整完文案之后,去小图那里生成配图;
  5. 小图(配图生成) → 路由函数(是否需要修改):条件边,告诉小精灵们生成完配图之后,去路由函数那里做选择题;
  6. 路由函数(是否需要修改) → 小艺(最终文案):如果needs_revisionTrue,就回到小艺那里修改文案;
  7. 路由函数(是否需要修改) → 小理(资料整理):如果needs_revisionFalse,就去小理那里整理资料;
  8. 小理(资料整理) → 终点:固定边,告诉小精灵们整理完资料之后,就结束工作。

那路由函数是什么样的呢?举个简化版的例子:

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,它有以下几个核心属性和方法:

  1. name:工具的名字,LLM通过这个名字来调用工具;
  2. description:工具的描述,告诉LLM这个工具是做什么的、什么时候用、怎么用;
  3. args_schema:工具的参数 schema,告诉LLM这个工具需要什么参数、参数的类型是什么、参数的描述是什么;
  4. _run:工具的同步执行方法,接收参数作为输入,返回结果作为输出;
  5. _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应用的三大核心部分:

  1. 状态(State):存储所有信息的“记忆库”;
  2. 图(Graph):包含节点、边、条件边、起点、终点的“控制流”;
  3. 外部能力:包含工具、LangChain插件、LangGraph插件、子图的“能力扩展”。

2.5 Mermaid 流程图(核心概念交互关系图)

为了让大家更直观地理解核心概念之间的交互关系,我们来看一个Mermaid流程图:

发送请求

传递初始状态

读取状态 调用工具

返回结果

返回状态增量

合并增量 生成新状态

传递新状态

满足条件A

满足条件B

满足条件C

读取状态 调用工具

返回结果

返回状态增量

合并增量 生成新状态

传递新状态

读取状态 调用工具

返回结果

返回状态增量

合并增量 生成新状态

传递新状态

返回最终状态

用户

起点

节点1 比如文案策划

工具 LangChain插件 LangGraph插件

图 控制流

状态 共享笔记本

路由函数 条件边

节点2 比如食材调研

节点3 比如配图生成

终点

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐