Family Notes: các vòng chốt mô hình note + tag
10b. Đã chốt (chủ dự án trả lời 2026-08-26)
| Q | Câu hỏi | Quyết định ✅ |
|---|---|---|
| Q2 | Nạp 4 ghi chép hiện có? | Nạp luôn vào hệ thống |
| Q3 | Note thuộc gia đình hay học sinh? | Đi theo cả gia đình |
| Q4 | Có lưu câu đánh giá cách cha mẹ đối xử với con? | Có lưu, nội bộ mentor đọc |
| Q5 | Khoá theo cả hồ sơ hay theo từng mẩu? | Khoá cả profile, không khoá lẻ từng mẩu |
| Q6 | Có ghi thông tin tài chính của gia đình? | Có ghi |
| Q7 | 5 mục bắt buộc + 4 mục tuỳ chọn? | Đồng ý (sửa lại ở Q29 bên dưới) |
| Q8 | Giữ tên tiếng Anh cho 3 insight? | Giữ Family Dynamics · Learning Environment · Hidden Motivation |
| Q9 | Cho thêm insight thứ tư? | Không. Đúng ba slot |
| Q10 | Next Actions thành việc thật trong Anchor? | Có |
| Q11 | "Lưu ý cho Mentor" hiện đầu tiên? | Có |
| Q13 | Ảnh gắn vào Family Note? | Ảnh gắn theo GIA ĐÌNH, không tách riêng "ảnh buổi thăm nhà" |
| Q22-25 | Đưa rubric 5 tiêu chí vào hệ thống? | Không đưa. Giữ là thói quen ngoài phần mềm |
| Q29 | JTBD là mục chuẩn? | JTBD là mục chuẩn; Pains gộp vào Concerns, không tách mục riêng |
| Q1 | Một bản sống hay nhiều bản theo lần gặp? | Phương án C: buổi gặp là bản ghi bất biến, hồ sơ sống do hệ tự dựng từ chúng |
| Q26 | "Simba" là gì? | Hệ thống cũ dành cho mentor. Sẽ thay bằng Nemo12 |
| Q27 | "Learner Profile" là gì? | Gần như Student Portrait đang có |
| Q41 | Hình dạng của Pains? | Không có mục Pains riêng — gộp vào concerns |
| Q42 | Cờ khoá hồ sơ nhạy cảm? | Chưa làm vội. Giữ nguyên REQ-MEN-01: mọi Dolphin xem mọi family, có audit |
Hệ quả phải xử lý
1. Q1 = C là quyết định nặng nhất, vì nó đặt ra hai tầng dữ liệu.
family_visits ← buổi gặp, BẤT BIẾN, chỉ nối thêm. Nguồn sự thật.
↓ (hệ tự dựng, KHÔNG sửa tay được)
Family Model ← hồ sơ sống: hiện trạng goals · concerns · insights · JTBDBa hệ quả đi kèm, cả ba đều là ràng buộc chứ không phải tuỳ chọn:
- Hồ sơ sống không có nút Sửa. Muốn đổi thì ghi thêm một mẩu mới vào một buổi. Có nút sửa là quay lại phương án A và mất chỗ dựa của mọi câu.
- Mỗi câu trong hồ sơ sống phải trỏ ngược về buổi sinh ra nó. Đây là thứ làm cho tiêu chí 5 của audit đạt được: mentor mới đọc một màn, mà vẫn kiểm được câu nào đến từ đâu.
- Biết thời điểm mới xử lý được chuyện thông tin cũ đi. Một concern ghi tháng Tư mờ dần theo
last_seen_at; không có tầng buổi gặp thì không có cột đó.
2. Cấu trúc mục chốt lại. Pains gộp vào concerns, JTBD lên mục chuẩn:
BẮT BUỘC Mục tiêu gia đình · 3 Insights · Concerns (gồm cả pains) · JTBD
Lưu ý cho Mentor (hiện ĐẦU TIÊN) · Next Actions · Evidence
TUỲ CHỌN Điều cần hiểu thêm về học sinh · Background gia đình · Relationship với Nemo123. Chưa làm cờ khoá (Q42) — nói rõ cái đang đánh đổi. REQ-MEN-01 giữ nguyên: mọi Dolphin xem mọi family, mỗi lượt ghi audit_log. Nghĩa là những câu như "bố thường xuyên chê và mỉa mai con" và các chi tiết tài chính mọi mentor trong đội đều đọc được. Đây là quyết định có ý thức của chủ dự án, không phải chỗ bị bỏ sót; ghi lại ở đây để khi đội đông lên thì có sẵn chỗ mở lại. Hai thứ vẫn giữ nguyên bất kể: không ra API công khai, và không vào prompt AI nếu chưa qua Context Builder.
4. Luật ghi thông tin tài chính (Q6, chủ dự án đồng ý). Ghi dữ kiện quan sát được — "mua kính 12 triệu cho con" — thay vì kết luận về mức sống — "gia đình khá giả". Không sinh phân loại, không sinh xếp hạng, không dùng làm điều kiện lọc gia đình.
5. Simba và Learner Profile (Q26-Q27). Simba là hệ mentor cũ, sẽ thay bằng Nemo12. Learner Profile ≈ Student Portrait đang chạy. Hai hệ quả khi nạp bốn ghi chép: Next Action "yêu cầu Tú upload sản phẩm lên hệ thống simba" phải trỏ lại sang Nemo12, và các insight cần "đưa vào Learner Profile" chính là đưa vào Student Portrait — thứ đã có sẵn chỗ chứa, không cần dựng mới.
10c. Chốt vòng 3 — mô hình NOTE + TAG (chủ dự án 2026-08-26)
Chỉ đạo: "làm sao để số lượng fields, và số lượng thông tin vô cùng ít. Ví dụ như có nhiều notes, và mỗi note thì có thể gắn một hoặc một vài tags."
Điều này thay thế phần lược đồ nhiều cột đã phác ở SDD-024 §2. Ghi lại ở đây làm nguồn, và SDD-024 sửa theo.
Toàn bộ mô hình
family_visits id · family_id · occurred_on · attendees · place(home|online|other) · created_by
└─ buổi gặp. BẤT BIẾN (Q1=C). Sáu cột, hết.
family_notes id · family_id · body · tags · learner_id? · visit_id? · reply_to_id?
· author_user_id · created_at · status(active|archived)
└─ MỌI THỨ KHÁC. Chín cột, trong đó bốn cột là sổ sách.Không có bảng family_context_items, không có family_signals, không có cột kind/topic/layer/confidence. Tất cả những thứ đó là tag.
Tag làm được việc của các cột đã bỏ
| Việc | Trước (cột) | Nay (tag) |
|---|---|---|
| Mẩu này thuộc mục nào | kind enum | goal · insight/dynamics · insight/environment · insight/motivation · concern · jtbd · mentor-note · next-action · background · relationship · student |
| Ba tầng sự thật | layer enum | said · seen · guess |
| Giả thuyết đang ở đâu | bảng riêng + trạng thái | guess (đang chờ) · guess:confirmed · guess:rejected |
| Nhạy cảm | cột riêng | sensitive |
| Số liệu hành vi | bảng metric | metric |
Ba thứ được thêm mà không cần cột nào
- Hộp vào biến mất như một khái niệm riêng. Một note chưa có tag chính là inbox. Không bảng riêng, không màn riêng, không luồng chuyển đổi. Phân loại = gắn tag.
- Note trả lời note.
reply_to_idlà cột duy nhất tôi giữ lại ngoài mức tối thiểu, vì nó mua được cả một chuỗi: giả thuyết → tiêu chí kiểm chứng → kết luận, mỗi bước là một note trả lời note trước. Không có nó thì ba thứ đó phải thành ba bảng. - Mục bắt buộc trở thành tín hiệu thay vì rào chắn. Không ép mỗi note đủ mục nữa; thay vào đó hệ nhìn cả gia đình và nói "nhà này chưa có note nào gắn
goal". Điều này tốt hơn phương án cũ: nó không chặn người đang ghi vội, mà vẫn chỉ ra chỗ thiếu.
Ba cái giá phải trả, và cách trả
| Cái giá | Xử lý |
|---|---|
Tag tự do thì trôi — concern · concerns · lo-lắng thành ba tag khác nhau | Có danh sách tag chuẩn gợi ý sẵn; vẫn gõ tag mới được nhưng tag lạ bị đánh dấu để rà lại. Không cấm, vì cấm thì lại thành biểu mẫu |
Tag loại trừ nhau vẫn gắn chung được — một note vừa said vừa guess là vô nghĩa | Hai nhóm loại trừ kiểm ở tầng API: tối đa một tag tầng, tối đa một tag mục. Đây là một luật, không phải một cột |
| Truy vấn chậm hơn cột | Chấp nhận. Quy mô ở đây là vài nghìn note, không phải vài triệu; và có index trên family_id |
Vì sao đổi hướng này đúng chứ không chỉ là gọn hơn
Bốn ghi chép mẫu là văn xuôi. Ép chúng vào mười lăm cột nghĩa là người ghi phải quyết định phân loại ngay lúc viết — đúng lúc họ vừa đi thăm nhà về và chỉ muốn ghi cho kịp. Với note + tag, họ dán cả bài vào một note, và việc cắt nhỏ + gắn tag làm sau, hoặc để AI đề xuất rồi bấm duyệt.
Nói cách khác: mô hình này là cách duy nhất khiến "dồn vào một chỗ, phân loại sau" thành thật thay vì thành một lời hứa trong tài liệu.
10d. Chốt vòng 4 — bộ tag đóng, reply một tầng, bỏ family_visits (2026-08-26)
Chỉ đạo: "Ưu tiên notes, mỗi note có thể gắn zero tag, 1 tag, hay nhiều tag. Và có thể reply vào note. Chỉ có đúng 1 tầng reply hoặc comment. Tags có sẵn là: pain, jtbd, event, goal, parent, child, opinion, fact, hypothesis. Tôi hơi lăn tăn về family visits, có thể bỏ đi cũng được."
Mô hình cuối
family_notes id · family_id · body · tags_json
· learner_id? · reply_to_id? · author_user_id · created_at · status
└─ MỘT bảng. Không còn family_visits.Bỏ family_visits. Một buổi thăm nhà nay là một note gắn event. Bảng thứ hai chỉ đáng tồn tại khi có thứ gì đó truy vấn riêng nó, mà hiện không có. Cái mất: không còn cột có cấu trúc cho ai đi · ở đâu (Q12) — hai thứ đó vào thân note. Chấp nhận được, vì Q12 vốn là mục "nên có" chứ không phải mục chặn.
Reply đúng một tầng. reply_to_id chỉ trỏ tới note gốc; API từ chối reply vào một reply. Đây là bất biến rẻ nhất có thể kiểm: reply_to_id IS NULL ở note được trỏ tới.
Chín tag, ba trục trộn phẳng
| Trục | Tag |
|---|---|
| Nói về ai | parent · child |
| Loại nội dung | pain · jtbd · event · goal |
| Mức chắc chắn | fact · opinion · hypothesis |
Ba trục nhưng một danh sách phẳng, không nhóm loại trừ. Nghĩa là gắn cả fact lẫn hypothesis vào một note vẫn được — hệ không chặn, chỉ nhắc nhẹ và để nút gợi ý AI đề nghị bỏ bớt. Chặn cứng là quay lại làm biểu mẫu.
Danh sách này đóng ở đợt đầu: chín tag, không cho gõ tag mới. Mở ra sau khi biết tag nào thật sự được dùng.
Bộ lọc mặc định ở đầu trang
Chọn một bộ lọc là hệ tự chọn sẵn vài tag:
| Bộ lọc | Chọn tag |
|---|---|
| Cần chú ý | pain + hypothesis |
| Về con | child |
| Về bố mẹ | parent |
| Đã kiểm chứng | fact |
| Mục tiêu & động lực | goal + jtbd |
| Chưa phân loại | note có zero tag |
Bộ lọc cuối quan trọng nhất: note zero tag chính là hộp vào, và nếu không có lối vào nó thì nó mục ruỗng ở đó mãi.
Nút gợi ý tag bằng AI
POST /v1/mentor/notes/{id}/suggest-tags → Workers AI qua gateway nemo12 → trả:
{ "add": [{"tag": "pain", "why": "..."}], "remove": [{"tag": "fact", "why": "mâu thuẫn với hypothesis"}] }Bốn ràng buộc, cả bốn đều rút từ bài học của các hệ tự gắn nhãn (§10e):
- Chỉ chọn trong chín tag, không bao giờ bịa tag mới.
- Mỗi đề xuất kèm một câu lý do — không có lý do thì người dùng chỉ có hai lựa chọn: tin mù hoặc tắt đi.
- Người bấm từng cái, có nút áp dụng tất cả nhưng không tự áp.
- Ghi lại tỉ lệ chấp nhận. Một tag bị từ chối quá nửa số lần thì định nghĩa tag đó sai, hoặc prompt sai — không phải người dùng sai.
10e. Rà soát các hệ tương tự — và điều rút ra
Ba lựa chọn vừa chốt (note phẳng + tag · reply một tầng · ba mức chắc chắn) không mới. Chúng trùng với những thứ đã được kiểm chứng hàng chục năm ở nơi khác, và chính điều đó là tin tốt. Dưới đây là cái đáng học và cái đáng tránh từ từng hệ.
1. Bệnh án SOAP — tiền lệ mạnh nhất cho fact · opinion · hypothesis
Ngành y dùng khuôn SOAP cho ghi chép bệnh nhân từ những năm 1960:
| SOAP | Nghĩa | Tag tương ứng |
|---|---|---|
| Subjective | bệnh nhân nói gì | opinion |
| Objective | thầy thuốc quan sát được | fact |
| Assessment | thầy thuốc diễn giải | hypothesis |
| Plan | định làm gì | (ở Nemo12 là Action trong Anchor) |
Ba tag của anh map gần như một-một vào S/O/A. Đây là bằng chứng mạnh rằng cách chia này đúng chứ không phải một tầng trừu tượng thừa: một ngành mà ghi sai có thể chết người đã hội tụ vào đúng ba mức ấy.
Cái đáng học: SOAP tách S và O để người đọc sau biết ai chịu trách nhiệm cho câu đó. Cùng một câu "cháu không tập trung" — nếu là S thì đó là lời mẹ, nếu là O thì đó là điều mentor thấy. Hai thứ dẫn tới hai hành động khác nhau.
Cái đáng chú ý: SOAP có P mà bộ tag này không có. Ở Nemo12, P nằm ở Anchor (Q10 đã chốt Next Action là Action thật). Nên không phải thiếu — nhưng phải nhớ rằng một note không bao giờ là một việc phải làm; muốn thành việc thì nó phải đi sang Anchor.
2. Slack — reply đúng một tầng là lựa chọn có chủ đích
Slack cố ý làm thread chỉ sâu một tầng. Reddit và diễn đàn cho lồng vô hạn, và kết quả là những cuộc trò chuyện không ai tìm lại được: một câu quan trọng nằm ở tầng bảy thì coi như đã mất.
Cái đáng học: một tầng là đủ cho 95% nhu cầu — bổ sung, đính chính, kết luận. Ai cần sâu hơn thì tạo note gốc mới. Bất biến này còn rẻ để kiểm: chỉ cần từ chối reply vào note đã có reply_to_id.
3. Gmail labels vs thư mục — bài học lớn nhất về tag
Gmail thắng thư mục vì một thứ không nằm ở chỗ gắn nhãn mà ở chỗ đọc lại: một email thuộc nhiều nhãn cùng lúc, và bạn tìm ra nó bằng bộ lọc chứ không phải bằng cách nhớ đã bỏ nó vào ngăn nào.
Cái đáng học: tag không có bộ lọc tốt thì là tag chỉ-ghi. Người ta gắn tag rồi không bao giờ dùng lại, và sau ba tháng thì thôi gắn. Đây chính là lý do bộ lọc mặc định ở đầu trang (§10d) không phải trang trí — nó là thứ làm cho việc gắn tag có nghĩa.
4. Zendesk · Intercom — hệ đã chạy AI gắn nhãn ở quy mô thật
Các hệ hỗ trợ khách hàng đã tự động gắn nhãn ticket bằng AI nhiều năm. Hai thất bại lặp lại ở mọi nơi:
- Tự gắn không hỏi → nhãn sai tích tụ, người dùng mất niềm tin vào toàn bộ hệ nhãn, rồi thôi lọc theo nhãn. Sửa được bằng: chỉ đề xuất.
- Không đo tỉ lệ chấp nhận → không ai biết nhãn nào đang hỏng. Sửa được bằng: ghi lại từng lần chấp nhận và từ chối.
Đây là gốc của bốn ràng buộc ở §10d.
5. Công tác xã hội và bảo vệ trẻ em — gần nhất về loại dữ liệu
Hồ sơ ca trong công tác xã hội chứa đúng loại nội dung mà bốn ghi chép của Nemo12 đang chứa: nhận định về cách cha mẹ đối xử với con, hoàn cảnh kinh tế, quan hệ trong nhà. Ngành này có hai luật viết bằng máu:
- Tách quan sát khỏi phán xét trong chính bản ghi — vì hồ sơ sẽ được đọc bởi người không có mặt lúc đó, và có thể được dùng cho một quyết định về đứa trẻ.
- Ghi rõ ai nói câu đó — một nhận định không có tác giả là một nhận định không ai chịu trách nhiệm.
Cả hai đã có trong thiết kế: fact/opinion/hypothesis và author_user_id. Cái chưa có: opinion không nói được đó là ý kiến của AI. Ý kiến của mẹ và nhận xét của mentor đang cùng một tag. Xem khuyến nghị bên dưới.
6. Tana · Obsidian · Notion — bẫy nở tag
Các hệ ghi chú cá nhân cho tự do tạo tag, và kết quả quen thuộc là vài trăm tag dùng một lần, ba biến thể của cùng một khái niệm, không ai lọc được gì.
Cái đáng học: giữ danh sách đóng ở đợt đầu — đúng như anh chọn. Mở ra sau, dựa trên số liệu tag nào thật sự được dùng, chứ không dựa trên cảm giác thiếu.
10f. Quyết định — chủ dự án uỷ quyền, hướng "giảm số lượng fields" (2026-08-26)
Trước hết một phân biệt quyết định mọi thứ bên dưới: tag không phải field. Thêm một tag không thêm cột nào — tags_json vẫn là một cột dù có 9 hay 12 tag. Hai thứ này là hai ngân sách khác nhau:
| Ngân sách | Cái giá khi vượt |
|---|---|
| Số cột | Schema phình, migration nhiều, mỗi cột là một chỗ để trống hoặc để sai |
| Số tag | Người gắn phải nhớ nhiều hơn; tag ít dùng thì gắn nửa vời, mà nửa vời thì tệ hơn không có |
Nên "giảm fields" không tự động có nghĩa là "giảm tag". Nó có nghĩa là: đừng bao giờ dựng một cột cho thứ mà một tag làm được, và trong nhóm tag thì chỉ giữ cái nào làm được việc mà không tag nào khác làm nổi.
Quyết định 1 — KHÔNG tách opinion. Giữ chín tag gốc.
Vấn đề có thật: parent + opinion mơ hồ giữa "ý kiến của phụ huynh" và "nhận định của mentor về phụ huynh".
Nhưng bốn ghi chép thật đã tự giải quyết chuyện này bằng câu chữ, không cần nhãn:
"Mẹ cho biết Tú rất hay hỏi" · "Bố lo Minh prompt chưa logic" · "Anh cho rằng nếp gia đình đã góp phần…"
Người viết tự nhiên nêu chủ ngữ. Một tag lặp lại điều mà câu văn đã nói là một tag người ta sẽ quên gắn — và tag gắn nửa vời thì mọi phép lọc sau đó đều sai.
Thay bằng một quy ước, tốn zero cột và zero tag: note gắn opinion phải nói rõ đó là ý kiến của ai ngay trong câu đầu. Nút gợi ý AI kiểm luôn điều này ("note gắn opinion mà chưa nói rõ của ai") — cùng một nút đã có, không thêm gì.
Quyết định 2 — KHÔNG thêm insight, money, for-mentor. Thêm ĐÚNG MỘT tag: key.
Ba đề xuất trước đó có ba lý do khác nhau, nhưng khi soi kỹ thì hai trong ba nói về cùng một thứ:
insight— thứ nên đọc trướcfor-mentor— thứ nên đọc trướcmoney— không phải chuyện đọc trước, mà là chuyện đối xử cẩn thận
Với hai cái đầu: chúng không phải một loại nội dung mới. Đối chiếu bốn ghi chép, ba "insight" thật ra đã là opinion hoặc hypothesis về parent/child — "gia đình có mức độ đầu tư rất cao" là một opinion về parent; "có vẻ gia đình không đơn thuần tìm một nơi dạy giỏi" tự nó đã ghi "có vẻ", tức là hypothesis. Thứ chúng mang thêm chỉ là độ nổi: cái này đọc trước.
Nên một tag key phục vụ cả hai nhu cầu, và đó là cách rẻ nhất để thi hành một quyết định đã chốt: Q11 nói "Lưu ý cho Mentor" phải hiện đầu tiên. Không có gì đánh dấu thì câu đó không thi hành được — sắp theo thời gian không ra được nó. key là thứ tối thiểu làm cho Q11 chạy.
Vì sao là tag chứ không phải cột is_key: cột là field, và field mới là thứ đang phải tiết kiệm.
Với money: không thêm. Yêu cầu thật của Q6 không phải "lọc ra được các note tiền bạc" mà là "ghi dữ kiện quan sát được thay vì kết luận về mức sống" — đó là một luật viết, không phải một nhãn. Tìm lại thì tìm bằng nội dung.
Bộ tag cuối: mười
| Trục | Tag |
|---|---|
| Nói về ai | parent · child |
| Loại nội dung | pain · jtbd · event · goal |
| Mức chắc chắn | fact · opinion · hypothesis |
| Độ nổi | key |
Danh sách đóng, không cho gõ tag mới ở đợt đầu. Mở ra sau, dựa trên số liệu tag nào thật sự được dùng.
Quyết định 3 — bộ lọc mặc định thêm một cái
| Bộ lọc | Chọn tag |
|---|---|
| Đọc trước | key |
| Cần chú ý | pain + hypothesis |
| Về con | child |
| Về bố mẹ | parent |
| Đã kiểm chứng | fact |
| Mục tiêu & động lực | goal + jtbd |
| Chưa phân loại | note zero tag |