
AI 家教狀態機詳解從 INIT 到 DONE每一輪 Turn 如何被「管住」標簽狀態機LLM應用架構Spring Boot教育科技Agent系列接《別再「套個大模型」了》技術深挖可控講題的編排實現。寫在前面接上大模型不等于接上「會教的老師」。模型會寫話術卻管不住「審題 → 分步 → 復述 → 收尾」的課堂節奏。本文講 AI 家教里的狀態機編排INIT→DONE各狀態職責、一輪Turn的前后端契約、冪等與后處理閘門、多問誤拆怎么防。一句話——狀態機控權模型負責怎么說后處理防止說崩。適合已接 LLM、卻被跳步 / 卡死 / 串學科折磨過的同學對照落地。1. 為什么必須上狀態機大模型擅長「寫得像老師」不擅長「嚴格服從課堂流程」。如果完全交給模型決定「講到哪了」常見后果是一步講完整題破壞分步 Reveal語文題突然教列方程只有一題卻不斷「下一問」收尾輪沒有出口學生無法結束所以我們把狀態推進權放在后端編排器把話術生成權交給模型再用后處理校正 Turn 的 UI/選項/下一狀態。一句話狀態機控權模型負責怎么說后處理防止說崩。2. 狀態一覽VIP 主路徑狀態職責學生常見動作典型下一狀態INIT審題 考查點 第一步提問打字回答THINKUNDERSTAND對齊理解 / 情緒與卡點處理選項或文本THINKTHINK題目解構、進入第一步選項或文本STEPSTEP一步一問可多輪選項 / 文本 / 下一步STEP或CHECKCHECK復述自檢按學科換話術打字復述SUMMARY/ 補講SUMMARY結構化總結看解析 / 結束 / 下一問EXTENDEXTEND收尾選擇區同上DONE或下一問重開DONE終態無互動DONE說明會話創建時會固化flow_typeVIP / Legacy后續turns:next只按該值路由。狀態在實現里多為字符串常量讀代碼時先確認鏈路再進 Handler。3. Turn 協議前后端的「一輪課」每一輪后端返回結構化 JSON示意{state:CHECK,message:做個復述自檢……語文設問→依據→收束,question:請用自己的話復述這題的賞析思路,options:[],ui:{allowTextInput:true,showNextButton:false},next_state:CHECK}字段含義字段含義message老師說的話氣泡主文question本輪向學生提的問題options可點選項空數組表示不靠選項推進ui.allowTextInput是否開放底部輸入ui.showNextButton是否顯示「下一步」next_state本輪結束后會話應落到的狀態三條鐵律建議寫進單測 / 后處理有question且無options→ 必須allowTextInputtrue并關閉孤立的「下一步」。進入 SUMMARY / 收尾→ 必須有可點出口查看解析 / 結束練習 / 多問時的下一問。禁止死鎖輪無選項 不可輸入 無下一步且非 DONE。這三條比「把 Prompt 寫得更長」可靠得多。4. 編排主流程偽代碼以下為 VIP「下一輪」的骨架邏輯示意非某一文件逐行拷貝function nextTurn(userId, explanationId, req): e loadOwnedExplanation(userId, explanationId) // —— 守衛 —— if turn : findByClientTurnId(req.clientTurnId): return replay(turn) // 冪等弱網連點不重復計分/不重復生成 if e.currentState DONE: return terminalDoneTurn() // 已結束不再寫庫 if req.currentState ! e.currentState and not isExitAction(req): // 結束/下一問等收口動作可放行 return softResyncTurn(e) // 并發提示帶回服務端當前態 // —— 多問誤拆糾正 / 懶加載拆分示意—— reconcileMisSplitIfStatementEnum(e) // ①②③「以上說法正確個數」→ 單問 // —— 按狀態分發 —— switch e.currentState: case CHECK: turn runCheck(req, e) // 空輸入→按學科發復述題有輸入→掌握判定 case SUMMARY: turn handleSummaryOption(req, e) // 僅處理選項類事件更穩 case EXTEND: turn handleExtend(req, e) case THINK: turn llmGenerate(buildCtx(e, req)) case STEP: maybeStepPaceNudge(e, req) // 輪次偏多催促而非硬砍死 turn llmGenerate(buildCtx(e, req)) default: turn llmGenerate(buildCtx(e, req)) // —— 后處理閘門比 Prompt 更硬—— postProcess(e, turn) // —— 落庫并推進 —— saveExplanationTurn(...) e.currentState turn.nextState updateExplanation(e) return turn4.1 CHECK掌握檢測學科感知function runCheck(req, e): if blank(req.userInput): return checkAskTurn(e.subject) // 語文設問→意象/詞句→收束 // 數學已知所求→關系/列式→代回核對 // 英語/史地政各自話術 if not masteryPass(req.userInput, e.question, e.subject): return masteryFailSummary(...) // 標準答案方向 薄弱點 收尾選項 return masteryPassSummary(...) // 同一輪給總結選項禁止「空橋接輪」空橋接輪是典型事故只說「接下來給你結構化總結」卻不給內容、不給選項、不給輸入——前端必卡死。正確做法是通過后同一輪交付總結與出口。4.2 postProcess最后一道閘function postProcess(e, turn): if turn.state INIT: turn.options [] ensureFirstStepAsk(turn) // 去掉全科通用卡點問卷 if hasQuestion(turn): allowInput(turn); hideNext(turn) if turn.state SUMMARY or turn.nextState SUMMARY: turn.nextState EXTEND ensureExitOptions(turn) // 查看解析 / 結束 / 下一問 injectNextSubQuestionIfNeeded(e, turn) if turn.state EXTEND: sanitizeExtendOptions(turn) forbidInteractiveDeadEnd(turn) // 非 DONE 不得死鎖5. 多問大題怎么推進又如何防誤拆5.1 數據模型sub_questions_json子問列表sub_question_index/sub_question_total當前問與總數Prompt 側優先喂「當前子問」附帶原題片段避免多問混講。5.2 下一問if user picks NEXT_SUB_Q and hasNext(e): advanceIndex(e) reset stepIndex return buildFirstTurnAsInit() // 下一問重新開場5.3 誤拆防護實戰結論中文試卷編號語義不統一形態常見含義(1)(2)(3)/第1問真·多問設問①②③④ 「以上說法正確的個數」說法枚舉 單題選擇規則上要強信號才拆說法枚舉強制單問歷史誤拆可 reconcile。6. 與 LLM 層如何協作簡圖編排器 buildCtx(狀態/題干/歷史摘要/學科/學段) │ ▼ TutorEngineRouter │ ├─ LangChainTutorEngine ──? LlmGateway │ ├─ TEXT │ └─ NATIVE FC多輪 tool loop硬上限 ├─ DeepSeek 降級路徑 ────────? LlmGateway.chatText └─ RuleBased 兜底 ───────────? 無外網也能走完主路徑工具側建議白名單 服務端執行如當前子問、步驟摘要、KB 檢索、錯因模式。定量驗算如雞兔更適合后置校驗流水線不一定要做成 Function Calling以免打亂引導式教學。Prompt 運行時讀庫可熱更新倉庫 Markdown 用于規范與引導入庫——改文件后記得同步庫表否則線上仍是舊約束。7. 客戶端只需做好三件事每輪帶上explanationId、currentState、eventType、clientTurnId嚴格按options/allowTextInput/showNextButton渲染不在前端「猜」業務連點防護穩定的clientTurnId服務端冪等不要用前端補丁修復后端死鎖。死鎖是編排/后處理的責任前端兜底只會掩蓋問題。8. 落地檢查清單可當 Code Review 列表INIT 是否還在甩全科通用「卡點問卷」有提問無選項時是否強制開放輸入CHECK 話術是否按subject分支掌握通過是否同一輪給出總結出口SUMMARY/EXTEND 是否必定能結束會話說法枚舉題是否不會被拆成多問clientTurnId是否真正冪等大模型失敗時 Rule/兜底是否仍能講完9. 小結AI 家教的狀態機本質是在回答一個問題開放生成與封閉流程之間如何做出穩定、可測、可運營的教學體驗我們的實踐答案是用狀態機定義「課怎么上」用 Turn 協議定義「這一分鐘師生怎么互動」用后處理定義「模型越界時系統怎么拉回來」用學科分支定義「同一流程下話術如何不同」下一篇AI 家教實戰Function Calling RAG增強講題卻不搶教學節奏。歡迎評論區交流你們的狀態劃分方式或「死鎖 / 串臺 / 誤拆」的真實案例。