lukesun1987 2024-07-12 09:30 采纳率: 0%
浏览 15
已结题

大模型Function Calling问题

各位专家,请教个问题,我用function calling方式调用天气预报接口,然后返回给大模型,但是大模型给我回答的不是天气预报相关的信息,是我参数那里传的有问题吗?我调的是星火的spark pro

public void run() {
            try {
                JSONObject requestJson=new JSONObject();

                JSONObject header=new JSONObject();  // header参数
                header.put("app_id",appid);
                header.put("uid",UUID.randomUUID().toString().substring(0, 10));

                JSONObject parameter=new JSONObject(); // parameter参数
                JSONObject chat=new JSONObject();
                chat.put("domain", Constant.DOMAIN);
                chat.put("temperature",0.5);
                chat.put("max_tokens",4096);
                parameter.put("chat",chat);

                JSONObject payload=new JSONObject(); // payload参数
                JSONObject message=new JSONObject();
                JSONArray text=new JSONArray();

                // 历史问题获取
                if(historyList.size()>0){
                    for(RoleContent tempRoleContent:historyList){
                        text.add(JSON.toJSON(tempRoleContent));
                    }
                }

                // 最新问题
                RoleContent roleContent=new RoleContent();
                roleContent.role="user";
                roleContent.content = NewQuestion;
                text.add(JSON.toJSON(roleContent));
                historyList.add(roleContent);

                message.put("text",text);
                payload.put("message",message);

                //Function call,当前Spark Pro/Max/4.0 Ultra 支持了该功能
                // **********************************************************
                JSONObject functions = new JSONObject();
                JSONArray textList = new JSONArray();

                textList.add(getWeather());
                textList.add(calculateRefundFee());

//                functions.put("type","function");
                functions.put("text",textList);
                payload.put("functions",functions);
                // **********************************************************

                requestJson.put("header",header);
                requestJson.put("parameter",parameter);
                requestJson.put("payload",payload);

                String cityName = NewQuestion;
                System.err.println("requestJson1:" + requestJson);
                // 可以打印看每次的传参明细
                webSocket.send(requestJson.toString());

                HashMap<String, Object> map = new HashMap<>();
                map.put("cityName" , cityName);
                String weatherData = new FunctionCaller().getWeather(map);

                //TODO 从getWeather接口返回获取argument
                String cName = "";
                String temp_C = "";
                String FeelsLikeC = "";
                String humidity = "";
                String weatherDesc = "";
                String observation_time = "";
                ObjectMapper mapper = new ObjectMapper();
                JsonNode rootNode;
                try {
                    rootNode = mapper.readTree(weatherData);
                    cName = rootNode.get("cityName").asText();
                    temp_C = rootNode.get("temp_C").asText();
                    FeelsLikeC = rootNode.get("FeelsLikeC").asText();
                    humidity = rootNode.get("humidity").asText();
                    weatherDesc = rootNode.get("weatherDesc").asText();
                    observation_time = rootNode.get("observation_time").asText();
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }

                ToolCallFunction tcf = ToolCallFunction.builder().name(
                        "getWeather").arguments(cityName).build();
                ToolCalls tc = ToolCalls.builder().id(function_call_id).type(ToolCalls.Type.FUNCTION.getName()).function(tcf).build();

                RoleContent roleContent1 = new RoleContent();
                roleContent1.role="assistant";
                roleContent1.content = NewQuestion;
                roleContent1.toolCalls = Collections.singletonList(tc);
                text.add(JSON.toJSON(roleContent1));
                historyList.add(roleContent1);

                String finalPrompt = cName +
                                ",今天的天气情况为" + weatherDesc +
                                ",气温为" + temp_C +
                                ",体感温度为" + FeelsLikeC +
                                ",湿度为" + humidity +
                                ",检测时间为" + observation_time;

                RoleContent roleContent2 = new RoleContent();
                roleContent2.role="tool";
                roleContent2.content = finalPrompt;
//                text.clear();
                text.add(JSON.toJSON(roleContent2));
                historyList.add(roleContent2);

                message.put("text",text);
                payload.put("message",message);
                requestJson.put("payload",payload);
                System.err.println("requestJson2:" + requestJson);
                webSocket.send(requestJson.toString());

                // 等待服务端返回完毕后关闭
                while (true) {
                    // System.err.println(wsCloseFlag + "---");
                    Thread.sleep(200);
                    if (wsCloseFlag) {
                        break;
                    }
                }
                webSocket.close(1000, "");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

public String getWeather(Map<String,Object> params) {
        String cityName = params.get("cityName").toString();
        System.out.println("调用getWeather接口:cityName:"+cityName);
//        if (cityName == null || cityName.isEmpty()) {
//            throw new IllegalArgumentException("City name must not be null or empty");
//        }

        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .build();

        try {
            Map<String, String> headers = new HashMap<>(16);
            headers.put("Content-Type", "application/json");
            Request.Builder builder = new Request.Builder()
                    .url("https://wttr.in/" + cityName + "?format=j1");
            builder.headers(Headers.of(headers));
            builder.method("GET", null);
            Request request = builder.build();
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                ResponseBody responseBody = response.body();
                JSONObject jsonObject = JSONObject.parseObject(responseBody.string());
                System.out.println("调用https://wttr.in/" + cityName + "?format" +
                        "=j1接口:cityName:"+cityName+",返回:"+jsonObject);
                JSONObject weatherData = new JSONObject();

                // Extract the desired weather data from the JSON response
                JSONArray currentCondition = jsonObject.getJSONArray("current_condition");
                JSONObject firstEntry = currentCondition.getJSONObject(0);
                weatherData.put("temp_C", firstEntry.getString("temp_C"));
                weatherData.put("FeelsLikeC", firstEntry.getString("FeelsLikeC"));
                weatherData.put("humidity", firstEntry.getString("humidity"));
                weatherData.put("weatherDesc", firstEntry.getString("weatherDesc"));
                weatherData.put("observation_time", firstEntry.getString("observation_time"));
                weatherData.put("cityName", params.get("cityName").toString());

                return weatherData.toString();
            } else {
                return "Failed.接口访问失败";
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "Error encountered while fetching weather data!";
        }
    }

第一次请求大模型的参数

{
    "payload": {
        "functions": {
            "text": [
                {
                    "name": "getWeather",
                    "description": "天气插件可以提供天气相关信息。你可以提供指定的地点信息,来精准检索到天气信息。",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "cityName": {
                                "description": "城市名称",
                                "type": "string"
                            }
                        },
                        "required": [
                            "cityName"
                        ]
                    }
                },
                {
                    "name": "calculateRefundFee",
                    "description": "计算退票费插件可以计算出退票的手续费。你可以提供票价、出发时间和退票时间,来计算退票的手续费。",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "departureTime": {
                                "description": "出发时间",
                                "type": "localDateTime"
                            },
                            "ticketPrice": {
                                "description": "票价",
                                "type": "double"
                            },
                            "refundTime": {
                                "description": "退票时间",
                                "type": "localDateTime"
                            }
                        },
                        "required": [
                            "ticketPrice",
                            "departureTime",
                            "refundTime"
                        ]
                    }
                }
            ]
        },
        "message": {
            "text": [
                {
                    "role": "user",
                    "content": "北京"
                }
            ]
        }
    },
    "parameter": {
        "chat": {
            "max_tokens": 4096,
            "domain": "generalv3",
            "temperature": 0.5
        }
    },
    "header": {
        "uid": "097236b0-2",
        "app_id": "61558de7"
    }
}

第二次请求大模型的参数

{
    "payload": {
        "functions": {
            "text": [
                {
                    "name": "getWeather",
                    "description": "天气插件可以提供天气相关信息。你可以提供指定的地点信息,来精准检索到天气信息。",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "cityName": {
                                "description": "城市名称",
                                "type": "string"
                            }
                        },
                        "required": [
                            "cityName"
                        ]
                    }
                },
                {
                    "name": "calculateRefundFee",
                    "description": "计算退票费插件可以计算出退票的手续费。你可以提供票价、出发时间和退票时间,来计算退票的手续费。",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "departureTime": {
                                "description": "出发时间",
                                "type": "localDateTime"
                            },
                            "ticketPrice": {
                                "description": "票价",
                                "type": "double"
                            },
                            "refundTime": {
                                "description": "退票时间",
                                "type": "localDateTime"
                            }
                        },
                        "required": [
                            "ticketPrice",
                            "departureTime",
                            "refundTime"
                        ]
                    }
                }
            ]
        },
        "message": {
            "text": [
                {
                    "role": "user",
                    "content": "北京"
                },
                {
                    "role": "assistant",
                    "toolCalls": [
                        {
                            "function": {
                                "name": "getWeather",
                                "arguments": "北京"
                            },
                            "id": "",
                            "type": "function"
                        }
                    ],
                    "content": "北京"
                },
                {
                    "role": "tool",
                    "content": "北京,今天的天气情况为[{\"value\":\"Sunny\"}],气温为30,体感温度为30,湿度为59,检测时间为02:08 AM"
                }
            ]
        }
    },
    "parameter": {
        "chat": {
            "max_tokens": 4096,
            "domain": "generalv3",
            "temperature": 0.5
        }
    },
    "header": {
        "uid": "097236b0-2",
        "app_id": "61558de7"
    }
}

  • 写回答

28条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-07-12 09:30
    关注
    获得0.30元问题酬金

    引自免费微信小程序:皆我百晓生

    根据您提供的信息和代码,您在大模型中的请求存在一些问题,可能是由于以下几个原因导致的:

    可能的问题和解决方法:

    参数传递问题:

    在您的大模型请求中,虽然您在 getWeather 函数中通过参数传递了 cityName,但在调用该函数时,您可能未正确传递必要的参数。您需要确保在调用函数时传递正确的参数。此外,检查其他参数是否也已正确传递。对于函数调用,请确保函数名和参数名称匹配。

    请求格式问题:

    在大模型请求的 JSON 格式中,可能需要满足特定的结构要求。您的第一次和第二次请求有所不同,请确保您的请求格式与您的 API 或大模型的期望格式相匹配。例如,检查 functions 是否具有正确的嵌套结构或所需的属性。确保 JSON 请求的其他部分也满足要求和格式正确。

    大模型函数实现问题:

    请确认您的 getWeather 函数在大模型中的实现是正确的。确保该函数能够正确处理输入参数并返回预期的结果。检查函数是否按照预期执行,包括与天气 API 的交互和返回数据的处理。如果函数内部逻辑存在问题,可能会导致返回意外的结果。

    请求顺序问题:

    如果您的程序逻辑中请求的顺序有误(例如发送两次请求时的时序问题),可能导致问题。确保按照正确的顺序发送请求,并且给每个请求足够的响应时间。如果大模型或后端服务需要特定的处理顺序或时间间隔,请遵循这些要求。

    调试建议:

    日志输出:

    增加更多的日志输出,例如在使用不同的API接口调用前后的请求内容、返回值等,有助于更好地定位问题所在。检查打印出的日志信息,查看是否有任何异常或错误消息。这些消息可能会指出问题的根本原因。您已经使用了 System.err.println 打印出请求详情和返回数据,这些可以帮助您诊断问题。确保这些日志中包含足够的信息以供分析。如果发现特定函数调用没有正确传递参数或其他错误,根据日志信息进行相应的调整。如果可能的话,检查网络响应状态码和错误信息,以了解后端服务层面是否有问题。另外,如果大模型有特定的日志系统或错误处理机制,请确保查看相关日志以获取更多信息。同时,您可以尝试分步调试您的代码以更精确地定位问题所在。针对每一部分的功能(如请求构造、函数处理逻辑等)分别进行测试和调试,以确保每一步都按照预期执行。最后,如果可能的话,尝试简化您的代码逻辑和请求结构以更容易地定位问题所在。简化后的代码更易于调试和理解,有助于更快地找到潜在的问题所在并进行修复。希望这些建议能帮助您解决问题!如果您还有其他疑问或需要进一步的帮助,请随时提问。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 7月20日
  • 创建了问题 7月12日

悬赏问题

  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见
  • ¥15 一共有五道问题关于整数幂的运算还有房间号码 还有网络密码的解答?(语言-python)
  • ¥20 sentry如何捕获上传Android ndk 崩溃
  • ¥15 在做logistic回归模型限制性立方条图时候,不能出完整图的困难
  • ¥15 G0系列单片机HAL库中景园gc9307液晶驱动芯片无法使用硬件SPI+DMA驱动,如何解决?