From 970d3cd4ac03d6fd7ea7281437147cc3c8a51410 Mon Sep 17 00:00:00 2001 From: gaoxiaolei-s59 <2995484417@qq.com> Date: Mon, 10 Aug 2026 18:12:05 +0800 Subject: [PATCH] docs: document tool error handling --- .../tutorial/agents.ipynb | 42 +++++++++++++++++++ .../core-user-guide/components/tools.ipynb | 41 ++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/python/docs/src/user-guide/agentchat-user-guide/tutorial/agents.ipynb b/python/docs/src/user-guide/agentchat-user-guide/tutorial/agents.ipynb index efd530e1b80a..9cc59b9948d1 100644 --- a/python/docs/src/user-guide/agentchat-user-guide/tutorial/agents.ipynb +++ b/python/docs/src/user-guide/agentchat-user-guide/tutorial/agents.ipynb @@ -419,6 +419,48 @@ "the agent can call other agents as tools to solve tasks." ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Tool Errors\n", + "\n", + "When an {py:class}`~autogen_agentchat.agents.AssistantAgent` calls tools\n", + "through its workbench, tool execution errors are returned as tool results\n", + "instead of being raised from {py:meth}`~autogen_agentchat.agents.BaseChatAgent.run`.\n", + "The corresponding {py:class}`~autogen_core.models.FunctionExecutionResult` has\n", + "`is_error=True` and the error text in `content`. This lets the agent reflect on\n", + "the failed tool call when `reflect_on_tool_use=True`, or return the error in a\n", + "{py:class}`~autogen_agentchat.messages.ToolCallSummaryMessage` when\n", + "`reflect_on_tool_use=False`.\n", + "\n", + "Use `tool_call_summary_format` when a static template is enough. The template\n", + "can include `{tool_name}`, `{arguments}`, `{result}`, and `{is_error}`. Use\n", + "`tool_call_summary_formatter` when you want code to branch on\n", + "`result.is_error`, for example to show full details for failures and a shorter\n", + "message for successful tool calls.\n", + "\n", + "```python\n", + "from autogen_core import FunctionCall\n", + "from autogen_core.models import FunctionExecutionResult\n", + "\n", + "\n", + "def format_tool_result(call: FunctionCall, result: FunctionExecutionResult) -> str:\n", + " if result.is_error:\n", + " return f\"Tool {call.name} failed: {result.content}\"\n", + " return f\"Tool {call.name} returned: {result.content}\"\n", + "\n", + "\n", + "agent = AssistantAgent(\n", + " name=\"assistant\",\n", + " model_client=model_client,\n", + " tools=[web_search],\n", + " tool_call_summary_formatter=format_tool_result,\n", + ")\n", + "```\n", + "\n" + ] + }, { "cell_type": "markdown", "metadata": {}, diff --git a/python/docs/src/user-guide/core-user-guide/components/tools.ipynb b/python/docs/src/user-guide/core-user-guide/components/tools.ipynb index 2599f4cebeae..304133e15313 100644 --- a/python/docs/src/user-guide/core-user-guide/components/tools.ipynb +++ b/python/docs/src/user-guide/core-user-guide/components/tools.ipynb @@ -131,6 +131,47 @@ "print(stock_price_tool.return_value_as_string(result))" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Handling Tool Errors\n", + "\n", + "When you call a {py:class}`~autogen_core.tools.BaseTool` directly with\n", + "{py:meth}`~autogen_core.tools.BaseTool.run_json`, exceptions raised by the\n", + "underlying function are raised to the caller. When tools are called through a\n", + "{py:class}`~autogen_core.tools.Workbench`, the workbench catches tool execution\n", + "exceptions and returns a {py:class}`~autogen_core.tools.ToolResult` with\n", + "`is_error=True`. The result text contains the formatted exception message, so\n", + "the caller can pass the error back to a model or handle it in application code.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from autogen_core.tools import StaticWorkbench\n", + "\n", + "\n", + "async def divide(x: float, y: float) -> float:\n", + " \"\"\"Divide x by y.\"\"\"\n", + " if y == 0:\n", + " raise ValueError(\"y must not be zero\")\n", + " return x / y\n", + "\n", + "\n", + "divide_tool = FunctionTool(divide, description=\"Divide x by y.\")\n", + "\n", + "async with StaticWorkbench([divide_tool]) as workbench:\n", + " error_result = await workbench.call_tool(\"divide\", {\"x\": 1, \"y\": 0}, cancellation_token)\n", + "\n", + "print(error_result.is_error)\n", + "print(error_result.to_text())\n" + ] + }, { "cell_type": "markdown", "metadata": {},