精品伊人久久大香线蕉,开心久久婷婷综合中文字幕,杏田冲梨,人妻无码aⅴ不卡中文字幕

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
【AI Agent】【LangGraph】1. 進階實戰:給你的 LangGraph 加入條件分支
userphoto

2024.04.26 山東

關注
  • · 歡迎 點贊 + 關注 ??,持續學習持續干貨輸出

公眾號內文章一覽


書接上文(【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[strstr]] = 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知識和實戰案例

  • · 歡迎 點贊 + 關注 ??,持續學習持續干貨輸出

公眾號內文章一覽

本站僅提供存儲服務,所有內容均由用戶發布,如發現有害或侵權內容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
正則表達之
徹底搞懂LangGraph:構建強大的Multi-Agent多智能體應用的LangChain新利器 【1】
關于Arduino圖形化編程工具 - ArduBlock的安裝
虛擬機中裝Red flag 5并安裝VMware
實用漢字源查詢工具網站-Zi Tools
Percona Online Tools MYSQL優化分析工具
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯系客服!

聯系客服

主站蜘蛛池模板: 揭阳市| 台中市| 拉萨市| 辽中县| 塔河县| 佛学| 北安市| 西盟| 灵璧县| 元谋县| 曲沃县| 渑池县| 贵港市| 蒲城县| 英德市| 姚安县| 河津市| 淮北市| 全州县| 得荣县| 台中市| 宝鸡市| 西乌| 长兴县| 大渡口区| 札达县| 温宿县| 大理市| 巩义市| 瑞金市| 丰城市| 晋城| 乌审旗| 探索| 博乐市| 潞西市| 阳信县| 西丰县| 通州区| 惠水县| 西平县|