【AI Agent系列】【LangGraph】1. 进阶实战:给你的 LangGraph 加入条件分支(Conditional edges)

本文涉及的产品
阿里云百炼推荐规格 ADB PostgreSQL,4核16GB 100GB 1个月
简介: 【AI Agent系列】【LangGraph】1. 进阶实战:给你的 LangGraph 加入条件分支(Conditional edges)
  • 大家好,我是同学小张,日常分享AI知识和实战案例
  • 欢迎 点赞 + 关注 👏,持续学习持续干货输出
  • 一起交流💬,一起进步💪。
  • 微信公众号也可搜【同学小张】 🙏

本站文章一览:


书接上文(【AI Agent系列】【LangGraph】0. 快速上手:协同LangChain,LangGraph帮你用图结构轻松构建多智能体应用),前面我们了解了 LangGraph 的概念和基本构造方法,今天我们来看下 LangGraph 构造中的进阶用法:给边加个条件 - 条件分支(Conditional edges)。

LangGraph 构造的是个图的数据结构,有节点(node) 和边(edge),那它的边也可以是带条件的。如何给边加入条件呢?可以通过 add_conditional_edges 函数添加带条件的边。

1. 完整代码及运行

废话不多说,先上完整代码,和运行结果。先跑起来看看效果再说。

from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, BaseMessage
from langgraph.graph import END, MessageGraph
import json
from langchain_core.messages import ToolMessage
from langchain_core.tools import tool
from langchain_core.utils.function_calling import convert_to_openai_tool
from typing import List
@tool
def multiply(first_number: int, second_number: int):
    """Multiplies two numbers together."""
    return first_number * second_number
model = ChatOpenAI(temperature=0)
model_with_tools = model.bind(tools=[convert_to_openai_tool(multiply)])
graph = MessageGraph()
def invoke_model(state: List[BaseMessage]):
    return model_with_tools.invoke(state)
graph.add_node("oracle", invoke_model)
def invoke_tool(state: List[BaseMessage]):
    tool_calls = state[-1].additional_kwargs.get("tool_calls", [])
    multiply_call = None
    for tool_call in tool_calls:
        if tool_call.get("function").get("name") == "multiply":
            multiply_call = tool_call
    if multiply_call is None:
        raise Exception("No adder input found.")
    res = multiply.invoke(
        json.loads(multiply_call.get("function").get("arguments"))
    )
    return ToolMessage(
        tool_call_id=multiply_call.get("id"),
        content=res
    )
graph.add_node("multiply", invoke_tool)
graph.add_edge("multiply", END)
graph.set_entry_point("oracle")
def router(state: List[BaseMessage]):
    tool_calls = state[-1].additional_kwargs.get("tool_calls", [])
    if len(tool_calls):
        return "multiply"
    else:
        return "end"
graph.add_conditional_edges("oracle", router, {
    "multiply": "multiply",
    "end": END,
})
runnable = graph.compile()
response = runnable.invoke(HumanMessage("What is 123 * 456?"))
print(response)

运行结果如下:

2. 代码详解

下面对上面的代码进行详细解释。

2.1 add_conditional_edges

首先,我们知道了可以通过 add_conditional_edges 来对边进行条件添加。这部分代码如下:

graph.add_conditional_edges("oracle", router, {
    "multiply": "multiply",
    "end": END,
})

add_conditional_edges接收三个参数:

  • 第一个为这条边的第一个node的名称
  • 第二个为这条边的条件
  • 第三个为条件返回结果的映射(根据条件结果映射到相应的node)

如上面的代码,意思就是往 “oracle” node上添加边,这个node有两条边,一条是往“multiply” node上走,一条是往“END”上走。怎么决定往哪个方向去:条件是 router(后面解释),如果 router 返回的是“multiply”,则往“multiply”方向走,如果 router 返回的是 “end”,则走“END”。

来看下这个函数的源码:

def add_conditional_edges(
    self,
    start_key: str,
    condition: Callable[..., str],
    conditional_edge_mapping: Optional[Dict[str, str]] = None,
) -> None:
    if self.compiled:
        logger.warning(
            "Adding an edge to a graph that has already been compiled. This will "
            "not be reflected in the compiled graph."
        )
    if start_key not in self.nodes:
        raise ValueError(f"Need to add_node `{start_key}` first")
    if iscoroutinefunction(condition):
        raise ValueError("Condition cannot be a coroutine function")
    if conditional_edge_mapping and set(
        conditional_edge_mapping.values()
    ).difference([END]).difference(self.nodes):
        raise ValueError(
            f"Missing nodes which are in conditional edge mapping. Mapping "
            f"contains possible destinations: "
            f"{list(conditional_edge_mapping.values())}. Possible nodes are "
            f"{list(self.nodes.keys())}."
        )
    self.branches[start_key].append(Branch(condition, conditional_edge_mapping))

重点是这一句:self.branches[start_key].append(Branch(condition, conditional_edge_mapping)),给当前node添加分支Branch。

2.2 条件 router

条件代码如下:判断执行结果中是否有 tool_calls 参数,如果有,则返回"multiply",没有,则返回“end”。

def router(state: List[BaseMessage]):
    tool_calls = state[-1].additional_kwargs.get("tool_calls", [])
    if len(tool_calls):
        return "multiply"
    else:
        return "end"

2.3 各node的定义

(1)起始node:oracle

@tool
def multiply(first_number: int, second_number: int):
    """Multiplies two numbers together."""
    return first_number * second_number
model = ChatOpenAI(temperature=0)
model_with_tools = model.bind(tools=[convert_to_openai_tool(multiply)])
graph = MessageGraph()
def invoke_model(state: List[BaseMessage]):
    return model_with_tools.invoke(state)
graph.add_node("oracle", invoke_model)

这个node是一个带有Tools 的 ChatOpenAI。在LangChain中使用Tools的详细教程请看这篇文章:【AI大模型应用开发】【LangChain系列】5. 实战LangChain的智能体Agents模块。简单解释就是:这个node的执行结果,将返回是否应该使用绑定的Tools。

(2)multiply

def invoke_tool(state: List[BaseMessage]):
    tool_calls = state[-1].additional_kwargs.get("tool_calls", [])
    multiply_call = None
    for tool_call in tool_calls:
        if tool_call.get("function").get("name") == "multiply":
            multiply_call = tool_call
    if multiply_call is None:
        raise Exception("No adder input found.")
    res = multiply.invoke(
        json.loads(multiply_call.get("function").get("arguments"))
    )
    return ToolMessage(
        tool_call_id=multiply_call.get("id"),
        content=res
    )
graph.add_node("multiply", invoke_tool)

这个node的作用就是执行Tools。

2.4 总体流程

如果觉得本文对你有帮助,麻烦点个赞和关注呗 ~~~


  • 大家好,我是 同学小张,日常分享AI知识和实战案例
  • 欢迎 点赞 + 关注 👏,持续学习持续干货输出
  • 一起交流💬,一起进步💪。
  • 微信公众号也可搜【同学小张】 🙏

本站文章一览:

相关实践学习
阿里云百炼xAnalyticDB PostgreSQL构建AIGC应用
通过该实验体验在阿里云百炼中构建企业专属知识库构建及应用全流程。同时体验使用ADB-PG向量检索引擎提供专属安全存储,保障企业数据隐私安全。
AnalyticDB PostgreSQL 企业智能数据中台:一站式管理数据服务资产
企业在数据仓库之上可构建丰富的数据服务用以支持数据应用及业务场景;ADB PG推出全新企业智能数据平台,用以帮助用户一站式的管理企业数据服务资产,包括创建, 管理,探索, 监控等; 助力企业在现有平台之上快速构建起数据服务资产体系
相关文章
|
10天前
|
机器学习/深度学习 人工智能 自然语言处理
Gemini 2.0:谷歌推出的原生多模态输入输出 + Agent 为核心的 AI 模型
谷歌最新推出的Gemini 2.0是一款原生多模态输入输出的AI模型,以Agent技术为核心,支持多种数据类型的输入与输出,具备强大的性能和多语言音频输出能力。本文将详细介绍Gemini 2.0的主要功能、技术原理及其在多个领域的应用场景。
111 20
Gemini 2.0:谷歌推出的原生多模态输入输出 + Agent 为核心的 AI 模型
|
10天前
|
人工智能 API 语音技术
TEN Agent:开源的实时多模态 AI 代理框架,支持语音、文本和图像的实时通信交互
TEN Agent 是一个开源的实时多模态 AI 代理框架,集成了 OpenAI Realtime API 和 RTC 技术,支持语音、文本和图像的多模态交互,具备实时通信、模块化设计和多语言支持等功能,适用于智能客服、实时语音助手等多种场景。
93 15
TEN Agent:开源的实时多模态 AI 代理框架,支持语音、文本和图像的实时通信交互
|
11天前
|
人工智能 自然语言处理 前端开发
Director:构建视频智能体的 AI 框架,用自然语言执行搜索、编辑、合成和生成等复杂视频任务
Director 是一个构建视频智能体的 AI 框架,用户可以通过自然语言命令执行复杂的视频任务,如搜索、编辑、合成和生成视频内容。该框架基于 VideoDB 的“视频即数据”基础设施,集成了多个预构建的视频代理和 AI API,支持高度定制化,适用于开发者和创作者。
74 9
Director:构建视频智能体的 AI 框架,用自然语言执行搜索、编辑、合成和生成等复杂视频任务
|
7天前
|
机器学习/深度学习 人工智能 算法
Meta Motivo:Meta 推出能够控制数字智能体动作的 AI 模型,提升元宇宙互动体验的真实性
Meta Motivo 是 Meta 公司推出的 AI 模型,旨在控制数字智能体的全身动作,提升元宇宙体验的真实性。该模型通过无监督强化学习算法,能够实现零样本学习、行为模仿与生成、多任务泛化等功能,适用于机器人控制、虚拟助手、游戏角色动画等多个应用场景。
35 4
Meta Motivo:Meta 推出能够控制数字智能体动作的 AI 模型,提升元宇宙互动体验的真实性
|
11天前
|
机器学习/深度学习 人工智能 物联网
AI赋能大学计划·大模型技术与应用实战学生训练营——电子科技大学站圆满结营
12月05日,由中国软件行业校园招聘与实习公共服务平台携手阿里魔搭社区共同举办的AI赋能大学计划·大模型技术与产业趋势高校行AIGC项目实战营·电子科技大学站圆满结营。
AI赋能大学计划·大模型技术与应用实战学生训练营——电子科技大学站圆满结营
|
16天前
|
机器学习/深度学习 人工智能 JSON
【实战干货】AI大模型工程应用于车联网场景的实战总结
本文介绍了图像生成技术在AIGC领域的发展历程、关键技术和当前趋势,以及这些技术如何应用于新能源汽车行业的车联网服务中。
251 33
|
19天前
|
人工智能 自然语言处理 JavaScript
Agent-E:基于 AutoGen 代理框架构建的 AI 浏览器自动化系统
Agent-E 是一个基于 AutoGen 代理框架构建的智能自动化系统,专注于浏览器内的自动化操作。它能够执行多种复杂任务,如填写表单、搜索和排序电商产品、定位网页内容等,从而提高在线效率,减少重复劳动。本文将详细介绍 Agent-E 的功能、技术原理以及如何运行该系统。
66 5
Agent-E:基于 AutoGen 代理框架构建的 AI 浏览器自动化系统
|
13天前
|
人工智能 自然语言处理 算法
AI时代的企业内训全景图:从案例到实战
作为一名扎根在HR培训领域多年的“老兵”,我越来越清晰地感受到,企业内训的本质其实是为企业持续“造血”。无论是基础岗的新人培训、技能岗的操作规范培训,还是面向技术中坚力量的高阶技术研讨,抑或是管理层的战略思维提升课,内训的价值都是在帮助企业内部提升能力水平,进而提高组织生产力,减少对外部资源的依赖。更为重要的是,在当前AI、大模型、Embodied Intelligence等新兴技术快速迭代的背景下,企业必须不断为人才升级赋能,才能在市场竞争中保持领先。
|
18天前
|
人工智能 自然语言处理 数据挖掘
田渊栋团队新作祭出Agent-as-a-Judge!AI智能体自我审判,成本暴跌97%
田渊栋团队提出Agent-as-a-Judge框架,利用智能体自身评估其他智能体的性能,不仅关注最终结果,还能提供中间反馈,更全面准确地反映智能体的真实能力。该框架在DevAI基准测试中表现出色,成本效益显著,为智能体的自我改进提供了有力支持。
35 7
|
26天前
|
人工智能 自然语言处理 搜索推荐
🤖【多Agent大爆炸】——灵活调用与实践指南,解锁AI协作新技能!
本文深入探讨了单Agent与多Agent在不同场景下的应用及优势,通过实例讲解多Agent如何实现高效协作,涵盖智能物流、教育、医疗等多个领域的实际应用,旨在帮助开发者掌握多Agent系统的调用与实践技巧。
94 5
下一篇
DataWorks