You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord机器人中OpenAI函数调用时类方法无法返回值求助

问题分析与修复方案

核心问题

你的代码存在三个关键问题,导致方法返回值无法被正确获取:

  1. 函数字典初始化时立即执行所有方法
    你在dict_function中直接调用了self.select_all_quotes()和self.add_quotes(...),这会在字典创建时就强制执行所有方法,而非根据OpenAI返回的function_name按需调用。更严重的是,当请求select_all_quotes时,regex_arguments是"{}",此时尝试获取regex_arguments["amount"]会抛出异常,直接进入except块返回response["content"](值为null),导致data无输出。

  2. 正则处理后的参数是字符串,未转为字典
    re.sub处理后得到的是JSON格式字符串,不是Python字典,直接用regex_arguments["amount"]会触发类型错误。

  3. 异常捕获范围过大
    宽泛的except:会掩盖所有错误,包括参数解析、方法调用异常,导致你无法定位具体问题,误以为是方法返回值的问题。

修复步骤

1. 修改函数字典的定义方式

将字典值改为函数对象,而非直接执行方法,实现按需调用:

dict_function = {
    "select_all_quotes": self.select_all_quotes,
    "add_quotes": self.add_quotes
}

2. 解析参数字符串为字典

使用json.loads将正则处理后的参数字符串转为字典,兼容空参数场景:

import json  # 新增导入json模块

# ...
regex_arguments = re.sub(r"\t|\n|\r|\s+", '', response["function_call"]["arguments"])
args = json.loads(regex_arguments) if regex_arguments else {}

3. 按需调用函数并传递参数

根据function_name从字典中取出函数,再根据函数需求传递参数:

function_name = function_call["name"]
function = dict_function[function_name]
# 针对不同函数传递对应参数
if function_name == "add_quotes":
    data = function(args["amount"])
else:
    data = function()

4. 缩小异常捕获范围

只捕获预期异常,保留错误信息便于调试:

try:
    # ... 你的核心逻辑代码 ...
except (KeyError, json.JSONDecodeError, mysql.connector.Error) as e:
    print(f"错误信息: {e}")
    return "请求参数错误,请检查输入。"
except Exception as e:
    print(f"未知错误: {e}")
    return "处理请求时发生异常,请重试。"

5. 修复add_quotes中的query_ai调用

原query_ai方法不支持自定义prompt,需修改以适配获取名言的场景:

def query_ai(self, prompt=None):
    openai.api_key = savedfile.openai_key()
    user_content = prompt if prompt else self.query
    # 获取名言时不需要触发函数调用,仅处理原始用户查询时传入functions参数
    functions = function_list() if not prompt else None
    completion = openai.ChatCompletion.create(
        model="gpt-3.5-turbo-0613",
        messages=[
            {"role": "system", "content": "You are a helpful assistant."},
            {"role": "user", "content": user_content},
        ],
        functions=functions
    )
    response = completion.choices[0].message
    # 自定义prompt场景直接返回内容,原始查询返回完整message
    return response["content"] if prompt else response

完整修复后的关键代码片段

import json  # 新增导入

class Quote_Getter(Sql_Query):
    def __init__(self,query):
        super().__init__()
        self.query = query

    def query_ai(self, prompt=None):
        openai.api_key = savedfile.openai_key()
        user_content = prompt if prompt else self.query
        functions = function_list() if not prompt else None
        completion = openai.ChatCompletion.create(
            model="gpt-3.5-turbo-0613",
            messages=[
                {"role": "system", "content": "You are a helpful assistant."},
                {"role": "user", "content": user_content},
            ],
            functions=functions
        )
        response = completion.choices[0].message
        return response["content"] if prompt else response

    def query_sort(self):
        response = self.query_ai()
        print(response)
        try:
            function_call = response["function_call"]
            regex_arguments = re.sub(r"\t|\n|\r|\s+", '', function_call["arguments"])
            print(regex_arguments)
            args = json.loads(regex_arguments) if regex_arguments else {}

            dict_function = {
                "select_all_quotes": self.select_all_quotes,
                "add_quotes": self.add_quotes
            }

            function_name = function_call["name"]
            function = dict_function[function_name]
            if function_name == "add_quotes":
                data = function(args["amount"])
            else:
                data = function()
            
            print(data)
            return data
        except (KeyError, json.JSONDecodeError) as e:
            print(f"参数解析错误: {e}")
            return "请求参数错误,请检查输入。"
        except Exception as e:
            print(f"处理错误: {e}")
            return response.get("content", "无法处理你的请求,请重试。")

    def answer_back(self):
         data = self.query_sort()
         return str(data)

    def add_quotes(self,amount):
        data = self.query_ai(f"Get me {amount} motivational quotes")
        data_list = [line.strip() for line in data.split("\n") if line.strip()]
        print(data_list)
        return self.insert_quotes_auto(data_list)

# Sql_Query类代码保持不变

验证修复效果

  • 请求"显示所有名言"时,代码会执行select_all_quotes(),正确返回名言列表并发送到Discord。
  • 请求"添加5条名言"时,代码会调用add_quotes(5),获取AI生成的名言后插入数据库,返回插入记录数。

内容的提问来源于stack exchange,提问作者Akashdeep Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 18:42:07