Tutorials Logic, IN info@tutorialslogic.com

LangChain Agents and Tools: Build Safe Tool-Calling Workflows

Tool Design Principles

Agents let a model choose what action to take next. A tool can be a search function, calculator, database lookup, ticket creator, calendar API, or internal service. The agent reads the user request, chooses a tool, passes arguments, observes the result, and continues until it can answer.

Agents are powerful, but they are not the default answer. If your workflow is known, build a chain. Use agents when tool choice or step order is genuinely dynamic.

Good tools are narrow, typed, well-named, and safe. The model should not need to guess what a tool does. Dangerous tools should require confirmation or operate in read-only mode by default.

  • Use clear tool names and docstrings because the model reads them.
  • Validate tool arguments with schemas.
  • Separate read tools from write tools.
  • Add authorization checks outside the model.

Tool-Calling Agent

This example exposes two safe tools. In production, tool functions should include logging, permissions, timeouts, and typed errors.

Tool-Calling Agent
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent

@tool
def calculate_monthly_cost(users: int, price_per_user: float) -> str:
    """Calculate monthly subscription cost for a number of users."""
    total = users * price_per_user
    return f"Monthly cost is ${total:.2f}"

@tool
def lookup_plan_limit(plan: str) -> str:
    """Return user limit for a plan. Valid plans: starter, growth, enterprise."""
    limits = {"starter": 5, "growth": 50, "enterprise": "custom"}
    return f"{plan} plan user limit: {limits.get(plan.lower(), 'unknown plan')}"

model = ChatOpenAI(model="gpt-4o-mini", temperature=0)
agent = create_react_agent(model, tools=[calculate_monthly_cost, lookup_plan_limit])

result = agent.invoke({
    "messages": [
        ("user", "If we have 18 users on the growth plan at $12.50 each, what is the monthly cost and is it within the plan limit?")
    ]
})

print(result["messages"][-1].content)
  • The tool docstrings are part of the agent interface.
  • Use agents for dynamic tool selection, not for simple fixed calculations.
  • LangGraph is often used with LangChain for stateful agent workflows.

Validate Tool Arguments at the Execution Boundary

Validate Tool Arguments at the Execution Boundary
def read_invoice(invoice_id: str, actor_roles: set[str]):
    if 'billing:read' not in actor_roles:
        raise PermissionError('billing access required')
    if not invoice_id.startswith('INV-'):
        raise ValueError('invalid invoice id')
    return {'id': invoice_id, 'status': 'paid'}

print(read_invoice('INV-204', {'billing:read'}))
Output
{'id': 'INV-204', 'status': 'paid'}
Before you move on

LangChain Agents and Tools: Build Safe Tool-Calling Workflows Mastery Check

4 checks
  • Give each tool a narrow purpose, precise schema, and description that supports reliable selection.
  • Validate arguments and outputs while enforcing authentication, authorization, timeouts, and resource limits.
  • Make retryable side effects idempotent and surface typed tool errors to the agent loop.
  • Trace tool selection, stop conditions, repeated calls, and unsafe requests in evaluation cases.

LangChain Agents Tools Questions Learners Ask

Use an agent when the model must choose among tools or determine the next step dynamically. Use a chain for known workflows.

No. Safety comes from limited tools, validation, permissions, confirmations, logging, and evaluation.

State what the tool does, its required inputs, and when it should not be called.

Next Step
Next Practice

Finish the concept here, then reinforce it with hands-on coding, interview prep, or a tool that matches the topic.

Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.