打造中国最大的
AI信息汇总平台


ChatGPT API 技巧教程

一起探索

导语:ChatGPT作为一种基于人工智能的自然语言处理工具,可以帮助你更好地解决这些问题,提高质量和效率。那么,本文将介绍如何使用ChatGPT的API接口,高效响应结果。


官方传送门:https://chat.openai.com


一、获取API密钥

1.注册ChatGPT账号:在官网上注册账号,进行实名认证并登录账号。

2.创建应用并获取API密钥:在控制台中创建一个新应用,即可获取API密钥。

二、调用API接口

使用ChatGPT的API接口,需要进行以下几个步骤:

1.设置请求URL:API请求URL为 https://api.openai.com/v1/engines/davinci-codex/completions。

2.设置请求头部:请求头部中需要包含Authorization字段和Content-Type字段,其中Authorization字段为Bearer API密钥,Content-Type字段为application/json。

3.设置请求参数:请求参数中需要包含prompt字段和max_tokens字段,其中prompt字段为文案的起始语句,max_tokens字段为要生成的文案的长度,stream[1]是否使用流的方式返回数据,下文会讲到。

4.发送请求并解析结果:使用相应的语言(如Java)发送HTTP请求,获取API返回的结果。

下面是一个Java的示例代码:

import java.net.*;import java.io.*;
public class ChatGPTAPI {  public static void main(String[] args) {  
  try {      URL url = new URL("https://api.chatgpt.com/v1/chat");      HttpURLConnection con = (HttpURLConnection) url.openConnection();      con.setRequestMethod("POST");      con.setRequestProperty("Content-Type", "application/json");      con.setRequestProperty("Accept", "application/json");      con.setDoOutput(true);      String jsonInputString = "{\"message\": \"Hello, ChatGPT!\"}";      byte[] input = jsonInputString.getBytes("utf-8");      con.getOutputStream().write(input, 0, input.length);      if (con.getResponseCode() != 200) {        throw new RuntimeException("Failed : HTTP error code : " + con.getResponseCode());      }      BufferedReader br = new BufferedReader(new InputStreamReader((con.getInputStream())));      String output;      System.out.println("Output from Server .... \n");      while ((output = br.readLine()) != null) {        System.out.println(output);      }      con.disconnect();    } catch (Exception e) {      System.out.println("Exception in NetClientGet:- " + e);    }  }}

这个只是最初的Demo,下面会教大家一步步演进

三、应用场景

创意写作研究咨询技术文档SEO优化
学术论文演讲稿教育培训社交媒体
内容创作个人陈述网站内容演讲稿
商业写作简历和求职信旅游文案新闻稿
学术编辑广告文案医疗文案多语言翻译
儿童读物电子商务小说

场景技巧:

change='XXX'sys_role_con="你是一位资深编程专家,负责代码变更的审查工作。需要给出审查建议。在建议的开始需明确对此代码变更给出「拒绝」或「接受」的决定,并且以格式「变更评分:实际的分数」给变更打分,分数区间为0~100分。然后,以精炼的语言、严厉的语气指出存在的问题。如果你觉得必要的情况下,可直接给出修改后的内容。建议中的语句可以使用emoji结尾。你的反馈内容必须使用严谨的markdown格式。'prompt= [    {'role': 'system',     'content': sys_role_con     },    {'role': 'user',     'content': f'请review这部分代码变更{change}',     },]这样可以实现角色提示的方式告诉OpenAI的能力,在这基础上可以扩展prompt

四、代码演进

痛点:

延迟高,体验差,达不到官方的效果。

优化:

秒级响应,流式响应,达到官方的流畅效果

教程如下:

修改请求参数(strem=True),接收端采用EventSource[1]事件监听。

可以详细阅读官方文档的这个参数说明

方案1:采用Websocket优化

# listernpublic void onEvent(EventSource eventSource, String id, String type, String data) {    log.info("OpenAI返回数据:{}", data);    if (data.equals("[DONE]")) {        log.info("OpenAI返回数据结束了");        client.sendEvent(SERVER_CHANNEL,"[DONE]");        return;    }    ObjectMapper mapper = new ObjectMapper();    ChatCompletionResponse completionResponse = mapper.readValue(data, ChatCompletionResponse.class); // 读取Json    Message delta = completionResponse.getChoices().get(0).getDelta();    JSONObject parse = JSONUtil.parseObj(delta);    parse.put("msgId", completionResponse.getId());    client.sendEvent(SERVER_CHANNEL, parse);}
# Controller@OnEvent(value = CLIENT_CHANNEL)public void startOrderDetailChangeListener(SocketIOClient client, AckRequest request, ChatObject chat){ //数据校验 if(chat.getUserName() == null){ return; }
String sessionId = client.getSessionId().toString(); log.info("SocketIO-消息通知-新增连接-sessionId: " + sessionId); clientMap.put(chat.getUserName(), client);
String msg = chat.getMessage(); String userName = chat.getUserName();
log.info("msg: ["+msg+"], uuid:[" +userName+"]"); String messageContext = (String) LocalCache.CACHE.get(userName); List messages = new ArrayList<>(); if (StrUtil.isNotBlank(messageContext)) { messages = JSONUtil.toList(messageContext, Message.class); if (messages.size() >= 10) { messages = messages.subList(1, 10); } Message currentMessage = Message.builder().content(msg).role(Message.Role.USER).build(); messages.add(currentMessage); } else { Message currentMessage = Message.builder().content(msg).role(Message.Role.USER).build(); messages.add(currentMessage); } SocketIOListener socketIOListener = new SocketIOListener(client); openAiStreamClient.streamChatCompletion(messages, socketIOListener); LocalCache.CACHE.put(userName, JSONUtil.toJsonStr(messages), LocalCache.TIMEOUT); log.info("event end");}
//  vue Clientexport class DataProvider {    clientid = '';    socket!: any;    constructor(private path: string) {        this.clientid = Date.parse(new Date().toString()).toString();        this.socket = io(this.path + `?username=${this.clientid}`, {            transports:["websocket"],            autoConnect:false,        });        this.socket.connect();    }    // 连接socket    connect() {        // this.socket.onconnected        this.socket.on("connect", () => {            console.log("连接成功");        });        this.socket.connect();
} // 接收消息 event(callback: any) { this.socket.on("s_channel", (data:any) => { if(data == '[DONE]') { callback({ content: null, formMe : false, messageId: data.msgId }) } const isContent = data.hasOwnProperty('content') if(!isContent) return; const newData :iChat = { content: data.content, formMe : false, messageId: data.msgId } callback(newData); }) } // 发送消息 sendMsg(data : string) { var jsonObject = {userName: this.clientid, message: data} this.socket.emit('c_channel' , jsonObject); }}

方案2.采用SSE[1](Server-Sent Events)优化

# listernpublic void onEvent(EventSource eventSource, String id, String type, String data) {    log.info("OpenAI返回数据:{}", data);    if (data.equals("[DONE]")) {        log.info("OpenAI返回数据结束了");        sseEmitter.send(SseEmitter.event()                .id("[DONE]")                .data("[DONE]")                .reconnectTime(3000));        return;    }    ObjectMapper mapper = new ObjectMapper();    ChatCompletionResponse completionResponse = mapper.readValue(data, ChatCompletionResponse.class); // 读取Json    sseEmitter.send(SseEmitter.event()            .id(completionResponse.getId())            .data(completionResponse.getChoices().get(0).getDelta())            .reconnectTime(3000));}# Controllerpublic SseEmitter chat(@RequestParam("message") String msg, @RequestHeader Map headers) throws IOException {    //默认30秒超时,设置为0L则永不超时    SseEmitter sseEmitter = new SseEmitter(0l);    String uid = headers.get("uid");    if (StrUtil.isBlank(uid)) {        throw new BaseException(CommonError.SYS_ERROR);    }    log.info("msg: ["+msg+"], uuid:[" +uid+"]");    String messageContext = (String) LocalCache.CACHE.get(uid);    List messages = new ArrayList<>();    if (StrUtil.isNotBlank(messageContext)) {        messages = JSONUtil.toList(messageContext, Message.class);        if (messages.size() >= 10) {            messages = messages.subList(1, 10);        }        Message currentMessage = Message.builder().content(msg).role(Message.Role.USER).build();        messages.add(currentMessage);    } else {        Message currentMessage = Message.builder().content(msg).role(Message.Role.USER).build();        messages.add(currentMessage);    }    sseEmitter.send(SseEmitter.event().id(uid).name("连接成功!!!!").data(LocalDateTime.now()).reconnectTime(3000));    sseEmitter.onCompletion(() -> {        log.info(LocalDateTime.now() + ", uid#" + uid + ", on completion");    });    sseEmitter.onTimeout(() -> log.info(LocalDateTime.now() + ", uid#" + uid + ", on timeout#" + sseEmitter.getTimeout()));    sseEmitter.onError(            throwable -> {                try {                    log.info(LocalDateTime.now() + ", uid#" + uid + ", on error#" + throwable.toString());                    sseEmitter.send(SseEmitter.event().id(uid).name("发生异常!").data(throwable.getMessage()).reconnectTime(3000));                } catch (IOException e) {                    e.printStackTrace();                }            }    );    OpenAIEventSourceListener openAIEventSourceListener = new OpenAIEventSourceListener(sseEmitter);    openAiStreamClient.streamChatCompletion(messages, openAIEventSourceListener);    LocalCache.CACHE.put(uid, JSONUtil.toJsonStr(messages), LocalCache.TIMEOUT);    return sseEmitter;
//  js Clientlet uuid_str = uuid();// const eventSource = new EventSource('http://localhost:8000/chat?message=' + messageElement.value);const eventSource = new EventSourcePolyfill('/chat?message=' + messageElement.value, {    headers: {        'uid': uid    }});eventSource.onopen = (event) => {    console.log("onopen", event.readyState, event.target);    sse = event.target;    //新增问题框    chat.innerHTML += '' + messageElement.value + '';    messageElement.value = null    //新增答案框    chat.innerHTML += '';};eventSource.onmessage = (event) => {    if (event.data == "[DONE]") {        text = '';        if (sse) {            sse.close();        }        return;    }    let json_data = JSON.parse(event.data)    if (json_data.content == null || json_data.content == 'null') {        text = '';        return;    }    text = text + json_data.content;    setText(text, uuid_str)
};eventSource.onerror = (event) => { console.log("onerror", event); alert("服务异常请重试!") if (event.readyState === EventSource.CLOSED) { console.log('connection is closed'); } else { console.log("Error occured", event); } event.target.close();};eventSource.addEventListener("customEventName", (event) => { console.log("Message id is " + event.lastEventId);});

五、架构搭建

代码的演进已经达到了优化,还有网络的优化,毕竟现在还得靠魔法,所以我整理了服务架构,不再使用魔法。

最后,本文介绍了如何全流程使用ChatGPT,在实际应用中,需要根据需求进一步调整代码逻辑,但是整体架构都是这样的。希望能帮助开发者快速构建自己的应用。

希望大家给个点赞加关注!不懂的欢迎留言提问!欢迎关注后记Prompt笔记

转载:ChatGPT API 技巧教程 (qq.com)

赞(0) 打赏
未经允许不得转载:AI爱好者 » ChatGPT API 技巧教程

评论 抢沙发

欢迎来到AI爱好者

我们旨在打造一个最具实力的中文AI交流社区平台,致力于为所有AI爱好者,创业者和使用者提供优质服务. 我们的宗旨是为广大用户提供免费解决方案,您可以通过问答形式提出与AI相关的任何问题.

AI社区AI工具

安全服务战略合作伙伴:麒麟盾 SCDN

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续提供更多优质内容,让我们一起创建更加美好的网络世界!

微信扫一扫打赏

登录

找回密码

注册