---
url: https://docs.nemo12.com/product/family-notes-review/decisions.md
description: >-
  Chủ dự án chốt gì qua bốn vòng: bỏ cột, mô hình note + tag, mười tag đóng,
  reply một tầng, rà các hệ tương tự (§10b tới §10f).
---

# 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](../../architecture/sdd-015-student-portrait.md)** đ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.**

```text
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 · JTBD
```

Ba 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:

```text
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 Nemo12
```

**3. 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](../../reference/context-builder.md).

**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](../../architecture/sdd-015-student-portrait.md) đ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](../../architecture/sdd-024-dory.md) §2. Ghi lại ở đây làm nguồn, và SDD-024 sửa theo.

### Toàn bộ mô hình

```text
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

1. **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.
2. **Note trả lời note.** `reply_to_id` là 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.
3. **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

```text
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ả:

```json
{ "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):

1. **Chỉ chọn trong chín tag**, không bao giờ bịa tag mới.
2. **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.
3. **Người bấm từng cái**, có nút áp dụng tất cả nhưng không tự áp.
4. **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 |
| --- | --- | --- |
| **S**ubjective | bệnh nhân **nói** gì | `opinion` |
| **O**bjective | thầy thuốc **quan sát** được | `fact` |
| **A**ssessment | thầy thuốc **diễn giải** | `hypothesis` |
| **P**lan | đị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:

1. **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ẻ.
2. **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ước
* `for-mentor` — thứ nên đọc trước
* `money` — 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** |
