LangChain custom tools: stop LLM guessing now

Blog 16 min read

Custom LangChain tools change generic LLMs into functional agents by enabling specific actions like math and code execution.

Real-world AI projects rarely succeed with off-the-shelf components alone, demanding the creation of custom tools to handle unique operational requirements. While prebuilt libraries offer a starting point, true utility emerges when developers architect specific objects that consume string inputs and return actionable data. This article demonstrates how to extend LLM capabilities beyond simple text generation by implementing a CircumferenceTool using the BaseTool class. You will learn why standard models fail at sequencing actions without external aids, how to define the mandatory name and description attributes for agent recognition, and the specific code structure required to execute mathematical logic within an agent workflow.

The guide moves from theoretical agent prevalence to practical implementation, showing how a simple function becomes a reliable interface for Large Language Models. By mastering these patterns, developers can replace token-based guessing with grounded, repeatable functions that solve concrete problems. The resulting systems do not just chat; they calculate, verify, and execute with precision that raw models cannot achieve independently.

The Role of Custom Tools in Extending LLM Agent Capabilities

LLM Agents and the Function of String-Based Custom Tools

LLM agents stand as powerful architectures for deploying Large Language Models (LLMs). These systems chain tool outputs into subsequent inputs to fix reasoning gaps, especially in math tasks where standard completion fails. The ReAct framework drives this cycle through thought, action, and observation loops. A LangChain tool acts as a discrete object taking string input and returning string output. This text-based interface lets the agent delegate operations like search queries or circumference calculations without exposing raw code execution. Agents use these tools to search the web, do math, run code, and more. Prebuilt suites help with rapid deployment, yet custom implementations become necessary when project needs outgrow standard libraries. Separating the planning agent from the execution tool stops hallucination during deterministic steps. Developers define explicit name and description attributes so the controller routes user requests correctly. Precise string schemas prevent parsing errors where the agent misinterprets return values. Complex, multi-step problems get solved through verified external functions instead of unreliable internal parameter estimation.

Extending Agent Capabilities Beyond Prebuilt LangChain Libraries

Generic web search fails when agents need domain-specific logic like image captioning. The LangChain system provides standard utilities, yet production systems demand custom tools to bridge reasoning gaps. Describing visual content requires integrating external models, a capability missing from default toolsets.

Developers construct these extensions by subclassing the BaseTool class to define input schemas and execution logic. This pattern enables the agent to invoke specialized functions, such as calculating circumference or processing multimedia, which standard libraries cannot address. Real-world projects frequently necessitate modifying existing utilities or building entirely new ones to satisfy unique requirements. Unlike rapid setup architectures found in other frameworks, this approach involves manually defining functions and initializing them within a specific list structure passed to the agent.

The initialization process strictly requires three components: the LLM instance, a conversational memory module, and the curated list of tools. Even a single custom tool must be wrapped in a list to match the expected interface. This explicit configuration ensures the agent routes queries to the correct function based on natural language descriptions.

Maintaining custom code introduces overhead that prebuilt solutions avoid. Engineers manage version compatibility and error handling for every external dependency they integrate. The constraint is direct control over execution behavior versus the convenience of managed services. Builders gain the ability to solve problems outside the training distribution of the base model.

Limitations appear when scaling these custom integrations across large teams. Documentation often lags behind code changes in fast-moving projects. Testing requirements multiply with each added external dependency. Deployment pipelines become more complex with custom logic embedded.

Static Tool Definitions Versus Flexible Autonomous Tool Creation

Static tool definitions force developers to implement functions in advance, limiting agents to a fixed set of capabilities set at initialization.

Traditional architectures rely on this human-implemented approach where every BaseTool subclass must be explicitly coded before deployment. This method ensures strict schema validation but prevents the agent from adapting to novel tasks outside its pre-configured list. Emerging research highlights a shift toward autonomous tool creation, where systems dynamically apply external software components without prior human definition. This transition enables LLM-powered knowledge assistants to perform complex, multi-step research by generating necessary function calls on the fly. Managing real-time feedback loops adds complexity compared to the stability of static lists. Static tools offer predictable execution paths. Flexible creation allows for iterative observation-driven flows that adjust strategies based on intermediate outputs.

Feature Static Definitions Flexible Creation
Initialization Manual list setup On-demand generation
Flexibility Low (fixed schema) High (adaptive)
Safety High (controlled) Variable (requires guardrails)
Use Case Repetitive tasks Novel problem solving

Operators weigh the reliability of pre-set schemas against the versatility of systems capable of flexible utilisation of external components. Current implementations primarily rely on tools implemented in advance by human developers, though the field is moving toward agents that can dynamically apply external software components. This evolution aims to maintain system stability while allowing agents to address unanticipated queries effectively.

Architecting Reliable Tool Execution with the ReAct Framework

ReAct Framework Mechanics: From User Input to Tool Execution

Thought precedes Action, which yields Observation, forming a loop that repeats until the task ends. This cycle lets the system alter its path based on live feedback from tool outputs. Initialization happens through `initialize_agent` from `langchain.agents`, setting the agent type to `chat-conversational-react-description`. Such a setup binds the ChatOpenAI model, configured as `gpt-3.5-turbo` with temperature 0, to the ConversationBufferWindowMemory object where `k=5` restricts context to the last five interactions.

Distinct mechanical stages break down the process:

  1. Thought: The model analyzes the prompt and determines if a tool is required based on provided descriptions.
  2. Action: The agent selects a tool, such as the Circumference calculator, and formats the input arguments.
  3. Observation: The tool executes the function and returns a string result to the context window.
Component Configuration Value Function
Agent Type `chat-conversational-react-description` Enables multi-step reasoning with memory
Memory Window `k=5` Retains last five human-AI exchanges
Model Temp `0` Minimizes randomness for strict tool adherence

A specific failure mode emerges when the system prompt omits an explicit ban on independent math reasoning, causing the agent to skip the Action phase completely. Unless instructions declare the assistant "terrible at maths," the model might hallucinate a Final Answer instead of calling the external calculator. This glitch shows the ReAct framework depends on the LLM following orders, a capability compromised if rigid prompting rules do not constrain the initial thought process.

Fixing Math Errors by Forcing Tool Usage in System Prompts

Early tests revealed inaccuracies because LLMs generally perform poor math due to overconfidence in their own numerical abilities. The agent wrongly bypassed tool execution, generating a "Final Answer" action right away rather than invoking the required function. This behavior originates from the probabilistic nature of large language models, which often favor fluent text generation over precise logical derivation when not explicitly constrained.

Engineers must modify the system prompt to state clearly that the assistant is "terrible at maths" to correct this deviation. Such an instruction directs the gpt-3.5-turbo instance to depend on its provided tool descriptions instead of internal calculation capabilities. Framing the model as incapable of independent math compels the agent to use external utilities for all numerical queries. This technique aligns with broader industry shifts where agents evolve from simple query-response systems into autonomous assistants capable of complex, multi-step problem solving using prebuilt agent architectures.

Applying this prompt constraint and re-running the test with a radius input of 7.81 resulted in the agent correctly using the Circumference calculator tool with Tool Input 7.81 and Observation 49.071677249072565. This specific configuration ensures the model treats mathematical operations as mandatory tool calls rather than optional generative tasks. The cost is a rigid conversational style, yet the gain in numerical reliability justifies the loss of conversational fluidity for technical applications. Builders should note that without such explicit prompting, even advanced models will frequently hallucinate results for simple geometry problems.

Mitigating Randomness with Low Temperature Settings for Tools

Setting the LLM temperature to 0 minimizes probabilistic token selection that causes tool invocation errors. High creativity settings introduce randomness into the execution loop, leading the model to hallucinate parameters or skip the Thought → Action → Observation cycle. When an agent ignores its Circumference calculator to guess a result, the failure stems from excessive sampling variance during prompt decoding.

Decreasing creativity encourages following strict instructions which is necessary when using tools. The limitation is a loss of conversational flexibility, as the model cannot generate varied phrasing when strictly bound to schema constraints. Operators must prioritize protocol adherence over linguistic diversity when configuring BaseTool subclasses for production workloads.

Setting Behavior Use Case
Temperature 0 Deterministic Tool execution, code generation
Temperature >0 Creative Brainstorming, draft writing

This configuration ensures the ChatOpenAI client returns consistent JSON structures rather than explanatory text. Without this constraint, the ReAct framework may struggle as the agent drifts from its set description during complex reasoning tasks. AI Agents News recommends locking temperature values for any workflow requiring external API integration.

Implementing a Circumference Calculator Using LangChain BaseTool

Defining CircumferenceTool Attributes and Methods

Subclassing BaseTool demands specific values for name and description so the agent recognizes the utility immediately. Setting name to "Circumference calculator" creates a unique identifier while the description string guides selection logic during runtime. These two mandatory attributes allow the agent to identify the tool within a list of many options. The description serves as a natural language explanation used by the LLM to decide when to use the tool, and should be explicit on what the tool does and when to use it.

Execution paths diverge based on whether the call is synchronous or asynchronous. The _run method handles standard synchronous calls, computing the result using the formula `float(radius)*2.0*pi`. Conversely, the _arun method manages asynchronous requests but currently raises a `NotImplementedError` since async tools are not covered in this context. Builders must remember that when a tool is used, the _run method is called by default, while _arun is called when a tool is to be used asynchronously.

  1. Define the class inheriting from BaseTool.
  2. Assign the static name and description attributes.
  3. Implement _run with the mathematical logic.
  4. Raise `NotImplementedError` inside _arun.

Precision in natural language documentation directly correlates with reliable tool use in production agents. Adding details on "when not to use it" can help if a tool is overused, though the LLM may be capable of identifying when the tool is needed without it.

Implementing Math Logic with Pi and Radius Inputs

Constructing the `_run` method requires importing `pi` from the `math` library to execute the formula `float(radius)*2.0*pi`. This specific calculation converts the input radius to a float before multiplying by `2.0` and `pi`. Developers building a custom tool must ensure this logic resides within the synchronous execution path.

The companion `_arun` method explicitly raises a `NotImplementedError` because asynchronous workflows are outside the current scope of this simple calculator. This design choice aligns with the chapter's focus on synchronous tool usage.

  1. Import `pi` from the standard `math` module.
  2. Cast the incoming `radius` argument to a float.
  3. Multiply the radius by `2.0` and `pi`.

Omitting a functional `_arun` implementation and raising an error instead clearly signals that the tool does not support async contexts. Supporting async operations is possible yet this example focuses on the standard synchronous pattern. Builders requiring high-concurrency environments must refactor this method to handle async contexts properly.

Method Purpose Implementation Status
`_run` Synchronous execution Active (Math logic)
`_arun` Asynchronous execution Disabled (Error)

This configuration ensures deterministic behavior for single-threaded agent loops while clearly signaling limitations for advanced users.

Configuring ChatOpenAI Temperature and Memory Window

Set the ChatOpenAI `temperature` parameter to exactly 0. A low temperature is useful when using tools as it decreases the amount of "randomness" or "creativity" in the generated text of the LLMs, which is ideal for encouraging it to follow strict instructions required for tool usage.

Concurrently, initialize ConversationBufferWindowMemory with `k=5` to retain the five most recent human-AI interactions. This setting configures the memory to "remember" the previous five exchanges between the human and the AI.

Parameter Configuration Operational Impact
temperature 0 Reduces randomness; encourages following strict instructions
k (memory) 5 Limits history to the previous five human-AI interactions
model_name gpt-3.5-turbo The specific OpenAI model used for this chat agent

Deploying these settings requires precise initialization before passing objects to the `initialize_agent` function within the LangChain framework.

The `k=5` setting defines the specific window of conversation history available to the agent. Builders should consider whether this fixed window size suffices for their specific query complexity or if a different memory management strategy is required for their use case.

Advanced Patterns for Multi-Parameter Tools and Image Captioning

Multi-Parameter Tool Logic and Validation Rules

Agents skip required inputs constantly, breaking multi-parameter tools unless descriptions enforce strict constraints. The PythagorasTool implementation accepts three optional floats: adjacent_side, opposite_side, and angle. Its description field carries a hard rule: "To use the tool, you must provide at least two of the following parameters." This instruction stops the model from guessing missing values, forcing strict adherence to geometric requirements before execution. Logic imports sqrt, cos, and sin from the math library to compute results only when the parameter count validates. If the agent provides fewer than two arguments, the tool returns a specific error string rather than a hallucinated number. This pattern aligns with strict schema definitions that prevent incorrect function execution by enforcing data types and validation rules. Embedding constraints in natural language descriptions introduces ambiguity if the LLM ignores the prompt preamble. Token usage increases for every tool call because the description must be re-transmitted to maintain context. The description field acts as the primary guardrail since the LLM is never given raw access to tools and relies entirely on these textual boundaries for safety.

Integrating Hugging Face BLIP for Image Captioning

Visual inputs baffle text-only LLMs until the Salesforce/blip-image-captioning-large model enters the workflow. Implementing this capability requires importing `BlipProcessor` and `BlipForConditionalGeneration` from the transformers library alongside torch for device management. The workflow initiates by downloading an image from a provided URL, converting it into a PIL object, and applying the processor before generation. Configuration defaults to 'cuda' when available, falling back to 'cpu' to ensure broad compatibility across deployment environments.

Operators must modify the agent prompt to explicitly instruct the use of this tool when image URLs appear in user queries. Without specific directive tuning, the LLM may attempt to hallucinate image content rather than invoking the ImageCaptionTool. Regarding execution flow, the current implementation raises a `NotImplementedError` for the `_arun` method, meaning these tools do not support async operations natively. Builders requiring non-blocking execution must implement custom threading or queue management outside the standard LangChain interface. This architectural constraint creates a bottleneck where visual processing blocks the entire agent thread until completion. Hugging Face offers improved token limits for such tasks, yet the synchronous nature of the tool call remains a latency factor. The integration transforms the agent into a multimodal system capable of describing scenes, though accuracy varies by subject matter specificity.

Validation Steps for Tool Inputs and Outputs

Parameter counts determine success before any calculation occurs. The PythagorasTool logic requires at least two values from adjacent_side, opposite_side, or angle to proceed. A test case using 51cm and 34cm yields an observation of 61.29437168288782, confirming the math library functions correctly. Conversely, image captioning tools may return descriptive text like "there is a monkey that is sitting in a tree" for an orangutan, revealing a semantic gap between model output and ground truth.

Check Type Input Example Expected Outcome
Parameter Count `{"adjacent_side": 34}` Error: Need two or more parameters
Numeric Precision `{"opposite_side": 51}` Float result within epsilon
Semantic Accuracy Image URL Caption matches visual entities

Agents increasingly attempt to dynamically apply external software components, yet they often lack inherent validation logic without explicit schema constraints. Tension exists between allowing flexible natural language queries and enforcing rigid function signatures required for execution. If the agent prompt omits the rule stating "provide at least two of the following parameters," the model may hallucinate missing values rather than request clarification. Builders must modify the agent prompt to include these validation rules as hard constraints within the system message. This ensures the LLM treats missing parameters as a failure condition rather than an opportunity for improvisation. Multi-parameter tools remain unreliable for production workloads without this step.

About

Diego Alvarez serves as Developer Advocate at AI Agents News, where he specializes in hands-on build guides and framework comparisons. His daily work involves constructing end-to-end agents using libraries like LangChain, CrewAI, and AutoGen, giving him direct insight into the limitations of prebuilt solutions. This article on building custom LangChain tools stems directly from his experience modifying standard patterns to fit complex, real-world engineering requirements. While LangChain offers a reliable library of existing tools, Alvarez frequently encounters scenarios where developers must engineer unique function-calling capabilities or integrate external ML models for tasks like image description. As AI Agents News provides technical coverage for engineers evaluating agentic frameworks, Alvarez's practical focus ensures this guide avoids theoretical hype. He connects the abstract concept of tool use to concrete implementation details, helping builders navigate the specific challenges of orchestration and reliability when extending LLM agents beyond basic templates.

Conclusion

Scaling these agents reveals that latency in synchronous calls becomes a hard bottleneck once workflow complexity increases. While improved token limits help, the real operational cost lies in managing the semantic gap between flexible natural language and rigid function signatures. Without explicit schema constraints, agents will hallucinate missing parameters rather than request clarification, turning every edge case into a production incident. You must treat validation logic as a core architectural requirement, not an afterthought.

Implement a strict policy where any tool requiring multiple inputs fails immediately if the agent prompt does not explicitly enforce parameter counts as hard constraints. Do not rely on the model to infer these rules from context alone. Schedule a review of your current system messages within the next sprint to ensure missing data triggers a set error state instead of improvisation. This shift prevents the system from degrading into unreliable behavior under load.

Start this week by auditing your PythagorasTool or similar multi-parameter functions to verify that the system message explicitly demands at least two values before execution. If the prompt allows the model to proceed with single inputs or invented data, rewrite it now to enforce a hard failure condition. Only by embedding these rules directly into the agent prompt can you ensure consistent, grounded performance.

Frequently Asked Questions

The agent will fail to recognize the object as a valid tool for execution. You must define both name and description attributes so the controller routes user requests correctly based on natural language.

No, even a single custom tool must be wrapped in a list to match the expected interface. This explicit configuration ensures the agent routes queries to the correct function based on descriptions.

It chains tool outputs into subsequent inputs through thought, action, and observation loops. This text-based interface lets the agent delegate operations like circumference calculations without exposing raw code execution to the model.

The _run method is called by default when a tool is used by the system. The _arun method is only called when a tool is specifically intended to be used asynchronously.

A low temperature is useful when using tools to ensure deterministic behavior during execution. This setting helps prevent hallucination during deterministic steps by reducing random variation in the model output.

References