Skip to main content
Đối với một agent mà bạn tự viết, hoặc một framework mà Failproof AI không có adapter cho. Không có gì phải công cụ hóa: bạn phát ra các sự kiện. Đây là cùng một API mà bốn adapter framework gọi bên dưới. Chúng là các bảng dịch của nó.

Cài đặt

Không có thêm gì, và không có phụ thuộc.

Công cụ hóa

Đọc từ trên xuống dưới và nó nói những gì nó có nghĩa: Và những gì mỗi cái thực sự phát ra: Mọi thứ bên trong có thể bỏ qua session_idagent_id. Các phạm vi liên kết danh tính trên các biến ngữ cảnh và mỗi lệnh gọi sự kiện đọc lại nó, vì vậy bạn không bao giờ phải điều phối các id thông qua các hàm của bạn. Cả ba đều hoạt động dưới async with cũng như with. Lồng các agent xây dựng cây. parent_id và độ sâu được tính từ ngăn xếp:

Cách một phạm vi đóng lại

agent() xử lý ngoại lệ cho bạn: Lỗi được phát ra trước agent_end, bởi vì bảng điều khiển đóng span tại agent_end và bất cứ điều gì sau đó được quy cho không có gì. Hủy bỏ không phải là thất bại, vì vậy các lần chạy bị hủy không làm ô nhiễm bề mặt lỗi. Ngoại lệ luôn được nâng lại: một phạm vi không bao giờ nuốt chửng.

Các phương thức sự kiện

Mười năm phương thức trong sáu gia đình. Hầu hết đều đi thành cặp — bạn phát ra phần mở, sau đó là phần đóng, và SDK đo khoảng thời gian giữa chúng.
Ưu tiên các phạm vi — agent()tool_call() — ở bất kỳ nơi nào chúng phù hợp. Chúng đảm bảo sự kiện đóng ngay cả khi phần nội dung tăng. Chuyển đến các phương thức này trực tiếp khi luồng điều khiển của bạn không lồng nhau, chẳng hạn như lệnh gọi mô hình bên trong một trợ giúp.
Hai gia đình con người chỉ theo hướng ngược lại.Không có framework nào báo hiệu cặp thứ hai, vì vậy nó luôn là của bạn để phát ra.
Chuyển request_id khi các lệnh gọi mô hình chạy đồng thời. Nếu không có nó, các yêu cầu và phản hồi ghép thành từng lệnh gọi trên mỗi agent — và các lệnh gọi đồng thời bị ghép sai, gắn mỗi phản hồi vào yêu cầu sai.

Ví dụ

Một vòng lặp gọi công cụ trên API OpenAI, không có framework agent:
Điều đó tạo ra cùng sáu loại sự kiện mà một adapter sẽ cung cấp cho bạn. Phiên bản chạy được hoàn chỉnh, với các định nghĩa công cụ, được gửi trong kho SDK dưới docs/manual/examples/.

Luồng và async

Các biến ngữ cảnh lan truyền vào các tác vụ asyncio một cách tự động. Họ không lan truyền vào các luồng mới, bởi vì một luồng bắt đầu với một ngữ cảnh trống.
Nếu không có propagate(), sự kiện của worker sẽ tăng lên một TypeError đặt tên cho phần sửa chữa chứ không là đếm không có session. Điều này cố ý: một sự kiện không có session bị bỏ qua bằng cách nhập và trả lời 200, đó là lỗi im lặng mà lớp danh tính tồn tại để ngăn chặn.

Công cụ hóa một framework mà không có adapter

Mỗi framework agent cung cấp cho bạn ba đường nối tương tự. Ánh xạ chúng và bạn có một dấu vết hoàn chỉnh — bốn adapter được gửi không làm gì nhiều hơn thế.
1

Dấu ngoặc lần chạy

2

Dấu ngoặc mỗi công cụ

Ở bất kỳ nơi nào framework gọi trình bao bọc công cụ hoặc middleware.
3

Ghép mỗi lệnh gọi mô hình

Có một nút, bước hoặc ranh giới middleware đáng xem? Bao nó trong một cặp hook — hook_triggered / hook_completed — không phải một agent() lồng nhau. agent_id là một khía cạnh cardinality thấp, và một mục nhập trên mỗi nút làm chìm nó. Các khoảng hook hiển thị cùng cách và cung cấp cho bạn độ trễ trên mỗi nút.
Tay và tự động soạn. Một adapter chạy bên trong một phạm vi viết tay tham gia session đó và phụ huynh của đó, vì vậy bạn nhận được một cây chứ không phải hai — hữu ích khi bạn công cụ hóa một framework tự bên cạnh một cái được hỗ trợ.
Hai lý do, và ba đường nối trên là câu trả lời cho cả hai:
  • autogen-core đã không được bảo trì kể từ tháng 9 năm 2025.
  • AG2 không cung cấp điểm đăng ký toàn bộ quy trình tương đương với các hook của các framework khác, vì vậy công cụ hóa nó có nghĩa là bao bọc mỗi agent ở mỗi trang xây dựng.
Ánh xạ các đường nối bằng tay ghi lại những sự kiện giống nhau, với cùng một độ tin cậy, như một adapter được gửi sẽ làm.

Đi sâu hơn

Cách ghi âm thực sự hoạt động. Không cần thiết phải bắt đầu.
Mỗi bản ghi có cùng một hình dạng: một span mở, công việc lồng nhau bên trong nó, và mỗi sự kiện mở nhận được một sự kiện đóng.Cặp là đơn vị. Mỗi sự kiện đóng mang một khoảng thời gian mà SDK đo lường từ sự kiện mở của nó.Dưới đây là một lần chạy thực tế trên mỗi framework — bắt được từ các ví dụ được gửi với SDK, tên mô hình bình thường hóa. Lưu ý bao nhiêu quay lại từ một lệnh gọi duy nhất.
14 events
Các nút trở thành các cặp hook, vì vậy bạn nhận được độ trễ trên mỗi nút mà không có chúng làm chìm danh sách agent.
Không có sự kiện kết thúc phiên. Một phiên không phải là cái gì bạn đóng — nó là một nhóm các sự kiện chia sẻ một session_id.Trạng thái được lấy từ hình dạng của dấu vết:Vì vậy, một phiên kết thúc khi mỗi cặp đóng. Các adapter phát ra agent_end cho bạn, và khi phân hủy chúng đóng bất cứ thứ gì vẫn mở và đánh dấu nó không đầy đủ — một lần chạy bị lỗi giải quyết dưới dạng done với một khoảng trống có thể nhìn thấy chứ không phải treo mãi mãi.
Đây là lý do tại sao một phiên có thể kéo dài hai lệnh gọi. Một interrupt() LangGraph tạm dừng lần chạy, span gốc cố ý để mở, và lệnh gọi tiếp tục đóng nó. Cả hai lệnh gọi là một phiên.
session_idagent_id là tùy chọn trên mỗi phương thức sự kiện. Bỏ qua, chúng giải quyết từ phạm vi bao quanh:
Chuyển chúng rõ ràng vẫn hoạt động và ưu tiên. Không có gì liên kết và không có gì được chuyển, lệnh gọi tăng lên TypeError đặt tên cho phần sửa chữa chứ không phải phát ra sự kiện không có phiên, cái mà ingest sẽ bỏ qua trong khi trả lời 200.Phạm vi liên kết danh tính trên các biến ngữ cảnh. Những cái đó lan truyền vào các tác vụ asyncio một cách tự động nhưng không vào các luồng mới — bao một worker trong failproofai_sdk.propagate().

Ai tạo ra id nào

Cách các adapter giải quyết session_id

Trận đấu đầu tiên thắng:
  1. Một session_id tùy chọn rõ ràng
  2. Siêu dữ liệu trên mỗi cuộc gọi
  3. Phạm vi session() bao quanh
  4. Siêu dữ liệu framework
  5. Id chạy của riêng framework
Nó không bao giờ được phát minh trong khi một trong những cái đó tồn tại — một id tổng hợp sẽ chia một lần chạy thành nhiều phiên.

Giữ agent_id cardinality thấp

Đó là khía cạnh chính trên mỗi bề mặt bảng điều khiển, và một cột LowCardinality(String). Một giá trị trên mỗi lần chạy làm giảm cột và lấp đầy thả xuống bộ lọc với một mục nhập trên mỗi lần chạy.Các adapter bảo vệ cột đó cho bạn:Id thực được giữ trên fw_agent_id / fw_run_id, nơi nó vẫn có thể truy vấn được mà không là một khía cạnh.
Bảo vệ này chỉ chạm vào các nhãn mà framework lựa chọn. Một agent_id mà bạn tự chuyển — để event.*, hoặc để failproofai_sdk.agent(...) — được ghi lại chính xác như đã cho. Im lặng viết lại một đối số rõ ràng sẽ tệ hơn cardinality mà nó ngăn chặn, vì vậy đặt tên cho các span của riêng bạn phù hợp.
Framework nào ghi lại gì, được đo lường từ các lần chạy trên:Một dấu gạch ngang có nghĩa là framework không có khái niệm như vậy. human_pausehuman_interrupt mô tả một người hành động trên agent, mà không có framework nào báo hiệu — tự phát ra những cái đó.
Một sự kiện không bao giờ đến một mình. Một cái mở một span, một cái đóng nó, và sự kiện đóng mang một khoảng thời gian mà SDK đo lường từ sự kiện mở của nó.
Một sự kiện mở mà không có sự kiện đóng là một span không bao giờ kết thúc. Phiên hiển thị vẫn chạy, mãi mãi, và khoảng thời gian hoạt động của nó tiếp tục phát triển. Đây là chế độ lỗi để xem xét khi bạn công cụ hóa bằng tay.

Quy tắc tương quan

  • Tái sử dụng cùng tool_call_id, hook_id, pause_id, hoặc input_id cho sự kiện hoàn thành phù hợp.
  • SDK tính toán duration_ms cho tool_result, hook_completed, agent_resume, và human_input. Chuyển nó cho những phương thức đó tăng ValueError.
  • duration_ms được chấp nhận trên model_response, bởi vì chỉ người gọi biết độ trễ nhà cung cấp thực sự. Nó phải là một số nguyên — một float tăng ValueError tại trang gọi, bởi vì máy chủ đọc cột dưới dạng số nguyên 32-bit không dấu và sẽ lưu trữ NULL cho bất cứ điều gì khác.
  • Khóa tương quan được phạm vi theo loại và phiên, vì vậy lệnh gọi công cụ và một hook có thể an toàn chia sẻ một id, và hai phiên đồng thời có thể tái sử dụng các id giống nhau mà không va chạm. Chúng không được phạm vi bởi agent: một cặp mở dưới một agent và đóng dưới một agent khác vẫn tương quan, đó là trường hợp thông thường trong các framework đa agent.
  • request_id ghép model_request với model_response. Nếu không có nó, các sự kiện mô hình ghép theo thứ tự trên mỗi agent, vì vậy các lệnh gọi đồng thời bị ghép sai.
  • Một cặp phân tách qua các quy trình vẫn tương quan xuôi dòng, nhưng SDK không thể tính toán khoảng thời gian trong quy trình của nó.
  • Bản đồ chờ đợi giữ tối đa 10.000 bắt đầu và loại bỏ mục nhập cũ nhất khi đầy.
Cài đặt failproofai-sdk cài đặt mọi thứ, cả bốn adapter được bao gồm. Các extras kéo framework, không phải adapter.
import failproofai_sdk được hợp đồng không phụ thuộc, được thực thi bởi một bài kiểm tra cài đặt bánh xe xây dựng với --no-deps và một bài kiểm tra khác chứng minh không có framework nào đến sys.modules.
Không có thuộc tính failproofai_sdk.crewai. Các adapter cố ý không được phơi bày trên gói cấp cao: chạm vào một cái sẽ nhập framework như một tác dụng phụ của truy cập thuộc tính, phá vỡ lời hứa không phụ thuộc. Sử dụng instrument().
Tự động phát hiện đọc sys.modules, không phải danh sách gói được cài đặt, vì vậy một framework bạn đã cài đặt nhưng không bao giờ nhập không được công cụ hóa và không bao giờ được nhập thay bạn. Để xem những gì được kết nối:
instrument("crewai") trên máy không có CrewAI không tăng. Nó ghi một cảnh báo và trả về (), vì vậy một framework bị thiếu không bao giờ hạ một quy trình cũng công cụ hóa những cái khác.Cảnh báo mang theo ImportError cơ bản, và tin nhắn đó đặt tên cho lệnh cài đặt chính xác — vì vậy bản sửa chữa nằm trong nhật ký của bạn, không bị ẩn.
Đặt FAILPROOFAI_SDK_STRICT=1 để làm cho nó tăng thay thế. Cờ đó được đọc một lần và được lưu trong bộ đệm, vì vậy xuất khẩu nó trước khi quy trình của bạn bắt đầu chứ không phải đặt nó giữa cuộc chạy.
instrument() phải đến sau nhập framework của bạn. Tự động phát hiện đọc sys.modules, vì vậy một cuộc gọi trần trên nhập tìm không có gì, cài đặt không có gì, và trả về ().
Sai cái này và quy trình chạy với SDK được nhập, adapter rõ ràng được cài đặt, và không một sự kiện được phát ra. Nó ghi một cảnh báo nói chính xác điều đó — vì vậy kiểm tra nhật ký của bạn trước khi một lần chạy ghi lại không có gì.
Spool là những gì làm cho điều này an toàn: agent của bạn không bao giờ chặn trên mạng, và mất điện Cloud có nghĩa là một thư mục phát triển chứ không phải các sự kiện bị mất.Mỗi xóa viết một tệp lô, .tmp đầu tiên, sau đó fsync, sau đó một đổi tên nguyên tử:
Daemon chỉ nhặt .jsonl, vì vậy nó không bao giờ có thể đọc một tệp nửa viết. Thân phần mang một dấu thời gian, id quy trình và số thứ tự, vì vậy hai quy trình xóa trong cùng một mili giây không thể va chạm. Hàng đợi bị giới hạn ở 10.000 sự kiện; quá điểm đó, nó bỏ cái cũ nhất và ghi nhật ký.
collector.redact không áp dụng cho các sự kiện SDK của bạn. Nó không bao giờ nhìn thấy chúng.
Daemon tàu lô của bạn. Nó không mở hoặc viết lại chúng.Chỉnh sửa chạy ở nơi daemon viết sự kiện riêng của nó — không phải ở nơi lô được gửi. Vì vậy, một lời nhắc hoặc một đối số công cụ giữ một khóa API vẫn giữ nó trên lẫn.Điều đó cố ý. Đây là các cuộc gọi công cụ hóa của riêng bạn, và viết lại chúng trong quá trình không có nghĩa là các sự kiện bạn nhận được không phải là các sự kiện bạn phát ra.
Bạn kiểm soát tải trọng tại nguồn, ở hai nơi:
  • Tắt quay phim nội dung trên adapter. Tên tùy chọn khác nhau, và một adapter không có cái nào — đây không phải là một công tắc chung duy nhất:
    • LangChain / LangGraph, Pydantic AI — capture_content=False
    • LlamaIndex — capture_messages=False
    • CrewAI — không có công tắc nội dung nào cả; session_id là tùy chọn duy nhất nó đọc, vì vậy lời nhắc và hoàn thành luôn được ghi lại.
    instrument() bỏ các tùy chọn một adapter không đọc, vì vậy chuyển tên sai không tăng và không thay đổi gì.
  • Đừng trao bí mật cho input= ở nơi đầu tiên.
collector.redact không phải là thay thế cho cái nào cả.
Một thư mục spool trống là trạng thái lành mạnh. Đừng sử dụng nó để kiểm tra giao hàng.
Daemon xóa mỗi lô trong vài mili giây gửi nó, vì vậy một ls đua với bộ sưu tập và cho thấy một phần nhỏ những gì bạn phát ra — không thể phân biệt với một SDK không ghi lại được gì.Để xác nhận các sự kiện thực sự hạ cánh, kiểm tra bảng điều khiển. Để xem spool lấp đầy, dừng daemon trước tiên.
Mỗi cuộc gọi lại chạy bên trong một trình bao bọc công việc duy nhất của nó là nâng lên lại, vì vậy cuộc gọi của bạn nằm trong chính xác một try và mọi thứ SDK làm xảy ra bên ngoài nó.Giá trị mặc định là đúng trong sản xuất và sai trong khi gỡ lỗi, bởi vì nó chỉ có thể chứng minh được “nó không bị sập”. Đặt FAILPROOFAI_SDK_STRICT=1 để làm cho một thất bại bị nuốt chửng trở nên ồn ào.

Vấn đề phổ biến

Một sự kiện mở không có sự kiện đóng: một model_request không có model_response, hoặc một tool_use không có tool_result. Sử dụng các phạm vi, chúng đảm bảo cặp ngay cả khi phần nội dung tăng. Nếu bạn gọi các phương thức sự kiện trực tiếp, sử dụng tryfinally.
Nó được đo lường từ sự kiện mở phù hợp, vì vậy nó bị từ chối trên tool_result, hook_completed, agent_resume, và human_input. Nó được chấp nhận trên model_response, bởi vì chỉ bạn biết độ trễ nhà cung cấp thực sự, và nó phải là một số nguyên.
Luồng không bao giờ kế thừa ngữ cảnh. Bao callable trong failproofai_sdk.propagate(). Xem Luồng và async.
Các trường bổ sung hợp nhất cuối cùng, vì vậy cái nào có tên giống như trường thực như model hoặc outcome sẽ ghi đè nó và thay đổi một cột được lưu trữ. Không gian tên của bạn; các adapter sử dụng tiền tố fw_.
agent_id là một khía cạnh cardinality thấp và bạn để một id chạy vào nó. Sử dụng một vai trò hoặc tên nút và để id thực vào một trường tải trọng.

Tiếp theo

Cách nó hoạt động

Cặp, id, vòng đời phiên và giao hàng.

Đọc một dấu vết

Theo nhân quả thông qua phiên bạn vừa bắt được.

Adapter framework

LangGraph, CrewAI, LlamaIndex, và Pydantic AI.