YouTip LogoYouTip

Langchain Tool Advanced

\\n\\n\\n\\nLangChain Tool Advanced Features | Online Tutorial\\n\\n\\n\\n

LangChain Tool Advanced Features | Tutorial

\\n\\n

URL Source: https://example.com/langchain/langchain-tool-advanced.html

\\n\\n
\\n\\n

In the previous section, we learned the basic usage of @tool. This section introduces advanced tool features: return_direct, InjectedToolCallId, ToolException, and error handling.

\\n\\n
\\n\\n

return_directβ€”β€”Return Final Result Directly

\\n\\n

By default, after tool execution, the result is returned to the model, which then generates the final response based on the tool result. However, sometimes the tool result itself is the final answer you want.

\\n\\n

After setting return_direct=True, the tool execution immediately ends the Agent loop, and the tool's returned content is used directly as the final output.

\\n\\n

Example

\\n\\n
from dotenv import load_dotenv\\n\\n load_dotenv()\\n\\nfrom langchain.tools import tool\\n\\nfrom langchain.agents import create_agent\\n\\nfrom langchain.chat_models import init_chat_model\\n\\nfrom langchain.messages import HumanMessage\\n\\n# Normal tool: result returned to model, model then summarizes\\n\\n@tool\\n\\ndef search_normal(keyword: str) ->str:\\n\\n"""Search Tutorial TUTORIAL courses (normal mode)"""\\n\\nreturn f"Search results: Python3 Basics, Python Data Analysis, Python Scraping Basics"\\n\\n# return_direct tool: result directly as final output\\n\\n@tool(return_direct=True)\\n\\ndef search_direct(keyword: str) ->str:\\n\\n"""Search Tutorial TUTORIAL courses (direct return mode).\\nUse this tool when the user only needs search results without additional analysis.\\n\\n """\\n\\nreturn f"Search results: Python3 Basics, Python Data Analysis, Python Scraping Basics"\\n\\nmodel = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)\\n\\n# Comparison: normal mode vs direct return mode\\n\\n agent_normal = create_agent(\\n\\n model=model,\\n\\n tools=,\\n\\n system_prompt="You are a learning advisor for Online Tutorial.",\\n\\n)\\n\\nagent_direct = create_agent(\\n\\n model=model,\\n\\n tools=,\\n\\n system_prompt="You are a learning advisor for Online Tutorial.",\\n\\n)\\n\\n# Normal mode: model will generate a summary based on search results\\n\\n result = agent_normal.invoke({\\n\\n"messages": [HumanMessage(content="Search Python courses")]\\n\\n})\\n\\nprint("=== Normal mode (model will process further) ===")\\n\\nprint(result.content[:150])\\n\\n# Direct return mode: tool result is the final answer\\n\\n result = agent_direct.invoke({\\n\\n"messages": [HumanMessage(content="Search Python courses")]\\n\\n})\\n\\nprint("\\\\n=== Direct return mode (tool result is final answer) ===")\\n\\nprint(result.content[:150])\\n
\\n\\n

Output:

\\n\\n
=== Normal mode (model will process further) ===\\nAt Tutorial TUTORIAL, I found the following Python-related courses for you:1. Python3 Basics - Suitable for beginners2. Python Data Analysis - Advanced learning3. Python Scraping Basics - Practical projects=== Direct return mode (tool result is final answer) ===\\nSearch results: Python3 Basics, Python Data Analysis, Python Scraping Basics\\n
\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
ModeAfter Tool ExecutionUse Case
return_direct=False (default)Model receives tool result β†’ model continues thinking β†’ generates final responseNeed analysis/summary/further decision
return_direct=TrueEnd immediately after tool execution β†’ tool result is final outputQuery type, data retrieval, pre-formatted results
\\n\\n
\\n

When you set return_direct=True, the Agent skips the subsequent model thinking step and directly returns the tool result. This is very valuable for saving tokens and reducing latency, but it also means the model will not do any secondary processing on the tool result.

\\n
\\n\\n
\\n\\n

InjectedToolCallIdβ€”β€”Get Tool Call ID

\\n\\n

Sometimes the tool needs to know "who called it"β€”InjectedToolCallId can inject the current tool_call_id into the tool function:

\\n\\n

Example

\\n\\n
from typing import Annotated\\n\\nfrom langchain.tools import tool, InjectedToolCallId\\n\\n@tool\\n\\ndef log_user_action(\\n\\n action: str,\\n\\n tool_call_id: Annotated[str, InjectedToolCallId],\\n\\n) ->str:\\n\\n"""Log user action to the logging system.\\nArgs:\\n\\n action: User action description\\n\\n tool_call_id: System automatically injected tool call ID\\n\\n """\\n\\n# In actual projects, this would write to database or send to logging service\\n\\nreturn f"Action logged (call ID: {tool_call_id}): {action}"\\n\\n# InjectedToolCallId parameter will be automatically injected, no need to pass manually\\n\\n result = log_user_action.invoke({"action": "User queried Python courses"})\\n\\nprint(result)\\n
\\n\\n

Output:

\\n\\n
Action logged (call ID: 00000000-0000-4000-8000-000000000001): User queried Python courses\\n
\\n\\n
\\n

Parameters marked with InjectedToolArg do not need to be provided by the Agent (model); they are automatically injected by the LangChain runtime framework. You don't need to describe these injected parameters in the tool function's docstring because the Agent won't see them.

\\n
\\n\\n
\\n\\n

ToolExceptionβ€”β€”Tool Exception Handling

\\n\\n

Errors may occur during tool execution. Use ToolException to throw explicit tool exceptions, letting the Agent know that something went wrong.

\\n\\n

Example

\\n\\n
from langchain.tools import tool, ToolException\\n\\n@tool\\n\\ndef get_user_info(user_id: int) ->str:\\n\\n"""Query user information by user ID.\\nArgs:\\n\\n user_id: User ID, must be a positive integer\\n\\n """\\n\\n# Data validation\\n\\nif user_id <=0:\\n\\n# Throw ToolException, not regular Exception\\n\\n# ToolException will be caught by Agent and reported to model\\n\\nraise ToolException(f"User ID must be a positive integer, received: {user_id}")\\n\\n# Simulate database query\\n\\n users ={\\n\\n1: "Zhang San (VIP member, registered on 2024-01-15)",\\n\\n2: "Li Si (Regular user, registered on 2024-03-20)",\\n\\n}\\n\\nif user_id not in users:\\n\\nraise ToolException(f"User with ID {user_id} not found")\\n\\nreturn users\\n\\n# Normal call\\n\\nprint(get_user_info.invoke({"user_id": 1}))\\n\\n# Exception call 1: invalid ID\\n\\ntry:\\n\\n get_user_info.invoke({"user_id": -1})\\n\\nexcept ToolException as e:\\n\\nprint(f"Tool exception: {e}")\\n\\n# Exception call 2: user does not exist\\n\\ntry:\\n\\n get_user_info.invoke({"user_id": 999})\\n\\nexcept ToolException as e:\\n\\nprint(f"Tool exception: {e}")\\n
\\n\\n

Output:

\\n\\n
Zhang San (VIP member, registered on 2024-01-15)\\nTool exception: User ID must be a positive integer, received: -1\\nTool exception: User with ID 999 not found\\n
\\n\\n
\\n\\n

handle_tool_errorsβ€”β€”Let Agent Handle Tool Errors Automatically

\\n\\n

When the model is allowed to handle tool errors (via ToolNode configuration), the model can try to correct parameters and call again:

\\n\\n

Example

\\n\\n
from langchain.tools import tool, ToolException\\n\\nfrom langchain.agents import create_agent\\n\\nfrom langchain.chat_models import init_chat_model\\n\\nfrom langchain.messages import HumanMessage\\n\\n@tool\\n\\ndef get_weather(city: str) ->str:\\n\\n"""Query weather for specified city.\\nArgs:\\n\\n city: City name, must be full Chinese name like "Hangzhou", "Beijing"\\n\\n """\\n\\n weather_data ={\\n\\n"Hangzhou": "Sunny, 25Β°C",\\n\\n"Beijing": "Cloudy, 18Β°C",\\n\\n"Shanghai": "Light rain, 22Β°C",\\n\\n}\\n\\nif city not in weather_data:\\n\\n# Throw ToolException when city is not in data\\n\\nraise ToolException(\\n\\n f"City '{city}' not found."\\n\\n f"Available cities: {', '.join(weather_data.keys())}."\\n\\n f"Please use full Chinese city names."\\n\\n)\\n\\nreturn f"{city} weather: {weather_data}"\\n\\nmodel = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)\\n\\n# When not using Agent, you can also control behavior with handle_tool_errors\\n\\n# Method 1: Return error message string (model
← Langchain Create_AgentLangchain Messages β†’