永远不要说再见,因为再见意味着离去,离去意味着遗忘。
01 Tool介绍
在LangChain中,Tools 是一个核心概念,它们允许模型与外部系统进行交互,从而扩展了基础语言模型的功能。Tools 可以被看作是代理(agent)可用的一系列功能,这些功能包括但不限于网络搜索、API调用、数据库查询、文件操作等。
LangChain Tools 的基本结构
- 名称 (name):工具的标识符。
- 输入(input):工具的输入
- 描述 (description):描述工具用途的字符串,这将帮助代理决定何时使用此工具。
- 函数 (func):实际执行工具功能的可调用对象。
- 返回直接结果 (return_direct):如果设置为True,则代理将直接返回工具的结果,而不是将其作为思考过程的一部分。
名称、描述和 JSON 架构可用于提示 LLM,以便它知道如何指定要执行的操作,然后要调用的函数等同于执行该操作。
工具的输入越简单,LLM 就越容易使用它。
02 LangChain中的默认Tools
LangChain内置了很多的预定义工具,我们可以格式化打印看下有多少:
class BaseTool
class Tool
class StructuredTool
class WikipediaQueryRun
class AINBaseTool
class AINAppOps
class AINOwnerOps
class AINRuleOps
class AINTransfer
class AINValueOps
class AIPluginTool
class ArxivQueryRun
class AzureAiServicesDocumentIntelligenceTool
class AzureAiServicesImageAnalysisTool
class AzureAiServicesSpeechToTextTool
class AzureAiServicesTextAnalyticsForHealthTool
class AzureAiServicesTextToSpeechTool
class AzureCogsFormRecognizerTool
class AzureCogsImageAnalysisTool
class AzureCogsSpeech2TextTool
class AzureCogsText2SpeechTool
class AzureCogsTextAnalyticsHealthTool
class BaseGraphQLTool
class RequestsGetTool
class RequestsPostTool
class RequestsPatchTool
class RequestsPutTool
class RequestsDeleteTool
class QuerySQLDataBaseTool
class InfoSQLDatabaseTool
class ListSQLDatabaseTool
class QuerySQLCheckerTool
class QuerySparkSQLTool
class InfoSparkSQLTool
class ListSparkSQLTool
class QueryCheckerTool
class BingSearchRun
class BingSearchResults
class BraveSearch
class BaseBrowserTool
class ClickTool
class CurrentWebPageTool
class ExtractHyperlinksTool
class ExtractTextTool
class GetElementsTool
class NavigateTool
class NavigateBackTool
class CogniswitchKnowledgeRequest
class CogniswitchKnowledgeStatus
class CogniswitchKnowledgeSourceFile
class CogniswitchKnowledgeSourceURL
class ConneryAction
class CopyFileTool
class DeleteFileTool
class FileSearchTool
class ListDirectoryTool
class MoveFileTool
class ReadFileTool
class WriteFileTool
class DataheraldTextToSQL
class DuckDuckGoSearchRun
class DuckDuckGoSearchResults
class E2BDataAnalysisTool
class EdenaiTool
class EdenAiSpeechToTextTool
class EdenAiTextToSpeechTool
class EdenAiExplicitImageTool
class EdenAiObjectDetectionTool
class EdenAiParsingIDTool
class EdenAiParsingInvoiceTool
class EdenAiTextModerationTool
class ElevenLabsText2SpeechTool
class GmailBaseTool
class GmailCreateDraft
class GmailGetMessage
class GmailGetThread
class GmailSearch
class GmailSendMessage
class GoogleCloudTextToSpeechTool
class GooglePlacesTool
class GoogleSearchRun
class GoogleSearchResults
class GoogleSerperRun
class GoogleSerperResults
class HumanInputRun
class IFTTTWebhook
class QueryPowerBITool
class InfoPowerBITool
class ListPowerBITool
class JiraAction
class JsonListKeysTool
class JsonGetValueTool
class MerriamWebsterQueryRun
class MetaphorSearchResults
class MojeekSearch
class NasaAction
class O365BaseTool
class O365CreateDraftMessage
class O365SearchEvents
class O365SearchEmails
class O365SendEvent
class O365SendMessage
class OpenWeatherMapQueryRun
class PolygonAggregates
class PolygonFinancials
class PolygonLastQuote
class PolygonTickerNews
class PubmedQueryRun
class RedditSearchRun
class SceneXplainTool
class SearchAPIRun
class SearchAPIResults
class SearxSearchRun
class SearxSearchResults
class ShellTool
class SlackBaseTool
class SlackGetChannel
class SlackGetMessage
class SlackScheduleMessage
class SlackSendMessage
class SleepTool
class StackExchangeTool
class SteamWebAPIQueryRun
class SteamshipImageGenerationTool
class VectorStoreQATool
class VectorStoreQAWithSourcesTool
class WolframAlphaQueryRun
class YahooFinanceNewsTool
class YouSearchTool
class YouTubeSearchTool
class ZapierNLARunAction
class ZapierNLAListActions
class PythonREPLTool
class PythonAstREPLTool
class InvalidTool
class ExceptionTool
class DataForSeoAPISearchRun
class DataForSeoAPISearchResults
class GoldenQueryRun
class GoogleFinanceQueryRun
class GoogleJobsQueryRun
class GoogleLensQueryRun
class GoogleScholarQueryRun
class GoogleTrendsQueryRun
class Memorize
我们可以挑几个简单看下:
- WikipediaQueryRun:用于向维基百科API发送查询并获取数据
- RequestsGetTool:使用HTTP GET方法从指定的URL获取数据。
- RequestsPostTool:使用HTTP POST方法向服务器发送数据。
- QuerySQLDataBaseTool:对数据库执行SQL查询并返回结果。
- ShellTool:执行shell命令。
- PythonREPLTool:执行Python命令
下面以WikipediaQueryRun为例子,简单解释说明下使用和原理。
基本使用如下:
from langchain_community.tools import WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper
api_wrapper = WikipediaAPIWrapper(top_k_results=1, doc_content_chars_max=100)
tool = WikipediaQueryRun(api_wrapper=api_wrapper)
tool.name
"""
wikipedia
"""
tool.description
"""
A wrapper around Wikipedia. Useful for when you need to answer general questions about people, places, companies, facts, historical events, or other subjects. Input should be a search query.
"""
tool.args
"""
{'query': {'title': 'Query', 'type': 'string'}}
"""
tool.return_direct
"""
False
"""
tool.run({"query": "langchain"})
"""
Page: LangChain\nSummary: LangChain is a framework designed to simplify the creation of applications
"""
在上面代码中,我们通过打印相关参数可以看到这个Tool的基本信息。最后通过tool.run方法执行此工具,搜索"langchain"得到了最终输出。
WikipediaAPIWrapper源码分析如下:
class WikipediaAPIWrapper(BaseModel):
"""
wiki百科工具的具体调用逻辑,包括
- 定义一些参数
- 具体执行逻辑
- 加载搜索结果为Document
- ...
"""
# 具体的调用客户端,通过pip install wikipedia后能拿到
wiki_client: Any
# 搜索结果的数量
top_k_results: int = 3
# 搜索结果的语言
lang: str = "en"
# 用于配置元数据信息
load_all_available_meta: bool = False
# 单个Document的内容长度
doc_content_chars_max: int = 4000
@root_validator()
def validate_environment(cls, values: Dict) -> Dict:
"""
环境验证,也就是有没有安装wikipedia三方库
不安装没法做请求
"""
try:
import wikipedia
wikipedia.set_lang(values["lang"])
values["wiki_client"] = wikipedia
except ImportError:
raise ImportError(
"Could not import wikipedia python package. "
"Please install it with `pip install wikipedia`."
)
return values
def run(self, query: str) -> str:
"""
具体的执行逻辑,本质还是做网络请求拿结果
"""
page_titles = self.wiki_client.search(
query[:WIKIPEDIA_MAX_QUERY_LENGTH], results=self.top_k_results
)
summaries = []
for page_title in page_titles[: self.top_k_results]:
if wiki_page := self._fetch_page(page_title):
if summary := self._formatted_page_summary(page_title, wiki_page):
summaries.append(summary)
if not summaries:
return "No good Wikipedia Search Result was found"
return "\n\n".join(summaries)[: self.doc_content_chars_max]
@staticmethod
def _formatted_page_summary(page_title: str, wiki_page: Any) -> Optional[str]:
"""
对接过进行封装展示(相当于格式化)
"""
return f"Page: {page_title}\nSummary: {wiki_page.summary}"
def _page_to_document(self, page_title: str, wiki_page: Any) -> Document:
"""
搜索结果转Document,方便后续LLM使用
"""
main_meta = {
"title": page_title,
"summary": wiki_page.summary,
"source": wiki_page.url,
}
add_meta = (
{
"categories": wiki_page.categories,
"page_url": wiki_page.url,
"image_urls": wiki_page.images,
"related_titles": wiki_page.links,
"parent_id": wiki_page.parent_id,
"references": wiki_page.references,
"revision_id": wiki_page.revision_id,
"sections": wiki_page.sections,
}
if self.load_all_available_meta
else {}
)
doc = Document(
page_content=wiki_page.content[: self.doc_content_chars_max],
metadata={
**main_meta,
**add_meta,
},
)
return doc
def _fetch_page(self, page: str) -> Optional[str]:
"""
这里还是具体的调用逻辑
"""
try:
return self.wiki_client.page(title=page, auto_suggest=False)
except (
self.wiki_client.exceptions.PageError,
self.wiki_client.exceptions.DisambiguationError,
):
return None
def load(self, query: str) -> List[Document]:
"""
从输入直接到Document集合,内部还是先获取结果,然后再封装
"""
return list(self.lazy_load(query))
def lazy_load(self, query: str) -> Iterator[Document]:
"""
从输入直接到Document集合,内部还是先获取结果,然后再封装
load(self, query: str) 本质还是调用这个方法
"""
page_titles = self.wiki_client.search(
query[:WIKIPEDIA_MAX_QUERY_LENGTH], results=self.top_k_results
)
for page_title in page_titles[: self.top_k_results]:
if wiki_page := self._fetch_page(page_title):
if doc := self._page_to_document(page_title, wiki_page):
yield doc
WikipediaQueryRun源码如下,本质还是对WikipediaAPIWrapper的调用:
class WikipediaQueryRun(BaseTool):
"""Tool that searches the Wikipedia API."""
name: str = "wikipedia"
description: str = (
"A wrapper around Wikipedia. "
"Useful for when you need to answer general questions about "
"people, places, companies, facts, historical events, or other subjects. "
"Input should be a search query."
)
api_wrapper: WikipediaAPIWrapper
def _run(
self,
query: str,
run_manager: Optional[CallbackManagerForToolRun] = None,
) -> str:
"""Use the Wikipedia tool."""
return self.api_wrapper.run(query)
源码分析到这,后续我们如果想自定义Tool,基本步骤也就出来了。怎么说呢,不难bro~
03 自定义Tool
有时候我们想“骚一下”,或者说LangChain内部预定义的Tools已经不能满足我们的使用需求了,这个时候自定义Tool的需求就来了。
一般情况下,自定义Tool需要定义以下几个组件:
- name (str) 是必需的,并且在提供给代理的一组工具中必须是唯一的*
- description (str) 是可选的,但建议使用,因为代理使用它来确定工具的使用情况*
- args_schema (Pydantic BaseModel) 是可选的,但推荐使用,可用于提供更多信息(例如,少量示例)或验证预期参数。*
@tool decorator
@tool 装饰器是定义自定义工具的最简单方法。默认情况下,装饰器使用函数名称作为工具名称,但可以通过传递字符串作为第一个参数来覆盖此名称。此外,装饰器将使用函数的文档字符串作为工具的描述 - 因此必须提供文档字符串。
基本使用如下:
@tool
def search(query: str) -> str:
"""Look up things online."""
return "LangChain"
print(search.name)
"""
search
"""
print(search.description)
"""
search(query: str) -> str - Look up things online.
"""
print(search.args)
"""
{'query': {'title': 'Query', 'type': 'string'}}
"""
# =================================================================
@tool
def multiply(a: int, b: int) -> int:
"""Multiply two numbers."""
return a * b
print(multiply.name)
"""
multiply
"""
print(multiply.description)
"""
multiply(a: int, b: int) -> int - Multiply two numbers.
"""
print(multiply.args)
"""
{'a': {'title': 'A', 'type': 'integer'}, 'b': {'title': 'B', 'type': 'integer'}}
"""
还可以通过将工具名称和 JSON 参数传递到工具装饰器中来自定义它们。
# 注意这里的命名空间,必须是langchain.pydantic_v1
from langchain.pydantic_v1 import BaseModel, Field
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)
"""
search-tool
"""
print(search.description)
"""
search-tool(query: str) -> str - Look up things online.
"""
print(search.args)
"""
{'query': {'title': 'Query', 'description': 'should be a search query', 'type': 'string'}}
"""
print(search.return_direct)
"""
True
"""
Subclass BaseTool
还可以通过对 BaseTool 类进行子类化来显式定义自定义工具,这种方式更灵活但是更复杂。
我们改造先上面的两个自定义Tool
from typing import Optional, Type
from langchain.pydantic_v1 import BaseModel, Field
from langchain.callbacks.manager import (
AsyncCallbackManagerForToolRun,
CallbackManagerForToolRun,
)
class SearchInput(BaseModel):
query: str = Field(description="should be a search query")
class CalculatorInput(BaseModel):
a: int = Field(description="first number")
b: int = Field(description="second number")
class CustomSearchTool(BaseTool):
name = "custom_search"
description = "useful for when you need to answer questions about current events"
args_schema: Type[BaseModel] = SearchInput
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")
class CustomCalculatorTool(BaseTool):
name = "Calculator"
description = "useful for when you need to answer questions about math"
args_schema: Type[BaseModel] = CalculatorInput
return_direct: bool = True
def _run(
self, a: int, b: int, run_manager: Optional[CallbackManagerForToolRun] = None
) -> int:
"""Use the tool."""
return a * b
async def _arun(
self,
a: int,
b: int,
run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
) -> str:
"""Use the tool asynchronously."""
raise NotImplementedError("Calculator does not support async")
打印参数,看下输出
search = CustomSearchTool()
print(search.name)
"""
custom_search
"""
print(search.description)
"""
useful for when you need to answer questions about current events
"""
print(search.args)
"""
{'query': {'title': 'Query', 'description': 'should be a search query', 'type': 'string'}}
"""
multiply = CustomCalculatorTool()
print(multiply.name)
"""
Calculator
"""
print(multiply.description)
"""
useful for when you need to answer questions about math
"""
print(multiply.args)
"""
{'a': {'title': 'A', 'description': 'first number', 'type': 'integer'}, 'b': {'title': 'B', 'description': 'second number', 'type': 'integer'}}
"""
print(multiply.return_direct)
"""
True
"""
StructuredTool dataclass
还可以使用 StructuredTool 数据类。这种方法是前两种方法的混合。它比从 BaseTool 类继承更方便,但提供了比仅使用装饰器更多的功能。
示例代码如下:
from langchain.tools import BaseTool, StructuredTool, tool
def search_function(query: str):
return "LangChain"
search = StructuredTool.from_function(
func=search_function,
name="Search",
description="useful for when you need to answer questions about current events",
)
print(search.name)
"""
Search
"""
print(search.description)
"""
Search(query: str) - useful for when you need to answer questions about current events
"""
print(search.args)
"""
{'query': {'title': 'Query', 'type': 'string'}}
"""
# ===============================================================
class CalculatorInput(BaseModel):
a: int = Field(description="first number")
b: int = Field(description="second number")
def multiply(a: int, b: int) -> int:
"""Multiply two numbers."""
return a * b
calculator = StructuredTool.from_function(
func=multiply,
name="Calculator",
description="multiply numbers",
args_schema=CalculatorInput,
return_direct=True,
)
print(calculator.name)
"""
Calculator
"""
print(calculator.description)
"""
Calculator(a: int, b: int) -> int - multiply numbers
"""
print(calculator.args)
"""
{'a': {'title': 'A', 'description': 'first number', 'type': 'integer'}, 'b': {'title': 'B', 'description': 'second number', 'type': 'integer'}}
"""
对于以上三种自定义Tool的方式,从打印结果来看基本一致,具体选择哪种方式还得看实际需求。这里我个人建议使用第一种装饰器的方式~
Handling Tool Errors
当工具遇到错误且未捕获异常时,代理将停止执行。如果希望代理继续执行,可以引发 ToolException 并相应地设置 handle_tool_error。
当抛出 ToolException 时,智能体不会停止工作,而是会根据工具的 handle_tool_error 变量处理异常,处理结果将作为观察结果返回给智能体,并以红色打印。
有点懵?看看代码理解一下~
from langchain_core.tools import ToolException
from langchain.tools import BaseTool, StructuredTool, tool
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",
)
search.run("test")
上面代码会直接抛异常报错,整个程序会停止工作。
我们将 handle_tool_error 设置成True,此时程序正常执行并输出错误信息。
search = StructuredTool.from_function(
func=search_tool1,
name="Search_tool1",
description="A bad tool",
handle_tool_error=True,
)
search.run("test") # The search tool1 is not available.
"""
[tool/start] [tool:Search_tool1] Entering Tool run with input:
"test"
[tool/end] [tool:Search_tool1] [1ms] Exiting Tool run with output:
"The search tool1 is not available."
"""
我们还可以定义一种自定义方法来处理工具错误,如下:
def _handle_error(error: ToolException) -> str:
return (
"The following errors occurred during tool execution:"
+ error.args[0]
+ "Please try another tool."
)
search = StructuredTool.from_function(
func=search_tool1,
name="Search_tool1",
description="A bad tool",
handle_tool_error=_handle_error,
)
search.run("test") # The following errors occurred during tool execution:The search tool1 is not available.Please try another tool.
"""
[tool/start] [tool:Search_tool1] Entering Tool run with input:
"test"
[tool/end] [tool:Search_tool1] [1ms] Exiting Tool run with output:
"The following errors occurred during tool execution:The search tool1 is not available.Please try another tool."
"""
实际开发中,建议在自定义Tool的时候加上错误处理。
04 Toolkits
顾名思义,这叫“工具包”。
工具包是旨在一起用于特定任务的工具集合。他们有方便的装载方法。所有工具包都公开一个 get_tools 方法,该方法返回工具列表。因此,您可以执行以下操作:
# Initialize a toolkit
toolkit = ExampleTookit(...)
# Get list of tools
tools = toolkit.get_tools()
# Create agent
agent = create_agent_method(llm, tools, prompt)
LangChain内置了很多常用的工具包,如下:
_module_lookup = {
"AINetworkToolkit": "langchain_community.agent_toolkits.ainetwork.toolkit",
"AmadeusToolkit": "langchain_community.agent_toolkits.amadeus.toolkit",
"AzureAiServicesToolkit": "langchain_community.agent_toolkits.azure_ai_services",
"AzureCognitiveServicesToolkit": "langchain_community.agent_toolkits.azure_cognitive_services", # noqa: E501
"CogniswitchToolkit": "langchain_community.agent_toolkits.cogniswitch.toolkit",
"ConneryToolkit": "langchain_community.agent_toolkits.connery",
"FileManagementToolkit": "langchain_community.agent_toolkits.file_management.toolkit", # noqa: E501
"GmailToolkit": "langchain_community.agent_toolkits.gmail.toolkit",
"JiraToolkit": "langchain_community.agent_toolkits.jira.toolkit",
"JsonToolkit": "langchain_community.agent_toolkits.json.toolkit",
"MultionToolkit": "langchain_community.agent_toolkits.multion.toolkit",
"NLAToolkit": "langchain_community.agent_toolkits.nla.toolkit",
"NasaToolkit": "langchain_community.agent_toolkits.nasa.toolkit",
"O365Toolkit": "langchain_community.agent_toolkits.office365.toolkit",
"OpenAPIToolkit": "langchain_community.agent_toolkits.openapi.toolkit",
"PlayWrightBrowserToolkit": "langchain_community.agent_toolkits.playwright.toolkit",
"PolygonToolkit": "langchain_community.agent_toolkits.polygon.toolkit",
"PowerBIToolkit": "langchain_community.agent_toolkits.powerbi.toolkit",
"SQLDatabaseToolkit": "langchain_community.agent_toolkits.sql.toolkit",
"SlackToolkit": "langchain_community.agent_toolkits.slack.toolkit",
"SparkSQLToolkit": "langchain_community.agent_toolkits.spark_sql.toolkit",
"SteamToolkit": "langchain_community.agent_toolkits.steam.toolkit",
"ZapierToolkit": "langchain_community.agent_toolkits.zapier.toolkit",
"create_json_agent": "langchain_community.agent_toolkits.json.base",
"create_openapi_agent": "langchain_community.agent_toolkits.openapi.base",
"create_pbi_agent": "langchain_community.agent_toolkits.powerbi.base",
"create_pbi_chat_agent": "langchain_community.agent_toolkits.powerbi.chat_base",
"create_spark_sql_agent": "langchain_community.agent_toolkits.spark_sql.base",
"create_sql_agent": "langchain_community.agent_toolkits.sql.base",
}
__all__ = [
"create_xorbits_agent",
"create_pandas_dataframe_agent",
"create_spark_dataframe_agent",
"create_python_agent",
"create_csv_agent",
]
这些工具包帮助我们快速方便的处理Json、CSV、Github、SQL、python等任务。
04 Tool as OpenAI Functions
专门适配OpenAI FunctionCall功能,只对gpt相关模型有效,目的是为了将我们定义的各种Tool转换成OpenAI Function。基本使用如下:
from langchain_community.tools import MoveFileTool
from langchain_core.messages import HumanMessage
from langchain_core.utils.function_calling import convert_to_openai_function
from langchain_openai import ChatOpenAI
model = ChatOpenAI(model="gpt-3.5-turbo")
# 创建tool集合
tools = [MoveFileTool()]
# 将tool转换成openai支持的function格式
functions = [convert_to_openai_function(t) for t in tools]
functions[0]
"""
{'name': 'move_file',
'description': 'Move or rename a file from one location to another',
'parameters': {'type': 'object',
'properties': {'source_path': {'description': 'Path of the file to move',
'type': 'string'},
'destination_path': {'description': 'New path for the moved file',
'type': 'string'}},
'required': ['source_path', 'destination_path']}}
"""
# 将消息和function传给模型执行,这里模型会自动调用tool
message = model.invoke(
[HumanMessage(content="move file foo to bar")], functions=functions
)
"""
AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\n "source_path": "foo",\n "destination_path": "bar"\n}', 'name': 'move_file'}})
"""
# 获取function_call,这里的内容都是MoveFileTool里面定义好的
message.additional_kwargs["function_call"]
"""
{'name': 'move_file',
'arguments': '{\n "source_path": "foo",\n "destination_path": "bar"\n}'}
"""
借助 OpenAI 聊天模型,我们还可以使用 bind_functions 自动绑定和转换类似函数的对象。
model_with_functions = model.bind_functions(tools)
model_with_functions.invoke([HumanMessage(content="move file foo to bar")])
"""
AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\n "source_path": "foo",\n "destination_path": "bar"\n}', 'name': 'move_file'}})
"""
或者,我们可以使用更新的 OpenAI API,它使用 tools 和 tool_choice 而不是 functions 和 function_call 通过使用 ChatOpenAI.bind_tools:
model_with_tools = model.bind_tools(tools)
model_with_tools.invoke([HumanMessage(content="move file foo to bar")])
"""
AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_btkY3xV71cEVAOHnNa5qwo44', 'function': {'arguments': '{\n "source_path": "foo",\n "destination_path": "bar"\n}', 'name': 'move_file'}, 'type': 'function'}]})
"""
05 总结
本篇文章主要是介绍Tool的基本配置,以及如何自定义Tool,并没有介绍如何使用Tool。
实际上,Tool一般会与Agent,也就是所谓的代理(也可以叫智能体)一起使用。这块内容下篇文章会介绍,感谢阅读。
以上就是本次 Tools 的全部内容,希望能给到你们一些小小的帮助。
如果能帮我点个免费的关注,那就是对我个人的最大的肯定。如果觉得写的还行,分享一下也是我生活的小确幸~
以上内容依据官方文档编写,官方地址:https://python.langchain.com/docs/modules/tools
Peace Guys~
- 【LangChain进阶教程】十、LangChain进阶之Retrievers
- 【LangChain进阶教程】九、LangChain进阶之Vector Stores
- 【LangChain进阶教程】八、LangChain进阶之Embedding Models
- 【LangChain进阶教程】七、LangChain进阶之Text Splitters