WEBSITE ĐANG PHÁT TRIỂN

Behind the scenes: team BKGlobal dùng Claude + Obsidian để xây knowledge graph xuyên base libraries và dự án

Sau gần 1 năm xây dựng, team BKGlobal có một Obsidian vault dùng chung — nơi Claude có thể traverse toàn bộ base libraries, ADR của từng project, và quyết định kỹ thuật qua các sprint. Bài này chia sẻ lý do chúng tôi làm, kiến trúc vault, những gì hoạt động tốt, và những gì chúng tôi phải làm lại.

Behind the scenes: team BKGlobal dùng Claude + Obsidian để xây knowledge graph xuyên base libraries và dự án

Câu chuyện bắt đầu: một new member, một câu hỏi, và 3 tiếng tìm kiếm

Tháng 8 năm ngoái, một developer mới join team BKGlobal và được giao task đầu tiên: tích hợp module xác thực của BKGlobal.Auth vào một client project mới. Module này là một phần của BKGlobal Core Framework — bộ base libraries .NET mà team chúng tôi maintain cho gần chục dự án.

Ba tiếng sau, developer đó hỏi tôi: "Anh ơi, tại sao BKGlobal.Auth không support refresh token rotation? Em đọc code thấy đó là limitation, nhưng không tìm được lý do ở đâu."

Câu trả lời thực ra không khó — chúng tôi đã bàn chuyện này cách đây 8 tháng, quyết định không làm vì client lúc đó không yêu cầu và thêm complexity không đáng. Có cả ADR ghi lại. Nhưng ADR đó nằm trong một Google Doc mà chỉ 2 người nhớ link. Không được index. Không được link từ code. Không searchable.

Đó là lúc tôi nhận ra: chúng tôi có knowledge nhưng không có knowledge graph. Mỗi thành viên team giữ một mảnh — trong đầu, trong chat history Slack, trong doc folder riêng. Claude thì chỉ biết những gì bạn paste vào session đó. Không có gì kết nối tất cả lại.


Bối cảnh: BKGlobal Core Framework và bài toán knowledge silo

Để hiểu scale của vấn đề, cần biết BKGlobal maintain một bộ base libraries dùng chung cho các dự án outsource:

Library Vai trò
BKGlobal.Auth JWT, refresh token, permission management
BKGlobal.DataAccess Dapper wrapper, Unit of Work, repository patterns
BKGlobal.Messaging Azure Service Bus abstraction
BKGlobal.FileStorage Azure Blob Storage, file processing
BKGlobal.Notification Email, push notification, webhook
Customized Piranha CMS BKGlobal fork của Piranha — thêm multi-tenant, custom content types

Mỗi library có lifecycle riêng, changelog, breaking changes, và rất nhiều "tại sao" đằng sau từng quyết định thiết kế. Trên các thư viện đó là 8–10 client projects đang active, mỗi project integrate các libraries theo cách khác nhau, override khác nhau, và có context business riêng.

Trước đây, khi một developer cần hiểu tại sao BKGlobal.DataAccess dùng Dapper thay EF Core cho read queries, họ phải hỏi trực tiếp. Khi một team cần biết project khác handle soft-delete thế nào trong Piranha CMS fork, họ grep qua codebase và guess. Không có cầu nối.


Giải pháp chúng tôi chọn: vault dùng chung + Claude làm "thủ thư"

Sau khi xem xét một vài options (Confluence, Notion, custom wiki), chúng tôi chọn Obsidian vì ba lý do rất thực dụng:

  1. Plain markdown — không bị lock-in, dễ migrate, Claude đọc natively
  2. Local-first + Git sync — vault là một Git repo, mọi thay đổi được track, không cần SaaS
  3. Wikilinks và backlinks — tạo ra graph tự nhiên khi viết đúng cách

Claude đóng vai trò "thủ thư kỹ thuật" — không chỉ đọc vault mà còn chủ động maintain: tạo cross-link, suggest backlink missing, và cập nhật notes khi có quyết định mới.


Kiến trúc vault: cấu trúc sau nhiều lần refactor

Phiên bản đầu tiên của vault chúng tôi flat hoàn toàn — tất cả notes trong một folder. Sau 3 tháng, tìm kiếm trở thành cực hình. Đây là cấu trúc hiện tại sau 2 lần refactor lớn:

bkglobal-knowledge-vault/
│
├── CLAUDE.md                    # Instruction set cho Claude — đọc đầu tiên
│
├── base-libraries/
│   ├── BKGlobal.Auth/
│   │   ├── overview.md          # Architecture, design decisions
│   │   ├── changelog.md         # Breaking changes theo version
│   │   ├── adr/
│   │   │   ├── ADR-0001-jwt-vs-session.md
│   │   │   ├── ADR-0002-refresh-token-scope.md
│   │   │   └── ADR-0003-no-rotation-decision.md    ← note đó!
│   │   └── integration-guide.md
│   ├── BKGlobal.DataAccess/
│   │   ├── overview.md
│   │   ├── adr/
│   │   │   └── ADR-0001-dapper-over-efcore-read.md
│   │   └── patterns/
│   │       ├── repository-pattern.md
│   │       └── unit-of-work.md
│   ├── BKGlobal.Messaging/
│   ├── BKGlobal.FileStorage/
│   ├── BKGlobal.Notification/
│   └── piranha-cms-fork/
│       ├── overview.md
│       ├── multi-tenant-design.md
│       └── custom-content-types.md
│
├── projects/
│   ├── _template/               # Template cho project mới
│   ├── project-ecommerce-A/
│   │   ├── status.md            # Single source of truth
│   │   ├── architecture.md
│   │   ├── decisions/           # Project-level ADRs
│   │   └── integration-notes/   # Cách dùng base libs trong project này
│   └── project-staffportal-B/
│       └── ...
│
├── patterns/                    # Cross-cutting patterns dùng nhiều projects
│   ├── soft-delete-strategy.md
│   ├── multi-tenant-isolation.md
│   ├── event-sourcing-when-to-use.md
│   └── api-versioning-approach.md
│
├── tech/                        # Notes về external libraries, tools
│   ├── azure-service-bus.md
│   ├── postgresql-tuning.md
│   └── docker-windows-gotchas.md
│
└── _agent/                      # Workspace của Claude
    ├── memory/
    │   ├── working/             # Active context 48h
    │   └── semantic/            # Distilled facts
    └── heartbeat/               # Daily reflection logs

Key insight: patterns/ folder là thứ tạo ra giá trị lớn nhất. Khi một solution xuất hiện ở nhiều project, chúng tôi extract nó thành một pattern note — và Claude tự động cross-reference khi làm việc với project mới.


CLAUDE.md: bộ não hướng dẫn của vault

File này ở root của vault, là thứ đầu tiên Claude đọc trong mọi session:

# BKGlobal Knowledge Vault — CLAUDE.md

## Mày là ai trong context này
Mày là technical knowledge manager của team BKGlobal. Khi được hỏi về bất kỳ
library hay project nào, LUÔN đọc file overview.md và ADR liên quan trước khi
trả lời. Không guess — nếu không có note, hỏi lại hoặc nói rõ là không có data.

## Tech stack chuẩn BKGlobal
- Backend: .NET 8 C#, Dapper (reads) + EF Core (writes), PostgreSQL / SQL Server
- Cloud: Azure — App Service, Service Bus, Blob Storage, Key Vault
- CMS: Piranha CMS (fork tại base-libraries/piranha-cms-fork/)
- Auth: BKGlobal.Auth (KHÔNG dùng ASP.NET Identity trực tiếp)

## Naming conventions trong vault
- ADR: ADR-NNNN-kebab-case-title.md (số 4 chữ số, bắt đầu từ 0001)
- Project notes: lowercase-kebab-case
- Wikilinks PHẢI dùng exact filename: [[ADR-0003-no-rotation-decision]]
- Tags: #adr #decision #pattern #breaking-change #todo-review

## Khi Claude viết note mới (bắt buộc)
1. YAML frontmatter với: date, tags, library/project, status, related
2. Thêm backlinks đến notes liên quan (dùng wikilinks)
3. Nếu là quyết định kiến trúc → tạo ADR trong folder adr/ của library/project đó
4. Nếu là pattern tái sử dụng → tạo note trong /patterns/ và link từ các project

## Active projects (update 2026-05-15)
- [[projects/project-ecommerce-A/status]] — Phase 4, tích hợp BKGlobal.Notification
- [[projects/project-staffportal-B/status]] — Maintenance, .NET 8 migration ongoing

## Libraries cần review gấp
- BKGlobal.Auth v2.3 → v3.0 có breaking change trên token claims format
  Xem: [[base-libraries/BKGlobal.Auth/changelog]]

Điểm quan trọng: chúng tôi viết CLAUDE.md bằng ngôn ngữ chỉ thị trực tiếp, không phải mô tả thụ động. "LUÔN đọc file overview.md", "Không guess" — càng cụ thể, Claude càng ít hallucinate.


Cross-referencing: cách vault tự kết nối theo thời gian

Phần thú vị nhất của kiến trúc này là cách knowledge tự lan rộng. Ví dụ thực tế:

Khi team project-ecommerce-A quyết định implement soft-delete, developer tạo note trong projects/project-ecommerce-A/decisions/soft-delete-approach.md. Claude được hỏi review note đó, và nhận ra pattern này đã xuất hiện trong một project trước. Claude suggest:

"Xem [[patterns/soft-delete-strategy]] — team project B đã implement tương tự tháng 3, có note về pitfall với Dapper query và deleted_at index. Muốn tôi link cross-reference vào note của bạn không?"

Sau vài tháng, patterns/soft-delete-strategy.md có backlinks từ 4 projects khác nhau. Ai join mới, hỏi về soft-delete, Claude trả lời ngay từ note đó — kèm link đến implementation cụ thể ở từng project.

Đây chính xác là knowledge graph tự tiến hóa: không phải chúng tôi chủ động build, mà mỗi interaction của Claude với vault tạo thêm một lớp liên kết.


Bài học rút ra sau gần 1 năm

Cái làm tốt:

Onboarding giảm đáng kể. Developer mới giờ có thể tự tìm context trước khi hỏi senior. Câu hỏi "tại sao library X làm vậy" giờ có answer trong vault — với reasoning đầy đủ, không chỉ "vì hồi đó chúng tôi chọn vậy".

ADR culture được enforce tự nhiên. Khi vault là nơi Claude làm việc, team tự nhiên viết ADR nhiều hơn — vì không có ADR, Claude không biết context và sẽ hỏi lại. Friction đủ nhỏ để không gây khó chịu, nhưng đủ để tạo thói quen.

Cross-project pattern discovery. Một số patterns chúng tôi không biết là đang dùng chung đến khi Claude point out. Ví dụ: cả 3 projects đang implement webhook signature verification theo cách gần giống nhau nhưng không đồng nhất — Claude flag điều này khi đọc 3 notes trong một session.

Cái phải làm lại:

Vault quá lớn quá nhanh. Tháng đầu không có content policy — ai cũng dump notes thoải mái. Đến tháng 3, vault có 400+ notes nhưng nhiều notes orphan, outdated, hoặc duplicate. Chúng tôi phải dành một sprint để cleanup và thêm quy tắc vào CLAUDE.md về khi nào nên tạo note mới vs cập nhật note cũ.

Git conflict trên vault. Vì vault là Git repo dùng chung, merge conflict trên markdown xảy ra thường xuyên hơn tưởng. Giải pháp: vault tổ chức theo "ownership" — mỗi subfolder có owner chính, người khác contribute qua PR. Nghe có vẻ overhead, nhưng thực ra chỉ mất 2–3 phút review per PR.

Claude không phải search engine. Ban đầu có developer dùng Claude như Google — "tìm tất cả notes về PostgreSQL". Claude làm được nhưng chậm và tốn token. Giải pháp thực dụng hơn: dùng Obsidian's built-in search cho discovery, chỉ dùng Claude khi cần reasoning về content tìm được.


Takeaway

Knowledge graph không tự xuất hiện — nó cần cấu trúc, convention, và một "thủ thư" duy trì nó theo thời gian. Claude + Obsidian đóng vai trò đó tốt hơn bất kỳ wiki tool nào chúng tôi từng dùng, vì nó active thay vì passive: Claude không chỉ đọc vault mà còn viết vào vault, liên kết vault, và cảnh báo khi vault có gap.

Nếu team bạn có base libraries dùng chung hoặc nhiều projects parallel, đây là pattern đáng đầu tư. Bắt đầu nhỏ: vault cho một library duy nhất, một CLAUDE.md tốt, và ADR folder. Sau 2–3 tháng, pattern sẽ tự lan ra.

Muốn đào sâu hơn về kỹ thuật setup? Xem bài Claude + Obsidian: 4 pattern knowledge graph tự tiến hóa — bài đó cover phần MCP setup và các pattern triển khai từ cơ bản đến nâng cao.


Son Do — BKGlobal Tech Team

#BKGlobal #AI #architecture #obsidian #knowledgemanagement #dotnet #teamwork #1percentbetter


Bài viết liên quan

Xem thêm
Ứng dụng & Xu hướng AI

Function calling với Gemma 4 – build AI agent chạy local, không cần API key

Gemma 4 của Google DeepMind – gia đình model open source giấy phép Apache 2.0 – hỗ trợ function calling native ngay từ khi training, không cần prompt engineering để "dụ" model gọi tool. Bài này tôi sẽ hướng dẫn bạn build một AI agent chạy hoàn toàn local qua Ollama, gọi được weather API, currency converter, news – không một dòng code nào cần API key, không một byte data nào rời khỏi máy bạn.

Ứng dụng & Xu hướng AI

So sánh GPT-5.5 vs Claude Opus 4.7 vs DeepSeek V4: chọn model nào cho dự án Việt Nam?

Tuần trước tôi test cả ba model trên các task thực tế của BKGlobal và kết quả không theo đúng kỳ vọng ban đầu. Claude Opus 4.7 thắng áp đảo về coding (64.3% SWE-bench Pro). GPT-5.5 bá đạo agentic + terminal workflows. DeepSeek V4 Pro có performance gần ngang Claude với giá rẻ hơn 7 lần — nhưng chỉ support text, không có image. Không có model nào "tốt nhất cho mọi thứ" — đây là guide để chọn đúng tool cho từng bài toán.