Khả năng quan sát cho tác nhân AI: Ghi lại quyết định, không chỉ mã HTTP 200
Một người dùng báo cáo rằng tác nhân (agent) “đã làm điều gì đó lạ” vào chiều hôm qua. Bạn mở nhật ký và thấy:
INFO agent run started
INFO calling tool: updateOrder
INFO tool returned 200
INFO agent run completed
Tác nhân đã gọi updateOrder, nhưng bạn không biết với đối số nào, dựa trên lệnh nào, vì sao chọn công cụ đó hay API đã trả về dữ liệu gì. Lần chạy được xem là thành công theo mọi chỉ số hiện có, nhưng bạn không thể tái tạo bất kỳ quyết định nào.
Các hệ thống tác nhân thường thất bại theo những cách chỉ trở nên rõ ràng khi nhìn lại. Vì vậy, nhật ký không phải phần phụ; nó là một sản phẩm của hệ thống.
Bài viết về khả năng quan sát API tập trung vào phía dịch vụ. Bài này tập trung vào lớp tác nhân nằm trên dịch vụ đó: cần ghi gì trong mỗi lần gọi công cụ, cách liên kết quyết định của mô hình với yêu cầu HTTP, dữ liệu nào phải biên tập và cách biến dấu vết thành bài kiểm thử.
Apidog đặc biệt hữu ích khi bạn đã có một dấu vết: cách nhanh nhất để hiểu một cuộc gọi sai thường là phát lại nó với cùng điểm cuối và quan sát kết quả.
Ba lớp cần có trong một dấu vết
Một tác nhân tạo ra sự kiện ở ba cấp độ. Hầu hết nhóm chỉ ghi lại lớp ở giữa.
1. Lớp suy luận
Đây là nơi mô hình đưa ra quyết định:
- Nó nhìn thấy gì trong ngữ cảnh?
- Những công cụ nào được cung cấp?
- Nó chọn công cụ nào?
- Các đối số được tạo ra là gì?
2. Lớp công cụ
Đây là trình thực thi của ứng dụng:
- Xác thực đối số.
- Áp dụng chính sách.
- Ánh xạ lời gọi công cụ thành yêu cầu HTTP.
- Xử lý kết quả và lỗi.
3. Lớp HTTP
Đây là đường truyền thực tế:
- Phương thức và URL.
- Tiêu đề và nội dung.
- Mã trạng thái.
- Độ trễ, số lần thử lại và khóa idempotency.
Gỡ lỗi gần như luôn liên quan đến nhiều lớp.
“Tác nhân gửi sai ID khách hàng” là lỗi suy luận, nhưng chỉ hiển thị ở lớp HTTP.
“API trả về mã 200 với nội dung trống” là lỗi HTTP, sau đó có thể xuất hiện dưới dạng một chuỗi suy luận kỳ lạ.
Nếu ba lớp không được liên kết bằng định danh chung, bạn sẽ phải tương quan theo thời gian. Cách này nhanh chóng thất bại khi hai lần chạy chồng lấn.
Quy tắc nền tảng:
- Một
trace_idcho mỗi lần chạy tác nhân. - Một
span_idcho mỗi lần gọi công cụ. - Cả hai xuất hiện trong mọi bản ghi ở cả ba lớp.
Dấu vết OpenTelemetry đã mô hình hóa chính xác cấu trúc này. Các quy ước ngữ nghĩa GenAI cũng đang bổ sung cách đặt tên thuộc tính để dữ liệu có thể di chuyển giữa các công cụ.
Ghi lại gì trong mỗi lần gọi công cụ?
Một bản ghi hữu ích có thể trông như sau:
{
"trace_id": "run_01J8ZK3M2Q",
"span_id": "call_004",
"parent_span_id": "call_003",
"timestamp": "2026-08-26T14:03:11.482Z",
"agent": "billing",
"step": 4,
"tool_name": "refundOrder",
"tool_args": { "orderId": "ord_92", "amount": 1200, "reason": "duplicate" },
"tools_available": ["getOrder", "listOrders", "refundOrder", "voidInvoice"],
"http": {
"method": "POST",
"url": "/v1/orders/ord_92/refund",
"request_body_hash": "sha256:1f4c...",
"status": 200,
"duration_ms": 412,
"retry_count": 1,
"idempotency_key": "9f2b7c14-6d3a-4b18"
},
"outcome": "success",
"tokens": { "prompt": 8420, "completion": 96 },
"policy": { "approval_required": true, "approved_by": "user_31", "dry_run": false }
}
Năm trường sau thường quyết định việc điều tra có thành công hay không.
tool_args
Đây là trường bị thiếu nhiều nhất và cũng là trường cần có nhất.
Ghi lại đối số do mô hình tạo ra trước khi trình thực thi chuẩn hóa hoặc biến đổi chúng. Nếu tác nhân gửi sai ID, lỗi sẽ xuất hiện ở đây.
tools_available
Trường này giải thích lựa chọn của mô hình. Nếu mô hình chọn một công cụ bất thường, câu hỏi đầu tiên là: nó còn những lựa chọn nào khác?
Chi phí lưu trữ rất nhỏ nhưng giá trị chẩn đoán lớn.
retry_count
Trường này phân biệt:
- API chậm nhưng thành công ngay lần đầu.
- API thất bại hai lần rồi mới thành công.
- Trình thực thi đã gửi cùng một yêu cầu nhiều lần.
Nếu không ghi lại, ba lần thử có thể trông giống như một cuộc gọi duy nhất.
outcome
Dùng một enum rõ ràng thay vì suy ra kết quả từ mã trạng thái:
success
failed
timed_out
blocked_by_policy
rejected_by_human
Hai trạng thái cuối rất quan trọng. Một cuộc gọi bị chính sách chặn là hàng rào bảo vệ đang hoạt động, không nhất thiết là lỗi. Trộn chúng với lỗi kỹ thuật sẽ làm sai tỷ lệ thất bại.
policy
Đây là dấu vết kiểm toán. Khi có người hỏi một hành động mang tính phá hủy có được phê duyệt hay không, trường này phải trả lời được:
- Có cần phê duyệt không?
- Ai đã phê duyệt?
- Phê duyệt lúc nào?
- Có đang chạy ở chế độ
dry_runkhông?
policy nên được kết hợp với cơ chế thực thi trong bài viết về hàng rào bảo vệ tác nhân AI.
Ghi lại quyết định, không chỉ hành động
Các lỗi khó nhất của tác nhân thường là lỗi lựa chọn. Để tái tạo chúng, hãy ghi lại đủ ngữ cảnh quyết định.
Lưu định nghĩa công cụ hoặc mã băm
Lưu phiên bản định nghĩa công cụ được sử dụng trong lần chạy, hoặc ít nhất là mã băm của chúng.
Khi độ chính xác lựa chọn thay đổi, nghi phạm đầu tiên thường là phần mô tả công cụ. Một mã băm cho biết ngay liệu bộ công cụ có thay đổi giữa lần chạy tốt và lần chạy lỗi hay không.
Văn bản trong schema có thể ảnh hưởng đáng kể đến hành vi mô hình. Xem thêm về thiết kế lược đồ công cụ cho tác nhân.
Ghi lại mô hình và cấu hình
Bản ghi lần chạy nên chứa:
- ID mô hình.
- Nhiệt độ (
temperature). - Phiên bản lời nhắc (
prompt_version). - Phiên bản ứng dụng hoặc agent runtime.
Hành vi có thể thay đổi giữa các phiên bản mô hình. Nếu thiếu những trường này, bạn có thể mất nhiều thời gian điều tra code trong khi nguyên nhân nằm ở cấu hình.
Ghi lại những gì mô hình đã thấy
Không phải lúc nào cũng nên lưu toàn bộ prompt vì chi phí và dữ liệu nhạy cảm. Một phương án cân bằng là lưu:
- Số lượng token.
- Kích thước prompt.
- Mã băm prompt.
- Phiên bản prompt.
Một lần chạy có prompt lớn gấp đôi bình thường là tín hiệu cho thấy dữ liệu ngoài dự kiến đã được thêm vào ngữ cảnh.
Lưu kết quả công cụ thô
Nếu trình thực thi cắt gọn phản hồi trước khi gửi cho mô hình, hãy lưu toàn bộ payload trong dấu vết.
Bài viết về giữ phản hồi công cụ khỏi cửa sổ ngữ cảnh đề cập cách kiểm soát dữ liệu đưa vào prompt. Tuy nhiên, bản ghi quan sát vẫn nên giữ phiên bản thô, nếu chính sách dữ liệu cho phép. Nếu không, bạn sẽ không biết dữ liệu bị thiếu từ API hay bị cắt trong runtime.
Biên tập dữ liệu trước khi lưu trữ
Dấu vết tác nhân đặc biệt nhạy cảm vì nó chứa cả yêu cầu lẫn lý do xung quanh yêu cầu đó. Prompt cũng thường thu thập dữ liệu cá nhân ngoài dự kiến.
Bốn quy tắc sau giúp giảm rủi ro.
Không lưu thông tin xác thực
Loại bỏ:
-
Authorization. - API key.
- Cookie.
- URL đã ký.
- Token trong query string hoặc request body.
Thay vì lưu giá trị, hãy lưu định danh của credential, chẳng hạn credential_id hoặc key_id. Bài viết về API key đặc quyền tối thiểu cho tác nhân giải thích vì sao việc định danh credential vẫn hữu ích: bạn biết tác nhân nào đã thực hiện hành động mà không làm lộ bí mật.
Biên tập tại ranh giới ghi nhật ký
Không nên đợi đến lúc truy vấn dữ liệu mới lọc bí mật. Khi đó bí mật đã có thể được ghi vào đĩa, sao chép hoặc đưa vào bản sao lưu.
Hãy biên tập trong middleware ghi nhật ký, trước khi bản ghi rời khỏi tiến trình.
Băm payload không thể lưu
Mã băm nội dung yêu cầu cho phép chứng minh hai cuộc gọi giống hệt nhau, phục vụ phần lớn điều tra về trùng lặp mà không cần giữ payload.
Ví dụ:
{
"request_body_hash": "sha256:1f4c...",
"payload_stored": false
}
Phân cấp thời gian lưu trữ
Một chính sách thực tế có thể là:
- Dấu vết đầy đủ: giữ trong một tuần.
- Dấu vết đã biên tập, không có payload: giữ trong một năm.
- Chỉ số tổng hợp: giữ lâu hơn nếu cần.
Phần lớn việc gỡ lỗi diễn ra trong vài ngày, còn câu hỏi kiểm toán thường xuất hiện trong vài tháng.
Biến dấu vết thành bài kiểm thử
Theo dõi tốt không chỉ giúp gỡ lỗi nhanh hơn. Nó còn tạo ra các trường hợp kiểm thử thực tế.
Phát lại mọi lần chạy thất bại
Mỗi lần chạy thất bại là một kịch bản:
- Lấy các lệnh gọi công cụ từ dấu vết.
- Phát lại chúng với API.
- Xác nhận lỗi.
- Sửa nguyên nhân.
- Giữ bản phát lại làm bài kiểm thử hồi quy.
Trong Apidog, bạn có thể dựng lại yêu cầu lỗi dưới dạng một trường hợp đã lưu, xác nhận hành vi sau khi sửa và chạy nó trong CI. Một sự cố đơn lẻ từ đó trở thành phạm vi kiểm thử lâu dài.
Dùng dấu vết để chọn mock
Dấu vết cho biết trực tiếp:
- Điểm cuối nào được gọi nhiều nhất.
- Trạng thái lỗi nào thực sự xảy ra.
- Dữ liệu nào thường xuất hiện trong phản hồi.
- Công cụ nào có ảnh hưởng lớn nhất đến luồng chạy.
Hãy xây dựng mock quanh các trường hợp này thay vì đoán. Xem thêm bài viết về chạy tác nhân với API mock thay vì production.
Phát hiện thay đổi chậm
Theo dõi hàng tuần:
- Phân phối lựa chọn công cụ.
- Tỷ lệ thử lại theo điểm cuối.
- Số lần gọi trên mỗi tác vụ hoàn thành.
- Tỷ lệ lần chạy bị chính sách chặn.
Một thay đổi nhỏ trong các chỉ số này có thể là tín hiệu sớm trước khi trở thành sự cố. Các kiểm thử cấp hợp đồng, như trong hướng dẫn kiểm thử hợp đồng API, có thể phát hiện thay đổi ở thượng nguồn.
Ba câu hỏi mà dấu vết phải trả lời được
“Tác nhân đã tính phí sai khách hàng như thế nào?”
Bạn cần:
- Đối số mô hình tạo ra.
- URL cuối cùng sau khi resolve.
- Bước ngay trước đó.
- Kết quả của các công cụ trước đó.
Trong nhiều trường hợp, ID bắt nguồn từ một kết quả công cụ có nhiều bản ghi khớp, rồi mô hình chọn bản ghi đầu tiên. Dấu vết phải cho thấy kết quả, sự mơ hồ và lựa chọn cuối cùng.
Nếu không có tool_args, bạn chỉ còn mã HTTP 200 và một khách hàng không hài lòng.
“Tác nhân ngừng hoạt động từ thứ Ba vì sao?”
So sánh lần chạy tốt và lần chạy lỗi theo từng trường:
- ID mô hình.
- Mã băm bộ công cụ.
- Phiên bản prompt.
- Kích thước phản hồi trung bình.
- Số token.
- Số lần thử lại.
Một trong các trường này thường cho biết điều gì đã thay đổi. Đây là lý do bản ghi lần chạy phải chứa cấu hình, không chỉ danh sách sự kiện.
“Có ai phê duyệt hành động này không?”
Khối policy phải trả lời trực tiếp:
-
approval_required. -
approved_by. - Thời điểm phê duyệt.
- Trạng thái thực thi.
Hãy ghi lại tại thời điểm quyết định được đưa ra, không cố tái tạo sau này.
Điểm chung của cả ba câu hỏi: không câu nào được trả lời bằng “công cụ trả về 200”. Chúng cần các trường nhỏ, rẻ để lưu nhưng không thể khôi phục sau khi sự việc xảy ra.
Lấy mẫu có chọn lọc
Theo dõi đầy đủ mọi lần chạy có thể tốn kém khi khối lượng lớn. Tuy nhiên, lưu lượng tác nhân không đồng nhất nên không nên lấy mẫu ngẫu nhiên theo tỷ lệ cố định.
Luôn giữ lại
- Mọi lần chạy thất bại.
- Mọi lần chạy bị chính sách chặn.
- Mọi lần chạy chứa thao tác ghi.
- Mọi lần chạy vượt ngưỡng độ trễ.
- Mọi lần chạy có retry hoặc timeout.
Đây là những lần chạy người dùng và đội vận hành có khả năng cần điều tra nhất.
Có thể lấy mẫu
Các lần chạy chỉ đọc thành công thường chiếm phần lớn khối lượng và ít thú vị khi xem riêng lẻ. Bạn vẫn cần giữ đủ mẫu để tính đường cơ sở.
Chương về giám sát hệ thống phân tán trong SRE của Google giải thích rõ vì sao nên lấy mẫu theo tín hiệu thay vì theo khối lượng. Nguyên tắc này áp dụng trực tiếp cho tác nhân.
Ngay cả khi loại bỏ payload, hãy giữ bản ghi khung gồm:
- Tên công cụ.
- Kết quả.
- Thời lượng.
- Trạng thái.
- Retry count.
Bản ghi khung rất nhỏ nhưng vẫn hỗ trợ các chỉ số quan trọng. Payload và prompt là phần tốn kém nhất, nên loại bỏ chúng trước.
Cẩn thận với tail sampling
Nếu quyết định giữ hay bỏ dấu vết sau khi lần chạy kết thúc, quyết định đó phải xảy ra sau khi biết kết quả cuối cùng.
Một lần chạy có thể trông bình thường ở bước 3 nhưng thất bại ở bước 9. Vì vậy, cần đệm dữ liệu trong khi chạy thay vì loại bỏ ngay từng span.
Nên lưu dấu vết ở đâu?
Các nguyên tắc trên giả định bạn sở hữu hệ thống lưu trữ. Điều này phù hợp khi tác nhân là dịch vụ của bạn gọi API của bạn, nhưng không phù hợp khi tác nhân chạy trên máy của nhà phát triển hoặc khách hàng.
Khi đó, dấu vết có thể nằm ở bất kỳ thiết bị đầu cuối nào đã chạy tác nhân.
Sharkly áp dụng cách tiếp cận khác: gắn dấu vết thực thi vào nhiệm vụ mà tác nhân được giao. Lịch sử chạy, nhật ký thực thi và kết quả nằm cạnh mục tiêu, trạng thái và chuỗi bình luận nơi con người xem xét công việc.
Lợi ích thực tế nằm ở khả năng truy xuất. Câu hỏi “Tại sao tác nhân làm điều đó?” trở thành việc mở nhiệm vụ thay vì tìm đúng máy, phiên làm việc và lịch sử terminal.
Cách này không thay thế OpenTelemetry, hệ thống quan sát hay môi trường runtime. Claude Code và Codex vẫn thực hiện công việc. Nó chỉ thay đổi nơi bản ghi kết thúc khi tác nhân không phải là một dịch vụ do bạn triển khai.
Theo dõi bốn chỉ số quan trọng
Dấu vết chỉ có giá trị khi được sử dụng. Bốn chỉ số sau nên có trên dashboard.
1. Số lần gọi trên mỗi tác vụ hoàn thành
Đây là thước đo hiệu quả trực tiếp nhất.
Nếu chỉ số tăng, tác nhân có thể đang khám phá quá nhiều, thường do:
- Mô tả công cụ kém.
- Prompt phình to.
- Một điểm cuối bắt đầu lỗi.
- Kết quả API không đủ rõ ràng.
2. Tỷ lệ retry theo điểm cuối
Chỉ số này xếp hạng các phụ thuộc kém tin cậy nhất và cho thấy khi nào một điểm cuối suy giảm.
Bài viết về phục hồi lỗi tác nhân trình bày cách xử lý các điểm cuối đứng đầu danh sách.
3. Tỷ lệ bị chính sách chặn
Chỉ số này nên thấp và ổn định.
Một mức tăng đột biến có thể cho thấy:
- Tác nhân đang cố thực hiện hành động không được phép.
- Chính sách quá chặt và trở thành nút cổ chai.
- Prompt hoặc mô tả công cụ đã thay đổi.
4. Thời gian đến lần gọi công cụ đầu tiên
Khởi đầu chậm thường liên quan đến prompt quá lớn. Kích thước prompt là một dạng “phình to âm thầm”: nó có thể tăng dần mà không ai chủ động quyết định tăng.
Checklist triển khai
- [ ] Một
trace_idcho mỗi lần chạy và mộtspan_idcho mỗi lần gọi công cụ. - [ ] ID được ghi ở cả lớp suy luận, lớp công cụ và lớp HTTP.
- [ ] Đối số mô hình được ghi trước khi chuẩn hóa.
- [ ] Danh sách công cụ có sẵn được lưu trong mỗi lần gọi.
- [ ] Kết quả dùng enum rõ ràng, bao gồm cả trạng thái bị chính sách chặn.
- [ ] Số lần retry được tách khỏi số lần gọi.
- [ ] Model, temperature, phiên bản prompt và mã băm bộ công cụ nằm trong bản ghi lần chạy.
- [ ] Kết quả công cụ thô được lưu, không chỉ phiên bản đã cắt gọn gửi cho mô hình.
- [ ] Credential được loại bỏ trong middleware.
- [ ] Payload không thể lưu được thay bằng mã băm.
- [ ] Thời gian lưu trữ được phân cấp theo độ nhạy cảm.
- [ ] Dấu vết lỗi có thể chuyển thành trường hợp kiểm thử và phát lại.
- [ ] Tail sampling chỉ quyết định sau khi biết kết quả cuối cùng.
Mục tiêu rất đơn giản: khi có người hỏi vì sao tác nhân làm điều gì đó, bạn trả lời được từ bản ghi thay vì phỏng đoán.
Bạn có thể tải Apidog để phát lại các cuộc gọi trong dấu vết và lưu các bản tái tạo thành bài kiểm thử.
Câu hỏi thường gặp
Nên dùng OpenTelemetry hay công cụ quan sát tác nhân chuyên dụng?
Dùng OpenTelemetry cho việc vận chuyển và mô hình hóa dấu vết. Nó đã xử lý tương quan, đồng thời hạ tầng hiện có của bạn có thể hiểu dữ liệu này.
Công cụ chuyên dụng cho tác nhân có thể bổ sung các chế độ xem hữu ích, nhưng dữ liệu nền vẫn nên có thể di chuyển được.
Chi phí lưu trữ đầy đủ dấu vết là bao nhiêu?
Thường thấp hơn dự kiến nếu áp dụng lưu trữ phân cấp:
- Payload đầy đủ trong vài ngày.
- Bản ghi có cấu trúc, không chứa nội dung, trong thời gian dài hơn.
- Mã băm và kích thước prompt thay vì lưu prompt mặc định.
Prompt thường là phần tốn kém nhất.
Có cần ghi lại văn bản suy luận của mô hình không?
Thông thường là không.
Công cụ được chọn, các đối số được tạo ra và những lựa chọn có sẵn đã giải thích phần lớn quyết định. Nếu nhà cung cấp cho phép truy cập nội dung suy luận, chỉ nên lưu cho các lần chạy thất bại và xem đó là dữ liệu nhạy cảm.
Làm sao theo dõi nhiều tác nhân?
Giữ một trace_id cho toàn bộ tác vụ và cấp một span riêng cho mỗi tác nhân. Ghi việc chuyển giao giữa các tác nhân thành một sự kiện.
Xem thêm về chuyển giao đa tác nhân và truyền ngữ cảnh.
Nếu tác nhân chạy trên máy khách hàng thì sao?
Ghi nhật ký cục bộ, biên tập tích cực và chỉ gửi số liệu tổng hợp, trừ khi người dùng đồng ý chia sẻ thêm.
Tên công cụ, kết quả và thời lượng thường đủ cho giám sát cấp đội ngũ mà không cần payload rời khỏi thiết bị.
Mã băm nội dung yêu cầu có thực sự hữu ích không?
Có, đối với phần lớn câu hỏi phổ biến.
Mã băm chứng minh hai cuộc gọi giống hệt nhau, hỗ trợ điều tra các lần ghi trùng lặp mà không cần lưu payload. Kết hợp mã băm với idempotency key còn giúp ngăn chặn nhiều trường hợp trùng lặp ngay từ đầu.
Tài liệu tham khảo
- Khả năng quan sát API
- Apidog
- Dấu vết OpenTelemetry
- Quy ước ngữ nghĩa GenAI
- Hàng rào bảo vệ tác nhân AI
- Thiết kế lược đồ công cụ cho tác nhân
- Giữ phản hồi công cụ khỏi cửa sổ ngữ cảnh
- API key đặc quyền tối thiểu cho tác nhân
- Chạy tác nhân với mock API thay vì production
- Kiểm thử hợp đồng API
- Giám sát hệ thống phân tán trong SRE
- Sharkly
- Phục hồi lỗi tác nhân
- Tải Apidog
- Chuyển giao đa tác nhân
- Idempotency key cho tác nhân

Top comments (0)