`on_tool_error` 不接收来自调用者的 `**kwargs`,而 `on_tool_start` 和 `on_tool_end` 则接收。
作者: Iris070308创建于 2026年9月28日更新于 2026年9月28日
标签bugcoreexternal
Repro: on_tool_error does not get the **kwargs that on_tool_start and on_tool_end do. BaseTool.run's docstring says the keyword arguments go to the tool callbacks. Exit code 1 means one of the callback events lost them.
Reproduction Steps / Example Code (Python)
import asyncio
from typing import Any
from langchain_core.callbacks import BaseCallbackHandler
from langchain_core.tools import StructuredTool, ToolException
class Capture(BaseCallbackHandler):
def __init__(self):
self.events = {}
def on_tool_start(self, serialized, input_str, **kwargs: Any):
self.events["start"] = kwargs
def on_tool_end(self, output, **kwargs: Any):
self.events["end"] = kwargs
def on_tool_error(self, error, **kwargs: Any):
self.events["error"] = kwargs
def boom(x: int) -> str:
"""Fail on purpose."""
raise ToolException("boom")
def fine(x: int) -> str:
"""Succeed."""
return "ok"
fail_tool = StructuredTool.from_function(boom)
ok_tool = StructuredTool.from_function(fine)
def probe(fail):
handler = Capture()
tool = fail_tool if fail else ok_tool
try:
tool.invoke({"x": 1}, {"callbacks": [handler]}, tenant="acme")
except Exception:
pass
return handler.events
async def aprobe(fail):
handler = Capture()
tool = fail_tool if fail else ok_tool
try:
await tool.ainvoke({"x": 1}, {"callbacks": [handler]}, tenant="acme")
except Exception:
pass
return handler.events
def report(label, failing, succeeding):
got = {
"on_tool_start": "tenant" in failing.get("start", {}),
"on_tool_end": "tenant" in succeeding.get("end", {}),
"on_tool_error": "tenant" in failing.get("error", {}),
}
missing = {
"on_tool_start": "tenant" not in failing.get("start", {}),
"on_tool_end": "tenant" not in succeeding.get("end", {}),
"on_tool_error": "tenant" not in failing.get("error", {}),
}
内容来源: langchain-ai/langchain