1
1
using BotSharp . Abstraction . Evaluations . Models ;
2
2
using BotSharp . Abstraction . Instructs ;
3
3
using BotSharp . Abstraction . Instructs . Models ;
4
+ using BotSharp . Abstraction . Models ;
4
5
5
6
namespace BotSharp . Core . Evaluations . Services ;
6
7
@@ -31,15 +32,19 @@ public async Task<EvaluationResult> Evaluate(string conversationId, EvaluationRe
31
32
return result ;
32
33
}
33
34
34
- var generatedConvId = await SimulateConversation ( initMessage , refDialogContents , request ) ;
35
+ var initialStates = GetInitialStates ( conversationId ) ;
36
+ var generatedConvId = await SimulateConversation ( initMessage , refDialogContents , request , initialStates ) ;
37
+ var metricResult = await EvaluateMetrics ( generatedConvId , refDialogContents , request ) ;
35
38
36
39
return new EvaluationResult
37
40
{
38
- GeneratedConversationId = generatedConvId
41
+ GeneratedConversationId = generatedConvId ,
42
+ MetricResult = metricResult
39
43
} ;
40
44
}
41
45
42
- private async Task < string > SimulateConversation ( string initMessage , IEnumerable < string > refDialogs , EvaluationRequest request )
46
+ private async Task < string > SimulateConversation ( string initMessage , IEnumerable < string > refDialogs ,
47
+ EvaluationRequest request , IEnumerable < MessageState > ? states = null )
43
48
{
44
49
var count = 0 ;
45
50
var duplicateCount = 0 ;
@@ -49,20 +54,22 @@ private async Task<string> SimulateConversation(string initMessage, IEnumerable<
49
54
var prevUserMsg = string . Empty ;
50
55
var curBotMsg = string . Empty ;
51
56
var prevBotMsg = string . Empty ;
57
+ var initialStates = states ? . ToList ( ) ?? [ ] ;
52
58
53
59
var storage = _services . GetRequiredService < IConversationStorage > ( ) ;
54
60
var agentService = _services . GetRequiredService < IAgentService > ( ) ;
55
61
var instructService = _services . GetRequiredService < IInstructService > ( ) ;
56
62
57
63
var query = "Please see yourself as a user and follow the instruction to generate a message." ;
58
64
var targetAgentId = request . AgentId ;
59
- var evaluatorAgent = await agentService . GetAgent ( BuiltInAgentId . Evaluator ) ;
60
- var simulatorPrompt = evaluatorAgent . Templates . FirstOrDefault ( x => x . Name == "instruction.simulator" ) ? . Content ?? string . Empty ;
65
+ var evaluator = await agentService . GetAgent ( BuiltInAgentId . Evaluator ) ;
66
+ var simulatorPrompt = evaluator . Templates . FirstOrDefault ( x => x . Name == "instruction.simulator" ) ? . Content ?? string . Empty ;
61
67
62
68
while ( true )
63
69
{
64
70
curDialogs . Add ( $ "{ AgentRole . User } : { curUserMsg } ") ;
65
- var dialog = await SendMessage ( targetAgentId , convId , curUserMsg ) ;
71
+ var dialog = await SendMessage ( targetAgentId , convId , curUserMsg , states : initialStates ) ;
72
+ initialStates = [ ] ;
66
73
67
74
prevBotMsg = curBotMsg ;
68
75
curBotMsg = dialog ? . RichContent ? . Message ? . Text ?? dialog ? . Content ?? string . Empty ;
@@ -80,30 +87,20 @@ private async Task<string> SimulateConversation(string initMessage, IEnumerable<
80
87
{
81
88
{ "ref_conversation" , refDialogs } ,
82
89
{ "cur_conversation" , curDialogs } ,
83
- { "additional_instruction" , request . AdditionalInstruction } ,
84
- { "stop_criteria" , request . StopCriteria }
90
+ { "additional_instruction" , request . Chat . AdditionalInstruction } ,
91
+ { "stop_criteria" , request . Chat . StopCriteria }
85
92
}
86
93
} ) ;
87
94
88
95
_logger . LogInformation ( $ "Generated message: { result ? . GeneratedMessage } , stop: { result ? . Stop } , reason: { result ? . Reason } ") ;
89
96
90
- if ( count > request . MaxRounds || ( result != null && result . Stop ) )
97
+ if ( count > request . Chat . MaxRounds || ( result != null && result . Stop ) )
91
98
{
92
99
break ;
93
100
}
94
101
95
-
96
- if ( curUserMsg . IsEqualTo ( prevUserMsg ) || curBotMsg . IsEqualTo ( prevBotMsg ) )
97
- {
98
- duplicateCount ++ ;
99
- }
100
- else
101
- {
102
- duplicateCount = 0 ;
103
- }
104
-
105
-
106
- if ( duplicateCount >= request . DuplicateLimit )
102
+ duplicateCount = curBotMsg . IsEqualTo ( prevBotMsg ) ? duplicateCount + 1 : 0 ;
103
+ if ( duplicateCount >= request . Chat . DuplicateLimit )
107
104
{
108
105
break ;
109
106
}
@@ -115,6 +112,38 @@ private async Task<string> SimulateConversation(string initMessage, IEnumerable<
115
112
return convId ;
116
113
}
117
114
115
+
116
+ private async Task < string ? > EvaluateMetrics ( string curConversationId , IEnumerable < string > refDialogs , EvaluationRequest request )
117
+ {
118
+ var storage = _services . GetRequiredService < IConversationStorage > ( ) ;
119
+ var agentService = _services . GetRequiredService < IAgentService > ( ) ;
120
+ var instructService = _services . GetRequiredService < IInstructService > ( ) ;
121
+
122
+ var curDialogs = storage . GetDialogs ( curConversationId ) ;
123
+ var curDialogContents = GetConversationContent ( curDialogs ) ;
124
+
125
+ var evaluator = await agentService . GetAgent ( BuiltInAgentId . Evaluator ) ;
126
+ var metricPrompt = evaluator . Templates . FirstOrDefault ( x => x . Name == "instruction.metrics" ) ? . Content ?? string . Empty ;
127
+ var query = "Please follow the instruction for evaluation." ;
128
+
129
+ var result = await instructService . Instruct < JsonDocument > ( metricPrompt , BuiltInAgentId . Evaluator ,
130
+ new InstructOptions
131
+ {
132
+ Provider = request . Provider ,
133
+ Model = request . Model ,
134
+ Message = query ,
135
+ Data = new Dictionary < string , object >
136
+ {
137
+ { "ref_conversation" , refDialogs } ,
138
+ { "cur_conversation" , curDialogs } ,
139
+ { "additional_instruction" , request . Metric . AdditionalInstruction } ,
140
+ { "metrics" , request . Metric . Metrics }
141
+ }
142
+ } ) ;
143
+
144
+ return result != null ? result . RootElement . GetRawText ( ) : null ;
145
+ }
146
+
118
147
private IEnumerable < string > GetConversationContent ( IEnumerable < RoleDialogModel > dialogs )
119
148
{
120
149
var contents = new List < string > ( ) ;
@@ -134,4 +163,30 @@ private IEnumerable<string> GetConversationContent(IEnumerable<RoleDialogModel>
134
163
135
164
return contents ;
136
165
}
166
+
167
+ private IEnumerable < MessageState > GetInitialStates ( string conversationId )
168
+ {
169
+ if ( string . IsNullOrWhiteSpace ( conversationId ) )
170
+ {
171
+ return [ ] ;
172
+ }
173
+
174
+ var db = _services . GetRequiredService < IBotSharpRepository > ( ) ;
175
+ var states = db . GetConversationStates ( conversationId ) ;
176
+ var initialStates = new List < MessageState > ( ) ;
177
+
178
+ foreach ( var state in states )
179
+ {
180
+ var value = state . Value ? . Values ? . FirstOrDefault ( x => string . IsNullOrEmpty ( x . MessageId ) ) ;
181
+
182
+ if ( string . IsNullOrEmpty ( value ? . Data ) )
183
+ {
184
+ continue ;
185
+ }
186
+
187
+ initialStates . Add ( new MessageState ( state . Key , value . Data , value . ActiveRounds ) ) ;
188
+ }
189
+
190
+ return initialStates ;
191
+ }
137
192
}
0 commit comments