पाठ 10 / 29

Graph के रूप में Tool-Calling Agent

मॉडल-और-tools चक्र को दो nodes और एक conditional edge के रूप में देखें।

ReAct-शैली का loop

क्लासिक agent छोटा graph है: model node messages देखकर या तो उत्तर देता है या tool माँगता है; conditional edge जाँचती है कि tool माँगा गया या नहीं; tools node उसे चलाकर परिणाम जोड़ता है; एक edge वापस मॉडल पर जाती है। Loop तब समाप्त होता है जब मॉडल बिना tool माँगे उत्तर दे, या सीमा आ जाए। असली उपयोग में model node tool schemas से बंधा chat model बुलाता है, और messages tool_calls वाले AIMessage और ToolMessage परिणाम होते हैं। LangGraph और LangChain तैयार सहायक (जैसे ToolNode और बने-बनाए agent constructors) देते हैं, इसलिए आप यह हाथ से कम लिखते हैं, पर एक बार बनाने से framework का व्यवहार स्पष्ट हो जाता है।

मॉडल, tools, loop

Tool-calling agent दो-node चक्र है: मॉडल निर्णय लेता है, tool node कार्य करता है, और परिणाम मॉडल को लौटता है।

चार हिस्से: मॉडल, tools, loop, सीमाएँ।
चित्र 3.1 — मॉडल, tools, loop और सीमाएँ।

शुरू से agent loop, चलाकर

मैंने यह Python virtual environment में langgraph 1.2.12 और langchain-core 1.6.6 के साथ ऑफ़लाइन चलाया। किसी API key या मॉडल की ज़रूरत नहीं क्योंकि मॉडल की जगह सादे Python functions हैं, इसलिए आउटपुट दोहराने योग्य है। एक scripted function मॉडल की भूमिका निभाता है: वह add, फिर mul माँगता है, फिर उत्तर देता है। Tools node चलाने से पहले tool नाम को allow-list से validate करता है। अंतिम message सूची loop का हर चरण दिखाती है।

import operator
from typing import Annotated, TypedDict
from langgraph.graph import StateGraph, START, END

TOOLS = {"add": lambda a, b: a + b, "mul": lambda a, b: a * b}

class State(TypedDict):
    messages: Annotated[list, operator.add]

script = iter([   # stands in for a model that asks for tools, then answers
    {"tool": "add", "args": {"a": 2, "b": 3}},
    {"tool": "mul", "args": {"a": 5, "b": 4}},
    {"final": "2+3 is 5 and 5*4 is 20."},
])

def model(state):
    return {"messages": [next(script)]}

def run_tool(state):
    call = state["messages"][-1]
    allowed = call["tool"] in TOOLS                      # validate before executing
    result = TOOLS[call["tool"]](**call["args"]) if allowed else "error: unknown tool"
    return {"messages": [{"tool_result": result}]}

def after_model(state):
    return END if "final" in state["messages"][-1] else "tools"

g = StateGraph(State)
g.add_node("model", model); g.add_node("tools", run_tool)
g.add_edge(START, "model")
g.add_conditional_edges("model", after_model, {END: END, "tools": "tools"})
g.add_edge("tools", "model")
out = g.compile().invoke({"messages": [{"user": "what is 2+3, then 5*4?"}]}, {"recursion_limit": 10})
for m in out["messages"]:
    print(m)

Output:

{'user': 'what is 2+3, then 5*4?'}
{'tool': 'add', 'args': {'a': 2, 'b': 3}}
{'tool_result': 5}
{'tool': 'mul', 'args': {'a': 5, 'b': 4}}
{'tool_result': 20}
{'final': '2+3 is 5 and 5*4 is 20.'}

त्वरित जाँच: Agent loop कब समाप्त होता है?

  • जब मॉडल बिना tool माँगे उत्तर दे, या सीमा आ जाए
  • ठीक एक tool call के बाद
  • कभी नहीं
  • जब GPU निष्क्रिय हो
Answer

जब मॉडल बिना tool माँगे उत्तर दे, या सीमा आ जाए — कोई tool न माँगा जाने पर conditional edge END पर route करती है।