Skip to content

Commit 721aaa7

Browse files
authored
Merge pull request #736 from iceljc/features/add-evaluation
refine stop condition
2 parents bb3e293 + 2836cce commit 721aaa7

File tree

4 files changed

+51
-28
lines changed

4 files changed

+51
-28
lines changed

src/Infrastructure/BotSharp.Abstraction/Evaluations/Models/EvaluationRequest.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,4 @@ public class EvaluationRequest : LlmBaseRequest
1212

1313
[JsonPropertyName("max_rounds")]
1414
public int MaxRounds { get; set; } = 20;
15-
16-
[JsonPropertyName("ref_conversation_id")]
17-
public string RefConversationId { get; set; } = null!;
1815
}

src/Infrastructure/BotSharp.Abstraction/Evaluations/Models/SimulationResult.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ public class SimulationResult
55
[JsonPropertyName("generated_message")]
66
public string GeneratedMessage { get; set; }
77

8-
[JsonPropertyName("stop")]
8+
[JsonPropertyName("stop_conversation")]
99
public bool Stop { get; set; }
1010

1111
[JsonPropertyName("reason")]

src/Infrastructure/BotSharp.Core/Evaluations/Services/EvaluatingService.Evaluate.cs

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,28 @@ public partial class EvaluatingService
88
{
99
public async Task<EvaluationResult> Evaluate(string conversationId, EvaluationRequest request)
1010
{
11+
var result = new EvaluationResult();
12+
if (string.IsNullOrEmpty(conversationId))
13+
{
14+
return result;
15+
}
16+
1117
var storage = _services.GetRequiredService<IConversationStorage>();
12-
var refDialogs = storage.GetDialogs(request.RefConversationId);
13-
var refDialogContents = GetConversationContent(refDialogs);
18+
var refDialogs = storage.GetDialogs(conversationId);
19+
20+
if (refDialogs.IsNullOrEmpty())
21+
{
22+
return result;
23+
}
1424

25+
var refDialogContents = GetConversationContent(refDialogs);
1526
var initDialog = refDialogs.FirstOrDefault(x => x.Role == AgentRole.User);
16-
var initMessage = initDialog?.RichContent?.Message?.Text ?? initDialog?.Content ?? "Hello";
27+
var initMessage = initDialog?.RichContent?.Message?.Text ?? initDialog?.Content;
28+
29+
if (string.IsNullOrWhiteSpace(initMessage))
30+
{
31+
return result;
32+
}
1733

1834
var generatedConvId = await SimulateConversation(initMessage, refDialogContents, request);
1935

@@ -23,28 +39,34 @@ public async Task<EvaluationResult> Evaluate(string conversationId, EvaluationRe
2339
};
2440
}
2541

26-
private async Task<string> SimulateConversation(string initMessage, IEnumerable<string> refConversation, EvaluationRequest request)
42+
private async Task<string> SimulateConversation(string initMessage, IEnumerable<string> refDialogs, EvaluationRequest request)
2743
{
2844
var count = 0;
29-
var curConvId = Guid.NewGuid().ToString();
30-
var curConversation = new List<string>();
31-
var curMessage = initMessage;
45+
var convId = Guid.NewGuid().ToString();
46+
var curDialogs = new List<string>();
47+
var curUserMsg = initMessage;
48+
var prevUserMsg = string.Empty;
49+
var curBotMsg = string.Empty;
50+
var prevBotMsg = string.Empty;
3251

3352
var storage = _services.GetRequiredService<IConversationStorage>();
3453
var agentService = _services.GetRequiredService<IAgentService>();
3554
var instructService = _services.GetRequiredService<IInstructService>();
3655

37-
var query = "Please take yourself as a user and follow the instruction to generate a message in the user tone.";
56+
var query = "Please see yourself as a user and follow the instruction to generate a message.";
3857
var targetAgentId = request.AgentId;
3958
var evaluatorAgent = await agentService.GetAgent(BuiltInAgentId.Evaluator);
4059
var simulatorPrompt = evaluatorAgent.Templates.FirstOrDefault(x => x.Name == "instruction.simulator")?.Content ?? string.Empty;
4160

4261
while (true)
4362
{
44-
curConversation.Add($"{AgentRole.User}: {curMessage}");
45-
var dialog = await SendMessage(targetAgentId, curConvId, curMessage);
46-
var botMessage = dialog?.RichContent?.Message?.Text ?? dialog?.Content ?? string.Empty;
47-
curConversation.Add($"{AgentRole.Assistant}: {botMessage}");
63+
curDialogs.Add($"{AgentRole.User}: {curUserMsg}");
64+
var dialog = await SendMessage(targetAgentId, convId, curUserMsg);
65+
66+
prevBotMsg = curBotMsg;
67+
curBotMsg = dialog?.RichContent?.Message?.Text ?? dialog?.Content ?? string.Empty;
68+
curDialogs.Add($"{AgentRole.Assistant}: {curBotMsg}");
69+
4870
count++;
4971

5072
var result = await instructService.Instruct<SimulationResult>(simulatorPrompt, BuiltInAgentId.Evaluator,
@@ -55,20 +77,24 @@ private async Task<string> SimulateConversation(string initMessage, IEnumerable<
5577
Message = query,
5678
Data = new Dictionary<string, object>
5779
{
58-
{ "ref_conversation", refConversation },
59-
{ "cur_conversation", curConversation },
80+
{ "ref_conversation", refDialogs },
81+
{ "cur_conversation", curDialogs },
6082
}
6183
});
6284

63-
if (count > request.MaxRounds || (result != null && result.Stop))
85+
_logger.LogInformation($"Generated message: {result?.GeneratedMessage}, stop: {result?.Stop}, reason: {result?.Reason}");
86+
87+
if (curUserMsg.IsEqualTo(prevUserMsg) || curBotMsg.IsEqualTo(prevBotMsg)
88+
|| count > request.MaxRounds || (result != null && result.Stop))
6489
{
6590
break;
6691
}
6792

68-
curMessage = result?.GeneratedMessage ?? string.Empty;
93+
prevUserMsg = curUserMsg;
94+
curUserMsg = result?.GeneratedMessage ?? string.Empty;
6995
}
7096

71-
return curConvId;
97+
return convId;
7298
}
7399

74100
private IEnumerable<string> GetConversationContent(IEnumerable<RoleDialogModel> dialogs)
@@ -85,7 +111,7 @@ private IEnumerable<string> GetConversationContent(IEnumerable<RoleDialogModel>
85111
role = AgentRole.Assistant;
86112
}
87113

88-
contents.Add($"{role}: {dialog.RichContent?.Message?.Text ?? dialog.Content}");
114+
contents.Add($"{role}: {dialog.RichContent?.Message?.Text ?? dialog.Content ?? string.Empty}");
89115
}
90116

91117
return contents;

src/Infrastructure/BotSharp.Core/data/agents/dfd9b46d-d00c-40af-8a75-3fbdc2b89869/templates/instruction.simulator.liquid

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ You are a conversaton simulator.
22
Please take the content in the [REFERENCE CONVERSATION] section as a reference, and focus on the [ONGOING CONVERSATION] section to generate a message based on the context.
33

44
** You need to take a close look at the content in both [REFERENCE CONVERSATION] and [ONGOING CONVERSATION], and determine whether to generate a text message or stop the ongoing conversation.
5-
** When you generate a message, please assume you as the user and reply as the user perceptive.
6-
** Please do not generate or append messages with similar meaning that you have already mentioned in the [ONGOING CONVERSATION].
7-
** If you see the assistant replies two or more than two similar messages in the [ONGOING CONVERSATION], please stop the [ONGOING CONVERSATION] immediately and turn the "stop" to true in the output json.
5+
** When you generate a message, please assume you are the user and reply in the user perceptive.
6+
** Please do not generate or append a message with similar meaning that you have already mentioned in the [ONGOING CONVERSATION].
7+
** If you see the assistant replies two or more than two similar messages in the [ONGOING CONVERSATION], please stop the conversation immediately.
88
** The output must be in JSON format:
99
{
10-
"generated_message": the generated text message as the user tone,
11-
"stop": a boolean to indicate whether to stop the [ONGOING CONVERSATION],
12-
"reason": the reason why you generate the message or stop the [ONGOING CONVERSATION]
10+
"generated_message": the generated text message using the user tone,
11+
"stop_conversation": the boolean value to indicate whether to stop the conversation,
12+
"reason": the reason why you generate the message or stop the conversation
1313
}
1414

1515

0 commit comments

Comments
 (0)