From 1224a74e63da45e3c231c17f6957cd0cf50973a0 Mon Sep 17 00:00:00 2001 From: Developer Date: Thu, 21 May 2026 11:53:24 +0800 Subject: [PATCH] fix: natural follow-up conversation flow - Grader: separate followup hint from scoring feedback - Interviewer: use followup hint directly without prefix/suffix - Restored standard and choice question presentation paths --- .../src/assessment/graph/nodes/grader.node.ts | 15 +++++++++--- .../graph/nodes/interviewer.node.spec.ts | 5 ++-- .../graph/nodes/interviewer.node.ts | 22 +----------------- server/test-output.txt | Bin 0 -> 16550 bytes 4 files changed, 15 insertions(+), 27 deletions(-) create mode 100644 server/test-output.txt diff --git a/server/src/assessment/graph/nodes/grader.node.ts b/server/src/assessment/graph/nodes/grader.node.ts index 3a07579..dc7b032 100644 --- a/server/src/assessment/graph/nodes/grader.node.ts +++ b/server/src/assessment/graph/nodes/grader.node.ts @@ -252,10 +252,15 @@ Format your response as JSON: shouldFollowUp = false; } + let followupHintMsg: AIMessage | null = null; if (shouldFollowUp && followupHints.length > 0) { const hint = followupHints[Math.min(currentFollowUpCount, followupHints.length - 1)]; - const hintLabel = isZh ? '追问方向' : isJa ? '追加の方向性' : 'Follow-up hint'; - enhancedFeedback = `${result.feedback}\n\n${hintLabel}: ${hint}`; + const hintLabel = isZh + ? `让我帮你完善一下:${hint}` + : isJa + ? `もう少し詳しく伺います:${hint}` + : `Let me help you elaborate: ${hint}`; + followupHintMsg = new AIMessage(hintLabel); } const feedbackMessage = new AIMessage( @@ -271,8 +276,12 @@ Format your response as JSON: saysIDontKnow, }); + const feedbackHistoryMessages = followupHintMsg + ? [feedbackMessage, followupHintMsg] + : [feedbackMessage]; + return { - feedbackHistory: [feedbackMessage], + feedbackHistory: feedbackHistoryMessages, scores: newScores, shouldFollowUp: shouldFollowUp, followUpCount: shouldFollowUp ? currentFollowUpCount + 1 : 0, diff --git a/server/src/assessment/graph/nodes/interviewer.node.spec.ts b/server/src/assessment/graph/nodes/interviewer.node.spec.ts index aad2c71..e6194f0 100644 --- a/server/src/assessment/graph/nodes/interviewer.node.spec.ts +++ b/server/src/assessment/graph/nodes/interviewer.node.spec.ts @@ -81,14 +81,13 @@ describe('interviewerNode', () => { }); describe('follow-up mode', () => { - it('should include feedback in follow-up prompt', async () => { + it('should use last feedbackHistory message content as follow-up prompt', async () => { const state = baseState({ shouldFollowUp: true, - feedbackHistory: [new AIMessage('Feedback: You need more details')], + feedbackHistory: [new AIMessage('You need more details')], }); const result = await interviewerNode(state); const msg = (result.messages as any)[0].content as string; - expect(msg).toContain('Follow-up'); expect(msg).toContain('You need more details'); }); diff --git a/server/src/assessment/graph/nodes/interviewer.node.ts b/server/src/assessment/graph/nodes/interviewer.node.ts index 10ef79b..3be8d7a 100644 --- a/server/src/assessment/graph/nodes/interviewer.node.ts +++ b/server/src/assessment/graph/nodes/interviewer.node.ts @@ -49,27 +49,7 @@ export const interviewerNode = async ( ) { const lastFeedbackMsg = state.feedbackHistory[state.feedbackHistory.length - 1]; - const feedbackText = lastFeedbackMsg.content.toString(); - - const feedbackMatch = feedbackText.match( - /(?:Feedback|反馈|フィードバック): ([\s\S]*)/i, - ); - const specificFeedback = feedbackMatch - ? feedbackMatch[1].trim() - : feedbackText; - - const followUpLabel = isZh - ? '补充追问' - : isJa - ? '追加の質問' - : 'Follow-up Clarification'; - const followUpInstruction = isZh - ? '根据以上反馈,请补充更具体的信息:' - : isJa - ? '上記のフィードバックに基づき、より具体的な情報を追加してください:' - : 'Based on the feedback above, please provide more specific details:'; - - prompt = `${followUpLabel}\n\n${specificFeedback}\n\n${followUpInstruction}`; + prompt = lastFeedbackMsg.content.toString(); } else if (currentQuestion.questionType === 'MULTIPLE_CHOICE' && currentQuestion.options?.length > 0) { const label = isZh ? `问题 ${currentQuestionIndex + 1}` diff --git a/server/test-output.txt b/server/test-output.txt new file mode 100644 index 0000000000000000000000000000000000000000..101ba1f0bbc65faa227427eaf42da7130b0411d2 GIT binary patch literal 16550 zcmeHOUvC>l5T9oxK0#kjk!T!IIdO~aG!$BB6N##Ape@Qn3COiC{}kJ4&L&Mm;FV_( zAA%3SJK~D~4}1;a_uKLIc747}{U@odoUGV;cYCulvpf5notgaiZyl2SA zDYv96P5A=fA;#~3vU0M5XG?M|(Z7zKhxmkMEb_$BUrJj4NOnN63yB)ChSt83?MS|q z1M|+7)Nm&PjpSI$+e5=ygnrwm#gV$baks#43wIkHpQq-^)gC3SLAt>7PuF4~1@wyy zKm2ZjHnqNpu@CX&0Mabtj_N!@o8u?x6<_x$;%Nj)OY(vFF3Ez&-E_`;QoqUB$ydT< zSPA(aa9Q_&eC99f%$EjWan^2M9?(C>{aM8QVP}5O9+A)dMa=wTc%~iWi?@sqN^k!K zu3aylp7II)eB15!^^-n)lG0PqeTnf%ab7my1zT@A!kzo_L~i4LAk*l1m!&*Io_B76 zvx2(01-|LoH@Cn%>Tw=XkK6)t3(Vt=ZZ!C!@Sp#^zCrCb|@2&*NHNlTVQAet=d4gs3COI_ZpTggkBt%9@*H z&bNeIcM*R#@Zq?6TDkMQu<>xc^+O;Jeq;tWkd0?oPsn4*ni@{N!kMPXOx`(ScZ)hc-8;i;}7_AKon&oHSo1A?=H6J$&gl8SZ7uotX#L4LRz?44oH08Z-=k%B<+;(0oo&v;T%!Jk7Cz^3&XwTuN?P%nAr<}1 z_1<%(zJm3%gt-lbt((1e85JRcd}r?6z+FCfKS^DY`+bZ`D%`1>(3iIPHshwOS+R98 z3n~4m;ZM=`9{%F`nF6#L)BVt)>q^ouK{-vMH5;$Rt zzaN{{b-CWVr)z^x88o(uNqzB>FeIL z0k@sh)Yk(wm9<{07pAwg9GObN^*_Ak%Celw|LI8dZuZe5cigF{Ltl@!er_H6=N_z} z4l5|iEn`zejbpsUI==|(_dKfTe4lLvIlT%nv;>>*Bg=0KA&FFV?9SaD3UjZCdNrDg zQ@Ss7jpkzi!PT;Fx6^};t}N$`iWSUh7AmU!q+^PU7f}MUGiE|XS^E@1iR?Jy19fy2t91lfZ z3z}8*tYrABqo7X(d$_;uvuq^Y|9Nb1LHnxL%bmjZqQts8 zsn=)E0VjsyY#=f1Xqu3ClJm{^aaX0kCrl4Q|MAQ3f1mzy{@9%Ef6`NrQFZWn?_#i7 zV;{ui;XUjMu-e~~+!M&z66RQJbu=6nS8?jd(z|bW<6*Jdio25!zfN>jr27v3s)?`E zLR{Spdxou^;U7;@Q{m6Q9sJoDPgB(l?{*Zgp_=g8sMFa%O0M#0M9TZ{bPkNyGpcX2 zhqq@1D}U|W`|HKld1GZ2@rkS*ZT7LUD%sJrvn0&1a#XC$_QEEK0BS4aA;8zbGzubG=;Op*U-uKD*=Rw$IQ=hFHk!|!9zWyFH~?;BcHer5_87vXgPii}a#d+`ru+y=)t-RhY*-cDTq EAFYw#I{*Lx literal 0 HcmV?d00001