基于 ChatGpt Api 开发的微信小程序

上周花了点时间开发一个微信小程序,接入了ChatGpt接口。实现了简单的上下文对话。



核心代码

  /**
     * 请求openai接口
     * @param int $selType
     * @param $params
     * @return mixed
     * @throws GuzzleException|ApiException
     * @throws Exception
     */
    protected function sendRequest(int $selType, $params)  :mixed
    {
        // 每个账号最多五个key,所以可以做相关轮训自增次数 防止限流(未尝试过是否有效 仅是个人认为的)。
        $this->keys   = ApiKey::getKeys();
        if(!$this->keys) {
            throw new Exception('未配置Api Key');
        }
        // 代理地址
        $proxyUrl = config('chatgpt.proxy_url');
        // 本地代理 还是第三方代理(云函数提供的地址)
        if (config('chatgpt.proxy_model') === 'vpn') {
            $proxy = config('chatgpt.proxy');
            $options = [
                'verify' => false,
                'proxy' => $proxy, //本地或者服务器代理地址
                'timeout' => 50
            ];
        } else {
            $options = [
                'verify' => false,
                'timeout' => 50
            ];
        }
        $response = (new Client($options))->request('POST', "$proxyUrl/v1/chat/completions", [
            'headers' => [
                'Content-Type' => 'application/json',
                'Authorization' => "Bearer $this->keys",
            ],
            'body' => json_encode([
                'model'             => config('chatgpt.model'),
                'messages'          => $this->getMessages($selType,$params),
                'stop'              => '\n',
            ], JSON_UNESCAPED_UNICODE)
        ]);

        switch ($response->getStatusCode()) {
            case 200:
                return json_decode($response->getBody()->getContents(), true);
            case 443:
                Log::channel('chat')->info('服务不可用-443',[
                    'params' => $response
                ]);
                throw new ApiException('服务不可用');
            default:
                Log::channel('chat')->info('服务不可用-网络异常',[
                    'params' => $response
                ]);
                throw new ApiException('网络异常');
        }
    }

    /**
     * 组装消息内容
     * @param int $selType
     * @param $params
     * @return array[]
     */
    protected function getMessages(int $selType,$params) :array
    {
        return match ($selType) {
            ChatEnum::MESSAGE_TYPE_TEXT => [
                [
                    'role' => 'user',
                    'content' => $params['message']
                ]
            ],
            ChatEnum::MESSAGE_TYPE_DIALOGUE => is_array($params['examples_context']) ? $params['examples_context'] : [],
            default => [],
        };
    }

    /**
     * 获取对话模式以及消息
     * @param string $message
     * @return array
     */
    protected function getContextMessage(string $message): array
    {
        $msg = [];
        $startTime = time() - 60 * 10;
        $endTime = time();

        $data = ChatMessage::query()
            ->where('user_id', $this->userId)
            ->where('add_time', '>', $startTime)
            ->where('add_time', '<', $endTime)
            ->limit(6)      // 查询最多6条上下文 进行分析。
            ->orderBy('add_time')
            ->select()
            ->get();
        if ($data->isEmpty()) {
            return [$message, ChatEnum::MESSAGE_TYPE_TEXT];
        } else {
            $data->each(function ($value) use (&$msg) {
                if ($value->is_question == ChatEnum::IS_QUESTION_NO) {
                    $msg[] = [
                        'role' => 'user',
                        'content' => $value->message
                    ];
                } else {
                    $msg[] = [
                        'role' => 'system',
                        'content' => $value->message
                    ];
                }
            });
            $msg[] = [
                'role' => 'user',
                'content' => $message
            ];
            return [$msg, ChatEnum::MESSAGE_TYPE_DIALOGUE];
        }
    }

关于如何注册chatgpt就不做相关教程了,网上教程太多了。尽量使用google邮箱注册,同时因为国内原因调用接口需要代理,如果部署服务器尽量使用海外服务器或者各大云厂商提供的云函数服务。

最后

因为接口调用并不是免费的,所以每个人都会有30次数限制(小程序)。同时openai对每个账号提供了18美刀接口的免费额度。

感谢PS& 如何自己开发

:point_right: openai接口文档

分享 小程序二维码

本作品采用《CC 协议》,转载必须注明作者和本文链接
不成大牛,不改個簽
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 10

openai-php/laravel 集成起来其实并没有那么麻烦,麻烦的是 apikey 和 代理服务器的获取 是有一定的门槛的。

1年前 评论
Latent (楼主) 1年前
Diudiuuuu 1年前

门槛不高魔法一下才9.9一个月,挺好用

1年前 评论
Latent (楼主) 1年前

file

现在很多人写代码都直接用ai了

1年前 评论

每个账号最多五个key是什么意思?

1年前 评论

学习了,谢谢

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!