langchain-Agent-工具篇

文章目录

  • 工具定义的方式
    • 加载langchain中的工具
    • 自定义工具的几种方式
      • @tool decorator
      • Tool dataclass
      • Subclass BaseTool
      • StructuredTool dataclass
  • 工具的异常处理

工具定义的方式

加载langchain中的工具

from langchain.agents import load_tools
llm = OpenAI(temperature=0)
tools = load_tools(["serpapi", "llm-math"], llm=llm)

自定义工具的几种方式

工具描述的重要组成部分

  • 名称(str),是必需的,并且必须在提供给代理的一组工具中是唯一的
  • 描述(str),是可选的,但建议使用,因为代理用于确定工具使用
  • return_direct(bool),默认为False,表示调用工具之后直接返回还是继续执行Agent的流程
  • args_schema(Pydantic BaseModel), 是可选的,但建议使用,可以用于提供更多信息或验证预期参数。需要从langchain.pydantic_v1导入BaseModel,如果直接从pydantic导入,可能会报错
  • handle_tool_error 表示工具异常时如何处理

导入需要的包

from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain.pydantic_v1 import BaseModel, Field # 不要直接使用pydantic
from langchain.tools import BaseTool, StructuredTool, tool, Tool

@tool decorator

使用@tool装饰器来定义工具,后面添加工具名称、参数描述、是否直接返回等内容。

# 定义参数描述
class SearchInput(BaseModel):
    query: str = Field(description="should be a search query")
# 定义工具
@tool("search-tool", args_schema=SearchInput, return_direct=True)
def search(query: str) -> str:
    """Look up things online."""
    return "LangChain"
# 查看工具的相关描述
print(search.name)
print(search.description)
print(search.args)
print(search.return_direct)
# 调用工具
tools = [search]
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent.run("please search the weather today")

Tool dataclass

class SearchInput(BaseModel):
    query: str = Field(description="should be a search query")
def search(query: str) -> str:
    return "LangChain"
tools = [
        Tool.from_function(
            func=search,
            name="Search-tool",
            description="Look up things online.",
            return_direct = True
        ) 
    ]

Subclass BaseTool

from typing import Optional, Type
from langchain.callbacks.manager import (
    AsyncCallbackManagerForToolRun,
    CallbackManagerForToolRun,
)

class SearchInput(BaseModel):
    query: str = Field(description="should be a search query")

class CustomSearchTool(BaseTool):
    name = "custom_search"
    description = "useful for when you need to answer questions about current events"
    args_schema: Type[BaseModel] = SearchInput
    return_direct: bool = True
 
    def _run(
        self, query: str, run_manager: Optional[CallbackManagerForToolRun] = None
    ) -> str:
        """Use the tool."""
        return "LangChain"

    async def _arun(
        self, query: str, run_manager: Optional[AsyncCallbackManagerForToolRun] = None
    ) -> str:
        """Use the tool asynchronously."""
        raise NotImplementedError("custom_search does not support async")
search = CustomSearchTool()
tools = [search]

StructuredTool dataclass

class SearchInput(BaseModel):
    query: str = Field(description="should be a search query")
    
def search_tool(query: str):
    return "LangChain"
    
search = StructuredTool.from_function(
    func=search_tool,
    name="Search",
    description="useful for when you need to answer questions about current thing",
    args_schema=SearchInput,
    return_direct=True,
    # coroutine= ... <- you can specify an async method if desired as well
)
tools = [search]

工具的异常处理

当工具遇到错误且未捕获异常时,代理将停止执行。如果希望代理继续执行,可以引发一个ToolException并相应地设置handle_tool_error。

当抛出ToolException时,代理不会停止工作,而是根据工具的handle_tool_error变量处理异常,并将处理结果作为观察返回给代理,并以红色打印。

您可以将handle_tool_error设置为True,将其设置为统一的字符串值,或将其设置为函数。如果它被设置为一个函数,那么这个函数应该接受一个ToolException作为参数并返回一个str值。

from langchain_core.tools import ToolException
def search_tool1(s: str):
    raise ToolException("The search tool1 is not available.")
search = StructuredTool.from_function(
    func=search_tool1,
    name="Search_tool1",
    description="A bad tool",
    handle_tool_error=True,
)

search.run("test")

你可能感兴趣的:(笔记,LLM,langchain)