Claude Code trong monorepo có thể trôi khi kho mã quá lớn. Tìm hiểu cách đặt ranh giới, tóm tắt cục bộ và quy trình lặp để giữ câu trả lời chính xác.

Claude Code trong monorepo có thể tỏ ra khó đoán vì lý do đơn giản: repo lớn hơn những gì mô hình có thể giữ trong “bộ nhớ làm việc” cùng lúc.
“Ngữ cảnh” là tập các file, đoạn mã, ghi chú và hướng dẫn mà Claude đã được thấy cho nhiệm vụ này, cộng với những gì nó có thể suy ra từ chúng. Khi chi tiết then chốt bị thiếu, Claude sẽ lấp những khoảng trống bằng phỏng đoán. Trong repo lớn, điều đó xảy ra thường hơn.
Ba kiểu sai sót sau đây xuất hiện lặp lại:
Đầu tiên, file bị bỏ sót. Một thay đổi có vẻ an toàn trong một thư mục thực ra phụ thuộc vào một type chia sẻ, một quy tắc config, hoặc bước build được định nghĩa ở chỗ khác. Nếu phụ thuộc đó không có trong ngữ cảnh, Claude có thể tự tin chỉnh sửa nhầm chỗ hoặc dừng lại vì không thấy nguồn sự thật thực.
Thứ hai, sự giống nhau giả. Monorepo thường chứa nhiều package nhìn giống nhau: hai module auth, ba client API, hoặc vài app React có cấu trúc thư mục tương tự. Claude có thể trộn mẫu giữa chúng, cập nhật helper ở package sai, hoặc import từ tên module “gần đúng”.
Thứ ba, trôi theo thời gian. Các codebase lớn thường có cách cũ và cách mới để làm cùng một việc. Nếu Claude chỉ thấy các file cũ, nó có thể sao chép các mẫu lỗi thời (tuỳ chọn config bị deprecate, API legacy) dù team đã chuyển sang cách khác.
Ví dụ thực tế thường gặp: bạn yêu cầu thay đổi nhỏ trên UI hóa đơn, và Claude chỉnh sửa một component payments chia sẻ được các app khác dùng vì nó không thấy wrapper đặc thù của app mà lẽ ra phải sửa.
Mục tiêu không phải là cho Claude thấy toàn bộ monorepo. Mục tiêu là cung cấp các đầu vào nhỏ, cố ý và vẫn trả lời câu hỏi: package bạn sửa, các phụ thuộc trực tiếp của nó, và một hai “nguồn sự thật” cho types và config. Ngoài ra, nêu rõ khu vực “không động” (app khác, infra, mã sinh ra) và xác nhận package nào sở hữu hành vi đó.
Độ chính xác phụ thuộc ít hơn vào lượng mã bạn dán và nhiều hơn vào việc bạn mô tả rõ ràng công việc.
Bắt đầu với kết quả bạn muốn: một sửa lỗi cụ thể, refactor hoặc câu trả lời. Một “câu hỏi về mã” có thể ở mức độ cao. Một yêu cầu “thực hiện thay đổi” cần ranh giới, đầu vào và kiểm tra thành công.
Trước khi chia sẻ bất cứ thứ gì, viết một câu hoàn thành cụm sau: “Sau khi xong, tôi cần có thể…”. Ví dụ: “chạy unit tests cho package X không thất bại” hoặc “thấy trường mới trong response API cho endpoint Y.” Câu đó trở thành sao Bắc Đẩu khi repo quá lớn.
Với thay đổi, chia sẻ tập artifacts nhỏ nhất có thể chứng minh thay đổi đúng: entry point(s), types/interfaces hoặc schema liên quan, một test đang fail hoặc bước tái tạo với kết quả mong đợi, và mọi config ảnh hưởng tới đường đi này (routing, feature flags, build hoặc lint rules). Nếu hữu ích, thêm bản đồ thư mục ngắn của package để Claude hiểu mỗi thư mục dùng để làm gì.
Nói rõ những gì không cần xem. Ghi: “Bỏ qua file sinh ra, thư mục vendor, build outputs, snapshots và lockfiles trừ khi tôi yêu cầu.” Điều đó ngăn lãng phí thời gian và chỉnh sửa những chỗ bạn sẽ không review.
Cũng thiết lập mong đợi về sự không chắc chắn. Yêu cầu Claude đánh dấu giả định và những điều chưa biết thay vì đoán mò. Ví dụ: “Nếu bạn không thấy nơi hàm này được gọi, hãy nói và đề xuất 2 cách để tìm nó.”
Trong monorepo lớn, độ chính xác giảm khi mô hình bắt đầu “giúp” bằng cách kéo vào mã lân cận không thuộc nhiệm vụ. Cách sửa đơn giản: định nghĩa cái nào nằm trong phạm vi và cái nào không trước khi yêu cầu sửa.
Bắt đầu với ranh giới phù hợp cách repo tổ chức: một package, service, app, hoặc thư viện chia sẻ. Nếu thay đổi là “cập nhật UI checkout”, ranh giới có lẽ là một package app, không phải mọi chỗ xuất hiện từ “checkout”.
Các tín hiệu giúp Claude ở yên chỗ gồm quy ước thư mục (apps/, services/, packages/, libs/), manifest của package (exports và dependencies), điểm vào công khai (file index, component/handler export), và test (thường tiết lộ bề mặt dự định). Một README trong thư mục có thể là dấu mốc ranh giới nhanh nhất.
Ranh giới hiệu quả nhất khi bạn gọi tên các cầu nối giữa chúng. Nêu rõ interface cụ thể Claude có thể động tới và coi mọi thứ khác là ngoài giới hạn. Cầu nối điển hình là hợp đồng HTTP API, topic và payload sự kiện, types chia sẻ, hoặc một tập nhỏ hàm export.
Cũng gọi tên các vùng “không động” bất cứ khi nào thay đổi không nên ảnh hưởng tới chúng. Những vùng phổ biến là cấu hình hạ tầng và triển khai, logic bảo mật và auth, thanh toán và billing, di chuyển dữ liệu và schema production, và thư viện chia sẻ dùng bởi nhiều team.
Một chi tiết prompt cụ thể giúp:
“Chỉ thay đổi bên trong packages/cart/ và test của nó. Bạn có thể đọc types chia sẻ ở packages/types/ nhưng không sửa. Không edit infra, auth, hay billing.”
Độ chính xác tăng khi bạn cung cấp một bản đồ nhỏ, ổn định của khu vực bạn muốn thay đổi. “Tóm tắt cục bộ” là bản đồ đó: đủ ngắn để đọc nhanh, đủ cụ thể để ngăn đoán mò.
Giữ mỗi tóm tắt khoảng 10–20 dòng. Viết như đang giao mã cho một đồng đội mới chỉ cần chạm tới ranh giới này, không phải cả repo. Dùng ngôn ngữ đơn giản và tên thật trong mã: thư mục, package, hàm export.
Một tóm tắt hữu ích trả lời năm câu hỏi:
Thêm một dòng “gotchas”. Đây là nơi ngăn lỗi tốn kém: cache ẩn, feature flags, bước migration, và bất cứ thứ gì phá im lặng.
Đây là template súc tích bạn có thể sao chép:
Local summary: <package/service name>
Purpose: <1 sentence>
Scope: <what to touch> | Not: <what not to change>
Entry points: <files/routes/commands>
Public surface: <exports/endpoints/events>
Data sources: <tables/collections/queues/caches>
Conventions: errors=<how>, logging=<how>, tests=<where/how>
Gotchas: <flags/caching/migrations/edge cases>
Example: nếu bạn chỉnh package billing, hãy nêu hàm chính tạo invoice, tên bảng nó ghi vào, và quy tắc lỗi có thể retry. Khi đó Claude sẽ tập trung vào ranh giới thay vì lang thang vào auth chia sẻ, config, hoặc package không liên quan.
Tóm tắt tốt nhất là tóm tắt Claude sẽ thấy khi cần. Đặt nó cạnh mã mô tả để khó bỏ qua và dễ sửa. Ví dụ, giữ một SUMMARY.md ngắn (hoặc phần README.md) trong từng thư mục package, service, hoặc app thay vì một tài liệu to ở root.
Một cấu trúc đơn giản, lặp lại giúp. Giữ đủ ngắn để mọi người duy trì:
YYYY-MM-DD - <what changed in one sentence>Tóm tắt sẽ lỗi thời vì những lý do dễ đoán. Đối xử với việc cập nhật như cập nhật một định nghĩa type: là một phần của hoàn tất công việc, không phải nhiệm vụ riêng.
Cập nhật tóm tắt khi refactor thay đổi cấu trúc hoặc tên, module mới trở thành cách chính để làm việc gì đó, API/event/schema thay đổi (dù test vẫn pass), ranh giới giữa package thay đổi, hoặc phụ thuộc bị xoá/ thay thế.
Thói quen thực tế: khi merge thay đổi, thêm một dòng “Last updated” ghi ngắn những gì thay đổi. Các công cụ như Koder.ai có thể đẩy nhanh thay đổi mã, nhưng tóm tắt là thứ giữ các thay đổi tương lai chính xác.
Độ chính xác thường tùy vào nhịp cuộc trò chuyện. Ép Claude kiếm ngữ cảnh từng phần nhỏ thay vì đoán từ một snapshot lớn.
Trước khi sửa, yêu cầu Claude mô tả những gì nó thấy và những gì nó cần. Bản đồ tốt ngắn: package chính liên quan, entry point cho luồng, và nơi test hoặc types nằm.
Prompt:
“Tạo bản đồ của thay đổi này: package liên quan, luồng chính, và điểm có thể chạm tới. Chưa đề xuất code.”
Chọn một lát hẹp: một tính năng, một package, một luồng người dùng. Nêu ranh giới rõ (ví dụ: “Chỉ thay đổi packages/billing-api. Không chạm shared-ui hoặc infra.”).
Một workflow giữ bạn kiểm soát:
Nếu Claude thiếu thứ gì, nó phải nói ra. Yêu cầu nó viết: (1) giả định đang có, (2) điều gì làm sai giả định đó, và (3) file tiếp theo cần để xác nhận.
Ví dụ: bạn cần thêm một field vào response Invoice trong một package. Claude yêu cầu handler, DTO/type definition, và một test. Bạn chỉ chia sẻ những file đó. Nếu dùng builder dạng chat như Koder.ai, cùng quy tắc áp dụng: cung cấp tập nhỏ nhất file nguồn, rồi mở rộng khi thực sự cần.
Hàng rào tốt nhất chống chỉnh sửa sai là một “hợp đồng” nhỏ viết trong prompt: chỗ Claude được phép động, cách bạn đánh giá thành công, và quy tắc nó phải theo.
Bắt đầu với ranh giới dễ tuân theo và kiểm chứng. Nêu rõ chỗ được phép sửa, và gọi tên vùng “không động” để không có cám dỗ lang thang.
Mẫu hợp đồng:
packages/payments/.packages/auth/, infra/, hoặc config chia sẻ.Rồi định nghĩa kiểm tra chấp nhận. Nếu thiếu, Claude có thể tạo code trông đúng nhưng phá các quy tắc thực tế của repo.
Quy ước style cũng quan trọng. Nói Claude theo pattern hiện có và tránh thêm dependency mới. Ví dụ: “Dùng helper lỗi hiện có trong package này; không thêm dependency; giữ tên hàm theo camelCase; đừng tạo layer kiến trúc mới.”
Cuối cùng, yêu cầu một kế hoạch ngắn trước khi sửa:
“Trước khi edit, liệt kê 3–5 file bạn nghĩ sẽ chạm tới và hành vi đổi ra sao. Chờ phê duyệt.”
Ví dụ:
“Fix rounding trong invoice totals. Chỉ edit packages/billing/src/ và test dưới packages/billing/test/. Acceptance: pnpm -C packages/billing test và typecheck. Dùng money utils hiện có; không rewrite API types. Cung cấp kế hoạch 4 bước trước.”
Cách nhanh nhất để có sửa sai trong monorepo là đưa Claude quá nhiều cùng lúc. Khi bạn dán một đống mã lớn, nó thường quay về mẫu chung thay vì thiết kế cụ thể repo bạn đang dùng.
Một bẫy khác là để nó đoán kiến trúc. Nếu bạn không cho thấy điểm vào thực sự, nó có thể chọn file đầu tiên trông hợp lý và cắm logic vào đó. Thực tế, độ chính xác đến từ một tập nhỏ file “nguồn sự thật” (entry modules, routers, service registries, docs ranh giới package). Nếu chúng không có trong ngữ cảnh, mô hình sẽ lấp khoảng trống.
Tên cũng có thể đánh lừa. Monorepo thường có ui, ui-kit, shared-ui, hoặc helper trùng tên như date.ts ở hai nơi. Nếu bạn trộn snippet từ cả hai, Claude có thể patch một file trong khi suy nghĩ về file kia. Ví dụ: bạn bảo thay đổi style nút, nó edit packages/ui/Button.tsx, nhưng app import packages/ui-kit/Button.tsx. Diff trông ổn nhưng production không thay đổi.
Config là nguồn drift im lặng khác. Hành vi có thể phụ thuộc env vars, feature flags, build settings, hoặc tooling workspace. Nếu bạn không nói tới chúng, Claude có thể bỏ một check “kỳ quặc” chỉ có ý nghĩa khi flag bật, hoặc thêm mã phá bước build.
Dấu hiệu bạn đang drift:
Xem import qua package là một quyết định, không phải mặc định. Giữ sửa local trừ khi bạn cố ý mở rộng phạm vi.
Cách nhanh nhất để có sửa đúng là bắt đầu với giới hạn, không phải khối lượng. Một prompt tốt có vẻ hơi nghiêm ngặt: nó nói Claude nên nhìn đâu, bỏ qua gì, và “xong” nghĩa là gì.
Trước khi dán mã, viết phần mở đầu ngắn cố định công việc vào một chỗ trong repo. Ghi package, thư mục chính xác, và mục tiêu cụ thể. Sau đó kèm tóm tắt cục bộ (mục đích, phụ thuộc chính, quy ước) và file entry neo thay đổi.
Checklist:
<package>/<path>. Mục tiêu: <một câu>. Bỏ qua mọi thứ khác trừ khi yêu cầu.<5-10 dòng>. Entry file: <path/to/file>.<...>. Không đổi: <folders/files or APIs>. Giữ hành vi: <what must stay true>.Nếu Claude đề xuất thay đổi ngoài ranh giới, coi đó là tín hiệu: hoặc thắt chặt prompt, hoặc mở rộng ranh giới có chủ ý và nêu lại rõ ràng.
Giả sử repo có apps/web-store (React) và packages/ui-kit (button, input, styles chia sẻ). Bạn muốn một tính năng nhỏ: thêm nút “Save for later” ở trang cart, dùng SaveIcon mới từ ui-kit. Không được thay đổi chỗ khác.
Trước khi yêu cầu sửa, tạo hai tóm tắt cục bộ làm ranh giới. Giữ ngắn, cụ thể, và có quan điểm về thứ quan trọng.
# apps/web-store/LOCAL_SUMMARY.md
Purpose: Customer shopping UI.
Entry points: src/routes.tsx, src/pages/cart/CartPage.tsx
Cart rules: cart state lives in src/cart/useCart.ts
Do not touch: checkout flow (src/pages/checkout), payments, auth.
Tests: npm test -w apps/web-store
# packages/ui-kit/LOCAL_SUMMARY.md
Purpose: shared UI components.
Exports: src/index.ts
Icons: src/icons/*, add new icons by exporting from index.
Do not touch: theming tokens, build config.
Tests: npm test -w packages/ui-kit
Rồi giữ vòng lặp chặt:
CartPage và ui-kit icons. Không sửa checkout/auth.”CartPage, useCart, ui-kit icons, ui-kit index).Sau thay đổi, ghi lại để ngữ cảnh tương lai vẫn nhỏ:
Nếu cách này hiệu quả với một người nhưng không với cả team, thiếu phần lặp lại. “Giữ ngữ cảnh tốt” phải là mặc định, không phải thói quen cá nhân.
Lưu một prompt skeleton mọi người có thể copy và điền. Giữ ngắn nhưng nghiêm ngặt. Bao gồm mục tiêu (done nghĩa là gì), phạm vi cho phép, ranh giới cứng (và lý do), tóm tắt cục bộ, và hợp đồng output (kế hoạch trước, rồi diff-style edits và tests).
Bỏ qua review lớn định kỳ mà không ai làm. Gắn cập nhật tóm tắt vào công việc bình thường: khi thay đổi làm thay đổi hành vi, phụ thuộc, hoặc API, cập nhật SUMMARY trong cùng PR.
Quy tắc đơn giản: nếu đồng đội sẽ hỏi “chuyện này nằm chỗ nào?” hoặc “cái này phụ thuộc ai?”, thì tóm tắt đã lỗi thời.
Nếu thích workflow bắt đầu bằng chat, Koder.ai có thể giúp làm iteration an toàn hơn. Chế độ Planning giúp đồng ý về phạm vi trước khi sửa, và snapshot với rollback cho phép thử thay đổi mà không bị kẹt khi phỏng đoán sai.
Claude kém chính xác hơn khi nó không thể “thấy” nguồn sự thật thực tế.
Trong một monorepo lớn, mô hình thường bỏ sót file phụ thuộc, nhầm lẫn giữa hai package giống nhau, hoặc sao chép mẫu cũ vì đó là thứ xuất hiện trong ngữ cảnh.
Đừng cố đưa cả kho mã. Bắt đầu với tập nhỏ nhất chứng minh thay đổi là đúng.
Mặc định tốt thường gồm:
Chia sẻ thứ neo hành vi, chứ không phải mọi thứ chỉ vì tên giống nhau.
Tập thực tế gồm:
Chọn một ranh giới phù hợp với cách repo tổ chức: package, app, hoặc service.
Rồi nêu rõ nó ra, kèm những gì nằm ngoài phạm vi. Ví dụ ràng buộc:
packages/cart/ và test của nó.”Vì monorepo thường có các module giống nhau (ui, ui-kit, shared-ui) và helper trùng tên (date.ts ở nhiều chỗ), Claude có thể áp dụng ý đúng vào package sai hoặc import từ tên module “gần đúng”.
Ngăn bằng cách gọi tên chính xác package và điểm vào bạn muốn sửa.
Tóm tắt cục bộ là một bản đồ ngắn về khu vực bạn muốn thay đổi, thường 10–20 dòng.
Bao gồm:
Đặt tóm tắt gần mã nó mô tả để dễ tìm và cập nhật.
Mặc định đơn giản:
SUMMARY.md hoặc phần nhỏ trong README.md của packageNói rõ trước với Claude rằng nó phải đánh dấu giả định và những phần không biết thay vì đoán mò.
Quy tắc hữu ích:
Dùng vòng lặp chặt chẽ để buộc Claude kiếm ngữ cảnh từng phần nhỏ:
Viết một “hợp đồng” nhỏ trong prompt và bắt buộc nó tuân theo:
Điều này giúp review dễ hơn và giảm sửa chéo ngoài ý muốn.