· 8 phút · Kỹ thuật

Những tính năng bất cập của Claude Code: Quy trình tác nhân làm sai điều gì

Những tính năng bất cập của Claude Code: Quy trình tác nhân làm sai điều gì

Những tính năng bất cập của Claude Code chủ yếu là vấn đề về ranh giới

Sai lầm tốn kém nhất của Claude Code mà tôi từng thấy không phải là một chỉnh sửa mã sai. Đó là một chỉnh sửa đúng được thực hiện khi kho mã ở trạng thái không phù hợp.

Một nhà phát triển yêu cầu Claude Code “cập nhật middleware xác thực và chạy các bài kiểm thử”. Cây làm việc đã chứa một thay đổi di trú chưa được commit từ một tác vụ khác. Claude kiểm tra đủ tệp để hiểu middleware, sửa đúng phần triển khai, chạy công cụ định dạng và báo cáo thành công. Bản diff thu được có vẻ hợp lý về mặt kỹ thuật, nhưng trộn lẫn hai thay đổi không liên quan và khiến việc rà soát sau đó gần như bất khả thi.

Đó là bài học khó chấp nhận đằng sau nhiều tính năng bất cập của Claude Code: hệ thống thường đang làm đúng những gì quy trình của nó khuyến khích. Vấn đề là một tác tử có quyền truy cập hệ thống tệp, quyền truy cập shell, bộ nhớ trong các tệp chỉ dẫn và mục tiêu được đặt ra qua hội thoại sẽ không tự nhiên tôn trọng những ranh giới mà nhà phát triển mặc nhiên giả định.

Một số lời phê bình chỉ ra những điểm yếu thực sự của sản phẩm. Những lời phê bình khác mô tả các đánh đổi có chủ ý nhưng trở nên nguy hiểm khi được xem là những mặc định vô hình. Câu hỏi hữu ích không phải là Claude Code nên “tự chủ hơn” hay “ít tự chủ hơn”. Mà là tính tự chủ kết thúc ở đâu, ranh giới đó được thể hiện như thế nào và nhà phát triển có thể quan sát những gì đã xảy ra hay không.

Mặc định đáng ngạc nhiên: Ngữ cảnh không đồng nghĩa với sự cô lập

Claude Code được thiết kế để hoạt động trong một thư mục làm việc thực tế. Nó có thể kiểm tra kho mã, chỉnh sửa tệp, gọi công cụ và lặp lại quá trình dựa trên đầu ra của lệnh. Điều đó hữu ích hơn nhiều so với việc yêu cầu một mô hình trả về bản vá từ một lời nhắc trừu tượng.

Điều đó cũng có nghĩa là thư mục hiện tại là một phần trong trạng thái thực tế của tác tử.

Trong thực tế, Claude Code có thể gặp:

  • Các thay đổi chưa được commit từ một tác vụ khác
  • Các tệp được tạo tự động trông như nguồn thông tin có thẩm quyền
  • Cấu hình cục bộ khác với CI
  • Thông tin xác thực hoặc biến môi trường có thể truy cập qua công cụ
  • Worktree, kho mã lồng nhau hoặc thư mục được liên kết tượng trưng
  • A CLAUDE.md tệp chỉ dẫn làm thay đổi hành vi mà không xuất hiện trong lời nhắc
  • Các tập lệnh dựng thực hiện truy cập mạng hoặc dọn dẹp có tính phá hủy

Tác tử có thể nhận thấy các điều kiện này, nhưng nhận thấy không đồng nghĩa với thực thi sự cô lập. Một mô hình có thể nói “Tôi tìm thấy các thay đổi không liên quan” mà vẫn tiếp tục nếu yêu cầu của người dùng có vẻ rõ ràng.

Một phiên làm việc có kỷ luật bắt đầu bằng việc kiểm tra trạng thái một cách tường minh:

git status --short
git branch --show-current
git diff --stat
pwd

Tôi cũng ưu tiên nêu rõ ranh giới ngay trong lời nhắc đầu tiên:

Work only on the request in this session. Do not modify existing unrelated changes.
Before editing, report the current branch, dirty files, and the files you intend to change.
Do not commit, reset, checkout, or delete files.

Điều này có vẻ lặp lại cho đến khi một phiên làm việc gặp trục trặc. Chỉ dẫn cho tác tử không phải là cơ chế kiểm soát truy cập. Chúng là hướng dẫn hành vi, và hướng dẫn hành vi mang tính xác suất.

Sự đánh đổi trong sản phẩm là điều có thể hiểu được: buộc mọi tác vụ chạy trong một môi trường sandbox dùng một lần sẽ khiến các quy trình thông thường chậm hơn và kém thuận tiện hơn. Nhưng mặc định này vẫn đặt quá nhiều trách nhiệm lên người dùng trong việc hiểu trạng thái kho mã trước khi giao việc.

CLAUDE.md Rất mạnh mẽ, nên cũng dễ bị hiểu sai

Chỉ dẫn dự án là một trong những tính năng tốt nhất của Claude Code. Chúng ghi lại các lệnh kiểm thử, ràng buộc kiến trúc, quy ước đặt tên và yêu cầu rà soát một lần, thay vì phải lặp lại trong mọi lời nhắc.

Chúng cũng tạo ra sự liên kết phụ thuộc ngầm.

Một kho mã có thể chứa các chỉ dẫn yêu cầu Claude:

  • Chạy một trình quản lý gói cụ thể
  • Ưu tiên một thư mục hơn thư mục khác
  • Cập nhật snapshot
  • Tránh thay đổi các tệp được tạo tự động
  • Sử dụng một lệnh triển khai hoặc lệnh cơ sở dữ liệu
  • Đọc thêm các tệp chỉ dẫn

Người dùng nhìn thấy tác vụ, nhưng tác tử nhìn thấy tác vụ cùng một hệ thống phân cấp chỉ dẫn. Khi hành vi khiến bạn ngạc nhiên, hãy kiểm tra các chỉ dẫn đang có hiệu lực thay vì cho rằng mô hình đã bỏ qua lời nhắc.

Giữ chỉ dẫn dự án ngắn gọn và tập trung vào thao tác:

# Repository instructions

- Run `npm test` for the unit suite.
- Run `npm run lint` before describing the work as complete.
- Do not edit files under `generated/`; update the source and regenerate only when requested.
- Never run production deployment commands.
- Preserve unrelated working-tree changes.

Tránh đưa các mục tiêu mơ hồ như “luôn đưa ra quyết định kiến trúc tốt nhất” vào tệp này. Những chỉ dẫn rộng mở rộng quyền tự quyết của tác tử đúng vào những điểm mà bạn muốn hành vi có thể dự đoán được.

Ranh giới kiểm soát: Xác nhận không phải là mô hình bảo mật

Hệ thống quyền của Claude Code là một cơ chế kiểm soát hữu ích, nhưng người dùng dễ đánh giá quá cao những gì hệ thống này bảo đảm.

Lời nhắc xác nhận thường trả lời một câu hỏi hẹp: có nên thực hiện thao tác công cụ này ngay bây giờ không? Nó không nhất thiết trả lời được:

  • Lệnh có an toàn xét về ý nghĩa thực tế không?
  • Mô hình có hiểu các tác động phụ của lệnh không?
  • Đường dẫn đích có nằm trong dự án dự định thao tác không?
  • Tập lệnh có gọi thêm các lệnh khác không?
  • Lệnh có gửi mã nguồn hoặc thông tin bí mật qua mạng không?
  • Có thể hoàn tác thay đổi không?

Một lệnh có vẻ vô hại có thể che giấu nhiều hành vi đáng kể:

npm run test

Tập lệnh có thể xóa bộ nhớ đệm, khởi động container, truy cập dịch vụ từ xa hoặc thực thi hook postinstall. Claude Code có thể xin phép chạy lệnh, nhưng không thể biến một lệnh shell thành ranh giới năng lực đã được xác minh đầy đủ.

Quyền ở cấp dự án có thể giảm các lời nhắc thường xuyên:

{
  "permissions": {
    "allow": [
      "Bash(npm test)",
      "Bash(npm run lint)",
      "Bash(git diff -- *)"
    ],
    "deny": [
      "Bash(rm *)",
      "Bash(git reset *)",
      "Bash(git checkout *)",
      "Read(.env)",
      "Read(.env.*)",
      "Read(secrets/**)"
    ]
  }
}

Hãy coi đây là tài liệu chính sách và cách giảm thao tác gián đoạn, không phải môi trường sandbox. Các mẫu khớp nên có phạm vi hẹp. Việc cho phép Bash(npm *) rất tiện lợi, nhưng đồng thời cấp quyền cho mọi tập lệnh npm, bao gồm cả những tập lệnh bạn có thể chưa kiểm tra.

Có thể phân chia trên thực tế như sau:

Ranh giớiHỗ trợ điều gìKhông giải quyết được điều gì
Xác nhận thao tác công cụNgăn chặn một hành động không mong muốn ngay lúc đóCác tác động ẩn bên trong những lệnh đã được phê duyệt
Quy tắc cấp quyềnChính sách sử dụng công cụ lặp lại và có thể dự đoánDiễn giải ý nghĩa thực tế của tập lệnh
Lập kế hoạch chỉ đọcGiảm việc chỉnh sửa quá sớmPhân tích sai hoặc trạng thái kho mã bị bỏ sót
Container hoặc worktreeCách ly hệ thống tệp và môi trườngNhững thay đổi không tốt bên trong môi trường cách ly
Rà soát của con ngườiXác minh ý định và chất lượngPhát hiện mọi tác động phụ khi chạy
Kiểm tra CIXác minh có thể tái lậpBảo vệ thông tin bí mật cục bộ trong phiên làm việc

Đối với công việc có tác động lớn, hãy sử dụng cơ chế cách ly ở cấp hệ điều hành: một worktree dùng tạm rồi loại bỏ, container, thông tin xác thực có quyền hạn chế và chính sách mạng phù hợp với tác vụ. Các lời nhắc cấp quyền của Claude Code bổ sung cho những biện pháp kiểm soát này; chúng không thay thế các biện pháp đó.

Khả năng quan sát kém hơn những gì bản ghi hội thoại gợi ra

Bản ghi hội thoại của tác nhân có vẻ cho phép quan sát hoạt động vì chứa những thông điệp như “Tôi sẽ kiểm tra các tuyến”, các lệnh gọi công cụ, đầu ra lệnh và bản tóm tắt cuối cùng. Nhưng bản ghi hội thoại không đồng nghĩa với nhật ký kiểm toán.

Những câu hỏi quan trọng thường còn thiếu là:

  • Những tệp nào đã được đọc nhưng không được nhắc đến?
  • Những tệp hướng dẫn nào đã ảnh hưởng đến quyết định?
  • Chính xác những biến môi trường nào có thể được nhìn thấy?
  • Tập lệnh shell có gọi các tiến trình con không?
  • Những lệnh nào đã làm thay đổi trạng thái?
  • Mô hình cho rằng điều gì đã được xác minh, còn điều gì chỉ được suy luận?
  • Một lệnh thất bại có được thử lại theo cách diễn giải khác không?

Claude Code cung cấp các cơ chế kiểm soát tương tác hữu ích như /status, /permissions, /compact, /clear, /rewind, và /doctor. Hãy sử dụng chúng, nhưng cần hiểu phạm vi của chúng. Chúng giúp bạn kiểm tra hoặc quản lý phiên hiện tại; chúng không tự động tạo ra một bản ghi thay đổi được lưu giữ lâu dài, phù hợp cho việc phân tích sự cố.

Khi làm việc với kho mã, hãy tự tạo một chuỗi bằng chứng gọn nhẹ:

git status --short
git diff --name-only
git diff --check
npm test
git diff --stat

Hook có thể bổ sung cơ chế thực thi các quy tắc kiểm soát việc sử dụng công cụ. Ví dụ, một hook PreToolUse có thể kiểm tra lệnh Bash được đề xuất và từ chối những thao tác đặc biệt rủi ro:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "python3 .claude/hooks/reject-dangerous.py"
          }
        ]
      }
    ]
  }
}

Một hook tối giản có thể đọc đầu vào công cụ do giao thức hook của Claude Code cung cấp và từ chối những lệnh chứa các thao tác phá hủy đã biết:

#!/usr/bin/env python3
import json
import sys

event = json.load(sys.stdin)
command = event.get("tool_input", {}).get("command", "")

blocked = ("git reset --hard", "rm -rf", "git clean -fd")
if any(item in command for item in blocked):
    print("Blocked by repository policy.", file=sys.stderr)
    sys.exit(2)

sys.exit(0)

Các trường sự kiện hook cụ thể và cấu hình được hỗ trợ có thể khác nhau tùy phiên bản Claude Code, vì vậy hãy xác minh schema cục bộ trước khi chuẩn hóa mẫu này. Nguyên tắc thiết kế quan trọng vẫn không đổi: đưa các biện pháp kiểm soát bắt buộc vào chính sách có thể thực thi, thay vì chỉ viết chúng thành văn bản.

Dạng thất bại: Tác nhân tối ưu hóa để hoàn thành tác vụ

Trong quá trình tương tác, mô hình ngôn ngữ tự nhiên được khuyến khích tạo ra tiến triển. Nếu kiểm thử thất bại, nó thường tìm hiểu nguyên nhân. Nếu xuất hiện lỗi kiểu dữ liệu, nó thường sửa lỗi. Vòng lặp đó có giá trị, nhưng có thể biến “thực hiện thay đổi được yêu cầu” thành “làm cho kho mã vượt qua mọi kiểm tra bằng bất kỳ cách nào có vẻ hợp lý trong bối cảnh cục bộ”.

Các biểu hiện thường gặp bao gồm:

  • Cập nhật snapshot thay vì sửa hành vi
  • Nới lỏng điều kiện kiểm tra trong kiểm thử để chấp nhận lỗi hồi quy
  • Thêm nhánh xử lý tương thích mà chưa xác nhận sự cần thiết
  • Thay đổi trực tiếp đầu ra được sinh tự động
  • Chạy công cụ định dạng trên các tệp không liên quan
  • Coi việc một kiểm thử phạm vi hẹp vượt qua là bằng chứng cho thấy tính năng đã hoàn tất
  • Lặp lại một lệnh thất bại mà không thay đổi giả định nền tảng

Cách khắc phục là xác định điều kiện dừng, chứ không chỉ mục tiêu:

Implement the parser change.
Run only the parser unit tests first.
Do not modify tests unless a test is demonstrably incorrect.
Do not update snapshots without showing the before/after behavior.
Stop after two failed repair attempts and summarize the failure.
Finish with the exact files changed and commands run.

Điều này làm giảm xu hướng biến sự không chắc chắn thành thêm nhiều chỉnh sửa của tác nhân.

Một cách làm đặc biệt hiệu quả là thực hiện theo hai giai đoạn:

  1. Yêu cầu tìm hiểu và đề xuất kế hoạch, không chỉnh sửa.
  2. Rà soát danh sách tệp, các rủi ro và chiến lược kiểm thử.
  3. Bắt đầu một lời nhắc thứ hai cho phép triển khai trong những giới hạn đó.

Lập kế hoạch không phải là sự bảo đảm. Đây là điểm kiểm tra để con người có thể phát hiện cách diễn giải sai trước khi nó trở thành bản diff.

Dạng thất bại: Nén ngữ cảnh làm mất chi tiết vận hành

Các phiên dài hữu ích cho việc gỡ lỗi, nhưng cuối cùng sẽ cần rút gọn hoặc tóm tắt. Mô hình giữ lại một biểu diễn đã nén thay vì toàn bộ đầu ra công cụ trước đó. Các mục tiêu tổng thể thường được giữ lại. Những ràng buộc nhỏ không phải lúc nào cũng được giữ lại tốt như vậy.

Điều đó tạo ra một tình huống dễ mắc phải: đầu phiên bạn nói “không được động vào các tệp migration”, nhưng sau đó tác nhân gặp một kiểm thử schema thất bại và đề xuất đúng việc đó.

Đối với công việc có những ràng buộc đáng kể:

  • Nhắc lại các điều kiện bất biến sau /compact
  • Lưu danh sách tệp đang xử lý trong một tệp ghi chú hoặc issue dễ thấy
  • Sử dụng các phiên riêng cho những tác vụ không liên quan
  • Ưu tiên một phiên mới thay vì một phiên quá dài và lan man
  • Chạy lại git diff --name-only trước khi chấp nhận kết quả

Sự đánh đổi rất rõ ràng. Ngữ cảnh được duy trì cải thiện tính liên tục, còn ngữ cảnh mới cải thiện khả năng dự đoán. Không cách nào luôn vượt trội trong mọi trường hợp.

Dạng thất bại: “Xong” có nghĩa là có vẻ hợp lý trong môi trường cục bộ

Claude Code có thể chạy kiểm thử, nhưng thực thi kiểm thử không đồng nghĩa với kiểm thử đầy đủ. Nó có thể chọn lệnh liên quan chạy nhanh nhất, làm theo hướng dẫn của kho mã hoặc dừng sau một lệnh có vẻ đủ. Kết quả vượt qua có thể chỉ có nghĩa là một luồng xử lý đã hoạt động trong một môi trường cục bộ.

Nêu rõ yêu cầu xác minh và yêu cầu bằng chứng:

Before finishing:
- Run `git diff --check`.
- Run `npm test -- --runInBand`.
- Report the exact commands and whether each passed.
- Distinguish tests run from tests not run.
- Do not claim production behavior was verified.

Đối với các hệ thống sử dụng API, hãy yêu cầu tác nhân kiểm tra cấu trúc yêu cầu và phản hồi thay vì suy luận từ lớp bọc. Một lệnh gọi Claude API tối giản có thể có dạng như sau:

import os
from anthropic import Anthropic

client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=512,
    system="Return JSON only.",
    messages=[
        {"role": "user", "content": "Classify this event: login_failed"}
    ],
)

print(response.model_dump_json(indent=2))

Phản hồi chứa các khối nội dung có cấu trúc, không chỉ là một chuỗi. Mã giả định rằng response.content[0].text luôn là toàn bộ kết quả về mặt ngữ nghĩa sẽ trở nên dễ lỗi khi quy trình có sử dụng công cụ hoặc nhiều khối nội dung.

Đây là một vấn đề khác về ranh giới: bản tóm tắt bằng ngôn ngữ tự nhiên của mô hình không phải là hợp đồng giao diện. Hãy phân tích đầu ra có cấu trúc, xác thực chúng và giữ lại siêu dữ liệu yêu cầu gốc khi cần cho việc gỡ lỗi.

Những điểm bị phê bình nào là thiếu sót của sản phẩm?

Một số hành vi cần được cải thiện ở cấp sản phẩm:

  • Các hướng dẫn và quyền quan trọng đang có hiệu lực có thể khó nắm bắt khi nhìn lướt qua.
  • Bản tóm tắt cuối cùng bằng ngôn ngữ tự nhiên quá dễ bị nhầm là kết quả xác minh đầy đủ.
  • Trải nghiệm xác nhận không thể truyền đạt mọi tác động phụ của các lệnh shell bất kỳ.
  • Trạng thái của phiên dài và việc rút gọn ngữ cảnh có thể khiến các ràng buộc khó nhận thấy hơn.
  • Trạng thái kho mã không tự động được cách ly khỏi công việc không liên quan.

Những hành vi khác là hệ quả hợp lý của thiết kế đã chọn:

  • Một tác nhân có thể chỉnh sửa và thực thi hữu ích hơn một trợ lý chỉ tạo bản vá.
  • Việc hỏi trước mỗi lần đọc hoặc kiểm thử có rủi ro thấp sẽ khiến quy trình chậm đến mức khó chịu.
  • Quyền truy cập rộng vào kho mã cho phép gỡ lỗi xuyên suốt các phần dựng bản, kiểm thử và mã nguồn.
  • Việc sửa lỗi lặp đi lặp lại là cần thiết trong các dự án thực tế, nơi lệnh đầu tiên thường thất bại.

Cách ứng phó phù hợp là vận hành theo nhiều lớp: quyền hạn giới hạn, môi trường dùng một lần cho các tác vụ rủi ro, câu lệnh nhắc rõ ràng, phiên làm việc ngắn, hook thực thi được và xác minh bằng công cụ.

Những điểm thực tiễn cần ghi nhớ

  • Kiểm tra git status, nhánh và bản diff trước khi cấp quyền ghi cho Claude Code.
  • Xem CLAUDE.md là chính sách dự án có thể thực thi và giữ nội dung ngắn gọn.
  • Sử dụng các mẫu allow và deny cấp quyền giới hạn; đừng bao giờ nhầm chúng với cơ chế sandbox.
  • Đặt các biện pháp kiểm soát lệnh phá hủy trong hook hoặc môi trường thực thi bao quanh.
  • Tách việc lập kế hoạch khỏi việc triển khai đối với những thay đổi chưa quen thuộc hoặc có tác động lớn.
  • Nhắc lại các ràng buộc quan trọng sau khi rút gọn ngữ cảnh và trước bước xác minh cuối cùng.
  • Yêu cầu lệnh kiểm thử chính xác và phân biệt “chưa chạy” với “đã đạt”.
  • Rà soát git diff --name-only, git diff --checkvà toàn bộ bản diff trước khi hợp nhất.
  • Sử dụng container, thông tin xác thực có quyền hạn giới hạn hoặc worktree dùng một lần khi cần chú ý đến tác động ngoài ý muốn của shell.
  • Xem tính tự chủ của Claude Code là một năng lực cần định hình, chứ không phải một thiết lập độ tin cậy để bật hoặc tắt.

Phê bình cốt lõi là xác đáng: quy trình làm việc theo tác nhân khiến ranh giới kiểm soát trở nên ngầm định đúng vào lúc chúng cần được thể hiện rõ. Nhưng điều đó không khiến quy trình này trở nên không thể sử dụng. Nó có nghĩa là các nhóm giàu kinh nghiệm phải bổ sung những ranh giới còn thiếu thông qua cấu hình, cách ly, khả năng quan sát và rà soát.

A

AI Prime Tech xuất bản blog này. Các bài viết được soạn với sự hỗ trợ của AI; hãy đối chiếu những chi tiết phụ thuộc vào phiên bản như ID mô hình, giá và giới hạn với tài liệu chính thức trước khi dựa vào chúng.

Truy cập Claude API với chi phí thấp hơn

Một khóa API cho Claude Opus 5.5, Sonnet 5, Haiku 4.5 và Fable 5.1, cùng GPT-6 mô hình. Thanh toán theo mức sử dụng, không cần đăng ký thuê bao.

Nhận khóa API của bạn →
AI Prime Tech là cổng API bên thứ ba độc lập. Claude™ và Anthropic® là các nhãn hiệu của Anthropic, PBC. Không hàm ý có sự liên kết hay chứng thực.