【.Net/C#之ChatGPT开发系列】四、ChatGPT多KEY动态轮询,自动删除无效KEY

ChatGPT是一种基于Token数量计费的语言模型,它可以生成高质量的文本。然而,每个新账号只有一个有限的初始配额,用完后就需要付费才能继续使用。为此,我们可能存在使用多KEY的情况,并在每个KEY达到额度上限后,自动将其删除。那么,我们应该如何实现这个功能呢?还请大家扫个小关。👇

ChatGPT多KEY轮询

为了实现多KEY管理,我们通常需要把所有密钥保存在数据库中,但为了简化演示,这里我使用Redis来进行存储和管理多个KEY。同样,我将重新创建一个名为ChatGPT.Demo4的项目,代码和ChatGPT.Demo3相同。

一、Redis密钥管理

1、定义IChatGPTKeyService接口

在根目录下,创建一个名为Extensions的文件夹,然后右键点击它,新建一个IChatGPTKeyService.cs接口文件,并写入以下代码:

public interface IChatGPTKeyService
{
    //初始话密钥
    public Task InitAsync();

    //随机获取密钥KEY
    public Task<string> GetRandomAsync();

    //获取所有密钥
    Task<string[]> GetAllAsync();

    //移除密钥
    Task RemoveAsync(string apiKey);
}

InitAsync方法用以初始化密钥,GetRandomAsync方法用于随机读取一个密钥,GetAllAsync方法用于读取所有密钥,RemoveAsync方法用于删除指定密钥。

2、实现IChatGPTKeyService服务

安装StackExchange.Redis库,这是一个用于访问和操作Redis数据库的.NET客户端。

PM> Install-Package StackExchange.Redis

右键点击Extensions文件夹,新建一个ChatGPTKeyService.cs文件,并在文件中写入以下代码:

using StackExchange.Redis;

public class ChatGPTKeyService : IChatGPTKeyService
{
    private ConnectionMultiplexer? _connection;
    private IDatabase? _cache;
    private readonly string _configuration;
    private const string _redisKey = "ChatGPTKey";

    public ChatGPTKeyService(string configuration)
    {
        _configuration = configuration;
    }

    private async Task ConnectAsync()
    {
        if (_cache != null) return;
        _connection = await ConnectionMultiplexer.ConnectAsync(_configuration);
        _cache = _connection.GetDatabase();
    }
    public async Task InitAsync()
    {
        await ConnectAsync();
        //使用Set对象存储密钥
        await _cache!.SetAddAsync(_redisKey, new RedisValue[] {
        "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1",
        "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx2",
        });
    }
    public async Task<string> GetRandomAsync()
    {
        await ConnectAsync();
        //使用Set随机返回一个密钥
        var redisValue = await _cache!.SetRandomMemberAsync(_redisKey);
        return redisValue.ToString();
    }

    public async Task<string[]> GetAllAsync()
    {
        await ConnectAsync();
        //读取所有密钥
        var redisValues = await _cache!.SetMembersAsync(_redisKey);
        return redisValues.Select(m => m.ToString()).ToArray();
    }

    public async Task RemoveAsync(string apiKey)
    {
        await ConnectAsync();
        await _cache!.SetRemoveAsync(_redisKey, apiKey);
    }
}

为了保存KEY,我们选择使用Redis的Set数据结构,它可以存储不重复的元素,并且可以随机返回一个元素。这样,我们就可以实现密钥的随机轮换功能。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

惑豁猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值