@@ -28,22 +28,31 @@ function getConversationState(conversationId, userType = 'high_school') {
2828function getNextQuestion ( conversationId , userType ) {
2929 const state = getConversationState ( conversationId , userType ) ;
3030
31- // Initial mode: ask 5-7 broad questions
32- if ( state . answers . length >= 7 ) {
31+ // Initial mode: ask 20-30 broad questions
32+ if ( state . answers . length >= 25 ) {
3333 return null ; // Done with initial questions
3434 }
3535
3636 // Get broad questions from different categories
37- const categories = [ 'skill' , 'interest' , 'scenario' ] ;
37+ const categories = [ 'skill' , 'interest' , 'scenario' , 'workstyle' ] ;
3838 const targetCategory = categories [ state . answers . length % categories . length ] ;
3939
4040 const availableQuestions = ALL_QUESTIONS . filter ( q =>
4141 q . category === targetCategory &&
42- ! state . asked Questions . has ( q . id )
42+ ! state . askedQuestions . has ( q . id )
4343 ) ;
4444
4545 if ( availableQuestions . length === 0 ) {
46- return null ;
46+ // Fallback to any category if no questions in target category
47+ const anyAvailable = ALL_QUESTIONS . filter ( q => ! state . askedQuestions . has ( q . id ) ) ;
48+ if ( anyAvailable . length === 0 ) return null ;
49+ const question = anyAvailable [ 0 ] ;
50+ return {
51+ id : question . id ,
52+ text : question . text ,
53+ type : 'yes_no_maybe' ,
54+ options : [ 'Có' , 'Có thể' , 'Không' ]
55+ } ;
4756 }
4857
4958 // Return first available question
@@ -200,33 +209,47 @@ function getCareerRecommendations(conversationId) {
200209 // Combine initial and refinement answers
201210 const allAnswers = [ ...state . answers , ...state . refinementAnswers ] ;
202211
203- if ( allAnswers . length < 3 ) {
204- throw new Error ( ' Need at least 3 answers to generate recommendations' ) ;
212+ if ( allAnswers . length < 10 ) {
213+ throw new Error ( ` Need at least 10 answers to generate recommendations (current: ${ allAnswers . length } )` ) ;
205214 }
206215
207216 // Calculate scores
208217 const scores = calculateCareerScoresFromAnswers ( allAnswers ) ;
209218
210- // Rank and normalize
211- const sortedCareers = Object . entries ( scores )
219+ // Filter out careers with very low scores (minimum threshold)
220+ const minScoreThreshold = Math . max ( ...Object . values ( scores ) ) * 0.1 ; // 10% of max score
221+ const filteredScores = Object . entries ( scores )
222+ . filter ( ( [ , score ] ) => score >= minScoreThreshold )
212223 . sort ( ( a , b ) => b [ 1 ] - a [ 1 ] )
213224 . slice ( 0 , 10 ) ;
214225
215- const totalScore = sortedCareers . reduce ( ( sum , [ , score ] ) => sum + score , 0 ) ;
226+ if ( filteredScores . length === 0 ) {
227+ throw new Error ( 'No careers match your profile' ) ;
228+ }
229+
230+ // Softmax normalization for smoother probability distribution
231+ const maxScore = filteredScores [ 0 ] [ 1 ] ;
232+ const expScores = filteredScores . map ( ( [ career , score ] ) => [
233+ career ,
234+ Math . exp ( ( score - maxScore ) / 50 ) // Temperature parameter = 50
235+ ] ) ;
236+
237+ const sumExp = expScores . reduce ( ( sum , [ , exp ] ) => sum + exp , 0 ) ;
216238
217- const recommendations = sortedCareers . map ( ( [ career , score ] ) => ( {
239+ const recommendations = expScores . map ( ( [ career , exp ] , index ) => ( {
218240 career_name : career ,
219- match_score : score ,
220- probability : totalScore > 0 ? ( score / totalScore ) : 0.1 ,
221- confidence : score > 100 ? 'high' : score > 50 ? 'medium' : 'low' ,
241+ match_score : Math . round ( filteredScores [ index ] [ 1 ] ) ,
242+ probability : exp / sumExp ,
243+ confidence : filteredScores [ index ] [ 1 ] > 150 ? 'high' :
244+ filteredScores [ index ] [ 1 ] > 75 ? 'medium' : 'low' ,
222245 reasons : generateReasons ( career , allAnswers )
223246 } ) ) ;
224247
225248 return {
226249 recommendations,
227250 totalAnswers : allAnswers . length ,
228251 mode : state . mode ,
229- canRefine : state . mode === 'initial' && allAnswers . length >= 5
252+ canRefine : state . mode === 'initial' && allAnswers . length >= 20
230253 } ;
231254}
232255
0 commit comments