☰
第五单元——第5课:工具出错后,让助手解释问题
2026/10/23 2:57:14 网站建设 项目流程

上一课给参数加了校验。这节处理下一步:

参数不合法、库存不足时,怎样把问题交回模型,让它向用户说明?

我们使用ToolNode的错误处理功能,把指定异常转换成错误类型的工具消息,再交给模型。其他未指定的代码错误仍然向外抛出,方便排查。

1. 复制上一课文件

另存为:

C:\Users\Administrator\langchain-study\unit5_lesson5_tool_errors.py

添加导入:

from langchain_core.tools import ToolException

上一课的ValidationError导入继续保留。

2. 将报价失败改成明确的异常

上一课在库存不足时返回普通字符串。这种方式也可以,但它在消息层面仍是一次正常返回。

本课用ToolException明确表示“本次工具操作没有成功”。

将calculate_quote函数替换为:

@tool(args_schema=QuoteInput) def calculate_quote(book_name: str, quantity: int) -> str: """检查指定图书的库存并计算报价,不下单、不扣库存。""" print("[报价工具] 参数校验通过,开始执行") name = book_name.strip().replace("《", "").replace("》", "") if name not in BOOK_PRICES or name not in BOOK_STOCK: raise ToolException( f"《{name}》的价格或库存记录不完整,无法报价。" "请用户确认书名,不要编造价格。" ) stock = BOOK_STOCK[name] if quantity > stock: raise ToolException( f"《{name}》当前只有 {stock} 本," f"无法满足 {quantity} 本的现货需求。" "请向用户说明,不要擅自减少数量或声称下单成功。" ) unit_price = BOOK_PRICES[name] total_price = unit_price * quantity return ( f"《{name}》单价 {unit_price} 元," f"{quantity} 本合计 {total_price} 元。" "这只是报价,尚未下单或扣减库存。" )

raise会立即结束当前函数的正常执行,不会继续计算下面的报价。

3. 指定哪些错误交给模型处理

将原来的:

builder.add_node("tools", ToolNode(tools))

替换为:

tool_node = ToolNode( tools, handle_tool_errors=( ToolException, ValidationError, ), ) builder.add_node("tools", tool_node)

这里配置的是异常类型的元组,不是调用这两个类。

它的含义是:

  • 预期的工具问题、参数校验问题:转换成错误消息,交回模型。
  • 未包含的异常,例如NameError:继续报错,不伪装成正常业务问题。

部分版本会把参数校验错误包装为ToolException的子类,这个配置也包含这些子类。错误消息会带上对应的工具调用编号。官方实现与说明

原来的这条边不变:

builder.add_edge("tools", "assistant")

所以模型拿到错误结果后,可以解释原因,而不是继续假装报价成功。

4. 补充系统提示词

在SystemMessage中追加:

"工具返回错误时,说明具体原因。" "参数缺失或超出允许范围时,请用户提供合法参数。" "库存不足或记录缺失时,不要反复调用相同工具。" "不得为了通过校验而擅自修改用户要求的数量。"

注意:这些提示是在指导模型,不能保证它绝不重复调用。上一课设置的recursion_limit继续保留。

5. 打印工具消息的状态

在程序最后找到:

if isinstance(message, ToolMessage): print("工具结果:", message.content)

改成:

if isinstance(message, ToolMessage): print("工具状态:", message.status) print("工具结果:", message.content)

现在可以区分:

工具状态: success

和:

工具状态: error

图正常运行结束,不代表其中每次工具调用都成功。

6. 做三个测试

运行:

python unit5_lesson5_tool_errors.py

每个问题单独重新运行一次:

问题观察重点
请给我2本《三体》的报价。库存充足时返回success
请给我9本《三体》的现货报价。若库存仍为8本,应返回error,说明库存不足
请给我2本《不存在的测试书》的报价。返回error,说明没有记录

第一项按原来的演示价格应为90元;后两项不应声称已经下单。

如果你输入“买负2本”,模型可能直接要求你修改数量,没有调用工具。这是合理行为,但不能用它证明参数校验已执行;校验本身仍用上一课的直接调用测试来验证。

本课要分清的三件事

  • 参数校验:输入格式和范围是否合法。
  • 工具错误处理:失败后,如何把原因交回模型。
  • 自动重试:同一个操作是否再执行一次。

本课没有增加自动重试。库存不足不是临时网络故障,重复查询通常解决不了。

另外,错误内容会被发给模型,所以只放必要的业务说明,不要把 API Key、数据库连接串或完整内部日志放进去。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询