AI Model Wiki

    Skip to main content
    16 min read
    Lesson 3 of 6

    Tool Calling & Building Agents

    From the course LangChain & AI Orchestration Frameworks

    Agents are LLM-powered systems that can take actions in the real world by calling tools — APIs, databases, code interpreters, and more.

    Defining Tools

    Tools are Python functions with clear descriptions that help the LLM decide when and how to use them:

    from langchain_core.tools import tool
    
    @tool
    def search_database(query: str, limit: int = 10) -> str:
        """Search the product database for items matching the query.
        Use when the user asks about specific products, prices, or availability."""
        results = db.search(query, limit=limit)
        return format_results(results)
    
    @tool
    def send_email(to: str, subject: str, body: str) -> str:
        """Send an email to a customer. Only use when explicitly asked to send a message."""
        email_service.send(to=to, subject=subject, body=body)
        return f"Email sent to {to}"
    

    The ReAct Pattern

    Most agents follow the ReAct (Reasoning + Acting) pattern:

    1. Observe: Receive user input and conversation history
    2. Think: Reason about what action to take next
    3. Act: Call a tool with specific arguments
    4. Observe: Receive tool output
    5. Repeat or Respond: Continue the loop or give a final answer

    Building with LangGraph

    LangGraph provides explicit control over agent behavior with state machines:

    from langgraph.graph import StateGraph, MessagesState
    from langgraph.prebuilt import ToolNode
    
    tools = [search_database, send_email]
    tool_node = ToolNode(tools)
    model_with_tools = model.bind_tools(tools)
    
    def agent(state: MessagesState):
        response = model_with_tools.invoke(state["messages"])
        return {"messages": [response]}
    
    def should_continue(state: MessagesState):
        last = state["messages"][-1]
        return "tools" if last.tool_calls else "end"
    
    graph = StateGraph(MessagesState)
    graph.add_node("agent", agent)
    graph.add_node("tools", tool_node)
    graph.set_entry_point("agent")
    graph.add_conditional_edges("agent", should_continue, {"tools": "tools", "end": "__end__"})
    graph.add_edge("tools", "agent")
    
    app = graph.compile()
    

    Agent Safety

    Agents with real-world actions need guardrails:

    • Confirmation loops: Require human approval before destructive actions (deleting data, sending emails)
    • Rate limiting: Cap the number of tool calls per turn and per session
    • Sandboxing: Run code execution in containers with no network access
    • Output validation: Verify tool arguments match expected schemas before execution

    Key Takeaways

    • •Tools are annotated functions with descriptions that guide the LLM's usage decisions
    • •The ReAct pattern loops through think → act → observe until the task is complete
    • •LangGraph provides explicit state machines for predictable agent control flow
    • •Always implement confirmation loops and rate limiting for agents with real-world actions
    0 of 6 lessons marked complete

    Progress is kept in this browser only.