工具
概觀
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[..., "string literal"] -- 為參數新增描述,該描述將在工具綱要中暴露。
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()
相關資源
有關更多資訊,請參閱以下資源: