前言
这是本人做的第一个项目。发此文特以记录在开发过程中的思路和踩过的坑。做法和思路不一定正确,希望如果有大佬看到了不足之处给与改正。欢迎有任何问题向我私信。
本功能的最终展示形态是通过预设好的模型,通过输入特定的关键词,向chatGPT提问并且获得返回结果。所有的客户端操作都会在网页上进行。
如果要转载,和我留言即可。
需求分析
- 客户端操作在网页上进行,那么这必然是一个web项目。
- 包含注册服务器、注册域名、服务器部署。
- 因为本人希望服务器用linux系统,又懒的在自己电脑上安装linux虚拟机。所以采用java开发,毕竟好部署。
- 需要连接到chatGPT
- 包含proxy部署、secret key获取、阅读api文档
- 开发进程
- 第零阶段,前期准备
- vpn、阿里云服务器、openai账号
- 第一阶段,基本开发。
- 1.1、将一个能响应请求的服务器部署到localhost
- 1.2、将该服务器部署到云服务器上
- 第二阶段,api连接
- 2.1、学会如何去调用api,成功去调用一个国内的api
- 2.2、加载proxy并访问该国内的api
- 2.3、以代理为基础,使用官方示范代码curl通chatGpt
- 2.4、调用chatGpt的api
- 第三阶段,测试与上线
- 3.1、本地调通
- 3.2、部署到云服务器上调通
- 第零阶段,前期准备
实操步骤
- 0:前期准备
- 关于飞机场的准备,我花了不少时间按照youtube上的教程搭建了一个海外服务器作为海外的代理站点。但是实际应用中,发现了如下几个问题
- 延迟高。可能是服务器选的比较拉,自己搞下来发现有将近800的ping。
- 防封使用的ws传输协议。该协议如果使用的话比较麻烦,毕竟okhttp只支持socks和http。要使用ws的话比较麻烦。
- 成本不划算。比使用第三方的飞机场要贵。
- 最后我使用了第三方。在linux上部署了clash,基于clash给出的端口进行proxy。即在开启clash服务的情况下(clash for windows 或是在linux上用clash core)。如何在服务器上部署clash的教程还是蛮多的。知乎和youtube上都有。
- 关于openai和阿里云服务器。这俩没啥好说的,网上教程多得是。
- 关于飞机场的准备,我花了不少时间按照youtube上的教程搭建了一个海外服务器作为海外的代理站点。但是实际应用中,发现了如下几个问题
- 1.1:将一个能响应请求的服务器部署到localhost
- 这里我采用的方法是thymleaf写前端网页。
- 网上关于thymleaf的教程很多了。
- 我在此列出困扰了我很多天的问题。
- 1、我发现通过输入url可以顺利的打开网页,但是通过点击的方式无法打开。
- 2、get请求发现url发生了变化,但是地址和form中指定的名字不一样
- 最后发现是目标网页(包括主页)放在了resource/public和resource/static文件夹下。放在这两个文件夹下是无法通过contriller的。
- 我最后部署的项目中,所有的网页资源都放在了template文件夹下。所有的网页都通过controller进行跳转。问题解决。
- 这里我采用的方法是thymleaf写前端网页。
- 1.2:将该服务器部署到云服务器上
- 这里搞了个阿里云的云服务器,当然是试用的免费的
- 我是使用的ubantu系统。用宝塔进行的安装。非常简单方便。
- 这里我踩过的坑是没有防火墙放行。这个要记得设置。如果用宝塔的话,也需要放行宝塔中的安全组。
- 2.1:学会如何去调用api,成功去调用一个国内的api
- 调用api的行为,可以去引入okhttp的类库。他本身有比较丰富的代码。
- 如果是第一次调用不知道怎么搞,推荐可以搞个飞书账号,飞书自带api调试台,还到右java-okhttp的示范代码。加上又是国内接口,也是免费。对于学习来说非常不错。
- 尽量不要使用sdk。还是用http连接更能体会到一些东西,sdk太方便了反而学到的比较少。
- 2.2:加载proxy并访问该国内的api
- 这个步骤其实卡了我好久。其实有两种方式对它进行实现。
- 第一个是通过设置系统变量。在业务逻辑中,建立client之前写好即可。
-
System.setProperty("http.proxyHost", "127.0.0.1"); System.setProperty("http.proxyPort", "7890"); System.setProperty("https.proxyHost", "127.0.0.1"); System.setProperty("https.proxyPort", "7890");
-
- 第二个是通过在okhttp中编辑client。不过我觉得还是第一个方便。
- 当然,如果对proxy质量不确定的话。有个工具是通过钉钉的电脑端。上面有个按钮可以检测代理。
- 我其实一开始的时候,是想在不安装clash的情况下,通过指定的ip和端口的方式进行访问的。但是我的调试屡屡失败(因为用的是ws协议,并不是http或是socks。这个设置起来坑还是蛮多的)。
- 最后还是换成了依赖clash提供的端口的方法。它的缺点是需要在linux上部署。这个部署其实还蛮麻烦的。不过好在服务器不用经常重启,部署一次就完事了。(我每次更新会直接在宝塔中重启项目,宝塔还是挺方便的,目前没出过啥问题)
- 2.3:以代理为基础,使用官方示范代码curl通chatGpt
- 其实这一步就是用终端代理的方法进行试错。
- 需要一个终端。我是使用的git。当然cmd也可以。注意这一步其实也要在服务器上进行试验的。
- 第一步需要设置代理。如果使用cmd的话,好像不能用export,用set吧
-
export http_proxy = http://127.0.0.1:1080 export https_proxy = http://127.0.0.1:1080
- 第二步输入测试代码:注意其中要填上自己的secret key
-
curl https://api.openai/v1/chat/completions -H 'Content-Type: application/json' -H 'Authorization: Bearer XXXXXXX' -d '{ "model": "gpt-3.5-turbo", "messages": [{"role": "user", "content": "This is a test"}], "temperature": 0.7 }'
-
当然如果这个curl不通,可以尝试一下curl一下谷歌看看。因为openai那边服务器确实有点一言难尽的。不过此时就要提个心眼。别代理的ip被openai封了
-
curl -i www.baidu //这是百度,检验至少能上网 curl -i www.google //这是谷歌,有返回就是有效
-
这一步一定要注意。curl通就行。ping不通很正常不要纠结。用的东西不一样!
-
2.4:调用chatGpt的api
-
这一步花费时间也较长。一开始的时候我是想用okhttp进行连接的。但是连接一直失败一直失败。服务器返回400 bad request。我检查了很多遍都没啥问题。我怀疑是他要求的content项中是一个list而不是json。
-
在花了很长很长时间之后,我放弃了使用okhttp建立连接,转而使用sdk。
-
是的没错。他居然有java的sdk。github地址:GitHub - TheoKanning/openai-java: OpenAI GPT-3 Api Client in Java
-
注意他返回的是一个ChatCompletionChoice的list。把它其中的content里的内容拿出来,就是最后想要的东西啦。
-
-
3.1 本地调通
-
在这个上面我出现了一点问题。就是我发现用户的长请求timeout的比例特别高。自己的访问总是失败。
-
这个问题解决的很快。它的service方法中有一个多态方法是可以填写timeout时间的。
-
直接贴整段代码吧
-
public static String askForResult(String input,Double temperature){ System.setProperty("http.proxyHost", "127.0.0.1"); System.setProperty("http.proxyPort", "7890"); System.setProperty("https.proxyHost", "127.0.0.1"); System.setProperty("https.proxyPort", "7890"); //配置需要输入的格式 List message =new ArrayList<>(0); message.add(new ChatMessage("user",input)); System.out.println("开始处理请求"); //设置timeout时间 Duration timeout = Duration.ofSeconds((long) 180.0); OpenAiService service = new OpenAiService(apiKey,timeout);//加载api key //做一个连接 ChatCompletionRequest request2=ChatCompletionRequest.builder() .model("gpt-3.5-turbo") .temperature(temperature) .messages(message) .build(); //对返回值进行解析(返回初始是一个list。把它拆开取值) List<ChatCompletionChoice> list =service.createChatCompletion(request2).getChoices(); ChatCompletionChoice ccc = list.get(0); String finalAnswer =ccc.getMessage().getContent(); // System.out.println(finalAnswer); System.out.println("返回成功"); return finalAnswer; }
-
-
3.2 部署到云服务器
-
这一步是我觉得最简单的。再吹一遍宝塔。
-
我是使用的ubantu系统,下载了一个clash core并启动。然后修改配置文件,最后布置docker。这个直接在youtube上跟着学就行了。
-
总结
- 实际上有些功能还没有实现,因为我暂时还没有连接与部署数据库。
- 比如说上下文的对话接续,是需要每次回答之后获取返回的对话唯一key,然后在这个key下进行下一个问题的。目前还没有做。
- 比如说对问题的检验。如果是比较笼统的问题需要用比较高的temprature,比较简单的问题需要用比较低的temprature。(如果temprature非常低的话你会看到一个过于正经的ai,正经到可能不能满足你的所有要求,比如至少200字这种)
更多推荐
JAVA SpringBoot部署自己的Chatgpt网站实录
发布评论