Conversation rate limit.
This commit is contained in:
parent
f7cbbe84de
commit
fee89ffb96
|
|
@ -51,6 +51,11 @@ public class DialogElement
|
|||
Content = content;
|
||||
RichContent = richContent;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{MetaData.Role}: {Content} [{MetaData.CreateTime}]";
|
||||
}
|
||||
}
|
||||
|
||||
public class DialogMetaData
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ public class ConversationSetting
|
|||
public bool EnableContentLog { get; set; }
|
||||
public bool EnableStateLog { get; set; }
|
||||
public CleanConversationSetting CleanSetting { get; set; }
|
||||
public RateLimitSetting RateLimit { get; set; }
|
||||
}
|
||||
|
||||
public class CleanConversationSetting
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
namespace BotSharp.Abstraction.Conversations.Settings;
|
||||
|
||||
public class RateLimitSetting
|
||||
{
|
||||
public int MaxConversationPerDay { get; set; } = 100;
|
||||
public int MaxInputLengthPerRequest { get; set; } = 256;
|
||||
public int MinTimeSecondsBetweenMessages { get; set; } = 2;
|
||||
}
|
||||
|
|
@ -32,7 +32,7 @@ public interface IRoutingService
|
|||
void ResetRecursiveCounter();
|
||||
Task<bool> InvokeAgent(string agentId, List<RoleDialogModel> dialogs);
|
||||
Task<bool> InvokeFunction(string name, RoleDialogModel message);
|
||||
Task<RoleDialogModel> InstructLoop(RoleDialogModel message);
|
||||
Task<RoleDialogModel> InstructLoop(RoleDialogModel message, List<RoleDialogModel> dialogs);
|
||||
|
||||
/// <summary>
|
||||
/// Talk to a specific Agent directly, bypassing the Router
|
||||
|
|
|
|||
|
|
@ -34,6 +34,9 @@ public partial class ConversationService
|
|||
|
||||
_storage.Append(_conversationId, message);
|
||||
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var dialogs = conv.GetDialogHistory();
|
||||
|
||||
var statistics = _services.GetRequiredService<ITokenStatistics>();
|
||||
var hooks = _services.GetServices<IConversationHook>().ToList();
|
||||
|
||||
|
|
@ -75,7 +78,7 @@ public partial class ConversationService
|
|||
var settings = _services.GetRequiredService<RoutingSettings>();
|
||||
|
||||
response = agent.Type == AgentType.Routing ?
|
||||
await routing.InstructLoop(message) :
|
||||
await routing.InstructLoop(message, dialogs) :
|
||||
await routing.InstructDirect(agent, message);
|
||||
|
||||
routing.ResetRecursiveCounter();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
using BotSharp.Abstraction.Functions;
|
||||
using BotSharp.Abstraction.Repositories.Filters;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
using BotSharp.Abstraction.Routing;
|
||||
|
||||
namespace BotSharp.Core.Routing.Functions;
|
||||
|
||||
|
|
@ -29,12 +27,14 @@ public class FallbackToRouterFn : IFunctionCallback
|
|||
return false;
|
||||
}
|
||||
|
||||
var routing = _services.GetRequiredService<IRoutingContext>();
|
||||
routing.Replace(targetAgent.Id);
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var dialogs = conv.GetDialogHistory();
|
||||
|
||||
var router = _services.GetRequiredService<IRoutingService>();
|
||||
var routing = _services.GetRequiredService<IRoutingService>();
|
||||
routing.Context.Replace(targetAgent.Id);
|
||||
message.CurrentAgentId = targetAgent.Id;
|
||||
var response = await router.InstructLoop(message);
|
||||
|
||||
var response = await routing.InstructLoop(message, dialogs);
|
||||
|
||||
message.Content = response.Content;
|
||||
message.StopCompletion = true;
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ public partial class RoutingService : IRoutingService
|
|||
return response;
|
||||
}
|
||||
|
||||
public async Task<RoleDialogModel> InstructLoop(RoleDialogModel message)
|
||||
public async Task<RoleDialogModel> InstructLoop(RoleDialogModel message, List<RoleDialogModel> dialogs)
|
||||
{
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
_router = await agentService.LoadAgent(message.CurrentAgentId);
|
||||
|
|
@ -77,9 +77,6 @@ public partial class RoutingService : IRoutingService
|
|||
RoleDialogModel response = default;
|
||||
|
||||
var states = _services.GetRequiredService<IConversationStateService>();
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var dialogs = conv.GetDialogHistory();
|
||||
|
||||
var executor = _services.GetRequiredService<IExecutor>();
|
||||
|
||||
var planner = GetPlanner(_router);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ public static class BotSharpLoggerExtensions
|
|||
services.AddScoped<IContentGeneratingHook, CommonContentGeneratingHook>();
|
||||
services.AddScoped<IContentGeneratingHook, TokenStatsConversationHook>();
|
||||
services.AddScoped<IContentGeneratingHook, VerboseLogHook>();
|
||||
services.AddScoped<IConversationHook, RateLimitConversationHook>();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
using BotSharp.Abstraction.Agents.Enums;
|
||||
using BotSharp.Abstraction.Repositories.Filters;
|
||||
using BotSharp.Abstraction.Users;
|
||||
|
||||
namespace BotSharp.Logger.Hooks;
|
||||
|
||||
/// <summary>
|
||||
/// To prevent users from overusing, if the character limit is exceeded or the sending frequency is too fast,
|
||||
/// a prompt message will be returned.
|
||||
/// </summary>
|
||||
public class RateLimitConversationHook : ConversationHookBase
|
||||
{
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly ILogger _logger;
|
||||
public RateLimitConversationHook(IServiceProvider services, ILogger<RateLimitConversationHook> logger)
|
||||
{
|
||||
_services = services;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public override async Task OnMessageReceived(RoleDialogModel message)
|
||||
{
|
||||
var settings = _services.GetRequiredService<ConversationSetting>();
|
||||
var rateLimit = settings.RateLimit;
|
||||
|
||||
// Check max input length
|
||||
var charCount = message.Content.Length;
|
||||
if (charCount > rateLimit.MaxInputLengthPerRequest)
|
||||
{
|
||||
message.Content = $"The number of characters in your message exceeds the system maximum of {rateLimit.MaxInputLengthPerRequest}";
|
||||
message.StopCompletion = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check message sending frequency
|
||||
var userSents = _dialogs.Where(x => x.Role == AgentRole.User)
|
||||
.TakeLast(2).ToList();
|
||||
|
||||
if (userSents.Count > 1)
|
||||
{
|
||||
var seconds = (DateTime.UtcNow - userSents.First().CreatedAt).TotalSeconds;
|
||||
if (seconds < rateLimit.MinTimeSecondsBetweenMessages)
|
||||
{
|
||||
message.Content = "Your message sending frequency exceeds the frequency specified by the system. Please try again later.";
|
||||
message.StopCompletion = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check the number of conversations
|
||||
var user = _services.GetRequiredService<IUserIdentity>();
|
||||
var convService = _services.GetRequiredService<IConversationService>();
|
||||
var results = await convService.GetConversations(new ConversationFilter
|
||||
{
|
||||
UserId = user.Id
|
||||
});
|
||||
|
||||
if (results.Count > rateLimit.MaxConversationPerDay)
|
||||
{
|
||||
message.Content = $"The number of conversations you have exceeds the system maximum of {rateLimit.MaxConversationPerDay}";
|
||||
message.StopCompletion = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -125,6 +125,11 @@
|
|||
"BatchSize": 50,
|
||||
"MessageLimit": 2,
|
||||
"BufferHours": 12
|
||||
},
|
||||
"RateLimit": {
|
||||
"MaxConversationPerDay": 100,
|
||||
"MaxInputLengthPerRequest": 256,
|
||||
"MinTimeSecondsBetweenMessages": 2
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue