工具
langchain.tools.tool ¶
tool(
name_or_callable: str | Callable | None = None,
runnable: Runnable | None = None,
*args: Any,
description: str | None = None,
return_direct: bool = False,
args_schema: ArgsSchema | None = None,
infer_schema: bool = True,
response_format: Literal["content", "content_and_artifact"] = "content",
parse_docstring: bool = False,
error_on_invalid_docstring: bool = True,
) -> BaseTool | Callable[[Callable | Runnable], BaseTool]
将 Python 函数和 `Runnable` 转换为 LangChain 工具。
可以作为带参数或不带参数的装饰器使用,从函数创建工具。
函数可以有任何签名——除非禁用,否则工具将自动推断输入模式。
要求
- 函数必须有类型提示,以便正确推断模式
- 当 `infer_schema=False` 时,函数必须是 `(str) -> str` 并且有文档字符串
- 与 `Runnable` 一起使用时,必须提供一个字符串名称
| 参数 | 描述 |
|---|---|
name_or_callable
|
工具的可选名称或要转换为工具的 `Callable`。会覆盖函数的名称。 必须作为位置参数提供。 |
runnable
|
要转换为工具的可选 `Runnable`。 必须作为位置参数提供。
类型: |
描述
|
工具的可选描述。 工具描述值的优先级如下
类型: |
*args
|
额外的 positional 参数。必须为空。
类型: |
return_direct
|
是否直接从工具返回,而不是继续代理循环。
类型: |
参数模式
|
供用户指定的可选参数模式。
类型: |
infer_schema
|
是否从函数的签名推断参数的模式。这也使得生成的工具的 `run()` 函数接受字典输入。
类型: |
response_format
|
工具响应格式。 如果为 `'content'`,则工具的输出被解释为 `ToolMessage` 的内容。 如果为 `'content_and_artifact'`,则输出应为与 `ToolMessage` 的 `(content, artifact)` 对应的二元组。
类型: |
parse_docstring
|
如果 `infer_schema` 和 `parse_docstring` 都为 True,将尝试从 Google 风格的函数文档字符串中解析参数描述。
类型: |
error_on_invalid_docstring
|
如果提供了 `parse_docstring`,配置是否在遇到无效的 Google 风格文档字符串时引发 `ValueError`。
类型: |
| 引发 | 描述 |
|---|---|
ValueError
|
如果提供了过多的 positional 参数(例如,违反 `*args` 约束)。 |
ValueError
|
如果提供了 `Runnable` 但没有提供字符串名称。当将 `tool` 与 `Runnable` 一起使用时,必须提供一个 `str` 名称作为 `name_or_callable`。 |
ValueError
|
如果第一个参数不是字符串或带有 `__name__` 属性的可调用对象。 |
ValueError
|
如果函数没有文档字符串,未提供描述,且 `infer_schema` 为 `False`。 |
ValueError
|
如果 `parse_docstring` 为 `True` 且函数具有无效的 Google 风格文档字符串,并且 `error_on_invalid_docstring` 为 True。 |
ValueError
|
如果提供的 `Runnable` 没有对象模式。 |
| 返回 | 描述 |
|---|---|
BaseTool | Callable[[Callable | Runnable], BaseTool]
|
该工具。 |
示例
@tool
def search_api(query: str) -> str:
# Searches the API for the query.
return
@tool("search", return_direct=True)
def search_api(query: str) -> str:
# Searches the API for the query.
return
@tool(response_format="content_and_artifact")
def search_api(query: str) -> tuple[str, dict]:
return "partial json of results", {"full": "object of results"}
解析 Google 风格的文档字符串
@tool(parse_docstring=True)
def foo(bar: str, baz: int) -> str:
"""The foo.
Args:
bar: The bar.
baz: The baz.
"""
return bar
foo.args_schema.model_json_schema()
{
"title": "foo",
"description": "The foo.",
"type": "object",
"properties": {
"bar": {
"title": "Bar",
"description": "The bar.",
"type": "string",
},
"baz": {
"title": "Baz",
"description": "The baz.",
"type": "integer",
},
},
"required": ["bar", "baz"],
}
请注意,如果文档字符串被视为无效,默认情况下解析将引发 `ValueError`。如果文档字符串包含函数签名中不存在的参数,或者无法解析为摘要和 `"Args:"` 块,则认为该文档字符串无效。示例如下
# No args section
def invalid_docstring_1(bar: str, baz: int) -> str:
"""The foo."""
return bar
# Improper whitespace between summary and args section
def invalid_docstring_2(bar: str, baz: int) -> str:
"""The foo.
Args:
bar: The bar.
baz: The baz.
"""
return bar
# Documented args absent from function signature
def invalid_docstring_3(bar: str, baz: int) -> str:
"""The foo.
Args:
banana: The bar.
monkey: The baz.
"""
return bar
langchain.tools.BaseTool ¶
基类:RunnableSerializable[str | dict | ToolCall, Any]
所有 LangChain 工具的基类。
这个抽象类定义了所有 LangChain 工具必须实现的接口。
工具是代理可以调用以执行特定操作的组件。
| 方法 | 描述 |
|---|---|
invoke |
将单个输入转换为输出。 |
ainvoke |
将单个输入转换为输出。 |
get_input_schema |
工具的输入模式。 |
get_output_schema |
获取可用于验证 |
response_format 类属性 实例属性 ¶
response_format: Literal['content', 'content_and_artifact'] = 'content'
工具响应格式。
如果为 `'content'`,则工具的输出被解释为 `ToolMessage` 的内容。如果为 `'content_and_artifact'`,则输出应为与 `ToolMessage` 的 `(content, artifact)` 对应的二元组。
invoke ¶
将单个输入转换为输出。
| 参数 | 描述 |
|---|---|
输入
|
类型: |
配置
|
调用
类型: |
| 返回 | 描述 |
|---|---|
输出
|
|
ainvoke 异步 ¶
将单个输入转换为输出。
| 参数 | 描述 |
|---|---|
输入
|
类型: |
配置
|
调用
类型: |
| 返回 | 描述 |
|---|---|
输出
|
|
get_input_schema ¶
get_input_schema(config: RunnableConfig | None = None) -> type[BaseModel]
get_output_schema ¶
get_output_schema(config: RunnableConfig | None = None) -> type[BaseModel]
获取可用于验证 Runnable 输出的 Pydantic 模型。
利用 configurable_fields 和 configurable_alternatives 方法的 Runnable 对象将具有一个动态输出模式,该模式取决于调用 Runnable 时使用的配置。
此方法允许获取特定配置的输出模式。
| 参数 | 描述 |
|---|---|
配置
|
生成模式时使用的配置。
类型: |
| 返回 | 描述 |
|---|---|
type[BaseModel]
|
一个可用于验证输出的 Pydantic 模型。 |
langchain.tools.InjectedState ¶
用于将图状态注入到工具参数中的注解。
此注解使工具能够访问图状态,而无需向语言模型暴露状态管理的细节。使用 `InjectedState` 注解的工具在执行期间会自动接收状态数据,同时对模型的工具调用接口保持不可见。
| 参数 | 描述 |
|---|---|
field
|
从状态字典中提取的可选键。如果为 `None`,则注入整个状态。如果指定,则仅注入该字段的值。这允许工具请求特定的状态组件,而不是处理整个状态结构。
类型: |
示例
from typing import List
from typing_extensions import Annotated, TypedDict
from langchain_core.messages import BaseMessage, AIMessage
from langchain.tools import InjectedState, ToolNode, tool
class AgentState(TypedDict):
messages: List[BaseMessage]
foo: str
@tool
def state_tool(x: int, state: Annotated[dict, InjectedState]) -> str:
'''Do something with state.'''
if len(state["messages"]) > 2:
return state["foo"] + str(x)
else:
return "not enough messages"
@tool
def foo_tool(x: int, foo: Annotated[str, InjectedState("foo")]) -> str:
'''Do something else with state.'''
return foo + str(x + 1)
node = ToolNode([state_tool, foo_tool])
tool_call1 = {"name": "state_tool", "args": {"x": 1}, "id": "1", "type": "tool_call"}
tool_call2 = {"name": "foo_tool", "args": {"x": 1}, "id": "2", "type": "tool_call"}
state = {
"messages": [AIMessage("", tool_calls=[tool_call1, tool_call2])],
"foo": "bar",
}
node.invoke(state)
注意
- `InjectedState` 参数会自动从呈现给语言模型的工具模式中排除
- `ToolNode` 在执行期间处理注入过程
- 工具可以混合使用常规参数(由模型控制)和注入参数(由系统控制)
- 状态注入发生在模型生成工具调用之后、工具执行之前
| 方法 | 描述 |
|---|---|
__init__ |
初始化 `InjectedState` 注解。 |
langchain.tools.InjectedStore ¶
用于将持久存储注入到工具参数中的注解。
此注解使工具能够访问 LangGraph 的持久存储系统,而无需向语言模型暴露存储细节。使用 `InjectedStore` 注解的工具在执行期间会自动接收存储实例,同时对模型的工具调用接口保持不可见。
存储提供了持久的、跨会话的数据存储,工具可以使用它来维护上下文、用户偏好或任何其他需要跨单个工作流执行持久化的数据。
警告
`InjectedStore` 注解需要 `langchain-core >= 0.3.8`
示例
from typing_extensions import Annotated
from langgraph.store.memory import InMemoryStore
from langchain.tools import InjectedStore, ToolNode, tool
@tool
def save_preference(
key: str,
value: str,
store: Annotated[Any, InjectedStore()]
) -> str:
"""Save user preference to persistent storage."""
store.put(("preferences",), key, value)
return f"Saved {key} = {value}"
@tool
def get_preference(
key: str,
store: Annotated[Any, InjectedStore()]
) -> str:
"""Retrieve user preference from persistent storage."""
result = store.get(("preferences",), key)
return result.value if result else "Not found"
与 `ToolNode` 和图编译一起使用
from langgraph.graph import StateGraph
from langgraph.store.memory import InMemoryStore
store = InMemoryStore()
tool_node = ToolNode([save_preference, get_preference])
graph = StateGraph(State)
graph.add_node("tools", tool_node)
compiled_graph = graph.compile(store=store) # Store is injected automatically
跨会话持久性
注意
- `InjectedStore` 参数会自动从呈现给语言模型的工具模式中排除
- 存储实例由 `ToolNode` 在执行期间自动注入
- 工具可以使用存储的 get/put 方法访问命名空间存储
- 存储注入要求图在编译时带有一个存储实例
- 多个工具可以共享同一个存储实例以实现数据一致性
langchain.tools.InjectedToolArg ¶
用于在运行时注入的工具参数的注解。
使用此类注解的工具参数不包含在发送给语言模型的工具模式中,而是在执行期间注入。
langchain.tools.InjectedToolCallId ¶
用于注入工具调用 ID 的注解。
此注解用于标记一个工具参数,该参数应在运行时接收工具调用 ID。
from typing import Annotated
from langchain_core.messages import ToolMessage
from langchain_core.tools import tool, InjectedToolCallId
@tool
def foo(
x: int, tool_call_id: Annotated[str, InjectedToolCallId]
) -> ToolMessage:
"""Return x."""
return ToolMessage(
str(x),
artifact=x,
name="foo",
tool_call_id=tool_call_id
)