使用libcurl调用Baichuan API时model参数已设置仍提示缺失
问题:调用百川AI API时提示未设置model参数(已配置该参数)
我按照建议使用cJSON库生成请求消息的数据段,通过curl构造请求头和数据部分,以POST方式发送请求,但系统提示未设置model参数,可实际上我已经配置了该参数。以下是我的代码及运行结果:
int main(int argc, char **argv){ CURL *curl; char *url = NULL; CURLcode res = CURLE_OK; url = "https://api.baichuan-ai.com/v1/chat/completions"; // 初始化用于存储响应数据的结构体 struct MemoryStruct chunk; chunk.memory = malloc(1); chunk.size = 0; char *auth_header = "Authorization: Bearer " KIMI_API; char *content_header = "Content-Type: application/json"; struct curl_slist *headers = NULL; headers = curl_slist_append(headers, auth_header); headers = curl_slist_append(headers, content_header); cJSON *data = cJSON_CreateObject(); char *messages = "巴黎奥运会中国体育代表团共获多少金牌?"; cJSON_AddStringToObject(data, "model", "Baichuan4"); cJSON_AddStringToObject(data, "messages", messages); cJSON_AddNumberToObject(data, "max_tokens", 1024); cJSON_AddNumberToObject(data, "temperature", 0.5); char *json_string = cJSON_Print(data); curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); printf("%s \n", json_string); if (curl) { curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk); res = curl_easy_perform(curl); if (res == CURLE_OK){ printf("Response:\n%s\n", chunk.memory); } else { printf("failed"); } curl_easy_cleanup(curl); } free(chunk.memory); return 0; }
运行结果:
{ "model": "Baichuan4", "messages": "巴黎奥运会中国体育代表团共获多少金牌?", "max_tokens": 1024, "temperature": 0.5 } Response: {"error":{"code":"model_is_empty","param":null,"type":"invalid_request_error","message":"you must provide a model parameter"}}
问题分析与修复
1. 核心错误:POST数据传递错误
你设置CURLOPT_POSTFIELDS时,传递的是cJSON对象指针data,但curl需要的是序列化后的JSON字符串(即你生成的json_string)。cJSON对象是内存中的结构体,直接传递给curl会导致发送的数据不是合法JSON,服务端无法解析到model参数。
2. 次要错误:messages参数格式不符合接口要求
百川AI的chat completions接口中,messages要求是数组格式,每个元素是包含role和content的对象,而非直接传字符串。即使修复第一个问题,这个错误也会导致接口调用失败。
修正后的代码
int main(int argc, char **argv){ CURL *curl; char *url = NULL; CURLcode res = CURLE_OK; url = "https://api.baichuan-ai.com/v1/chat/completions"; // 初始化用于存储响应数据的结构体 struct MemoryStruct chunk; chunk.memory = malloc(1); chunk.size = 0; char *auth_header = "Authorization: Bearer " KIMI_API; char *content_header = "Content-Type: application/json"; struct curl_slist *headers = NULL; headers = curl_slist_append(headers, auth_header); headers = curl_slist_append(headers, content_header); cJSON *data = cJSON_CreateObject(); // 修正messages参数格式:数组+role+content结构 cJSON *messages = cJSON_CreateArray(); cJSON *user_msg = cJSON_CreateObject(); cJSON_AddStringToObject(user_msg, "role", "user"); cJSON_AddStringToObject(user_msg, "content", "巴黎奥运会中国体育代表团共获多少金牌?"); cJSON_AddItemToArray(messages, user_msg); cJSON_AddStringToObject(data, "model", "Baichuan4"); cJSON_AddItemToObject(data, "messages", messages); // 添加数组到对象 cJSON_AddNumberToObject(data, "max_tokens", 1024); cJSON_AddNumberToObject(data, "temperature", 0.5); char *json_string = cJSON_Print(data); curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); printf("%s \n", json_string); if (curl) { curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_string); // 传递序列化后的JSON字符串 curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk); res = curl_easy_perform(curl); if (res == CURLE_OK){ printf("Response:\n%s\n", chunk.memory); } else { printf("failed"); } curl_easy_cleanup(curl); } free(chunk.memory); cJSON_Delete(data); // 释放cJSON对象内存 free(json_string); // 释放序列化后的字符串内存 return 0; }
关键修正点
- 将
CURLOPT_POSTFIELDS的参数从data改为json_string,确保发送合法JSON文本。 - 重构
messages为接口要求的数组结构,每个消息包含role和content字段。 - 添加cJSON对象和字符串的内存释放,避免内存泄漏。
内容的提问来源于stack exchange,提问作者L JF
相关产品推荐
相关产品推荐

