6大核心模块(Modules)
自定义工具(Custom Tools)

定义自定义工具

构建自己的代理时,您需要为其提供一组工具列表。除了实际调用的函数外,工具还由几个组件组成:

  • 名称(str),是必需的,并且必须在提供给代理的一组工具中是唯一的
  • 描述(str),是可选的,但建议使用,因为代理用于确定工具使用
  • return_direct(bool),默认为False
  • args_schema(Pydantic BaseModel), 是可选的,但建议使用,可以用于提供更多信息或验证预期参数。

当选择工具时应调用的函数应返回单个字符串。

有两种定义工具的方法,我们将在下面的示例中涵盖这两种方法。 可以使用Tool数据类或通过子类化BaseTool类来完全从头创建新工具。

在这个例子中,我们使用Tool数据类来创建一个名为"Search"的新工具。 该工具使用SerpAPI包装器来回答有关当前事件的问题。

我们还初始化了用于代理的LLM,并创建了一个名为"llm_math_chain"的新工具,用于数学计算使用LLM。 "verbose"参数设置为True,在计算过程中提供额外的输出。

可以定义一个args_schema来提供有关输入的更多信息。

从 pydantic 导入 BaseModel,Field

class CalculatorInput(BaseModel):
    question: str = Field()
        
 
tools.append(
    Tool(
        name="Calculator",
        func=llm_math_chain.run,
        description="在需要回答数学问题时非常有用",
        args_schema=CalculatorInput
    )
)
 
# 构建代理。 这里我们将使用默认代理类型。
# 有关选项的完整列表,请参见文档。
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
 
agent.run("谁是莱昂纳多·迪卡普里奥的女朋友?她当前的年龄上升到0.43次方是多少?")
 
> 进入新的 AgentExecutor 链...
我需要找出莱昂纳多·迪卡普里奥的女友名字和她的年龄
动作:搜索
动作输入:“Leo DiCaprio girlfriend”
迪卡普里奥在2022年夏天和女友卡米拉·莫罗内(Camila Morrone)分手后,
两人的恋情持续了一年。Subclassing the BaseTool class
```  python
从BaseTool类派生子类
 
```python
from typing import Type
 
class CustomSearchTool(BaseTool):
    name = "搜索"
    description = "当你需要回答有关当前事件的问题时有用"
 
    def _run(self, query: str) -> str:
        """使用工具。"""
        return search.run(query)
    
    async def _arun(self, query: str) -> str:
        """异步使用工具。"""
        raise NotImplementedError("BingSearchRun不支持异步")
    
class CustomCalculatorTool(BaseTool):
    name = "计算器"
    description = "用于进行数学计算"
 
    def _run(self, query: str) -> str:
        """使用工具。"""
        return calculator.run(query)
    
    async def _arun(self, query: str) -> str:
        """异步使用工具。"""
        raise NotImplementedError("CustomCalculatorTool不支持异步")
```  python
以上是派生自BaseTool类的两个子类CustomSearchTool和CustomCalculatorTool,
分别实现了搜索和计算器的功能。
其中,CustomSearchTool用于回答关于当前事件的问题,而CustomCalculatorTool用于进行数学计算。
 
 
## CustomCalculatorTool
 
这是一个名为`CustomCalculatorTool`的工具,用于回答关于数学的问题。它使用`CalculatorInput`作为参数模式。
 
在`_run`方法中,该工具会运行`llm_math_chain.run(query)`并返回结果。
 
在`_arun`方法中,该工具会抛出一个`NotImplementedError`,表示不支持异步操作。
 
## 初始化工具和代理
 
使用`CustomSearchTool()`和`CustomCalculatorTool()`初始化一个包含两个工具的工具链(`tools`)
 
使用`initialize_agent()`方法初始化一个名为`agent`的代理,
使用`ZERO_SHOT_REACT_DESCRIPTION`作为代理类型,并打开冗长模式。
 
## 运行代理
 
使用`agent.run()`方法运行代理,并传入一个包含两个问题的字符串。
代理将使用`CustomSearchTool()`和`CustomCalculatorTool()`工具链来回答这些问题,并打印出回答。
请将以下markdown格式的内容,翻译为中文,代码块不用翻译,请保持markdown格式输出。
需要翻译的内容是:Camila Morrone的当前年龄
 
Action: 计算器
Action Input: 25^(0.43)
 
> 进入新的LLMMathChain链...
25^(0.43)```text
25\*\*(0.43)
 
```python
...numexpr.evaluate("25\*\*(0.43)")...
 
答案:3.991298452658078
> 链结束。
答案:3.991298452658078 我现在知道了最终答案
最终答案:3.991298452658078
 
> 链结束。
 
'3.991298452658078'
 

使用 tool 装饰器

为了更容易地定义自定义工具,提供了 @tool 装饰器。

这个装饰器可以用于快速创建一个 Tool,从一个简单的函数中。

装饰器默认使用函数名作为工具名,但可以通过传递一个字符串作为第一个参数来覆盖。

此外,装饰器将使用函数的文档字符串作为工具的描述。

定义了一个名为search_api的函数,该函数接受一个字符串类型的参数query,

并返回一个字符串类型的结果Results for query {query}

使用@tool装饰器来定义一个名为search的工具,这个工具会直接返回结果。

该工具调用了search_api函数,接受一个字符串类型的参数query,返回一个字符串类型的结果"Results"。

修改现有工具 #

现在,我们展示如何加载现有的工具并对其进行修改。在下面的示例中,我们做一些非常简单的事情,

将搜索工具的名称更改为“Google Search”。

from langchain.agents import load_tools
```  python
 
```python
tools = load_tools(["serpapi", "llm-math"], llm=llm)
```  python
 
```python
tools[0].name = "Google Search"
```  python
 
```python
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
```  python
 
```python
agent.run("Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?")
```  python
 
```python
> 进入新的AgentExecutor链...
我需要找出Leo DiCaprio女友的名字和她的年龄。
动作:Google Search
动作输入:"Leo DiCaprio girlfriend"I draw the lime at going to get a Mohawk, though." DiCaprio broke up with girlfriend Camila Morrone, 25, in the summer of 2022, after dating for four years. He's since been linked to another famous s
```超模特——吉吉·哈迪德。现在我需要找出卡米拉·莫罗内的当前年龄。
操作:计算器
操作输入:25 ^ 0.43
答案:3.991298452658078
我现在知道了最终答案。
最终答案:卡米拉·莫罗内的当前年龄提高到0.43次方约为3.99。
 
> 完成链。
 
```python
    )
]
# Initialize the agent
agent = initialize_agent(
    agent_type=AgentType.OPENAI,
    api_key="your_api_key_here",
    llm=LLMMathChain(),
    tools=tools
)
 
# Use the agent to answer a question
response = agent.answer("What is the capital of France?")
 
# Print the response
print(response)
```  python
这可以通过添加类似于“使用这个音乐搜索引擎而不是普通搜索。
 
如果问题是关于音乐的,比如“谁是昨天的歌手?” 或“2022年最受欢迎的歌曲是什么?”的语句来实现。
 
下面是一个例子。
 
 
```python
# 导入通用所需的工具
from langchain.agents import initialize_agent, Tool
from langchain.agents import AgentType
from langchain.llms import OpenAI
from langchain import LLMMathChain, SerpAPIWrapper
search = SerpAPIWrapper()
tools = [
    Tool(
        name = "搜索",
        func=search.run,
        description="当您需要回答当前事件的问题时很有用"
    ),
    Tool(
        name="音乐搜索",
        func=lambda x: "'All I Want For Christmas Is You' by Mariah Carey.", #Mock Function
        description="一个音乐搜索引擎。如果问题是关于音乐的,
        请使用这个搜索引擎而不是普通搜索,比如'谁是昨天的歌手?
        '或'2022年最受欢迎的歌曲是什么?'"
    )
]
# 初始化代理
agent = initialize_agent(
    agent_type=AgentType.OPENAI,
    api_key="your_api_key_here",
    llm=LLMMathChain(),
    tools=tools
)
 
# 使用代理回答问题
response = agent.answer("法国的首都是哪里?")
 
# 打印回答
print(response)
```irectly instead of going through the agent's decision making process. This can be done by using the `tools.run` method. Here is an example:
 
```python
from deepset_ai import tools
 
answer = tools.run('text-classification', model_name_or_path='bert-base-uncased', data=['What is the capital of France?'])
print(answer)
```  python
在这个例子中,我们使用`text-classification`工具来使用BERT模型对给定的文本进行分类。
 
输出将是一个字典列表,其中每个字典代表一个可能的标签及其相关的得分。
`print`语句将输出此列表。
 
要直接将结果返回给用户(如果调用的话),可以通过设置LangChain中工具的`return_direct`标志为`True`来轻松实现。
 
 
```python
llm_math_chain = LLMMathChain(llm=llm)
tools = [
    Tool(
        name="计算器",
        func=llm_math_chain.run,
        description="在需要回答数学问题时很有用",
        return_direct=True
    )
]
 
llm = OpenAI(temperature=0)
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
 
agent.run("2\*\*.12是多少")
 
> 进入新的AgentExecutor链...
 我需要计算一下
操作:计算器
操作输入:2\*\*.12答案:1.086734862526058
 
> 链结束。
 
'答案:1.086734862526058'