Reputation: 69
I want to create a custom tool class with an additional property, let's say number
. How can I change this code so that it doesn't throw an error?
Code:
from langchain.tools import BaseTool
class MyTool(BaseTool):
name = "Whatever"
description = "Whatever"
def __init__(self):
self.number = 123
def _run(self):
pass
def _arun(self):
pass
tool = MyTool()
Error:
ValueError: "MyTool" object has no field "number"
Upvotes: 2
Views: 2627
Reputation: 51
I was able to solve this problem for myself!
You need to define a custom class property and give it a value in __init__
.
Class property must be public!
from typing import Type
from langchain.pydantic_v1 import BaseModel, Field
from langchain.tools import BaseTool
from langchain.callbacks.manager import AsyncCallbackManagerForToolRun, CallbackManagerForToolRun
from .my_vector_search_class import MyVectorSearchClass
class VectorSearchSchema(BaseModel):
query: str = Field(description="Search question or thesis")
class VectorSearchTool(BaseTool):
name = "VectorSearch"
description = "Use this when you need to find information from the documentation or FAQ."
args_schema: Type[BaseModel] = VectorSearchSchema
my_vector_search_property: MyVectorSearchClass = None
def __init__(self):
super().__init__()
self.my_vector_search_property = MyVectorSearchClass()
def _run(
self, query: str, run_manager: CallbackManagerForToolRun = None
) -> str:
context = self.my_vector_search_property.run(query)
return context
async def _arun(
self, query: str, run_manager: AsyncCallbackManagerForToolRun = None
) -> str:
raise NotImplementedError("VectorSearchTool does not support async")
langchain==0.2.13
Upvotes: 0
Reputation: 408
This worked for me
from langchain.tools import BaseTool
from langchain.pydantic_v1 import Extra
class MyTool(BaseTool):
name = "Whatever"
description = "Whatever"
class Config:
extra = Extra.allow
def __init__(self, number):
super().__init__(number=number)
self.number = number # not needed but helps with type hinting
def _run(self):
return self.number
def _arun(self):
return self.number
tool = MyTool()
Related: https://github.com/langchain-ai/langchain/discussions/17232
Upvotes: 2
Reputation: 11
Try this:
from langchain.tools import BaseTool
class MyTool(BaseTool):
name = "Whatever"
description = "Whatever"
number: int
def __init__(self, number: int = 123):
super(MyTool, self).__init__(number=number)
def _run(self):
print("run:", self.number)
def _arun(self):
print("arun:", self.number)
tool_1 = MyTool()
tool_2 = MyTool(number=321)
Upvotes: 1
Reputation: 2866
Please find solution below
from langchain import LLMMathChain
from langchain.agents import AgentType, initialize_agent
from langchain.chat_models import ChatOpenAI
from langchain.tools import BaseTool
from typing import Any
class MyTool(BaseTool):
name = "Custom Tool"
description = "This tool multiplies a number by itself"
def _run(self, number: str) -> Any:
return float(number) * float(number)
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
llm = ChatOpenAI(temperature=0)
llm_math_chain = LLMMathChain(llm=llm, verbose=True)
tools = [MyTool()]
agent = initialize_agent(
tools,
llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True, max_iterations=3,
early_stopping_method='generate'
)
agent(
"Result of 5"
)
Upvotes: 0