C++代码实现调用OpenAi接口Api

在网上找了一圈C++如何调用OpenAi的接口,找到的例子比较简单,完全照搬下来修改一下也能用,不过i整合在自己的类里面就莫名奇妙的问题:

1. 比如 coredump

     url_easy_perform的执行和curl_easy_setopt放在了两个函数中就出问题了,很奇怪。。。至今不知道原因,有知道的小伙伴可以评论告诉我。O(∩_∩)O

    暖心提示:

    curl_easy_setopt和url_easy_perform 别分开写。

2. 发送api key,放入head中时,

     curl_slist_append的返回值必须用同一个head指针来接收才行,例如:

     struct curl_slist* headers

      curl_slist_append(this->headers, contentType_header.c_str());

       curl_slist_append(this->headers, contentType_header.c_str());

       就会导致认证失败,因为必须:

       headers = curl_slist_append(this->headers, contentType_header.c_str());

       headers = curl_slist_append(this->headers, contentType_header.c_str());

       你以为就这?还有:

       你下一次使用前要把 headers = NULL才行(贴个没问题的代码截图如下):

       

    ======================================================================

上示例代码:

sudo apt install nlohmann-json3-dev

Ubuntu 22.04上面安装下上面的json库

1. openai.h

#pragma once

#include <nlohmann/json_fwd.hpp>
#include <nlohmann/json.hpp>
#include <curl/curl.h>
#include <string>
using namespace std;
using namespace nlohmann;

class OpenAi {
    public:
        static OpenAi* GetInstance();
        ~OpenAi();
        const std::string& GetClassName();
        void Initialize();
        void Finalitialize();
        void SetModel(const std::string& model = "gpt-3.5-turbo");
        void SetUri(const std::string& uri = "https://api.openai.com/v1/chat/completions");
        void SetApiKey(const std::string& apiKey);
        void SetRole(const std::string& role = "user");
        void SetContent(const std::string& content);
        void SetContentType(const std::string& contentType = "application/json");
        void PostMessage();
        std::string GetResponse();
        void Reset();
        void Test();
    private:
        OpenAi();
        std::string _className;
        std::string _model;
        std::string _uri;
        std::string _apiKey;
        std::string _role;
        std::string _content;
        std::string _contentType;
        nlohmann::json request;
    private:
        struct curl_slist* headers;
        CURL* curl;
        std::string response;
        CURLcode res;
        void set_curl_headers();
        void set_curl_request();
        static size_t WriteCallback(void* contents, size_t size, size_t nmemb, string* response);
};

2. openai.cpp

#include <exception>
#include <iostream>
#include <ostream>
#include <string>
#include "openai.h"
static OpenAi* openai_instance = nullptr;

OpenAi::OpenAi():_className("OpenAi"),
                 headers(nullptr),
                 curl(nullptr) {
    curl_global_init(CURL_GLOBAL_DEFAULT);
}
OpenAi::~OpenAi() {
    curl_global_cleanup();
}
const std::string& OpenAi::GetClassName() {
    return _className;
}

void OpenAi::Initialize() {
    this->curl = curl_easy_init();
    this->SetModel();
    this->SetUri();
    this->SetRole();
    this->SetContentType();
}

void OpenAi::Finalitialize() {
    if(this->curl) {
        curl_easy_cleanup(this->curl);
        this->curl = nullptr;
    }
    if(this->headers) {
        curl_slist_free_all(headers);
        this->headers = nullptr;
    }
    if(openai_instance) {
        delete openai_instance;
        openai_instance = nullptr;
    }
}

OpenAi* OpenAi::GetInstance() {
    if(openai_instance == nullptr) {
        openai_instance = new OpenAi();
    }

    return openai_instance;
}

void OpenAi::SetModel(const std::string& model) {
    this->_model.assign(model);
}

void OpenAi::SetUri(const std::string& uri) {
    this->_uri.assign(uri);
}

void OpenAi::SetApiKey(const std::string& apiKey) {
    this->_apiKey.assign(apiKey);
}

void OpenAi::SetRole(const std::string& role) {
    this->_role.assign(role);
}

void OpenAi::SetContent(const std::string& content) {
    this->_content.assign(content);
}

void OpenAi::SetContentType(const std::string& contentType) {
    this->_contentType.assign(contentType);
}

void OpenAi::PostMessage() {
    this->set_curl_headers();
    this->set_curl_request();
}

void OpenAi::set_curl_headers() {
    std::string contentType_header = "Content-Type: " + this->_contentType;
    std::string auth_header = "Authorization: Bearer " + this->_apiKey;
    std::cout<<contentType_header<<std::endl;
    std::cout<<auth_header<<std::endl;
    if(this->headers) {
        curl_slist_free_all(headers);
        this->headers = nullptr;
    }
    this->headers = curl_slist_append(this->headers, contentType_header.c_str());
    this->headers = curl_slist_append(this->headers, auth_header.c_str());
    curl_easy_setopt(this->curl, CURLOPT_HTTPHEADER, this->headers);
}
void OpenAi::set_curl_request() {
    //std::cout<<__func__<<":"<<__LINE__<<std::endl;
    std::string prompt = this->_content;
    json requestData;
    if(!this->response.empty()) {
        this->response.clear();
    }
    this->request["model"] = this->_model;
    this->request["messages"][0]["role"] = this->_role;
    this->request["messages"][0]["content"] = this->_content;
    this->request["temperature"] = 0;
    string requestDataStr = this->request.dump().c_str();
    std::cout<<requestDataStr<<std::endl;
    curl_easy_setopt(this->curl, CURLOPT_URL, this->_uri.c_str());
    curl_easy_setopt(this->curl, CURLOPT_POSTFIELDS, requestDataStr.c_str());
    curl_easy_setopt(this->curl, CURLOPT_POSTFIELDSIZE, requestDataStr.length());
    curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, OpenAi::WriteCallback);
    curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, &this->response);
    //std::cout<<__func__<<":"<<__LINE__<<std::endl;
    this->res = curl_easy_perform(this->curl);
}

std::string OpenAi::GetResponse() {
    if (this->res != CURLE_OK) {
        std::cerr << "Failed to make request: " << curl_easy_strerror(res) << std::endl;
    } else {
        // Process the API response here
        //std::cout<<__func__<<":"<<__LINE__<<std::endl;
        if(!this->response.empty()) {
            //std::cout<<__func__<<":"<<__LINE__<<"->Response:"<<std::endl;
            //std::cout<<this->response<<std::endl;
            try {
                json jresponse = json::parse(this->response);
                std::cout<<jresponse.dump()<<std::endl;
            } catch(std::exception& e) {
                std::cout<<e.what()<<std::endl;
            }
        }
    }

    return this->response;
}

size_t OpenAi::WriteCallback(void* contents, size_t size, size_t nmemb, string* response) {
    size_t totalSize = size * nmemb;
    response->append((char*)contents, totalSize);
    return totalSize;
}

void OpenAi::Reset() {
    this->SetModel();
    this->SetUri();
    this->SetRole();
    this->SetContentType();
}
void OpenAi::Test() {
    if (this->curl) {
        this->set_curl_headers();
        this->set_curl_request();
    }
}
 

 3. 测试程序文件 openai_self.cpp

#include <iostream>
#include <string>
#include "openai.h"

using namespace std;
using namespace nlohmann;

int main(int argc, char** argv) {
    int ret = 0;
    OpenAi* openai = OpenAi::GetInstance();
    openai->Initialize();
    openai->SetApiKey("");  // 设置你自己的API Key
    openai->SetModel();
    openai->SetContent("Who are you?");
    openai->PostMessage();
    std::string res = openai->GetResponse();
    if(!res.empty()) {
        std::cout<<"Response ->:"<<std::endl;
        std::cout<<res<<std::endl;
    } else {
        std::cout<<"No response!"<<std::endl;
    }

    return ret;
}
 

 4. makefile

.DEFAULT_GOAL := openai
.PHONY: openai all

CXX = g++
CXXFLAGS = -std=c++11 -g
LDFLAGS = -lcurl

one_sources = openai_self.cpp openai.cpp

all: openai
    @echo "===== $@ start ====="
    @echo "===== $@ end ====="

openai:
    @echo "===== $@ start ====="
    $(CXX) $(CXXFLAGS) $(one_sources) -o $@ $(LDFLAGS)
    @echo "===== $@ end ====="
clean_openai:
    @echo "===== $@ start ====="
    @rm -rf openai
    @echo "===== $@ end ====="

clean: clean_openai
    @echo "===== $@ start ====="
    @echo "===== $@ end ====="
 

 5. 直接执行 make命令编译出openai程序

6. ./openai 程序执行结果:

   

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/144072.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

简单实现接口自动化测试(基于python+unittest)

简介 本文通过从Postman获取基本的接口测试Code简单的接口测试入手&#xff0c;一步步调整优化接口调用&#xff0c;以及增加基本的结果判断&#xff0c;讲解Python自带的Unittest框架调用&#xff0c;期望各位可以通过本文对接口自动化测试有一个大致的了解。 引言 为什么要做…

设置虚拟机静态IP

1、修改配置文件 /etc/sysconfig/network-scripts/ifcfg-ens160 将BOOTPROTOdhcp改为static&#xff0c;天机IPADDR192.168.10.13 2、重启网络服务 systemctl restart network

亚马逊云科技携手普华永道,在跨境数据传输方面打造适合中企的安全合规方案

第六届中国国际进口博览会于昨日圆满落下帷幕。11月9日下午&#xff0c;在普华永道解码数字产品与解决方案之道专场中&#xff0c;亚马逊云科技安全合规服务总监白帆先生和普华永道中国网络安全及隐私保护合伙人黄思维先生带来了基于跨境数据传输的合规性讨论&#xff0c;并正式…

技术管理责任制度《二》

技术管理责任制度《二》 彩虹图纸管理软件_图纸管理系统_图纸文档管理软件系统_彩虹EDM【官网】 1、技术档案&#xff0c;指本企业进行生产经营活动所用的一切重要图片、图纸、光碟、图书、报表、技术资料、有关设备、技术的文字说明等技术文件&#xff0c;整理后归并文件档案…

求推荐哪个好用的ERP或CRM软件?有ERP、CRM一体化的软件吗?

推荐好用的ERP或CRM软件&#xff1f;那么&#xff0c;有软件能够实现ERP、CRM一体化吗&#xff1f; 当然有&#xff0c;我们公司就在使用这样一个一体化平台。 只要你能够准确地理解业务逻辑&#xff0c;即使没有编程经验和代码基础&#xff0c;也能够利用简道云轻松创建各种…

动静态库。

gcc去 1、默认路径/usr/include里面去找 2、当前目录去找 但是mymath.h根本不在这里面&#xff0c;所以就报错了 你可以在.c中 #include “./lib/include/” 指明头文件在哪里&#xff0c;但是不推荐 &#xff0c;建议在gcc时处理

使用 PYTORCH 进行图像风格迁移

一、介绍 本教程介绍如何实现 由 Leon A. Gatys、Alexander S. Ecker 和 Matthias Bethge 开发的神经风格算法。神经风格或神经传输允许您拍摄图像并以新的艺术风格再现它。该算法采用三幅图像&#xff0c;即输入图像、内容图像和风格图像&#xff0c;并将输入更改为类似于内容…

python使用redis模块来跟redis实现交互

大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 redis模块的使用&#xff1a; 1.安装模块: pip3 install redis 2.导入模块&#xff1a;import redis 3.连接方式&#xff1a; 严格连接模式&#xff1a;rredis.StrictR…

认不清车辆车型品牌种类?AI模型来助力,基于YOLO开发大规模车辆检测识别分析系统

随着汽车市场的蓬勃发展&#xff0c;已经涌现诞生了大量的品牌的车型&#xff0c;让人一时间眼花缭乱&#xff0c;很多时候看到一辆汽车只能大概知道这是什么品牌的&#xff0c;但是具体的子品牌详情就不得而知了&#xff0c;有没有可能构建这样的识别模型&#xff0c;让我们在…

LLM实现RPA

“PROAGENT: 从机器人流程自动化到代理流程自动化”这篇论文有几个创新点是比较有意思的&#xff1a;1.通过描述方式生成执行链&#xff0c;执行链通过代码方式生成保证执行链的稳健、可约束2.对执行过程抽取出数据结构&#xff0c;数据结构也通过代码生成方式来约束3.整个过程…

名片识别软件哪个好?

名片扫描软件是一种方便快捷的名片信息录入工具&#xff0c;可以将纸质名片转化为电子版&#xff0c;方便存储、编辑和管理。在市场上&#xff0c;有很多名片扫描软件可供选择&#xff0c;那么哪个好呢&#xff1f;本文将从专业角度出发&#xff0c;为您详细介绍。 首先&#x…

TypeError: Can‘t parse ‘center‘. Sequence item with index 0 has a wrong type

报错代码 import sys sys.path.append(rD:\文档\Temp\WX-FIles\data) # sys.path.append(rD:\文档\Temp\WX-FIles\data)p11 [125, 195] p12 [200, 275] # and the corresponding two points on the second image are:p21 [120, 190] p22 [200, 280] # TODO: write your ow…

集团VPN问题排查及核心交换机(思科C9500)路由编写

前言 昨天发现子公司A无法访问子公司B的服务器。已知之前是可以的。经过tracert及ping的简单排查。发现&#xff0c;A没有经过飞塔200F的防火墙出去。 已知集团使用两套防火墙。思科2110以及飞塔200F。并且在上方都做了VPN的配置。200F承接SD-WAN。 我们知道&#xff0c;当A公…

MySQL 社区开源备份工具 Xtrabackup 详解

文章目录 前言1. Xtrabackup 介绍1.1 物理备份与逻辑备份区别1.2 Xtrabackup 系列版本 2. Xtrabackup 部署2.1 下载安装包2.2 二进制部署2.3 程序文件介绍2.4 备份需要的权限 3. Xtrabackup 使用场景3.1 本地全量备份3.2 本地压缩备份3.3 全量流式备份3.3.1 备份到远程主机3.3.…

Unity Meta Quest 一体机开发(五):手势抓取概述

文章目录 &#x1f4d5;教程说明&#x1f4d5; Oculus Integration 中的三种手势抓取方式⭐Hand Grab⭐Touch Hand Grab⭐Distance Hand Grab 此教程相关的详细教案&#xff0c;文档&#xff0c;思维导图和工程文件会放入 Seed XR 社区。这是一个高质量知识星球 XR 社区&#…

F8652X 984865265 F8652E 984865264

F8652X 984865265 F8652E 984865264 亚历克能够满足最严格的建筑规范开箱-不需要大量的定制&#xff0c;设计时间或劳动力&#xff0c;或专门的布线系统。 模块化ALEC系统包括三个简单的硬件组件——区域控制器(ZC001)、标准按钮墙板和物联网(IoT)网关。该系统可以无限扩展&…

【自动化测试】Jenkins持续集成-设置执行环境+构建触发器(超细整理)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、Jenkins流水线…

海思SD3403,SS928/SS927/SS926,hi3519dv500,hi3516dv500移植yolov7(2)

0.前言 上一节主要在讲如何做数据处理和模型训练。简单验证了一下模型的量化导出。这一节来配置一下转换模型所需要的环境。 1.合作交流 容我先打个广告&#xff0c; 我司推出的目标识别跟踪模块&#xff0c;支持热红外、可见光主流多光谱视频输入与目标识别跟踪等功能…

electronjs入门-编辑器应用程序

我们将在Electron中创建一个新项目&#xff0c;如我们在第1章中所示&#xff0c;名为“编辑器”&#xff0c;我们将在下一章中使用它来创建编辑器&#xff1b;在index.js中&#xff0c;这是我们的主要过程&#xff1b;请记住为Electron软件包放置必要的依赖项&#xff1a; npm…

30个Python操作小技巧

1、列表推导 列表的元素可以在一行中进行方便的循环。 numbers [1, 2, 3, 4, 5, 6, 7, 8] even_numbers [number for number in numbers if number % 2 0] print(even_numbers)输出&#xff1a; [1,3,5,7]同时&#xff0c;也可以用在字典上。 dictionary {first_num: 1,…