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数据结构,它可以存储不重复的元素,并且可以随机返回一个元素。这样,我们就可以实现密钥的随机轮换功能。