Chuyển đến nội dung chính
Hướng dẫn AI

Kiểm tra lệnh gọi công cụ của tác nhân AI bằng ToolReplay

Hướng dẫn này trình bày cách cài đặt ToolReplay, chuẩn bị bản ghi JSONL nghiêm ngặt và tệp phạm vi, chạy các cuộc kiểm tra replay, scope, seal và verify, diễn giải báo cáo xác định, tích hợp kiểm tra vào CI, đồng thời tìm hiểu mô hình bảo mật và các giới hạn của dự án.

Kiểm tra lệnh gọi công cụ AI bằng ToolReplay

ToolReplay làm gì

ToolReplay kiểm tra các lệnh gọi công cụ của tác nhân AI đã được ghi lại mà không gọi công cụ thực tế. Công cụ này phân tích bản ghi để xác định ba vấn đề: phản hồi không xác định, các lệnh gọi dư thừa và các lệnh gọi nằm ngoài quyền đã khai báo của tác nhân. ToolReplay cũng có thể niêm phong bản ghi bằng chuỗi băm SHA-256 và xác minh rằng tệp đã niêm phong chưa bị chỉnh sửa.

Vì ToolReplay phát lại các phản hồi đã ghi thay vì thực hiện lệnh gọi trực tiếp, việc kiểm tra an toàn, không gây tác dụng phụ, có thể tái tạo và vẫn sử dụng được ngay cả khi các công cụ ban đầu không khả dụng.

Cài đặt và chạy ToolReplay

ToolReplay yêu cầu Python 3.11 trở lên và không có phụ thuộc thời gian chạy bên thứ ba. Công cụ không truy cập mạng.

Từ bản sao mã nguồn, chạy trực tiếp mô-đun:

python -m toolreplay version

Bạn cũng có thể cài đặt tập lệnh dòng lệnh:

pip install .
toolreplay version

Cả hai cách đều in ra phiên bản đã cài đặt, chẳng hạn:

toolreplay 0.6.0

Tìm hiểu định dạng bản ghi

Bản ghi là một tệp JSON Lines. Mỗi dòng không trống đại diện cho một lần gọi công cụ và phải chứa chính xác bốn trường:

  • index: một số nguyên bắt đầu từ 0 và tăng chính xác 1 đơn vị.
  • tool: tên công cụ được gọi.
  • args: một đối tượng chứa các đối số của công cụ.
  • response: một đối tượng chứa phản hồi công cụ đã ghi.

Một bản ghi hợp lệ có dạng:

{"index": 4, "tool": "write_file", "args": {"path": "docs/intro.md", "text": "edited"}, "response": {"ok": true}}

Việc phân tích cú pháp được thiết kế nghiêm ngặt. Các trường không xác định, trường bị thiếu, kiểu đối tượng không hợp lệ, chỉ mục không phải số nguyên và chỉ mục không đúng thứ tự đều gây ra lỗi nghiêm trọng. Giá trị Boolean không được chấp nhận là số nguyên, dù Python coi bool là lớp con của int.

ToolReplay so sánh các lệnh gọi bằng JSON chuẩn hóa: tên công cụ và các đối số được mã hóa với khóa đã sắp xếp và không có khoảng trắng không cần thiết. Vì vậy, các đối tượng đối số có thứ tự khóa khác nhau vẫn đại diện cho cùng một lệnh gọi. Phản hồi cũng sử dụng cách mã hóa chuẩn hóa tương tự khi ToolReplay kiểm tra tính xác định.

Chạy kiểm tra phát lại

Lệnh replay kiểm tra bản ghi dựa trên các phản hồi đã ghi của chính bản ghi đó. Hãy thử mẫu chứa lỗi trong kho mã:

python -m toolreplay replay samples/session-dirty.jsonl

Lệnh này tạo ra báo cáo xác định, theo từng dòng:

calls: 6
divergence: index 5
findings: 2
index 2: redundant-call: tool 'read_file' repeats the identical call at index 1 with no state change between them
index 5: non-determinism: tool 'search' returned a different response than the identical call at index 3

Phần tiêu đề được đọc từ trên xuống dưới. calls: 6 nghĩa là đã phân tích sáu bản ghi hợp lệ. divergence: index 5 xác định điểm đầu tiên mà tại đó một lần chạy lại có tính xác định sẽ không khớp với bản ghi. findings: 2 đếm số phát hiện được liệt kê sau đó.

Các phát hiện được sắp xếp theo chỉ mục rồi theo loại, vì vậy những lần kiểm tra lặp lại trên cùng một đầu vào sẽ tạo ra kết quả giống hệt nhau ở cấp độ byte.

Tính không xác định

ToolReplay ghi nhớ phản hồi đầu tiên cho mỗi lệnh gọi chuẩn hóa. Nếu sau đó một lệnh gọi giống hệt có phản hồi đã ghi khác, công cụ sẽ báo cáo tính không xác định. Trong mẫu, lệnh gọi search cho install xuất hiện tại các chỉ mục 3 và 5, nhưng các phản hồi báo cáo số lượng kết quả khác nhau. Chỉ mục 5 trở thành điểm phân kỳ.

Điều này quan trọng đối với tác nhân vì quyết định dựa trên câu trả lời đầu tiên có thể thay đổi nếu câu trả lời thứ hai được trả về. Phát hiện này cho thấy phiên làm việc phụ thuộc vào thông tin không ổn định trong bản ghi.

Lệnh gọi dư thừa

Một lệnh gọi lặp lại chỉ dư thừa khi không có sự kiện đã ghi nào giữa hai lệnh gọi có thể làm thay đổi trạng thái. Các trình biến đổi mặc định là write_file, delete_file, create_file, move_file và run_command. Bất kỳ lệnh gọi khác nào nằm giữa hai lệnh gọi giống hệt cũng được xử lý thận trọng như một thay đổi trạng thái có thể xảy ra.

Trong mẫu, read_file đọc docs/intro.md tại các chỉ mục 1 và 2 mà không có thay đổi trạng thái xen giữa, nên chỉ mục 2 bị đánh dấu. Một lần đọc sau lệnh gọi write_file sẽ không được coi là dư thừa.

Kiểm tra quyền của tác nhân

Sử dụng scope khi bạn có khai báo quyền cho tác nhân:

python -m toolreplay scope samples/session-dirty.jsonl samples/scope.json

Mẫu này tạo ra:

calls: 6
findings: 1
index 4: permission-overreach: tool 'write_file' is not in the declared scope for agent 'docs-reader'

Phát lại và phạm vi là hai lệnh riêng biệt theo thiết kế. Phát lại đánh giá một phiên dựa trên chính phiên đó và chỉ cần bản ghi. Phạm vi so sánh từng lệnh gọi với một tệp quyền riêng biệt.

Tệp phạm vi là một đối tượng JSON chứa tên tác nhân và danh sách chính xác các công cụ được phép:

{"agent": "docs-reader", "allowed_tools": ["read_file", "list_dir", "search"]}

Tên công cụ được đối sánh chính xác và phân biệt chữ hoa chữ thường. Các trường bị thiếu, kiểu không chính xác hoặc phần tử không phải chuỗi đều bị từ chối. Việc kiểm tra phạm vi dựa trên tên; công cụ không kiểm tra các đối số hoặc xác định liệu công cụ được phép có nhắm đến đường dẫn được cho phép hay không.

Niêm phong bản ghi

Lệnh seal chuyển đổi bản ghi thành tệp JSONL được liên kết bằng chuỗi băm:

python -m toolreplay seal samples/session-dirty.jsonl > sealed.jsonl

Mỗi liên kết được niêm phong chứa các trường của bản ghi gốc cùng với prev và digest. Liên kết đầu tiên sử dụng 64 ký tự thập lục phân bằng 0 làm digest trước đó. Mỗi digest SHA-256 tiếp theo bao gồm digest trước đó và các byte chuẩn hóa của bản ghi hiện tại, bao gồm chỉ mục, công cụ, đối số và phản hồi.

Vì mỗi liên kết phụ thuộc vào liên kết đứng trước, việc thay đổi một bản ghi trước đó sẽ làm thay đổi digest của bản ghi đó và tất cả digest tiếp theo. Do đó, chuỗi giúp phát hiện các chỉnh sửa và xác định vị trí liên kết đầu tiên bị hỏng.

Xác minh tệp đã niêm phong

Xác minh một chuỗi nguyên vẹn bằng:

python -m toolreplay verify sealed.jsonl

Tệp không bị thay đổi sẽ báo:

chain: intact

Nếu phản hồi được ghi lại hoặc bất kỳ trường nào khác trong chuỗi bị sửa đổi, quá trình xác minh sẽ báo liên kết đầu tiên bị hỏng cùng digest mong đợi và digest được tìm thấy:

chain: broken
first broken link: index 3
expected: 34d19a9dfb112baa07afa37994ddcbbebe2973674385f3942340653d08d205bd
found: 40aadf3b8156217f0b5b1d95010b6b79f82a26ccf5e780aed0f5f311f865028a

Việc niêm phong phát hiện các chỉnh sửa sau khi niêm phong, bao gồm thay đổi thứ tự, chỉ mục, công cụ, đối số và phản hồi. Đây không phải là chữ ký số: bất kỳ ai có thể chỉnh sửa tệp cũng có thể niêm phong lại tệp. Để xác lập nguồn gốc, cần ký digest cuối cùng bằng một khóa được quản lý bên ngoài ToolReplay.

Sử dụng ToolReplay trong CI

Mã thoát của ToolReplay phù hợp để dùng làm điều kiện kiểm soát bản dựng:

  • 0: kiểm tra nhật ký sạch hoặc chuỗi nguyên vẹn.
  • 1: có phát hiện hoặc chuỗi bị hỏng.
  • 2: xảy ra lỗi sử dụng, chẳng hạn đầu vào sai định dạng hoặc thiếu tệp.

Chạy kiểm tra phát lại và phạm vi trực tiếp trong một tác vụ CI:

python -m toolreplay replay session.jsonl
python -m toolreplay scope session.jsonl scope.json

Mã thoát 1 có nghĩa là công cụ đã hoàn tất việc kiểm tra và phát hiện vấn đề cần báo cáo. Mã thoát 2 có nghĩa là không thể chạy kiểm tra, vì vậy hệ thống tự động có thể phân biệt đầu vào sai định dạng với một phát hiện thực tế.

Để so sánh có thể tái lập, hãy niêm phong từng lần chạy và đối chiếu kết quả:

python -m toolreplay seal run-a.jsonl > run-a.sealed.jsonl
python -m toolreplay seal run-b.jsonl > run-b.sealed.jsonl
git --no-pager diff --no-index run-a.sealed.jsonl run-b.sealed.jsonl

Vì các báo cáo không chứa dấu thời gian hoặc giá trị ngẫu nhiên, đầu vào giống hệt nhau sẽ tạo ra đầu ra giống hệt nhau. Dòng đã niêm phong đầu tiên khác biệt cho biết vị trí hai lần chạy không còn nhất quán, trong khi digest thay đổi cho thấy các liên kết tiếp theo phụ thuộc vào khác biệt đó.

Sử dụng nâng cao và giới hạn thực tế

  • Giữ bản ghi phiên dễ nối thêm. JSON Lines cho phép trình tạo nối thêm từng bản ghi cho mỗi lần gọi và giúp dễ dàng xem xét các thay đổi trong hệ thống kiểm soát phiên bản.
  • Bảo toàn các phản hồi đã ghi. Replay không gọi các công cụ thực; nó chỉ có thể phát hiện những vấn đề được thể hiện trong bản ghi phiên.
  • Diễn giải tính dư thừa một cách thận trọng. Danh sách mutator mặc định là cố định, còn các công cụ có khả năng thay đổi tùy chỉnh không nằm trong danh sách đó được xem là chỉ đọc khi phân tích tính dư thừa.
  • Ghi nhớ ranh giới so sánh. Tính không xác định chỉ được phát hiện khi cùng một lệnh gọi chuẩn hóa được lặp lại. Các lệnh gọi khác nhau nhưng có phản hồi liên quan về mặt ngữ nghĩa không được đánh giá về tính tương đương.
  • Tách biệt quyền hạn và mục tiêu. Kiểm tra phạm vi chỉ kiểm tra tên công cụ. Chúng không thể phát hiện trường hợp một công cụ được cho phép được sử dụng trên tài nguyên bị cấm.
  • Dùng niêm phong để bảo đảm toàn vẹn, không phải danh tính. Chuỗi cho biết tệp có bị thay đổi sau khi niêm phong hay không, nhưng không chứng minh được ai đã tạo chuỗi.

Chạy bộ kiểm thử

Dự án sử dụng framework unittest trong thư viện chuẩn của Python và không có phần phụ thuộc kiểm thử bên thứ ba. Từ thư mục gốc của kho mã, chạy:

python -m unittest discover -s tests

Các bài kiểm thử bao phủ việc phân tích cú pháp bản ghi phiên nghiêm ngặt, mã hóa chuẩn hóa, tạo chuỗi băm và phát hiện giả mạo, các phát hiện khi phát lại, thực thi phạm vi, hoạt động CLI và mã thoát.

Kết luận

ToolReplay cung cấp một quy trình kiểm tra tập trung cho các phiên tác nhân AI. Bắt đầu với replay để tìm hành vi không nhất quán hoặc lãng phí, dùng scope để kiểm tra quyền công cụ đã khai báo, và dùng seal cùng verify để phát hiện các thay đổi sau khi ghi lại. Việc xác thực đầu vào nghiêm ngặt và các báo cáo tất định giúp công cụ phù hợp cho gỡ lỗi, xem xét, kiểm soát phiên bản và thực thi trong CI.