0

Mimir: Tôi Xây Dựng Công Cụ Hiểu Code Nguồn Mở Để AI Thực Sự Hiểu Được Codebase Của Bạn

Vấn Đề

Mọi AI coding assistant tôi từng dùng — Claude, Copilot, Cursor — đều làm cùng một thứ khi bạn hỏi về codebase: nó grep, đoán mò, và hy vọng may mắn.

Hỏi nó "Cái gì sẽ bị vỡ nếu tôi thay đổi UserService?" — nó sẽ đọc vài file nó đoán là liên quan, đưa ra câu trả lời nghe có vẻ tự tin, và bỏ sót một nửa phạm vi ảnh hưởng.

Không phải lỗi của AI. Nó không có bản đồ.

Vì vậy tôi đã tự xây một cái.


Mimir Là Gì?

Mimir là một code intelligence engine viết bằng Go, lập chỉ mục toàn bộ repository của bạn thành một knowledge graph có kiểu dữ liệu và cung cấp nó cho AI agents thông qua MCP (Model Context Protocol).

Hãy nghĩ nó như việc trao cho AI assistant một GPS thay vì một bản vẽ tay cẩu thả.

# Cài đặt
go install github.com/thuongh2/git-mimir/cmd/mimir@latest

# Index dự án của bạn
mimir analyze .

# Khởi động MCP daemon
mimir daemon start

# Tự động cấu hình editor
mimir setup

Vậy thôi. AI agent của bạn giờ đây có đầy đủ knowledge graph của toàn bộ codebase.


Cơ Chế Hoạt Động

Khi bạn chạy mimir analyze, đây là những gì diễn ra bên trong:

1. Parse AST Song Song Một goroutine pool duyệt qua repo và parse từng file bằng go-tree-sitter. Hỗ trợ 8 ngôn ngữ: TypeScript, JavaScript, Go, Python, Rust, Java, C, C++. Parser workers được tạo sẵn từ đầu (tạo một tree-sitter parser tốn ~5ms — nên tái sử dụng thay vì tạo mới mỗi file).

2. Resolver Nhận Biết Scope Sau khi tất cả file được parse, một resolver hai giai đoạn xây dựng các edge xuyên file. Giai đoạn 1: xây symbol table đầy đủ (dạng trie). Giai đoạn 2: resolve các call site. Mỗi edge có điểm confidence (0.60–1.00) thể hiện độ chắc chắn của việc resolve.

3. Lưu Trữ Knowledge Graph Tất cả đi vào SQLite (pure Go, không CGO qua modernc.org/sqlite) với:

  • BM25 full-text index cho tìm kiếm từ khóa
  • HNSW vector index qua sqlite-vec cho tìm kiếm ngữ nghĩa
  • Louvain community detection để phân cụm module

4. MCP Server Một background daemon cung cấp 7 tool cho bất kỳ AI agent nào hỗ trợ MCP.


7 MCP Tools — Với Ví Dụ Thực Tế

query() — Tìm Bất Cứ Thứ Gì, Nhanh Chóng

Bạn hỏi: "Xử lý thanh toán nằm ở đâu trong code?"

Không có Mimir, AI đọc 3–4 file nó đoán là liên quan và bỏ sót entry point thực sự nằm sâu trong service layer.

Với Mimir:

query("payment processing")

→ ProcessGroup: checkout-flow
    entry: OrderController.handleCheckout (api/order.go:42)
    → PaymentService.charge (services/payment.go:88)
    → StripeGateway.createIntent (gateways/stripe.go:31)
    → OrderRepository.markPaid (repo/order.go:120)

AI giờ biết toàn bộ call chain chỉ trong một lần hỏi. Không cần đoán mò nữa.


context() — Nhìn 360 Độ Về Một Symbol

Bạn hỏi: "Giải thích cách AuthMiddleware hoạt động và ai gọi nó."

context("AuthMiddleware")

→ Symbol: AuthMiddleware (middleware/auth.go:15)
   Kind: Function | Package: middleware

→ Callers (nơi gọi đến):
   - router.Setup (router/router.go:28)         confidence: 0.95
   - router.SetupAdmin (router/admin.go:14)     confidence: 0.95

→ Callees (nơi nó gọi đến):
   - TokenValidator.Validate (auth/token.go:44) confidence: 0.90
   - UserRepository.FindByID (repo/user.go:67)  confidence: 0.85
   - logger.Warn (pkg/logger/logger.go:33)      confidence: 0.95

→ Cluster: auth-middleware (cohesion: 0.97)
   Members: middleware/auth.go, middleware/rate_limit.go, middleware/cors.go

AI ngay lập tức biết: ai dùng nó, nó phụ thuộc vào gì, và nó thuộc module nào. Không phải nhảy file lung tung nữa.


impact() — Biết Cái Gì Vỡ Trước Khi Chạm Vào

Đây là tool quan trọng nhất. Chạy nó trước mỗi lần chỉnh sửa.

Tình huống: Bạn muốn thay đổi signature của UserRepository.FindByID.

impact("UserRepository.FindByID", "upstream")

→ Target: UserRepository.FindByID (repo/user.go:67)

→ Depth 1 — SẼ BỊ VỠ (callers trực tiếp):
   - AuthMiddleware (middleware/auth.go:55)          confidence: 0.85
   - ProfileController.getProfile (api/profile.go:30) confidence: 0.90
   - AdminController.getUser (api/admin.go:88)        confidence: 0.90

→ Depth 2 — CÓ THỂ BỊ ẢNH HƯỞNG:
   - router.Setup → AuthMiddleware
   - router.SetupAdmin → AdminController
   - handleGetUser (api/user.go:22)

→ Tóm tắt rủi ro: 3 caller trực tiếp, 5 symbol bị ảnh hưởng tổng cộng trên 4 file

Giờ AI có thể nói chính xác: "Thay đổi này sẽ vỡ 3 function trong 4 file. Đây là những gì cần cập nhật."

Không còn câu "Tôi nghĩ thay đổi này nên an toàn." nữa.


detect_changes() — Phân Tích Rủi Ro Trước Khi Commit

Bạn đã code 2 tiếng. Trước khi commit:

detect_changes()

→ File đã thay đổi: 3
   Sửa đổi: services/payment.go, repo/order.go
   Thêm mới: services/refund.go

→ Symbol đã thay đổi:
   - PaymentService.charge — 4 caller bị ảnh hưởng
   - OrderRepository.markPaid — 2 caller bị ảnh hưởng

→ Process bị ảnh hưởng:
   - checkout-flow (RỦI RO CAO — 2/5 bước đã thay đổi)
   - admin-refund-flow (RỦI RO THẤP — 1/8 bước đã thay đổi)

→ Khuyến nghị: Xem lại các caller của checkout-flow trước khi commit.

AI nhận được báo cáo rủi ro đầy đủ về các thay đổi của bạn trước khi chúng rời khỏi máy.


rename() — Đổi Tên An Toàn Trên Toàn Bộ Codebase

Đổi tên một symbol được dùng nhiều nơi rất đáng sợ nếu không có công cụ. Mimir làm điều này an toàn.

rename("UserService", "AccountService", dry_run: true)

→ Trạng thái: dry_run (xem trước)
→ File bị ảnh hưởng: 12
→ Tổng số chỉnh sửa: 34
   Graph edits (tham chiếu có kiểu): 28
   Text search edits (string literal, comment): 6

→ Xem trước:
   api/user.go:15      — UserService → AccountService
   api/user.go:44      — UserService → AccountService
   services/auth.go:8  — UserService → AccountService
   ... (29 dòng nữa)

Chạy dry-run trước. Xác nhận. Sau đó chạy không có dry_run: true để áp dụng toàn bộ 34 thay đổi cùng lúc.


cypher() — Truy Vấn Đồ Thị Nâng Cao

Dùng khi bạn cần câu trả lời mà các tool khác không cung cấp trực tiếp:

# Tìm tất cả function được export nhưng không ai gọi (code chết)
cypher("SELECT n.name, n.file_path FROM nodes n
        WHERE n.exported = 1 AND n.kind = 'Function'
        AND NOT EXISTS (SELECT 1 FROM edges e WHERE e.to_uid = n.uid)")

→ Columns: [name, file_path]
→ Rows:
   ["generateLegacyToken", "auth/legacy.go"]
   ["formatOldResponse", "api/v1/format.go"]
   ["debugDumpState", "internal/debug.go"]

"Đây là 3 function được export nhưng không ai gọi. Có thể xóa an toàn."


Quy Trình Khuyến Nghị

1. query()          — tìm code liên quan nằm ở đâu
2. context()        — hiểu sâu về symbol trước khi chạm vào
3. impact()         — luôn chạy trước khi sửa bất kỳ function dùng chung nào
4. detect_changes() — trước mỗi lần commit

AI theo quy trình này sẽ ít mắc lỗi "Tôi vô tình phá vỡ luồng xác thực" hơn nhiều.


Tại Sao Lại Là Go?

Phiên bản tiền nhiệm của Mimir là GitNexus, viết bằng Node.js. Nó hoạt động, nhưng chậm và nặng. So sánh:

Chỉ số GitNexus (Node.js) Mimir (Go)
Index lần đầu, 1.000 file ~45 giây < 8 giây
Index tăng dần ~45 giây (full) < 2 giây
Độ trễ tìm kiếm hybrid ~300ms < 80ms
Kích thước binary 350 MB < 20 MB
RAM khi index ~800 MB < 120 MB

Viết lại bằng Go không chỉ vì tốc độ. SQLite driver pure Go có nghĩa là không CGO — binary tĩnh đơn lẻ, không phụ thuộc thư viện hệ thống, chạy được trên mọi máy Linux/macOS ngay lập tức.


Hỗ Trợ Editor

mimir setup tự động cấu hình MCP cho:

  • Claude Code (~/.claude/mcp.json)
  • VS Code + Copilot (settings.json qua github.copilot.mcpServers)
  • VS Code MCP (mcp.json qua servers)
  • Cursor (mcp.json)
  • Windsurf (mcp.json)
  • Zed (settings.json qua context_servers)
  • OpenCode (~/.config/opencode/config.json)
  • Antigravity (settings.json qua github.copilot.mcpServers)

Tự Động Thiết Lập Mỗi Khi Analyze

Chạy mimir analyze không chỉ index code. Nó còn:

  • Khởi động MCP daemon chạy nền
  • Ghi cấu hình MCP vào các editor
  • Cài Claude Code hooks (tăng cường tìm kiếm bằng đồ thị + tự động re-index sau khi ghi file)
  • Ghi 4 skill vào .claude/skills/mimir/ (exploring, debugging, impact analysis, refactoring)
  • Tạo AGENTS.mdCLAUDE.md với thống kê index mới nhất

Index Tăng Dần

Sau lần index đầy đủ đầu tiên, Mimir chỉ xử lý lại những gì thay đổi:

git diff HEAD → file đã thay đổi
→ file bị xóa: xóa node + cascade-delete edge
→ file bị sửa: xóa node/edge → re-parse + re-resolve
→ file mới: parse + resolve + insert
→ re-cluster các community bị ảnh hưởng
→ re-trace các execution flow liên quan

Index đầy đủ: ~8 giây. Index tăng dần: < 2 giây.


Giao Diện Web

Không phải AI agent? Vẫn có giao diện trực quan:

mimir serve
# Mở http://localhost:7842

Đồ thị force-directed chạy bằng Sigma.js v2 + Graphology. Khám phá cluster, trace execution flow, xem mối quan hệ giữa các symbol một cách trực quan.


Bắt Đầu Ngay

# Cài đặt một dòng
curl -fsSL https://raw.githubusercontent.com/thuongh2/git-mimir/main/install.sh | sh

# Hoặc qua Go
go install github.com/thuongh2/git-mimir/cmd/mimir@latest

# Index, khởi động daemon, cấu hình editor
mimir analyze .
mimir setup

GitHub: github.com/thuongh2/git-mimir License: MIT

Mọi đóng góp đều được chào đón — xem tab Issues trên GitHub.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí