langgraph-tools

LangGraph Tool Calling

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "langgraph-tools" with this command: npx skills add yonatangross/orchestkit/yonatangross-orchestkit-langgraph-tools

LangGraph Tool Calling

Integrate tool calling into LangGraph workflows.

Basic Tool Binding

from langchain_core.tools import tool from langchain_anthropic import ChatAnthropic

@tool def search_database(query: str) -> str: """Search the database for information.""" return db.search(query)

@tool def send_email(to: str, subject: str, body: str) -> str: """Send an email to a recipient.""" email_service.send(to, subject, body) return f"Email sent to {to}"

Bind tools to model

tools = [search_database, send_email] model = ChatAnthropic(model="claude-sonnet-4-20250514") model_with_tools = model.bind_tools(tools)

Agent node

def agent_node(state: State): response = model_with_tools.invoke(state["messages"]) return {"messages": [response]}

ToolNode for Execution

from langgraph.prebuilt import ToolNode from langgraph.graph import StateGraph, START, END

Create tool execution node

tool_node = ToolNode(tools)

Build agent graph

builder = StateGraph(MessagesState) builder.add_node("agent", agent_node) builder.add_node("tools", tool_node)

Routing based on tool calls

def should_continue(state: MessagesState) -> str: last_message = state["messages"][-1] if last_message.tool_calls: return "tools" return END

builder.add_edge(START, "agent") builder.add_conditional_edges("agent", should_continue, {"tools": "tools", END: END}) builder.add_edge("tools", "agent") # Return to agent after tool execution

graph = builder.compile()

Force Tool Calling

Force model to call at least one tool

model.bind_tools(tools, tool_choice="any")

Force specific tool

model.bind_tools(tools, tool_choice="search_database")

Structured output via tool (guaranteed schema)

from pydantic import BaseModel

class SearchResult(BaseModel): query: str results: list[str] confidence: float

model.bind_tools([SearchResult], tool_choice="SearchResult")

Dynamic Tool Selection

from sentence_transformers import SentenceTransformer

embedder = SentenceTransformer("all-MiniLM-L6-v2")

Pre-compute tool embeddings

TOOL_EMBEDDINGS = { tool.name: embedder.encode(tool.description) for tool in all_tools }

def select_relevant_tools(query: str, all_tools: list, top_k: int = 5) -> list: """Select most relevant tools based on query.""" query_embedding = embedder.encode(query)

similarities = [
    (tool, cosine_similarity(query_embedding, TOOL_EMBEDDINGS[tool.name]))
    for tool in all_tools
]

sorted_tools = sorted(similarities, key=lambda x: x[1], reverse=True)
return [tool for tool, _ in sorted_tools[:top_k]]

def agent_with_dynamic_tools(state: State): """Bind only relevant tools to reduce context.""" relevant_tools = select_relevant_tools( state["messages"][-1].content, all_tools, top_k=5 )

model_bound = model.bind_tools(relevant_tools)
response = model_bound.invoke(state["messages"])
return {"messages": [response]}

Tool Interrupts (Approval Gates)

from langgraph.types import interrupt

@tool def delete_user(user_id: str) -> str: """Delete a user account. Requires approval.""" # Interrupt for human approval response = interrupt({ "action": "delete_user", "user_id": user_id, "message": f"Approve deletion of user {user_id}?", "risk_level": "high" })

if response.get("approved"):
    db.delete_user(user_id)
    return f"User {user_id} deleted successfully"
return "Deletion cancelled by user"

@tool def transfer_funds(from_account: str, to_account: str, amount: float) -> str: """Transfer funds between accounts. Requires approval for large amounts.""" if amount > 1000: response = interrupt({ "action": "transfer_funds", "from": from_account, "to": to_account, "amount": amount, "message": f"Approve transfer of ${amount}?" })

    if not response.get("approved"):
        return "Transfer cancelled"

execute_transfer(from_account, to_account, amount)
return f"Transferred ${amount} from {from_account} to {to_account}"

Streaming from Tools

from langgraph.config import get_stream_writer

@tool def long_running_analysis(data: str) -> str: """Analyze data with progress updates.""" writer = get_stream_writer()

writer({"status": "starting", "progress": 0})

for i, chunk in enumerate(process_chunks(data)):
    writer({
        "status": "processing",
        "progress": (i + 1) * 10,
        "current_chunk": i
    })

writer({"status": "complete", "progress": 100})
return "Analysis complete"

Error Handling in Tools

@tool def api_call_with_retry(endpoint: str) -> str: """Call external API with automatic retry.""" for attempt in range(3): try: response = requests.get(endpoint, timeout=10) response.raise_for_status() return response.json() except requests.RequestException as e: if attempt == 2: return f"Error: Failed after 3 attempts - {str(e)}" time.sleep(2 ** attempt) # Exponential backoff

Parallel Tool Execution

from langgraph.prebuilt import ToolNode

ToolNode executes multiple tool calls in parallel by default

tool_node = ToolNode(tools)

If agent returns multiple tool_calls, they execute concurrently

Results are returned in order matching the tool_calls

Key Decisions

Decision Recommendation

Tool count 5-10 tools max per agent (use dynamic selection for more)

Approval gates Use interrupt() for destructive/high-risk operations

Error handling Return error strings, don't raise (lets agent recover)

Streaming Use get_stream_writer() for long-running tools

Common Mistakes

  • Too many tools (context overflow, poor selection)

  • Raising exceptions in tools (crashes agent loop)

  • Missing tool descriptions (LLM can't choose correctly)

  • Not using tool_choice when specific tool is required

Evaluations

See references/evaluations.md for test cases.

Related Skills

  • langgraph-supervisor

  • Supervisor agents with tool-calling workers

  • langgraph-human-in-loop

  • Approval gates for dangerous tools

  • langgraph-streaming

  • Stream tool execution progress

  • langgraph-routing

  • Route based on tool results

  • langgraph-state

  • Track tool call history in state

  • function-calling

  • General LLM function calling patterns

Capability Details

bind-tools

Keywords: bind_tools, tool calling, function calling, LLM tools Solves:

  • Attach tools to language models

  • Enable function calling in agents

  • Configure tool selection behavior

tool-node

Keywords: ToolNode, execute tools, tool execution, prebuilt Solves:

  • Execute tool calls from LLM responses

  • Handle parallel tool execution

  • Integrate tools into graph workflows

dynamic-tools

Keywords: dynamic, select tools, many tools, relevance Solves:

  • Handle large tool inventories

  • Select relevant tools per query

  • Reduce context usage

tool-interrupts

Keywords: interrupt, approval, gate, human review, dangerous Solves:

  • Add approval gates to dangerous tools

  • Implement human oversight

  • Control high-risk operations

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

ui-components

No summary provided by upstream source.

Repository SourceNeeds Review
General

responsive-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
General

domain-driven-design

No summary provided by upstream source.

Repository SourceNeeds Review
General

dashboard-patterns

No summary provided by upstream source.

Repository SourceNeeds Review