Bỏ qua để đến nội dung

Exercise with AI - Linear Tools

DomainsDOL EnglishUX7.774 words39 min read
draftbyDOL Product Design
  • Vấn đề: Học viên có thể nghĩ ra ý rời rạc nhưng không biết phát triển thành một flow nói có logic. Khi nói dài hơn 1 câu, các ý dễ bị ngang hàng, lặp lại, hoặc đi lan man.
  • Đối tượng chính: Học viên luyện IELTS Speaking cần triển khai câu trả lời bằng Linearthinking trước khi chuyển sang luyện nói cả bài.
  • Tín hiệu thành công: Học viên tự tạo được idea flow trên canvas, gắn đúng Linear Tool cho từng ý, thấy AI hoàn thiện từng ý thành câu nói tự nhiên, rồi dùng các câu đó để luyện nói.
  • Source inventory ghi Linear Tools dùng demo https://speakinglineartools.dol.vn/ và note là “Giống hệt như app đã deploy”.
  • Speak Many Sentences dùng cùng app, khác ở tab luyện nói từng câu: https://speakinglineartools.dol.vn/sis.html.
  • Vì vậy file này mô tả canvas engine của Linear Tools; PRA_EXAI_Speak_Many_Sentences.md chỉ ghi phần package/delta cho luyện nói.

Linear Tools là trải nghiệm canvas-based idea flow. Học viên bắt đầu từ một câu hỏi Speaking, tạo Answer, rồi thêm các panel theo chiều ngang hoặc chiều dọc để phát triển ý bằng Linear Tool.

AI không thay học viên nghĩ ý. Học viên nhập note ngắn trong từng panel; AI side panel bên phải dùng note đó, tool label, và quan hệ parent-child trên canvas để hoàn thiện thành câu nói tự nhiên. Kết quả của bước này là một chuỗi câu có thể chuyển tiếp sang tab Luyện nói cả bài.

  • File này là canonical spec cho Linear Tool canvas engine: question -> idea flow canvas -> AI sentence composer -> speaking rehearsal.
  • Speak Many Sentences build trên engine này như learner-facing package có thêm progress/replay.
FieldMô tả
exercise_typeDạng bài hiện tại, dùng để nhớ mic check theo từng loại bài
question_idID câu hỏi được giao hoặc câu hỏi user chọn
question_textCâu hỏi Speaking hiển thị ở start card và Question node
mic_check_keyKey lưu trạng thái mic, khuyến nghị user_id + exercise_type
mic_check_statusunchecked, passed, skipped, failed
mic_permission_statusunknown, granted, denied
entry_statemic_check, start_card, canvas_started

Canvas không phải grid cố định. Canvas là một graph trực quan gồm các node và edge:

ElementVai trò
QuestionCâu hỏi gốc, là root context, không phải câu luyện nói
AnswerCâu trả lời trực tiếp đầu tiên
Description / Cause / EffectCác Linear Tool dùng để phát triển ý (3 loại - không có Opinion)
Horizontal edgeMở một ý mới phát triển trực tiếp từ answer/main idea
Vertical edgeĐào sâu node ngay trước đó
AI side panelHoàn thiện note trong mỗi node thành câu nói có thể luyện
FieldMô tả
idĐịnh danh kỹ thuật của node
tool_typeanswer, description, cause, hoặc effect
noteÝ ngắn user nhập trong canvas
generated_sentenceCâu nói AI hoàn thiện từ note
parent_idNode mà ý này đang phát triển
relationhorizontal hoặc vertical
display_labelLabel học viên thấy, ví dụ #2, #2.A
statusEmpty, editing, analyzing, ready, needs_fix
FieldMô tả
selected_node_idNode đang được focus trên canvas
active_sentence_node_idNode/card đang được chọn để luyện nói
add_branch_source_idNode nguồn khi user bấm nút mũi tên/plus thêm nhánh
add_branch_directionhorizontal hoặc vertical
tool_menu_node_idNode đang mở menu đổi tool
canvas_zoomZoom hiện tại của canvas
canvas_viewportTọa độ pan/viewport hiện tại
is_fullscreenCanvas đang ở chế độ toàn màn hình hay không
right_panel_modeidea_suggestions, sentence_practice, full_speaking

Tab Luyện nói cả bài dùng output của canvas nhưng có attempt snapshot riêng để việc chấm bài ổn định.

FieldMô tả
script_snapshotFull answer text tại thời điểm user bấm luyện nói
sentence_segmentsDanh sách câu theo flow ordering, giữ node_id, tool_type, display_label
attempt_noLần nói hiện tại, ví dụ #1
recording_statusidle, recording, processing, completed, needs_retry
user_recording_urlAudio user nói full answer trong một lần
transcriptSTT từ bản thu full answer
alignmentMapping transcript với sentence_segments để highlight
full_scoreĐiểm tổng 0-100 cho bài nói
coverage_statusenough, partial, hoặc silent
is_staleAttempt cũ không còn khớp khi canvas/script đã đổi
  • Mic check chỉ xuất hiện khi user chưa có reusable mic status cho mic_check_key hiện tại. Reusable status gồm passed hoặc skipped.
  • Khuyến nghị lưu theo user_id + exercise_type để user chỉ cần test một lần cho cùng dạng bài. Nếu trình duyệt báo đổi mic, revoke permission, hoặc audio input liên tục silent ở lần ghi âm thật, hệ thống có thể yêu cầu test lại.
  • Mic check không chấm nội dung và không ảnh hưởng điểm bài nói. Mục tiêu chỉ là xác nhận:
    • user đã cấp quyền mic;
    • input có tín hiệu âm thanh đủ nghe;
    • recorder/STT có thể nhận audio.
  • UI test mic nên đơn giản:
    • tiêu đề Kiểm tra microphone;
    • waveform + countdown ngắn, ví dụ 5s;
    • prompt nói thử, ví dụ: “Hãy nói gì đó bất kỳ…” + một câu vui dễ đọc;
    • link phụ: Bỏ qua, mic của tôi đã sẵn sàng.
  • Nếu user bấm bỏ qua, hệ thống cho vào bài và lưu skipped theo key này để lần sau không hỏi lại. Nếu lần ghi âm thật silent thì invalidate skipped và quay lại message retry/mic check.
Trường hợpMessage UI thân thiệnCTA phù hợp
Cần test mic lần đầu”Kiểm tra mic một lần để AI nghe rõ bài nói của bạn nhé.”Bắt đầu kiểm tra
Đang test”Hãy nói gì đó bất kỳ trong vài giây nhé.”-
Mic pass”Mic đã sẵn sàng. Bắt đầu luyện nhé.”Tiếp tục
Không có tín hiệu”AI chưa nghe thấy tiếng. Bạn kiểm tra mic rồi thử lại nhé.”Thử lại
Permission denied”Bạn cần cho phép dùng micro để luyện nói.”Mở quyền micro
User bỏ qua”Bạn có thể bắt đầu ngay. Nếu AI không nghe thấy tiếng, hệ thống sẽ nhắc kiểm tra lại mic.”Bắt đầu
  • Entry mặc định của bài là câu hỏi cho sẵn. User trả lời theo câu hỏi này, không tự do nói một chủ đề khác.
  • Start card hiển thị câu hỏi, ví dụ What do you usually do to relax?, CTA Bắt đầu, và social proof nếu có.
  • Khi user bấm Bắt đầu, canvas tạo Question root và node Answer đầu tiên.
  • Question node là context cố định, không phải node user luyện nói.
  • Answer node là nơi user nhập ý trả lời trực tiếp cho câu hỏi được giao. Node này là nền cho toàn bộ Linear Tool flow phía sau.
  • Nếu Answer đang trống, user không được mở thêm node hoặc chuyển sang luyện cả bài. UI focus vào Answer và nhắc trả lời câu hỏi trước.
  • Mỗi panel là một Idea Node.
  • User nhập note ngắn bằng tiếng Anh hoặc tiếng Việt.
  • Node sau Answer phải có tool label rõ ràng: Description, Cause, hoặc Effect (3 loại Linear Tool, không có Opinion).
  • Mỗi node có thể đổi tool label; khi đổi label, AI recompute suggestion theo logic mới.
  • Plus ngang bắt đầu flow thêm một nhánh ý mới phát triển từ answer/main idea.
  • Plus dọc bắt đầu flow thêm một ý đào sâu node đang chọn.
  • Khi user bấm nút mũi tên/plus thêm nhánh, hệ thống mở popover chọn Linear Tool thay vì tạo node ngay lập tức.
  • Nếu node nguồn đang trống, user không tạo được node mới. UI focus lại input của node nguồn và nhắc điền ý trước.
  • Nếu node nguồn đã có nội dung và AI đang phân tích, user vẫn được tạo node mới để giữ momentum.
  • Nếu AI đã trả về lỗi blocking cho bất kỳ node nào trong flow, user không tạo thêm node mới cho tới khi các lỗi blocking đó được sửa.
  • Canvas nên nudge học viên quay lại mở nhánh ngang sau khoảng 2-3 ý dọc để tránh lan man. Đây là coaching rule, không phải hard delete dữ liệu.
  • Popover mở tại nút mũi tên/plus của node đang chọn.
  • Header nên nói rõ node nguồn, ví dụ Chọn Linear Tool phát triển "#di xem phim".
  • Popover có 2 mode:
    • AI gợi ý: AI đề xuất 2-3 tool cards phù hợp với node nguồn.
    • Tự viết: user tự chọn tool type rồi nhập note trong node mới.
  • Mỗi AI suggestion card gồm:
    • tool label (Description, Cause, hoặc Effect);
    • note gợi ý ngắn;
    • câu giải thích ngắn để user hiểu suggestion đang phát triển ý theo hướng nào.
  • Khi user chọn AI suggestion:
    • tạo node mới theo add_branch_direction;
    • set tool_type theo card;
    • prefill note bằng note gợi ý;
    • set node mới thành selected_node_id;
    • AI composer tạo hoặc refresh generated_sentence.
  • Khi user chọn Tự viết:
    • tạo node mới rỗng với tool type user chọn;
    • focus input của node mới;
    • chưa báo lỗi empty cho tới khi user bấm plus/chuyển luyện nói.
  • Nếu source node đang empty hoặc flow còn needs_fix, popover không nên mở rộng danh sách suggestion; chỉ hiển thị message ngắn và focus node cần sửa.
  • Click vào badge tool trên node mở menu Chỉnh tool hiện tại.
  • Menu hiển thị tool hiện tại ở trạng thái disabled/checked, các tool còn lại là lựa chọn có thể đổi.
  • Đổi tool chỉ đổi vai trò logic của node, không xóa note user đã nhập.
  • Sau khi đổi tool:
    • set node về analyzing;
    • clear warning cũ của node đó;
    • AI recompute generated_sentence theo tool mới và parent-chain hiện tại;
    • side panel card giữ cùng display_label, chỉ cập nhật tool label và sentence.
  • Nếu đổi tool làm nội dung không khớp, AI có thể trả needs_fix với message Wrong tool.
  • Menu có thể có Xóa nhánh, nhưng không áp dụng cho QuestionAnswer root.
  • Xóa nhánh xóa node hiện tại và toàn bộ node con của nó. Nếu nhánh đã có audio/attempt hoặc nhiều node con, UI nên xác nhận ngắn trước khi xóa.
  • Khi xóa hoặc đổi tool làm script thay đổi, full speaking attempt cũ phải bị mark stale.
  • Canvas có các control điều hướng: phóng to, thu nhỏ, fit view, và toàn màn hình.
  • Các control này chỉ thay đổi viewport, không thay đổi graph data, ordering, score, hoặc completion.
  • Zoom in/out: điều chỉnh canvas_zoom; giữ node đang chọn gần trung tâm nếu có thể.
  • Fit view: đưa toàn bộ graph liên quan vào viewport; nếu đang chọn node, ưu tiên fit cả node chọn và các node kết nối gần nó.
  • Fullscreen: mở canvas ở không gian rộng hơn để user thao tác nhiều nhánh. Side panel có thể thu gọn hoặc chuyển thành overlay, nhưng không làm mất state đang luyện.
  • Khi thoát fullscreen, giữ lại selected_node_id, active_sentence_node_id, và viewport gần nhất nếu hợp lý.
  • Control cần có tooltip/icon rõ ràng; không dùng text dài trên canvas.
  • Linear Tool gồm 3 loại (không có Opinion - quan điểm/nhận định cá nhân được hiểu là một dạng Description về cảm xúc/đánh giá, không cần tool riêng):
  • Description: cụ thể hóa ý trước đó bằng hành động, đối tượng, nơi chốn, thời điểm, điều kiện, tính chất, hoặc biểu hiện.
  • Cause: giải thích lý do cho node trước đó.
  • Effect: nêu hệ quả của node trước đó.
  • AI phải hiểu rõ node dọc phát triển parent node trực tiếp, không tự động quy về Answer.
  • Panel bên phải hiển thị các câu nói đã được AI hoàn thiện từ canvas.
  • Mỗi suggestion card giữ tool label và display_label tương ứng với node trên canvas.
  • Khi user chọn một node, side panel ưu tiên suggestion của node đó và dùng parent-chain làm context.
  • Khi user click một suggestion card, card đó trở thành active item để luyện nói. Canvas cũng highlight node tương ứng.
  • AI không tự ghi đè note trong canvas. AI chỉ tạo hoặc cập nhật generated_sentence.
  • Side panel có thể hiển thị “Tiếp tục chờ ý tưởng của bạn…” khi node chưa đủ note để compose.
  • Nếu logic yếu, AI hiển thị warning nhẹ tại node hoặc side panel, ví dụ: tool label không khớp nội dung, node dọc không thật sự phát triển parent, hoặc flow quá sâu.
  • Active card là bridge giữa canvas idea và luyện nói từng câu.
  • Click card trong side panel:
    • set active_sentence_node_id;
    • set selected_node_id cùng node;
    • scroll/center node trên canvas nếu node đang ngoài viewport;
    • expand card để hiện Nghe mẫuLuyện nói.
  • Active state phải hiển thị đồng bộ:
    • node trên canvas có border/indicator active;
    • card bên phải có border/controls active;
    • các card khác vẫn xem được nhưng không mở control luyện nói chính.
  • Khi user bấm Luyện nói trên active card:
    • chỉ thu âm câu của card đó;
    • node/card chuyển sang recording state;
    • sau khi nói xong, highlight pronunciation nằm trong card và có thể phản chiếu nhẹ trên node.
  • Nếu user click card khác trong lúc đang recording, hệ thống nên hỏi/dừng attempt hiện tại trước khi chuyển active item.

Validation của canvas phải bảo vệ chất lượng flow nhưng không làm user mất nhịp khi AI còn đang xử lý.

Trạng tháiUser có được tạo node mới?UI response
Node trống, user chưa bấm plusKhông cần báo lỗiChỉ hiện placeholder
User bấm plus từ node trốngKhôngFocus node nguồn + nhắc “Điền ý cho ô này trước nhé.”
Node có nội dung, AI đang analyzingCho mở add-branch popover và tạo node sau khi user chọn tool/suggestion
AI trả về readySentence card được cập nhật
AI trả về needs_fixKhôngKhóa tạo node mới; hiển thị lỗi thân thiện tại node và side panel
User sửa node lỗi, AI analyzing lạiChưa khóa theo lỗi cũ nếu nội dung đã thay đổiCho tạo tiếp trong lúc chờ kết quả mới

Message phải ngắn, thân thiện, và chỉ rõ việc user nên làm tiếp. Không dùng wording kiểu “sai”, “lỗi”, “không đúng” trên UI chính; dùng badge/state để hệ thống hiểu severity, còn copy nói theo hướng hỗ trợ.

Trường hợpKhi nào xảy raBranch gatingMessage trên cardMessage/label ở side panelQuick action
Empty idleNode chưa có nội dung, user chưa bấm plusKhông báo lỗiPlaceholder: “Chi tiết rõ hơn…”Không hiện warning-
Empty branch attemptUser bấm plus từ node trốngChặn tạo node mới”Điền ý cho ô này trước nhé.""Cần có ý trước khi mở nhánh mới.”Focus input
Empty answerAnswer node trống nhưng user bấm plus hoặc chuyển tab luyện nóiChặn tạo node/chuyển luyện nói”Trả lời câu hỏi này trước nhé.""Cần có câu trả lời đầu tiên để bắt đầu phát triển ý.”Focus Answer (đã có design - frame Empty trong file Figma: tooltip “Empty thì không được tạo thêm” + side-block icon ⊘ trên active card + side panel hiện “Chờ nội dung…” cho card #2)
AI analyzingNode có nội dung, AI đang phân tíchCho tạo node mớiKhông warning; có loading nhỏ nếu cần”Chờ nội dung…”-
Too shortNote có nội dung nhưng quá ngắn để compose câu tự nhiênChặn sau khi AI trả needs_fix”Ý này còn hơi ngắn. Thêm chi tiết như hành động, đối tượng hoặc thời điểm để rõ ý hơn nhé.”Badge: “Cần thêm chi tiết""Viết rõ hơn”
Too vagueAI không hiểu rõ user muốn nói gìChặn sau khi AI trả needs_fix”AI chưa hiểu rõ ý này lắm. Bạn viết cụ thể hơn một chút nhé.”Badge: “Chưa rõ ý""Viết cụ thể hơn”
Off-topicNote chưa liên quan rõ tới câu hỏi hoặc answer chínhChặn sau khi AI trả needs_fix”Ý này chưa nối rõ với câu hỏi lắm. Bạn thử kéo nó gần hơn với chủ đề chính nhé.”Badge: “Chưa sát đề""Đổi ý”
Wrong tool - generalNội dung hợp với tool khác hơn tool đang chọnChặn sau khi AI trả needs_fix”Ý này nghe giống {tool} hơn. Đổi sang {tool} để flow tự nhiên hơn nhé.”Badge: “Nên đổi tool""Đổi sang {tool}“
Description lacks detailNode Description nhưng note không mô tả rõ ai/cái gì/ở đâu/khi nàoChặn sau khi AI trả needs_fix”Ý này cần mô tả rõ hơn. Thêm ai, cái gì, ở đâu hoặc khi nào nhé.”Badge: “Cần mô tả rõ hơn""Thêm chi tiết”
Cause lacks reasonNode Cause nhưng note chưa nói lý doChặn sau khi AI trả needs_fix”Ý này chưa nói rõ lý do. Thử viết vì sao điều đó xảy ra nhé.”Badge: “Cần lý do""Thêm lý do”
Effect lacks resultNode Effect nhưng note chưa nêu hệ quảChặn sau khi AI trả needs_fix”Ý này chưa cho thấy kết quả sau đó. Thử viết điều gì xảy ra tiếp theo nhé.”Badge: “Cần hệ quả""Thêm hệ quả”
Wrong parentNode dọc không phát triển node cha trực tiếpChặn sau khi AI trả needs_fix”Ý này có vẻ đang nối với một ý khác. Bạn thử đặt nó dưới node phù hợp hơn nhé.”Badge: “Cần nối lại flow""Chọn node cha”
Duplicate ideaNote lặp lại nội dung đã có trong flowChặn nếu làm flow không thêm ý mới; nếu nhẹ thì chỉ warning”Ý này hơi giống một ý phía trên. Bạn thử đổi sang một góc khác nhé.”Badge: “Hơi trùng ý""Thử góc khác”
ContradictionNote mâu thuẫn với answer hoặc node trước mà không phải contrast có chủ đíchChặn sau khi AI trả needs_fix”Hai ý này đang hơi ngược nhau. Bạn muốn giữ hướng nào rõ hơn?”Badge: “Ý đang lệch hướng""Chọn hướng chính”
Too longUser nhập cả đoạn dài vào một nodeKhông chặn nếu AI vẫn compose được; ưu tiên soft hint”Ý này hơi dài. Bạn có thể tách thành 2 ý để flow dễ theo dõi hơn.”Badge: “Có thể tách ý""Tách thành 2 ý”
Too deepNhánh dọc đã đi quá sâuKhông chặn mặc định; dùng nudge”Nhánh này đang đi khá sâu rồi. Có thể mở thêm một ý mới bên cạnh nhé.”Badge: “Nên mở nhánh mới""Mở nhánh ngang”
Delete branch with childrenUser bấm Xóa nhánh trên node có node conXác nhận trước khi xóa”Nhánh này có ý con bên dưới. Xóa nhánh sẽ xóa các ý đó luôn nhé.”-“Xóa nhánh” / “Giữ lại”
Switch active while recordingUser click card khác khi câu hiện tại đang ghi âmChặn chuyển trực tiếp”Bạn dừng câu đang nói trước rồi chuyển sang câu khác nhé.”-“Dừng nói”

Khi có needs_fix, các nút plus vẫn có thể hiện nhưng disabled. Tooltip/callout ngắn: “Bạn cần hoàn thiện các nội dung trước”.

  • Câu nói hoàn chỉnh phải follow thứ tự đọc tự nhiên, không chỉ thứ tự tạo node.
  • Rule mặc định: đọc Answer trước, sau đó đi qua từng nhánh ngang từ trái sang phải; trong mỗi nhánh, đọc node cha rồi các node dọc liên quan trước khi sang nhánh ngang tiếp theo.
  • display_label cần giữ dấu quan hệ để user hiểu flow, ví dụ #2 là nhánh chính và #2.A là ý dọc của nhánh đó.
  • Mỗi generated_sentence trở thành một câu để luyện nói.
  • Học viên tập trung một câu tại một thời điểm.
  • Pronunciation feedback highlight từng từ: xanh = ổn, đỏ = cần cải thiện.
  • Học viên được nói lại nhiều lần và nghe câu mẫu.
  • Hệ thống nối các generated_sentence theo flow ordering thành một full answer script.
  • Tab này không phải nơi chỉnh ý. Nếu muốn đổi nội dung, user quay lại tab Lên ý tưởng hoặc bấm Tiếp tục phát triển.
  • Mục tiêu chính: yêu cầu user nói liền mạch toàn bộ câu trả lời trong một lần ghi âm, không chỉ nghe mẫu hoặc ghép các câu đã luyện lẻ.
  • Panel bên phải hiển thị:
    • header Luyện nói cả bài;
    • bối cảnh/câu hỏi;
    • chip tóm tắt tool count, ví dụ DESCRIPTION: 2, CAUSE: 3, EFFECT: 3;
    • full answer script;
    • CTA Luyện nói, Nghe mẫu, và warning nếu user chưa luyện full bài.
  • Khi user bấm Luyện nói, hệ thống tạo script_snapshot, bắt đầu recording, và đổi CTA sang trạng thái đang nói, ví dụ Đang nói #1 + Dừng nói.
  • Khi user bấm Nói xong/Dừng nói, hệ thống transcribe + align bản thu với script rồi trả về:
    • highlight ngay trong full answer text;
    • nút Nghe lại, Nói lại;
    • score tổng, ví dụ Điểm luyện nói: 80/100;
    • message định hướng tiếp theo.
  • Highlight nên ở cấp cụm từ/từ, nhưng feedback chính vẫn là fluency toàn bài. Không biến tab này thành màn sửa phát âm từng từ chi tiết.
  • Hover hoặc click vào highlight có thể mở annotation ngắn để giải thích vì sao đoạn đó tốt/chưa tốt; annotation không được che mất đoạn text đang đọc.
  • Nếu user sửa canvas sau khi đã nói full bài, attempt cũ vẫn giữ để nghe lại nhưng bị đánh dấu is_stale; user cần luyện lại để completion tính theo script mới.
StateKhi nàoUI chínhCompletion impact
not_readyCanvas chưa đủ readiness hoặc còn needs_fixDisable Luyện nói; nhắc hoàn thiện ý trước (xem frame Empty trong Figma cho UI khi Answer card chưa có nội dung)Chưa tính hoàn thành
idle_readyFull script đã sẵn sàng, user chưa ghi âmHiển thị script + Luyện nói + Nghe mẫu + warning cần luyện full bàiChưa tính hoàn thành
recordingUser đang nói full answerĐang nói #n hoặc Nói nhiều #n; nút Dừng nói; có thể highlight tiến độ nhẹChưa tính hoàn thành
processingUser vừa dừng nói, AI đang chấmDisable CTA chính; hiện trạng thái đang chấmChưa tính hoàn thành
completedCó transcript, alignment, score, coverage đủHiển thị highlight, Nghe lại, Nói lại, score, Tiếp tụcCó thể tính hoàn thành
needs_retryKhông nghe thấy tiếng hoặc user mới nói một phầnGiữ script, show message retry, CTA Nói lạiChưa tính hoàn thành
staleUser đổi canvas/script sau attemptAttempt cũ nghe lại được nhưng không còn tính cho script hiện tạiCần luyện lại
Trường hợpMessage UI thân thiệnCTA phù hợp
Canvas chưa sẵn sàng”Bạn hoàn thiện các ý trước rồi luyện cả bài nhé.”Tiếp tục phát triển
Chưa luyện full bài”Bạn cần luyện nói đầy đủ câu trả lời để hoàn thành bài tập này.”Luyện nói
Mic chưa được cấp quyền”Cho phép dùng micro để bắt đầu luyện nói nhé.”Thử lại
Đang ghi âm”Cứ nói liền mạch đến hết câu trả lời nhé.”Dừng nói
Đang chấm”AI đang chấm bài nói của bạn…”-
Không nghe thấy tiếng”AI chưa nghe thấy bài nói. Kiểm tra micro rồi thử lại nhé.”Nói lại
Nói quá ngắn / thiếu nhiều đoạn”Bạn mới nói một phần câu trả lời. Thử nói liền mạch cả bài một lần nữa nhé.”Nói lại
Nói xong, kết quả tốt”Bạn có thể làm câu tiếp theo, hoặc tiếp tục luyện lại câu trả lời hiện tại.”Tiếp tục, Nói lại
Nói xong, cần cải thiện”Bài nói đã được lưu. Bạn có thể nói lại để mượt hơn trước khi tiếp tục.”Nói lại, Tiếp tục
Script đã đổi sau khi nói”Nội dung bài nói đã thay đổi. Bạn luyện lại một lần để lưu kết quả mới nhé.”Luyện nói lại
Bài mẫu chưa tải được”Chưa tải được bài mẫu. Bạn vẫn có thể luyện nói trước.”Luyện nói
BướcUser làm gìHệ thống/AI phản hồi
0.1Vào bài Linear ToolCheck mic_check_key = user_id + exercise_type
0.2Nếu mic đã pass hoặc đã được user xác nhận bỏ qua trước đóBỏ qua màn test mic, đi thẳng tới start card
0.3Nếu mic chưa passHiển thị màn Kiểm tra microphone
0.4User nói thử trong 5sHiển thị waveform; kiểm tra permission + audio signal
0.5Mic passLưu mic_check_status = passed cho dạng bài này
0.6Không nghe thấy tiếngKhông lưu pass; nhắc thử lại hoặc kiểm tra quyền mic
0.7User chọn bỏ quaCho vào start card và lưu mic_check_status = skipped
0.8User bấm Bắt đầu ở start cardTạo Question node và Answer #1 node
BướcUser làm gìHệ thống/AI phản hồi
1.1Nhìn Question nodeThấy câu hỏi đã chọn/được giao, dùng làm context cố định
1.2Nhập answer trực tiếp vào Answer #1AI analyze + compose câu answer đầu tiên
1.3Bấm plus khi Answer trốngKhông tạo node mới; focus Answer và nhắc trả lời câu hỏi trước
1.4Bấm mũi tên/plus từ node có nội dungMở popover chọn Linear Tool phát triển node đó
1.5Bấm plus khi flow có node needs_fixKhông tạo node mới; nhắc hoàn thiện nội dung trước
1.6Chọn card AI gợi ýTạo node mới theo hướng plus, prefill note, AI compose sentence
1.7Chọn Tự viếtTạo node mới rỗng, focus input để user nhập note
1.8Bấm badge tool trên nodeMở menu đổi tool hoặc xóa nhánh
1.9Đổi tool labelGiữ note, AI hiểu lại vai trò logic và recompute sentence
1.10Gõ/chỉnh note ngắnAI analyze + compose câu nói ở side panel
1.11Bấm zoom/fit/fullscreenCanvas đổi viewport, không đổi dữ liệu flow
1.12Bấm chuyển tab luyện nóiHệ thống dùng flow ordering để tạo danh sách câu luyện

Đây là bước hỗ trợ khi package bật sentence drill. Với flow 2 tab hiện tại, completion chính nằm ở Bước 3 - Luyện nói cả bài.

BướcUser làm gìHệ thống/AI phản hồi
2.1Mở tab/section luyện nói các câuDanh sách sentence cards hiển thị theo flow ordering
2.2Click một suggestion card trong side panelSet card đó thành active item, highlight node tương ứng trên canvas
2.3Nghe mẫuPhát TTS của câu đang active
2.4Bấm mic/Luyện nói trên active cardSTT + pronunciation assessment cho câu đang active
2.5Xem highlightTừ đúng/sai được tô màu trong active card
2.6Nói lạiUpdate highlight và lưu best attempt cho node/card đó
2.7Click card khácChuyển active item nếu không có recording đang chạy
BướcUser làm gìHệ thống/AI phản hồi
3.1Mở tab Luyện nói cả bàiHệ thống assemble full answer script theo flow ordering, hiển thị bối cảnh + tool chips + script
3.2Chưa luyện, chỉ đọc scriptHiển thị warning: “Bạn cần luyện nói đầy đủ câu trả lời để hoàn thành bài tập này.”
3.3Bấm Nghe mẫuPhát full TTS; có thể highlight theo script nếu audio timing có sẵn
3.4Bấm Luyện nóiTạo script_snapshot, xin quyền mic nếu cần, bắt đầu ghi âm full answer
3.5Đang nóiCTA chuyển sang Đang nói #n hoặc Nói nhiều #n; hiện Dừng nói
3.6Bấm Nói xong / Dừng nóiDừng ghi âm, gửi audio đi STT + alignment + scoring
3.7AI xử lý xongHiển thị transcript alignment bằng highlight, score tổng, Nghe lại, Nói lại
3.8Hover/click highlightHiển thị annotation ngắn: phát âm tốt, thiếu từ, nói khác script, hoặc cần rõ hơn
3.9Bấm Nói lạiTạo attempt mới trên cùng script; giữ best/latest attempt trong session
3.10Bấm Tiếp tục phát triểnQuay lại canvas để chỉnh ý; nếu script đổi, full speaking attempt cũ bị đánh dấu stale
3.11Bấm Tiếp tụcChỉ enable sau khi có full attempt đủ coverage; chuyển sang câu/bài tiếp theo
TriggerAI actionHiển thị trên UI
User vào bàiCheck mic status theo user_id + exercise_typeTest mic hoặc start card
Mic test có tín hiệuSave mic_check_status = passedCho qua start card
Mic test silent/deniedKhông save passMessage retry/permission
User bấm Bắt đầu trên start cardCreate Question root + Answer #1Canvas started
User nhập Answer #1Compose answer sentence theo given questionSide panel card đầu tiên
Node idle sau khi user nhập noteCompose hoặc refresh generated_sentenceSide panel card tương ứng
User chọn nodeLoad suggestion theo selected node + parent-chainHighlight node và card liên quan
User bấm mũi tên/plus thêm nhánhLoad add-branch suggestions theo source node + directionPopover AI gợi ý / Tự viết
User chọn AI suggestionCreate node with suggested tool/noteNode mới + side panel card mới
User click badge toolOpen tool menuMenu đổi tool / xóa nhánh
User đổi tool labelReinterpret note theo tool mớiSuggestion update, warning nếu mismatch
User xóa nhánhDelete node + descendants sau xác nhận nếu cầnRecompute ordering; mark attempts stale nếu script đổi
User dùng zoom/fit/fullscreenUpdate viewport onlyCanvas thay đổi khung nhìn, không đổi graph
User click suggestion cardSet active sentence/nodeCard mở control luyện nói, node được highlight
User bấm Luyện nói trên active cardStart sentence-level recordingActive node/card recording state
User bấm plus từ node trốngKhông tạo nodeFocus input + “Điền ý cho ô này trước nhé.”
User bấm plus khi AI đang analyzing node có nội dungVẫn cho mở add-branch popoverNode cũ vẫn loading, user có thể chọn tool để tạo node mới
AI trả needs_fix cho node bất kỳLock tạo node mớiNode/card có warning, plus disabled
User sửa node needs_fixClear lỗi cũ, analyze lạiPlus được mở trong lúc chờ kết quả mới
User thêm node dọcTreat node mới as child of selected nodeEdge dọc + label như #2.A
Flow quá sâuNudge mở nhánh ngang mớiWarning nhẹ, không xóa node
Node thiếu noteKhông compose full sentencePlaceholder chờ ý tưởng
Chuyển sang luyện nóiFreeze flow ordering tạm thờiDanh sách câu luyện
Mở tab luyện cả bài khi canvas chưa sẵn sàngKhông tạo script luyện nóiNhắc hoàn thiện ý trước
Mở tab luyện cả bài khi script sẵn sàngAssemble full script theo flow orderingPanel Luyện nói cả bài + warning chưa luyện
User bấm Luyện nóiFreeze script_snapshot cho attempt hiện tạiRecording state
User bấm Dừng nóiTranscribe, align, score full attemptProcessing state
Coverage đủLưu full attempt, hiển thị score + highlightEnable Tiếp tục
Coverage thiếu hoặc không có tiếngKhông tính completionMessage retry + Nói lại
User đổi canvas sau full attemptMark attempt cũ staleNhắc luyện lại theo script mới
User hover/click highlightReturn annotation ngắn theo spanPopover/tooltip gần đoạn text
Thời điểmAudio sourceTrigger
Test micShort microphone sampleUser nói thử trong preflight
Sau khi có generated_sentencePre-generate TTS per sentenceTự động, chạy ngầm nếu khả thi
Bước luyện từng câuPlay sentence TTSUser bấm nghe mẫu
Active sentence recordingSentence-level recordingUser bấm Luyện nói trên active card
Bước luyện cả bàiConcat hoặc stream các sentence TTSUser bấm play full
Bài full của userFull recording trong một lần nóiUser bấm Luyện nói rồi Dừng nói
Nghe lại bài userPlayback full recording; có thể seek theo segment nếu alignment có sẵnUser bấm Nghe lại
  • Question.
  • Answer trả lời trực tiếp cho câu hỏi được giao.
  • Có ít nhất 2 supporting Linear Tool nodes.
  • Mỗi supporting node có tool label và note.
  • Không còn node needs_fix.
  • AI đã tạo generated_sentence cho các node được đưa vào bài nói.
  • Mic check không phải hard gate nếu user đã có một full recording nghe được. Nếu user skip mic check nhưng audio thật bị silent, hệ thống invalidate skipped và quay lại retry/mic check.
  • Canvas đạt readiness.
  • Full answer script đã được assemble theo flow ordering.
  • Không còn sentence segment đang analyzing.
  • Nếu user đã nói full bài trước đó nhưng canvas/script thay đổi, attempt cũ không còn tính completion cho script mới.
MứcĐiều kiệnLabel
Chưa đạtChưa nói hoặc > 50% từ đỏ-
Đạt<= 30% từ đỏ”Phát âm ổn”
Xuất sắc100% xanh”Phát âm chuẩn”

Per-sentence scoring chỉ là hard gate khi package có bước luyện từng câu. Với tab luyện cả bài, dùng score tổng và coverage để quyết định completion.

SignalVai tròCompletion rule
CoverageUser có nói đủ phần lớn full answer khôngHard gate
FluencyMức liền mạch, ít ngắt quãng, tự nhiênFeedback chính
PronunciationPhát âm theo từ/cụm nổi bậtFeedback phụ, không biến thành drill từng từ
CoherenceLogic bài nói có nối ý được khôngChủ yếu kế thừa từ canvas; chỉ flag nếu transcript lệch mạnh

V1 recommendation: completion cần coverage_status = enough, không bắt buộc score phải đạt 80/100. Score dùng để thúc đẩy nói lại, còn quyền Tiếp tục mở sau khi user đã thật sự nói full answer.

  • Session tính là hoàn thành khi:
    • Canvas đạt readiness.
    • Full speaking readiness đạt.
    • Học viên đã ghi âm full answer ít nhất 1 lần.
    • Full attempt có coverage đủ, không phải silent/partial.
    • Nếu sentence drill được bật, per-sentence practice có thể là gate riêng của package đó, không phải gate mặc định của flow 2 tab.
  • Không yêu cầu mọi từ phải xanh hoặc score tổng phải đạt 100/100.
  • Mini-map / fit-to-screen: hữu ích khi canvas có nhiều nhánh, tránh user mất phương hướng.
  • Branch focus mode: click một nhánh để side panel chỉ hiện câu của nhánh đó; giảm overload khi flow dài.
  • Tool mismatch hint: AI phát hiện note kiểu nguyên nhân nhưng node đang để Description, rồi đề xuất đổi tool label.
  • Depth nudge: sau 2-3 node dọc, UI gợi ý mở nhánh ngang mới thay vì tiếp tục kéo dọc.
  • Version history per sentence: lưu các generated sentence gần nhất khi user chỉnh note, để tránh mất câu tốt.
  • Mini-map: nếu graph thường lớn hơn viewport, thêm mini-map compact hơn các nút zoom rời.
  • Full-answer attempt history: lưu best/latest attempt để user so sánh lần nói đầu và lần nói lại.
  • Auto-scroll script during recording: nếu full answer dài, script tự giữ đoạn đang nói trong viewport.
  • Sentence-level heatmap after full attempt: sau khi nói xong, click một câu trong script để thấy đoạn audio tương ứng và lỗi nổi bật.
  • Knowledge base: Logic Linear Tools, chiều ngang/chiều dọc, và Part-specific framework.
  • Mic permission + audio signal detector: Kiểm tra mic preflight và phát hiện silent recording.
  • AI composer: Convert note + tool label + parent-chain thành sentence.
  • Branch suggestion engine: Đề xuất Linear Tool + note khi user bấm thêm nhánh từ một node.
  • Canvas viewport engine: Pan, zoom, fit view, fullscreen, và center selected node.
  • TTS engine: Pre-generate audio mẫu khi có sentence.
  • Speech-to-text + pronunciation assessment: Nhận diện câu nói, align với script, đánh giá phát âm per word/cụm từ.
  • Full answer scorer: Tính coverage, fluency, pronunciation, và score tổng cho attempt nói liền mạch.
#QuestionStatus
1Demo deployed có phải source-of-truth 1:1 cho interaction v1, hay chỉ là reference để nâng cấp?Cần confirm product/tech
2Side panel có cần nút Accept / Regenerate, hay auto-refresh là đủ cho v1?Cần quyết định UX
3Khi user đổi flow sau khi đã luyện nói, có freeze attempt cũ hay recompute toàn bộ?Đề xuất V1: freeze attempt cũ theo snapshot, mark stale nếu script đổi
4TTS latency có đủ nhanh để pre-gen sau mỗi sentence update không?Cần confirm tech
5Ngưỡng “Đạt” cụ thể có giữ <= 30% từ đỏ không?Chỉ áp dụng rõ cho sentence drill; full speaking ưu tiên coverage + score tổng
6Mic check có cần invalidate theo device/browser không?Đề xuất V1: nhớ passed/skipped theo user_id + exercise_type, invalidate khi permission revoked, device đổi, hoặc recording thật silent
7AI suggestion khi thêm nhánh có cần cache theo node không?Đề xuất V1: cache ngắn theo node_id + note + tool_type + direction, refresh khi note/tool đổi
  • 2026-04-29: Loại bỏ Opinion khỏi Linear Tool framework - chỉ còn 3 loại: Description, Cause, Effect. Cập nhật ở Element table, tool_type enum, F2 node label rule, F2.1 Add Branch popover, F3 Linear Tool Logic, và F5.1 validation catalog (xóa case Opinion lacks viewpoint). Lý do: quan điểm/nhận định cá nhân về một node được hiểu là một dạng Description về cảm xúc/đánh giá; không cần tool riêng.
  • 2026-04-29: Confirm Empty Answer (not_ready) UI đã có thiết kế trong Figma (frame Empty) - tooltip “Empty thì không được tạo thêm” + ⊘ icon trên active card + side panel “Chờ nội dung…” cho card pending. Confirm Tự viết tab đã có sẵn trong Add Branch popover (2 tab: AI gợi ý + Tự viết).
  • 2026-04-29: Tài liệu hóa các state Full Speaking còn thiếu UI - processing, needs_retry, stale, và session completion sau 4 câu - dưới dạng wireframe trong Figma section Wireframe - Logic bổ sung (Linear Tool).
  • 2026-04-24: Bổ sung canvas operations - thêm nhánh bằng popover AI gợi ý/tự viết, đổi tool bằng badge menu, viewport controls, và active sentence card để luyện nói từng câu.
  • 2026-04-24: Bổ sung entry flow - mic check preflight nhớ theo user + exercise type, start card với câu hỏi cho sẵn, và Question -> Answer canvas start.
  • 2026-04-24: Bổ sung logic tab Luyện nói cả bài - attempt snapshot, recording states, full speaking messages, coverage gate, hover annotation, stale attempt khi script đổi.
  • 2026-04-24: Cập nhật branch gating và validation message catalog - node trống chặn tạo node mới; node đang AI analyzing vẫn cho tạo tiếp; node có lỗi needs_fix khóa tạo mới cho tới khi sửa.
  • 2026-04-21: Reframe Linear Tools từ outline grid sang canvas graph; bổ sung node/edge model, AI sentence composer panel, flow ordering, canvas readiness, và cải tiến dài hạn.
  • 2026-04-06: Rewrite - bổ sung Features, User Actions per bước, AI-UI Interaction, System Audio, Completion & Scoring.
  • 2026-04-06: Khởi tạo draft từ meeting note.