跳到主要內容
Open In ColabOpen on GitHub

如何從工具返回工件

先決條件

本指南假設您熟悉以下概念

工具是可以被模型調用的實用程式,其輸出旨在回饋給模型。然而,有時工具的執行會產生我們希望下游組件可以存取的工件,但我們不希望將其暴露給模型本身。例如,如果工具返回自訂物件、資料框架或影像,我們可能希望將有關此輸出的一些元資料傳遞給模型,而無需將實際輸出傳遞給模型。同時,我們可能希望能夠在其他地方存取此完整輸出,例如在下游工具中。

Tool 和 ToolMessage 介面使區分工具輸出中哪些部分用於模型(這是 ToolMessage.content)以及哪些部分用於模型外部(ToolMessage.artifact)成為可能。

需要 langchain-core >= 0.2.19

此功能已在 langchain-core == 0.2.19 中新增。請確保您的套件是最新的。

定義工具

如果我們希望我們的工具區分訊息內容和其他工件,我們需要在定義工具時指定 response_format="content_and_artifact",並確保我們返回 (content, artifact) 的元組

%pip install -qU "langchain-core>=0.2.19"
import random
from typing import List, Tuple

from langchain_core.tools import tool


@tool(response_format="content_and_artifact")
def generate_random_ints(min: int, max: int, size: int) -> Tuple[str, List[int]]:
"""Generate size random ints in the range [min, max]."""
array = [random.randint(min, max) for _ in range(size)]
content = f"Successfully generated array of {size} random ints in [{min}, {max}]."
return content, array
API 參考:tool

使用 ToolCall 調用工具

如果我們僅使用工具參數直接調用工具,您會注意到我們只會取回 Tool 輸出的內容部分

generate_random_ints.invoke({"min": 0, "max": 9, "size": 10})
'Successfully generated array of 10 random ints in [0, 9].'

為了取回內容和工件,我們需要使用 ToolCall(它只是一個具有 "name"、"args"、"id" 和 "type" 鍵的字典)調用我們的模型,ToolCall 具有生成 ToolMessage 所需的額外資訊,例如工具調用 ID

generate_random_ints.invoke(
{
"name": "generate_random_ints",
"args": {"min": 0, "max": 9, "size": 10},
"id": "123", # required
"type": "tool_call", # required
}
)
ToolMessage(content='Successfully generated array of 10 random ints in [0, 9].', name='generate_random_ints', tool_call_id='123', artifact=[2, 8, 0, 6, 0, 0, 1, 5, 0, 0])

與模型一起使用

使用工具調用模型,我們可以輕鬆地使用模型來調用我們的 Tool 並生成 ToolMessage

pip install -qU "langchain[openai]"
import getpass
import os

if not os.environ.get("OPENAI_API_KEY"):
os.environ["OPENAI_API_KEY"] = getpass.getpass("Enter API key for OpenAI: ")

from langchain.chat_models import init_chat_model

llm = init_chat_model("gpt-4o-mini", model_provider="openai")
llm_with_tools = llm.bind_tools([generate_random_ints])

ai_msg = llm_with_tools.invoke("generate 6 positive ints less than 25")
ai_msg.tool_calls
[{'name': 'generate_random_ints',
'args': {'min': 1, 'max': 24, 'size': 6},
'id': 'toolu_01EtALY3Wz1DVYhv1TLvZGvE',
'type': 'tool_call'}]
generate_random_ints.invoke(ai_msg.tool_calls[0])
ToolMessage(content='Successfully generated array of 6 random ints in [1, 24].', name='generate_random_ints', tool_call_id='toolu_01EtALY3Wz1DVYhv1TLvZGvE', artifact=[2, 20, 23, 8, 1, 15])

如果我們僅傳入工具調用參數,我們只會取回內容

generate_random_ints.invoke(ai_msg.tool_calls[0]["args"])
'Successfully generated array of 6 random ints in [1, 24].'

如果我們想要宣告式地建立鏈,我們可以這樣做

from operator import attrgetter

chain = llm_with_tools | attrgetter("tool_calls") | generate_random_ints.map()

chain.invoke("give me a random number between 1 and 5")
[ToolMessage(content='Successfully generated array of 1 random ints in [1, 5].', name='generate_random_ints', tool_call_id='toolu_01FwYhnkwDPJPbKdGq4ng6uD', artifact=[5])]

從 BaseTool 類別建立

如果您想直接建立 BaseTool 物件,而不是使用 @tool 修飾函數,您可以像這樣做

from langchain_core.tools import BaseTool


class GenerateRandomFloats(BaseTool):
name: str = "generate_random_floats"
description: str = "Generate size random floats in the range [min, max]."
response_format: str = "content_and_artifact"

ndigits: int = 2

def _run(self, min: float, max: float, size: int) -> Tuple[str, List[float]]:
range_ = max - min
array = [
round(min + (range_ * random.random()), ndigits=self.ndigits)
for _ in range(size)
]
content = f"Generated {size} floats in [{min}, {max}], rounded to {self.ndigits} decimals."
return content, array

# Optionally define an equivalent async method

# async def _arun(self, min: float, max: float, size: int) -> Tuple[str, List[float]]:
# ...
API 參考:BaseTool
rand_gen = GenerateRandomFloats(ndigits=4)
rand_gen.invoke({"min": 0.1, "max": 3.3333, "size": 3})
'Generated 3 floats in [0.1, 3.3333], rounded to 4 decimals.'
rand_gen.invoke(
{
"name": "generate_random_floats",
"args": {"min": 0.1, "max": 3.3333, "size": 3},
"id": "123",
"type": "tool_call",
}
)
ToolMessage(content='Generated 3 floats in [0.1, 3.3333], rounded to 4 decimals.', name='generate_random_floats', tool_call_id='123', artifact=[1.5789, 2.464, 2.2719])

此頁面是否對您有幫助?