一、理论概述
ChatGpt接口目前只能在国外互联网环境中使用,国内想要使用相关服务的话可以寻求代理,在这里使用的是一台国外服务器安装Nginx服务进行相关代理。
二、环境要求
- 一台拥有公网IP的国外服务器
- 一个域名及免费ssl证书(可在腾讯云免费申请ssl证书)
- 一个ChatGpt账号及相关的APIkey
以上就是所有需要用到的环境,请注意,如要使用接口还需要充值API额度。除此之外还需要将你的域名解析到公网IP上。完成准备工作后进行以下操作。
三、Nginx转发
- 在服务器中安装nginx,这里使用的是docker服务,根据以往博文中可自行安装Docker服务。
#服务器中新建一个nginx目录,下级目录新建conf.d、logs、ssl三个目录
mkdir -p nginx/conf.d
mkdir -p nginx/logs
mkdir -p nginx/ssl
#在nginx目录中新建start.sh脚本
vim start.sh
docker stop nginx
docker rm nginx
docker run -p 80:80 -p 443:443 --name nginx --net=host --restart=always --privileged=true \
-v `pwd`/conf.d/:/etc/nginx/conf.d \
-v `pwd`/logs/:/var/log/nginx \
-v `pwd`/ssl/:/var/ssl \
-e TZ="Asia/Shanghai" \
nginx:latest
#输入 :wq 保存后授权并执行即可
chmod a+x start.sh
./start.sh
- 将域名ssl证书放置在ssl目录下后,编辑nginx转发代理,执行
start.sh
脚本重启nginx服务。
vim conf.d/gpt.conf
#填入域名信息
server {
listen 443 ssl;
server_name 域名;
ssl_certificate /var/ssl/域名.crt; #配置证书位置
ssl_certificate_key /var/ssl/域名.key; #配置秘钥位置】
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1.2;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
underscores_in_headers on;
charset utf-8;
location /v1/ {
proxy_ssl_server_name on;
proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
proxy_pass https://api.openai.com;
}
}
以上便完成了针对chatgpt接口地址 api.openai.com
的转发工作,转发后的地址既是你的域名。
四、Java实例调用实现多轮对话
- 新建Maven项目ChatGPTClient,在
pom.xml
中添加后续用到的依赖,重构后拉取。
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.3</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version> <!-- 使用最新的可用版本 -->
</dependency>
- java代码
import okhttp3.*;
import com.google.gson.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class ChatGPTClient {
private final String apiKey;
private final OkHttpClient client;
private final List<Message> messages;
private final Gson gson;
private int tokenCount = 0;
private int inputTokenCount = 0;
private int outputTokenCount = 0;
public ChatGPTClient(String apiKey) {
this.apiKey = apiKey;
this.client = new OkHttpClient();
this.messages = new ArrayList<>();
this.gson = new Gson();
}
public String sendMessage(String message) throws IOException {
updateTokenCount(message, true);
messages.add(new Message("system", "user", message));
//model模型选择可以有gpt-3.5-turbo、gpt-4、gpt-4-turbo价格以此类推
RequestBody body = RequestBody.create(
MediaType.get("application/json; charset=utf-8"),
"{\"model\": \"gpt-3.5-turbo\", \"messages\": " + gson.toJson(messages) + "}"
);
Request request = new Request.Builder()
.url("https://你的域名地址/v1/chat/completions")
.addHeader("Authorization", "Bearer " + this.apiKey)
.addHeader("Content-Type", "application/json")
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
JsonObject respJson = JsonParser.parseString(response.body().string()).getAsJsonObject();
JsonArray choices = respJson.getAsJsonArray("choices");
if (choices != null && choices.size() > 0) {
JsonObject firstChoice = choices.get(0).getAsJsonObject();
String aiResponse = firstChoice.getAsJsonObject("message").get("content").getAsString();
updateTokenCount(aiResponse, false);
messages.add(new Message("system", "assistant", aiResponse));
System.out.println("输入的 Token 数: " + inputTokenCount);
System.out.println("输出的 Token 数: " + outputTokenCount);
System.out.println("总使用的 Token 数: " + tokenCount);
return aiResponse;
}
}
return "无法获取响应。";
}
private void updateTokenCount(String text, boolean isInput) {
int count = 0;
for (char c : text.toCharArray()) {
count += (String.valueOf(c).matches("[\\u0000-\\u00ff]") ? 1 : 4);
}
int tokens = (int) Math.ceil(count / 4.0);
tokenCount += tokens;
if (isInput) {
inputTokenCount += tokens;
} else {
outputTokenCount += tokens;
}
}
private static class Message {
String role;
String content;
public Message(String type, String role, String content) {
this.role = role;
this.content = content;
}
}
public static void main(String[] args) throws IOException {
ChatGPTClient client = new ChatGPTClient("YOUR-API-KEY");
Scanner scanner = new Scanner(System.in, "UTF-8");
String input;
while (true) {
System.out.print("输入消息(输入 'bye' 结束对话): ");
input = scanner.nextLine();
if ("bye".equalsIgnoreCase(input)) {
break;
}
String response = client.sendMessage(input);
System.out.println("ChatGPT 回应: " + response);
}
}
}
在以上代码中,增加了每次对话后所使用的token值,以便查询核对接口使用费。可在官网查询相关定价。