> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Building a Custom Tool

> Explains building a LangChain custom tool that returns flight status, inspects tool metadata, and integrates the tool output into a prompt, LLM, and output parser chain

Now that we understand the concept of tools in LangChain, this lesson puts everything together by building a compact custom tool that returns flight status information. The example demonstrates:

* How to convert a Python function into a LangChain tool using the `@tool` decorator.
* How to inspect generated tool metadata (name, description, args).
* How to call the tool, use its output as context in a prompt, and run a prompt → LLM → output-parser chain.

The following concise, corrected example shows the end-to-end flow.

```python theme={null}
from langchain.tools import BaseTool, StructuredTool, tool
from langchain_core.prompts import PromptTemplate
from langchain_openai import OpenAI
from langchain_core.output_parsers import StrOutputParser

@tool
def GetFlightStatus(flight_no: str) -> str:
    """Gets flight status and schedule"""
    # In a real application you could invoke an external API here.
    return f"Flight {flight_no} departed at 5:20 PM. It is on-time and expected to arrive at 8:10 PM at Gate B."

# Inspect tool metadata provided by the decorator
print(GetFlightStatus.name)
print(GetFlightStatus.description)
print(GetFlightStatus.args)

# Build a prompt template that expects a context and a query
prompt = PromptTemplate.from_template(
    "Based on the context: {context},\nanswer the query: {query} about flight {flight} in one word."
)

# LLM and output parser
llm = OpenAI()
output_parser = StrOutputParser()

# Compose the chain: prompt -> llm -> output parser
chain = prompt | llm | output_parser

# Example flight and invoking the tool to fetch context
flight = "EK524"
context = GetFlightStatus.run(flight)

# Use the chain to answer specific queries based on the tool-provided context
status_answer = chain.invoke({"context": context, "query": "status", "flight": flight})
departure_answer = chain.invoke({"context": context, "query": "departure time", "flight": flight})
arrival_answer = chain.invoke({"context": context, "query": "arrival time", "flight": flight})
gate_answer = chain.invoke({"context": context, "query": "gate", "flight": flight})

print("Status:", status_answer)
print("Departure:", departure_answer)
print("Arrival:", arrival_answer)
print("Gate:", gate_answer)
```

Expected metadata printed when inspecting the tool:

```text theme={null}
GetFlightStatus
GetFlightStatus(flight_no: str) -> str - Gets flight status and schedule
{'flight_no': {'title': 'Flight No', 'type': 'string'}}
```

Example of the chain invocation outputs (based on the static tool response above):

```text theme={null}
Status: On-time
Departure: 5:20 PM
Arrival: Expected
Gate: B
```

Tool metadata reference

| Field       | Description                         | Example                                                                    |
| ----------- | ----------------------------------- | -------------------------------------------------------------------------- |
| Name        | Tool name exposed to LangChain      | `GetFlightStatus`                                                          |
| Description | Short summary of the tool's purpose | `GetFlightStatus(flight_no: str) -> str - Gets flight status and schedule` |
| Args        | Argument schema for the tool        | `{'flight_no': {'title': 'Flight No', 'type': 'string'}}`                  |

Notes on what's happening

* Decorating the function with `@tool` converts it into a StructuredTool-like object that LangChain can inspect and call. The decorator exposes metadata such as `name`, `description`, and `args` (the argument schema).
* `GetFlightStatus.run(flight)` executes the function and returns the static context string shown above. In production you would call a live flight-status API inside this function and return the real response.
* The `PromptTemplate` uses the tool output as `context`. The chain (`prompt | llm | output_parser`) takes the populated prompt, sends it to the LLM, and then parses the output into a simple string using `StrOutputParser`.
* This follows a retrieve-and-read pattern where the retrieval step is replaced by a tool call that supplies up-to-date context to the LLM.

<Callout icon="lightbulb" color="#1CB2FE">
  This example uses a static response to keep the demonstration simple. For production, replace the static return with a real API call (include robust error handling, retries, and rate limiting). Also ensure the tool returns well-structured, documented data that your prompt and output parser expect.
</Callout>

Next steps

* Replace the static `GetFlightStatus` implementation with a real flight-status API to return live information.
* Build additional tools (e.g., airport info, weather) and explore creating an agent that selects between them to fulfill more complex user requests.
* Read more about LangChain tools and agents:
  * [LangChain Tools and Agents Guide](https://langchain.readthedocs.io/)
  * [OpenAI API Documentation](https://platform.openai.com/docs)

By following this pattern you can develop robust tool-backed chains that keep the LLM focused on reasoning while delegating data retrieval and structured logic to external functions.

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/langchain/module/06905b96-585d-4c9e-835a-d8fcaca76e2a/lesson/f564445e-f3df-4cae-9d49-986dc4a02a02" />

  <Card title="Practice Lab" icon="flask-conical" cta="Learn more" href="https://learn.kodekloud.com/user/courses/langchain/module/06905b96-585d-4c9e-835a-d8fcaca76e2a/lesson/a39008e8-97e9-4813-a404-3c1006e6e97c" />
</CardGroup>
