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

GitNexus + CodeGraph + BMAD: Đọc Code Bằng Index, Đo Bằng Token

Đo thật 2 knowledge graph trên monorepo 3.600 file: cái nào rẻ hơn, mù ở đâu, và cách chia vai trong workflow BMAD.

Mình cài GitNexus và CodeGraph để agent đọc code rẻ hơn. Nghe rất hợp lý: index sẵn cả repo, hỏi một câu là ra, khỏi grep lòng vòng. Nhưng khi đo thật bằng byte trên một monorepo 3.600 file, con số đầu tiên đi ngược kỳ vọng — có trường hợp index còn đắt hơn đọc file thẳng tới 30%.

Tiết kiệm token không đến từ "đọc gọn hơn". Nó đến từ "không đọc file sai".

Bài này là kết quả đo thật hai engine knowledge-graph trên một repo Go + TypeScript + Vue cỡ 3.600 file, cùng cách mình gắn chúng vào quy trình BMAD (Analyst → PM → Architect → SM → Dev → QA). Không có con số nào ước lượng — tất cả lấy từ wc -c và query trực tiếp vào file index.

Hai Index, Hai Triết Lý Trái Ngược

Điểm mấu chốt mà tài liệu của cả hai đều không nói rõ: chúng thay thế hai thứ khác nhau.

🔍

CodeGraph — thay thế Read

Trả về structure kèm source verbatim nguyên file, ~17kB mỗi call (khoảng 6 file). Không cần đọc lại file đã hiện.

  • Có watcher ~500ms
  • Gắn cờ "no covering tests"
  • Bắt được hop động Vue

🧭

GitNexus — thay thế Grep

Trả về structure thuần, ~1–3kB. Muốn code thì thêm cờ để lấy source ở mức symbol, không phải cả file.

  • Cypher query tự do
  • Phủ .md / .sql / migration
  • Không có watcher

Vì CodeGraph trả nguyên văn file, nó không nén nội dung. Đọc một hàm 44 dòng qua CodeGraph tốn đúng số token như Read cả file chứa nó, cộng thêm metadata. Đó là lý do ở scope nhỏ mà bạn đã biết chính xác path, Read thẳng vẫn rẻ nhất.

Vùng Phủ — Chỗ Quyết Định Mọi Thứ

Mình đếm trực tiếp trong index của cả hai. Phần thân code gần như trùng khớp, nhưng phần còn lại thì một bên trắng hoàn toàn:

Loại file CodeGraph GitNexus ✨
Go / TypeScript / Vue 1.396 / 1.033 / 325 1.398 / 1.030 / 325
Markdown (.md) ❌ 0 ✅ 350
SQL (.sql) ❌ 0 ✅ 327
Migration ❌ 0 ✅ 145
Watcher tự cập nhật ✅ ~500ms ❌ analyze tay
Cờ test coverage ✅ Có ❌ Không

Với một persona Architect, cái cột "0" kia là chí tử. Mục Data layer của bản thiết kế cần biết query .sql nào chạm bảng nào, migration nào đã đổi schema. CodeGraph không thấy một file nào trong số đó. GitNexus trả lời bằng một câu Cypher:

# .sql nào chạm bảng app_settings?
gitnexus cypher -r <REPO> \
  "MATCH (f:File) WHERE f.filePath ENDS WITH '.sql'
   AND f.content CONTAINS 'app_settings'
   RETURN f.filePath AS p" --limit 20

Nó trả về đúng 3 file query cộng 1 migration. Cùng cách đó, mình tìm được cả file .md đang ghi quyết định thiết kế cho chính việc đang làm — thứ mà một index chỉ-code không bao giờ thấy.

Chi Phí Thật, Đo Bằng Byte

# cùng một symbol, 3 cách hỏi
gitnexus context <Sym> 2.454 B # không source
gitnexus context <Sym> --content 3.753 B # CÓ source, 44 dòng
codegraph_explore 17.000 B # dump 2–6 file nguyên vẹn

Chênh 4,5 lần, vì GitNexus trả đúng thân hàm bạn hỏi còn CodeGraph trả cả file (và thường kèm 1–2 file không liên quan). Quy ra một lượt đọc code cho persona Architect — đã trừ phần chi phí cố định đọc tài liệu, vốn giống nhau ở mọi phương án:

Phương án Byte So với baseline Đủ mục Data layer?
Read + Grep thủ công 74 kB ✅ (đắt)
Chỉ CodeGraph 50 kB −32% ❌ mù .sql
Hybrid cả hai 37 kB −50%
Chỉ GitNexus 26 kB −65%

Chia Vai Theo Loại Việc, Không Theo Tool Ưa Thích

Con số ở trên chỉ đúng cho việc đọc để thiết kế. Lúc đang sửa code thì bức tranh đảo chiều, và đây là chỗ dễ sai nhất:

1. Design / review / audit → GitNexus

Architect, Analyst, PM, post-review, security audit. Đọc nhiều nhưng không sửa code, nên index đứng im không gây hại. Rẻ nhất và phủ đủ tài liệu.

2. Implement / fix bug → CodeGraph

Dev đang sửa file liên tục. GitNexus sẽ trả code ngay sau khi bạn ghi file — đúng lúc nguy hiểm nhất. Watcher của CodeGraph mới bám được nhịp này.

3. Dưới 5 file, đã biết path → Read thẳng

Ở scope nhỏ, metadata và over-fetch của index làm nó đắt hơn Read khoảng 30%. Đừng dùng index chỉ vì đã cài nó.

Năm Cái Bẫy Mình Đã Đạp

⚠️ Bẫy đắt nhất: trong Cypher, đừng bao giờ RETURN f hay RETURN fn. Node có prop content chứa toàn bộ nội dung file — một query trả 2 dòng đã ngốn ~10kB. Luôn liệt kê prop cụ thể: RETURN f.filePath.

  • Query bằng từ khái niệm thì CodeGraph lệch âm thầm. Mình hỏi về một seam kiến trúc, có chữ "tag" trong câu, nó trả về nguyên service quản lý tag của module khác — trông rất hợp lý. Phải query bằng tên định danh thật (package/type/func/file), một concern một call.
  • Edge EMITS_EVENT của GitNexus là rác. 238 edge với src == event == tên file, chỉ bắt $emit của Vue. Muốn tìm listener của một event backend thì dùng full-text trên content — nó trả về tên hàm chứ không chỉ số dòng như grep.
  • Edge QUERIES gần như vô dụng nếu backend không phải Prisma. 2.068 edge nhưng chỉ 25 cái chạm file Go.
  • Execution flow bị nhiễu ở repo Go. Mọi "process" đều root ở main() nên ra toàn "Main → Config". Bỏ qua cho việc thiết kế.
  • Nhớ cờ chỉ định repo. Registry chứa nhiều repo cùng lúc; thiếu -r là lỗi ngay.

Gắn Vào BMAD Như Thế Nào

Kết luận chỉ có giá trị khi nó nằm trong prompt của từng persona, không phải trong đầu một người. Mình viết một playbook code-graph.md làm nguồn sự thật duy nhất, rồi nối vào các slash-command:

Luồng Đã Chốt

/bmad-architect — bước 0
Đối chiếu indexed commit vs current commit
lệch → analyze lại (~100s)
Đọc code bằng GitNexus, không Read từng file
/bmad-dev chuyển sang CodeGraph
✅ watcher thấy file vừa sửa

Một chi tiết vận hành đáng kể: GitNexus tự chèn một khối hướng dẫn vào CLAUDE.md mỗi lần index. Khối đó ra lệnh dùng MCP tool trong khi repo của mình chỉ có CLI, và áp mandate nặng hơn quy trình đã chốt — để nguyên thì mọi phiên sau sẽ gọi tool không tồn tại. Xoá cũng vô nghĩa vì nó sinh lại. Cách xử lý: đặt phần bảo lưu ngoài cặp marker <!-- gitnexus:start/end -->, trỏ về playbook làm nguồn sự thật.

🧪 Đừng Tin Suy Luận — Chạy Thử

Giả thuyết "note ngoài marker sẽ sống sót" nghe hợp lý, nhưng mình commit trước rồi chạy full re-index để thử thật:

gitnexus analyze -f → 103.1s | 69.342 nodes

Kết quả

Note nguyên vẹn. Diff duy nhất là dòng đếm symbol bên trong marker — nên mình ghi luôn cảnh báo "thấy CLAUDE.md dirty sau analyze là bình thường".

Phần thưởng bất ngờ

Cờ no covering tests mà CodeGraph gắn cho một middleware bảo mật vừa port hoá ra đúng. Test bổ sung sau đó đưa coverage lên 83,9% và 57,0% — cùng lúc lộ một bug guard idempotent thật.

Chốt Lại

  • Index không nén code. Lợi ích thật là không đọc file sai, nên đừng kỳ vọng giảm một nửa token chỉ vì đã cài tool.
  • Chọn theo loại việc: design → GitNexus (−65%), implement → CodeGraph (vì watcher), scope nhỏ → Read thẳng.
  • Coverage tài liệu quan trọng ngang coverage code. Một index mù .sql.md không đỡ được persona Architect.
  • Ghi kết luận vào repo, không vào memory. Playbook commit cùng code thì máy khác và phiên khác đều áp dụng được.
  • Đo, đừng đoán. Cả hai giả định ban đầu của mình đều sai cho tới khi chạy wc -c.

🔗 Tài Nguyên

# dựng index trên máy mới
gitnexus analyze
codegraph init -i

Bài viết được thực hiện bởi team Loc Nguyen Data — chuyên tư vấn và triển khai giải pháp AI/Data cho doanh nghiệp.