工具
概觀
LangChain 中的工具抽象概念將 Python 函數與綱要關聯,該綱要定義函數的名稱、描述和預期引數。
工具可以傳遞給支援工具呼叫的聊天模型,允許模型請求執行具有特定輸入的特定函數。
主要概念
- 工具是一種封裝函數及其綱要的方式,可以傳遞給聊天模型。
- 使用@tool裝飾器建立工具,這簡化了工具建立的過程,支援以下功能
- 自動推斷工具的名稱、描述和預期引數,同時也支援自訂。
- 定義返回工件(例如圖像、資料框架等)的工具
- 使用注入工具引數從綱要(以及從模型)中隱藏輸入引數。
工具介面
工具介面在BaseTool類別中定義,該類別是可執行介面的子類別。
對應於工具綱要的關鍵屬性
- name:工具的名稱。
- description:工具功能的描述。
- args:屬性,返回工具引數的 JSON 綱要。
執行與工具關聯的函數的關鍵方法
- invoke:使用給定的引數調用工具。
- ainvoke:使用給定的引數非同步調用工具。用於使用 Langchain 進行非同步程式設計。
使用 @tool
裝飾器建立工具
建議的工具建立方式是使用@tool裝飾器。此裝飾器旨在簡化工具建立過程,應在大多數情況下使用。定義函數後,您可以使用@tool裝飾它,以建立實作工具介面的工具。
from langchain_core.tools import tool
@tool
def multiply(a: int, b: int) -> int:
"""Multiply two numbers."""
return a * b
有關如何建立工具的更多詳細資訊,請參閱如何建立自訂工具指南。
LangChain 還有其他幾種建立工具的方法;例如,通過子類化BaseTool類別或使用 StructuredTool
。這些方法在如何建立自訂工具指南中顯示,但我們通常建議在大多數情況下使用 @tool
裝飾器。
直接使用工具
定義工具後,您可以通過調用函數直接使用它。例如,要使用上面定義的 multiply
工具
multiply.invoke({"a": 2, "b": 3})
檢查
您還可以檢查工具的綱要和其他屬性
print(multiply.name) # multiply
print(multiply.description) # Multiply two numbers.
print(multiply.args)
# {
# 'type': 'object',
# 'properties': {'a': {'type': 'integer'}, 'b': {'type': 'integer'}},
# 'required': ['a', 'b']
# }
如果您正在使用預先建置的 LangChain 或 LangGraph 組件,例如create_react_agent,您可能不需要直接與工具互動。但是,了解如何使用它們對於偵錯和測試可能很有價值。此外,在建置自訂 LangGraph 工作流程時,您可能會發現有必要直接使用工具。
配置綱要
@tool
裝飾器提供了其他選項來配置工具的綱要(例如,修改名稱、描述或解析函數的文檔字串以推斷綱要)。
請參閱@tool 的 API 參考以獲取更多詳細資訊,並查看如何建立自訂工具指南以獲取範例。
工具工件
工具是可以由模型調用的實用程式,其輸出旨在回饋給模型。但是,有時,我們希望使工具執行的工件可供鏈或代理中的下游組件訪問,但我們不想將其暴露給模型本身。例如,如果工具返回自訂物件、資料框架或圖像,我們可能希望將有關此輸出的一些中繼資料傳遞給模型,而無需將實際輸出傳遞給模型。同時,我們可能希望能夠在其他地方訪問此完整輸出,例如在下游工具中。
@tool(response_format="content_and_artifact")
def some_tool(...) -> Tuple[str, Any]:
"""Tool that does something."""
...
return 'Message for chat model', some_artifact
有關更多詳細資訊,請參閱如何從工具返回工件。
特殊類型註釋
在工具的函數簽章中可以使用許多特殊類型註釋來配置工具的執行階段行為。
以下類型註釋將移除工具綱要中的引數。這對於不應暴露給模型且模型不應能夠控制的引數非常有用。
- InjectedToolArg:值應在執行階段使用
.invoke
或.ainvoke
手動注入。 - RunnableConfig:將 RunnableConfig 物件傳遞給工具。
- InjectedState:將 LangGraph 圖的整體狀態傳遞給工具。
- InjectedStore:將 LangGraph 儲存物件傳遞給工具。
您也可以將 Annotated
類型與字串文字一起使用,以為相應的引數提供描述,該引數將會在工具的綱要中暴露。
- Annotated[..., "字串文字"] -- 將描述新增到將在工具綱要中暴露的引數。
InjectedToolArg
在某些情況下,需要在執行階段將某些引數傳遞給工具,但不應由模型本身產生。為此,我們使用 InjectedToolArg
註釋,它允許從工具的綱要中隱藏某些參數。
例如,如果工具需要 user_id
在執行階段動態注入,則可以按以下方式結構化
from langchain_core.tools import tool, InjectedToolArg
@tool
def user_specific_tool(input_data: str, user_id: InjectedToolArg) -> str:
"""Tool that processes input data."""
return f"User {user_id} processed {input_data}"
使用 InjectedToolArg
註釋 user_id
引數會告訴 LangChain,此引數不應作為工具綱要的一部分暴露。
有關如何使用 InjectedToolArg
的更多詳細資訊,請參閱如何在執行階段將值傳遞給工具。
RunnableConfig
您可以使用 RunnableConfig
物件將自訂執行階段值傳遞給工具。
如果您需要從工具內部存取 RunnableConfig 物件。這可以通過在工具的函數簽章中使用 RunnableConfig
註釋來完成。
from langchain_core.runnables import RunnableConfig
@tool
async def some_func(..., config: RunnableConfig) -> ...:
"""Tool that does something."""
# do something with config
...
await some_func.ainvoke(..., config={"configurable": {"value": "some_value"}})
config
不會成為工具綱要的一部分,並且會在執行階段注入適當的值。
您可能需要存取 config
物件以手動將其傳播到子類別。如果您在 非同步環境中使用 python 3.9 / 3.10,並且需要手動將 config
物件傳播到子呼叫,則會發生這種情況。
請閱讀傳播 RunnableConfig 以獲取更多詳細資訊,以了解如何手動將 RunnableConfig
向下傳播到呼叫鏈(或升級到 Python 3.11,這不再是一個問題)。
InjectedState
有關更多詳細資訊,請參閱 InjectedState 文件。
InjectedStore
有關更多詳細資訊,請參閱 InjectedStore 文件。
最佳實務
在設計要由模型使用的工具時,請記住以下幾點
- 命名良好、文檔正確且類型提示正確的工具更易於模型使用。
- 設計簡單且範圍狹窄的工具,因為它們更易於模型正確使用。
- 使用支援工具呼叫 API 的聊天模型來利用工具。
工具組
LangChain 具有工具組的概念。這是一個非常薄的抽象概念,它將設計為一起用於特定任務的工具分組在一起。
介面
所有工具組都公開了一個 get_tools
方法,該方法返回工具列表。因此您可以執行
# Initialize a toolkit
toolkit = ExampleTookit(...)
# Get list of tools
tools = toolkit.get_tools()
相關資源
有關更多資訊,請參閱以下資源