Skip to content

Commit 8ca1667

Browse files
committed
Add custom and built-in Langchain tools for mathematical operations and search functionality
1 parent d941679 commit 8ca1667

File tree

5 files changed

+189
-0
lines changed

5 files changed

+189
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from langchain.tools import BaseTool
2+
from typing import Type
3+
from pydantic import BaseModel, Field
4+
import asyncio
5+
6+
class MultiplyInput(BaseModel):
7+
a: int = Field(..., description="First number to multiply")
8+
b: int = Field(..., description="Second number to multiply")
9+
10+
# On inheriting from BaseTool class, we can create a custom tool
11+
class MultiplyTool(BaseTool):
12+
"""Multiply two numbers."""
13+
14+
name: str = "multiply"
15+
description: str = "Multiply two numbers"
16+
args_schema: Type[BaseModel] = MultiplyInput
17+
18+
def _run(self, a: int, b: int) -> int:
19+
return a * b
20+
21+
async def _arun(self, a: int, b: int) -> int: # async method can be used to ensure concurrency
22+
return a * b
23+
24+
# multiply_tool = MultiplyTool()
25+
# result = multiply_tool.invoke({'a': 2, 'b': 3})
26+
# print(result)
27+
28+
# print(multiply_tool.name)
29+
# print(multiply_tool.description)
30+
# print(multiply_tool.args)
31+
32+
async def _():
33+
multiply_tool = MultiplyTool()
34+
result = await multiply_tool.ainvoke({'a': 6, 'b': 7})
35+
print("Async Result:", result)
36+
print("Tool name:", multiply_tool.name)
37+
print("Description:", multiply_tool.description)
38+
print("Args Schema:", multiply_tool.args_schema.schema())
39+
40+
asyncio.run(_())
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from langchain_community.tools import DuckDuckGoSearchRun, ShellTool
2+
3+
# Built-in Tool - DuckDuckGo Search
4+
search_tool = DuckDuckGoSearchRun() # Tools are runnables
5+
results = search_tool.invoke('top news in India today')
6+
print(results)
7+
8+
print(search_tool.name) # Name of the tool
9+
print(search_tool.description) # Description of the tool
10+
print(search_tool.args) # Arguments of the tool
11+
print(search_tool.metadata) # Metadata of the tool
12+
13+
# Built-in Tool - Shell Tool
14+
shell_tool = ShellTool()
15+
results = shell_tool.invoke('ls -l')
16+
print(results)
17+
18+
# Refer to Langchain documentation for more built-in tools
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
from langchain_core.tools import tool
2+
3+
# Custom tools
4+
@tool
5+
def add(x: int, y: int) -> int:
6+
"""Adds two numbers."""
7+
return x + y
8+
9+
@tool
10+
def subtract(x: int, y: int) -> int:
11+
"""Subtracts two numbers."""
12+
return x - y
13+
14+
@tool
15+
def multiply(x: int, y: int) -> int:
16+
"""Multiplies two numbers."""
17+
return x * y
18+
19+
@tool
20+
def divide(x: int, y: int) -> float:
21+
"""Divides two numbers."""
22+
return x / y
23+
24+
@tool
25+
def power(x: int, y: int) -> int:
26+
"""Raises x to the power of y."""
27+
return x ** y
28+
29+
def calculate_factorial(n: int) -> int:
30+
"""Calculates the factorial of n."""
31+
if n < 0:
32+
raise ValueError("Factorial is not defined for negative numbers.")
33+
if n == 0 or n == 1:
34+
return 1
35+
return n * calculate_factorial(n - 1)
36+
@tool
37+
def factorial(x: int) -> int:
38+
"""Calculates the factorial of x."""
39+
return calculate_factorial(x)
40+
41+
class MathToolkit:
42+
"""A toolkit for performing various mathematical operations."""
43+
44+
def __init__(self):
45+
self.tools = [add, subtract, multiply, divide, power, factorial]
46+
47+
def get_tools(self):
48+
"""Returns the available tools."""
49+
return self.tools
50+
51+
def execute_tool(self, tool_name: str, *args):
52+
"""Executes a tool by its name with the given arguments."""
53+
for tool in self.tools:
54+
if tool.name == tool_name:
55+
input_keys = tool.args
56+
if len(input_keys) != len(args):
57+
raise ValueError(f"{tool_name} expects {len(input_keys)} arguments, got {len(args)}.")
58+
input_dict = dict(zip(input_keys, args))
59+
return tool.invoke(input_dict)
60+
raise ValueError(f"Tool {tool_name} not found in toolkit.")
61+
62+
toolkit = MathToolkit()
63+
tools = toolkit.get_tools()
64+
65+
for tool in tools:
66+
print(tool.name,"-->",tool.description)
67+
68+
print("Addition result:", toolkit.execute_tool("add", 5, 3))
69+
print("Subtraction result:", toolkit.execute_tool("subtract", 5, 3))
70+
print("Multiplication result:", toolkit.execute_tool("multiply", 5, 3))
71+
print("Division result:", toolkit.execute_tool("divide", 5, 3))
72+
print("Power result:", toolkit.execute_tool("power", 5, 3))
73+
print("Factorial result:", toolkit.execute_tool("factorial", 5))
74+
75+
76+
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from langchain_core.tools import tool
2+
from pydantic import BaseModel, Field
3+
4+
# Custom Tools
5+
# Step 1 - Create a function
6+
def multiply(a, b):
7+
"""Multiply two numbers."""
8+
return a * b
9+
10+
# Step 2 - Add type hints
11+
def multiply(a: int, b: int) -> int:
12+
"""Multiply two numbers."""
13+
return a * b
14+
15+
# Step 3 - add tool decorator
16+
@tool
17+
def multiply(a: int, b: int) -> int:
18+
"""Multiply two numbers."""
19+
return a * b
20+
21+
# Step 4 - invoke the tool
22+
result = multiply.invoke({'a': 5, 'b': 4})
23+
print(result)
24+
25+
# Tool attributes
26+
print(multiply.name)
27+
print(multiply.description)
28+
print(multiply.args)
29+
30+
print(multiply.args_schema.model_json_schema()) # Passed to the LLM - tools are not sent, its schema is sent
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from langchain.tools import StructuredTool
2+
from pydantic import BaseModel, Field
3+
4+
# Custom Tools - Using StructuredTool
5+
class MultiplyInput(BaseModel):
6+
a: int = Field(required=True, description="First number to multiply")
7+
b: int = Field(required=True, description="Second number to multiply")
8+
9+
def multiply_two_numbers(a: int, b: int) -> int:
10+
"""Multiply two numbers."""
11+
return a * b
12+
13+
multiply_tool = StructuredTool.from_function(
14+
func=multiply_two_numbers,
15+
name="multiply",
16+
description="Multiply two numbers",
17+
args_schema=MultiplyInput
18+
)
19+
20+
result = multiply_tool.invoke({'a': 6, 'b': 9})
21+
print(result)
22+
23+
print(multiply_tool.name)
24+
print(multiply_tool.description)
25+
print(multiply_tool.args)

0 commit comments

Comments
 (0)