Haki agentów

Agent Hooks to kluczowa funkcja Agent Framework, która umożliwia stosowanie mechanizmów nadzoru i kontroli działania w czasie wykonywania w ściśle określonych punktach działania agenta. Implementuje neutralny względem frameworków kontrakt AGENT-HOOKS-0.1, dzięki czemu silniki polityk, bramki akceptacji, mechanizmy kontroli budżetu, filtry treści i mechanizmy kontroli ruchu wychodzącego mogą korzystać z jednego wspólnego interfejsu sterowania.

Important

Agent Hooks to płaszczyzna sterowania, a nie płaszczyzna telemetrii. Każdy interceptor zwraca decyzję. W trybie enforce framework egzekwuje ten werdykt; w trybie evaluate_only zapisuje ten werdykt bez zmiany wykonywania. Użyj observability do pasywnego śledzenia, metryk i dzienników.

Agent Hooks nie jest jeszcze dostępny dla .NET. Użyj oprogramowania pośredniczącego agenta, zatwierdzania narzędzi i bezpieczeństwa agenta, aby dodać kontrolki środowiska uruchomieniowego do agentów .NET.

Agent Hooks jest eksperymentalny w Python. Fabryka emituje ExperimentalWarning element po pierwszym użyciu, a jego interfejs API może ulec zmianie przed ogólną dostępnością.

Kiedy używać punktów zaczepienia agenta

Użyj Agent Hooks, gdy niezależnie opracowane mechanizmy kontrolne wymagają jednego wspólnego, egzekwowalnego kontraktu obejmującego dane wejściowe agenta, wywołania modelu, wywołania narzędzi i dane wyjściowe końcowe.

Capability Użyj go do
Haki agentów Standaryzacja decyzji dotyczących zasad, przekształceń, zatwierdzeń, budżetów i kontroli ruchu wychodzącego w całym cyklu życia agenta.
Oprogramowanie pośredniczące agenta Specyficzne dla aplikacji działanie przekrojowe, które nie wymaga kontraktu Agent Hooks ani jego podstawowych gwarancji środowiska wykonawczego.
Zabezpieczenia dla agenta z FIDES Deterministyczne etykiety i zasady przepływu informacji dla niezaufanej lub poufnej zawartości.
Zatwierdzanie narzędzi Potwierdzenie przez człowieka poszczególnych wywołań funkcji-narzędzi.
Obserwowalność Ślady pasywne, metryki i dzienniki, które nie sterują wykonywaniem.

Co wymusza platforma Agent Framework

Po dodaniu Hooków agenta do agenta Agent Framework stosuje skoordynowaną warstwę egzekwowania w ramach uruchomień agenta, wywołań modelu i wywołań narzędzi. Środowisko uruchomieniowe zapewnia następujące gwarancje:

  • Niepowodzenie zamknięte: Odmowa blokuje chronioną akcję. Nieprawidłowe konteksty, nieprawidłowe werdykty, awarie interceptorów i niepowodzenia egzekwowania nie prowadzą do cichego obchodzenia mechanizmów kontrolnych.
  • Zapis zwrotny transformacji: Transformacja zmienia natywne komunikaty, argumenty narzędzi, wyniki narzędzi lub odpowiedź końcową, z których faktycznie korzysta wykonanie. Jeśli nie można zastosować przekształcenia, uruchomienie kończy się w trybie zamkniętym.
  • Buforowane przesyłanie strumieniowe: Żadna aktualizacja nie dociera do wywołującego, dopóki pełna odpowiedź modelu i końcowe dane wyjściowe nie przejdą przez odpowiednie punkty przechwycenia.
  • Trwałe przechowywanie zależne od werdyktu: Trwałe przechowywanie czeka na werdykt, który go dotyczy. Standardowe utrwalanie po zakończeniu działania czeka na output; utrwalanie historii dla poszczególnych wywołań usługi czeka na każde post_model_call.
  • Kompletna instalacja pakietu: Części agenta, czatu i funkcji są instalowane jako jedna jednostka, więc niekompletna granica wymuszania nie może zostać przypadkowo skonfigurowana.

Kontrakt opiera się na współpracy, a nie stanowi granicy izolacji między procesami. Przechwytniki działają w procesie hosta i otrzymują dane potrzebne do podejmowania decyzji. Rejestruj tylko przechwytniki, którym ufasz.

Instalowanie punktów zaczepienia agenta

Zainstaluj pakiet SDK Agent Hooks jako zależność bezpośrednią:

pip install agent-hooks-sdk

Jeśli używasz uv:

uv add agent-hooks-sdk

Zależność agent-hooks-sdk jest importowana z opóźnieniem. Importowanie agent_framework nie powoduje załadowania zestawu SDK, chyba że tworzysz pakiet oprogramowania pośredniczącego Agent Hooks.

Uwaga / Notatka

agent-framework-core nie zawiera dodatkowego agent-hooks. Zainstaluj agent-hooks-sdk oddzielnie przed utworzeniem pakietu oprogramowania pośredniczącego Agent Hooks.

Dodawanie przechwytywania

Interceptor otrzymuje agent_hooks.AgentContext (mapowanie kontekstu w specyfikacji, a nie agent_framework.AgentContext używane przez warstwę pośrednią agenta) i zwraca werdykt. Poniższy interceptor blokuje końcowe dane wyjściowe zawierające słowo secret. W tym przykładzie przyjęto założenie, że client jest już skonfigurowanym klientem czatu platformy Agent Framework.

from agent_framework import Agent, create_agent_hooks_middleware
from agent_hooks import ALLOW, AgentContext, InterceptionBlocked, Verdict


class SecretEgressGuard:
    def intercept(self, context: AgentContext) -> Verdict:
        if (
            context["interception_point"] == "output"
            and "secret" in str(context["target"]).lower()
        ):
            return Verdict.deny(
                reason="secret_in_output",
                message="The final response contains restricted content.",
            )
        return ALLOW


hooks = create_agent_hooks_middleware(
    {"secret-egress": SecretEgressGuard()},
)

agent = Agent(
    client=client,
    instructions="You are a helpful assistant.",
    middleware=[hooks],
)

try:
    response = await agent.run("Summarize the account details.")
except InterceptionBlocked as exc:
    print(f"Blocked: {exc.result.verdict.reason}")

Przekaż pakiet jako jeden z elementów listy middleware agenta. Zainstaluj dokładnie jeden pakiet Agent Hooks na każdym agencie.

Punkty przechwytywania

Struktura agenta automatycznie emituje odpowiednie punkty przechwytywania:

Punkt przechwycenia Kiedy jest emitowany Przekształć cel
agent_startup Przed pierwszymi danymi wejściowymi w sesji Agent Hooks Nie można przekształcić
input Gdy zewnętrzne żądanie trafia do agenta Treść wejściowa i rola
pre_model_call Przed każdym żądaniem modelu Komunikaty wysyłane do modelu
post_model_call Po każdej pełnej odpowiedzi modelu Treść odpowiedzi, wywołania narzędzi wykonywane przez framework oraz powód zakończenia
pre_tool_call Przed każdym uruchomieniem narzędzia przez framework Argumenty dla narzędzia
post_tool_call Po pomyślnym lub nieudanym działaniu narzędzia Wynik narzędzia
output Zanim ostateczna odpowiedź osiągnie obiekt wywołujący Końcowa zawartość odpowiedzi
agent_shutdown Gdy sesja Agent Hooks zostanie ukończona, zakończy się niepowodzeniem lub zostanie anulowana Nie można przekształcić

agent_startup.tools_registered to migawka narzędzia uruchamiania. Każdy ładunek danych pre_model_call zawiera narzędzia obowiązujące dla tego wywołania modelu w swoim opcjonalnym polu tools. Obejmuje to narzędzia dodane w trakcie działania przez dostawców kontekstu, połączone serwery MCP lub mechanizmy stopniowego ujawniania. To pole jest pomijane, jeśli wywołanie nie zawiera narzędzi lub nie można rzutować zestawu narzędzi.

Przebieg, który wywołuje narzędzie, zwykle generuje:

agent_startupinputpost_tool_callpre_tool_callpost_model_callpre_model_callpre_model_callpost_model_calloutputagent_shutdown

Werdykty

Umowa ma trzy decyzje: allow, denyi transform. Pakiet SDK dla Pythona udostępnia również funkcje pomocnicze do obsługi ostrzeżeń i odrzuceń, które można uchylić.

Result Interfejs programistyczny Python Behavior
Allow ALLOW lub Verdict(decision=Decision.ALLOW) Kontynuuj z celem bez zmian.
Zezwalaj z ostrzeżeniem Verdict.warn(...) Kontynuuj i uwzględnij ostrzeżenie w rekordzie przechwytywania.
Odmów Verdict.deny(...) Zablokuj zabezpieczone działanie.
Odrzuć oczekujące zatwierdzenie Verdict.escalate(...) Blokuj, o ile skonfigurowany mechanizm rozstrzygania zatwierdzenia nie zwróci decyzji zezwalającej.
Przekształć Verdict(decision=Decision.TRANSFORM, transform=Transform(...)) Przepisz wartość pod $target, a następnie kontynuuj, używając przepisanej wartości.

Odmowy na poziomie uruchomienia i na poziomie modelu powodują wystąpienie InterceptionBlocked i uniemożliwiają dotarcie chronionego wyniku do wywołującego lub do kolejnego etapu. Na styku narzędzia odmowa wynikająca z zasad uniemożliwia wykonanie działania przez narzędzie lub odrzuca jego wynik i zwraca do modelu błąd kontroli zawierający przyczynę wynikającą z zasad, bez ładunku docelowego objętego odmową. Umożliwia to kontynuowanie pętli agenta. Błąd hosta lub błąd egzekwowania powoduje zatrzymanie uruchomienia.

Przerwać uruchomienie z oprogramowania pośredniczącego funkcji

Zaimportuj MiddlewareFailure z agent_frameworkpliku . Warstwa pośrednia funkcji zwykle przekształca zwykły wyjątek w wynik błędu narzędzia, a następnie pozwala na dalsze wykonywanie pętli agenta. Jeśli middleware funkcji nie może bezpiecznie kontynuować, zgłoś wyjątek MiddlewareFailure na podstawie wyjątku bazowego. Środowisko uruchomieniowe przerywa przebieg i propaguje błąd do obiektu wywołującego zamiast konwertować go na wynik narzędzia.

Nie przechwytuj MiddlewareFailure w middleware. Przechwycenie go pozwala pętli działać dalej i zmienia zachowanie z typu fail-closed na fail-open. Agent Hooks używa tego sygnału wewnętrznie, gdy zawodzi jego warstwa wymuszania middleware funkcji. Przekaż niestandardowe middleware typu fail-closed w sekwencji, na przykład middleware=[policy_middleware].

W przypadku współbieżnych wywołań narzędzi środowisko uruchomieniowe anuluje równoległe wywołania podrzędne będące w toku, zanim przekaże dalej błąd. Anulowanie jest współpracy, więc narzędzie synchroniczne, które jest już uruchomione w wątku procesu roboczego, może zakończyć swoje skutki uboczne, ale jego wynik jest odrzucany.

Zastosuj przekształcenie

Ścieżka przekształcenia musi zaczynać się od $target. Na przykład interceptor może zastąpić zawartość odpowiedzi końcowej:

from agent_hooks import ALLOW, AgentContext, Decision, Transform, Verdict


class OutputRedactor:
    def intercept(self, context: AgentContext) -> Verdict:
        if context["interception_point"] != "output":
            return ALLOW

        return Verdict(
            decision=Decision.TRANSFORM,
            reason="redacted_output",
            transform=Transform(
                path="$target.content",
                value="[Response removed by policy]",
            ),
        )

Przekształcenia są stosowane do wartości w Agent Framework Content, z zachowaniem obsługiwanej zawartości zaawansowanej zamiast sprowadzania każdej wartości do zwykłego tekstu. Źle sformułowana ścieżka lub niezgodne zastąpienie kończy się niepowodzeniem zamiast kontynuować oryginalną wartość.

Zatwierdzanie narzędzia i przekształcanie argumentów

Mechanizm zatwierdzania narzędzia Agent Framework oraz punkt integracji zatwierdzania Agent Hooks to odrębne mechanizmy. W przypadku narzędzia funkcji z approval_mode="always_require" Agent Framework tworzy prośbę o zatwierdzenie przez człowieka, zanim zostanie uruchomione oprogramowanie pośredniczące funkcji. Przekształcenie pre_tool_call może zatem zmienić argumenty po tym, jak użytkownik zatwierdził pierwotne wartości.

Warning

Nie przekształcaj argumentów w pre_tool_call dla narzędzi, które używają approval_mode="always_require". Przekształć wywołanie narzędzia w post_model_call, aby żądanie zatwierdzenia struktury zawierało przekształcone wartości, albo zwróć Verdict.escalate(...) w pre_tool_call i obsłuż zatwierdzenie za pomocą haków agenta resolver.

Przesyłanie strumieniowe i trwałość

Agent Hooks zachowuje interfejs API przesyłania strumieniowego, ale wykorzystuje semantykę buforowanego wyjścia. Struktura agenta tworzy kompletną odpowiedź modelu, emituje post_model_call, tworzy ostateczną odpowiedź agenta i emituje output przed wydaniem aktualizacji. Jeśli którykolwiek z punktów odmówi odpowiedzi, obiekt wywołujący nie otrzyma żadnych częściowych aktualizacji.

To zachowanie odbywa się kosztem opóźnienia generowania token po tokenie na rzecz wymuszania trybu fail-closed dla danych wyjściowych. Transformacja danych wyjściowych znajduje również odzwierciedlenie w aktualizacjach, które zostaną ostatecznie przekazane wywołującemu.

Utrwalanie jest kontrolowane przez punkt przecięcia, który obejmuje operację utrwalania:

  • Domyślnie historia i inne zadania dostawcy wykonywane po zakończeniu uruchomienia czekają na werdykt output. Odrzucone dane wyjściowe nie są zapisywane, a transformacja danych wyjściowych jest zapisywana po przekształceniu.
  • Gdy ustawisz require_per_service_call_history_persistence=True w konstruktorze Agent lub client.as_agent(...), każda wymiana z modelem jest zapisywana po tym, jak zezwoli na to werdykt post_model_call. Późniejsza output odmowa nie cofa historii, która została już wcześniej dozwolona.
  • W przypadku domyślnej trwałości po zakończeniu działania próby ponowienia następują po ostatecznej decyzji output. Zamiast tego tryb dla każdego wywołania usługi zapisuje każdą odpowiedź modelu, która przechodzi przez post_model_call.

Important

Jeśli zawartość modelu nie może zostać trwale zapisana, wymuś tę zasadę na poziomie post_model_call, gdy require_per_service_call_history_persistence=True. Polityka ruchu wychodzącego obejmująca wyłącznie dane wyjściowe chroni to, co dociera do wywołującego, ale nie usuwa retroaktywnie wymian z modelem, które zostały już dozwolone i zapisane w post_model_call.

Sesje i rekordy inspekcji

Domyślnie każde uruchomienie agenta tworzy jedną sesję Agent Hooks. agent_startup i agent_shutdown wyznaczają początek i koniec przebiegu, a rekordy otrzymują jeden identyfikator sesji i monotonicznie rosnący numer sekwencyjny.

Użyj record_sink, aby otrzymać każdy InterceptionRecord:

records = []

hooks = create_agent_hooks_middleware(
    {"secret-egress": SecretEgressGuard()},
    record_sink=records.append,
)

Rekordy przechwycenia zawierają decyzję, przyczynę, podsumowanie mechanizmu przechwytującego, tryb, tożsamość i sekwencję bez kopiowania przechwyconego ładunku do rekordu audytu. Sam przechwytywacz nadal otrzymuje pełny kontekst.

Obejmij wiele przebiegów w ramach jednej sesji

Użyj create_agent_hooks_middleware_from_emitter(), gdy aplikacja utrzymuje dłużej trwającą sesję Agent Hooks, na przykład rozmowę z jednym dziennikiem zatwierdzeń:

from agent_framework import Agent, create_agent_hooks_middleware_from_emitter
from agent_hooks import AgentContextBuilder, InterceptionEmitter


emitter = InterceptionEmitter().register(SecretEgressGuard())
builder = AgentContextBuilder(
    agent_id="support-agent",
    framework="agent-framework",
    session_id="conversation-42",
)

hooks = create_agent_hooks_middleware_from_emitter(emitter, builder)
agent = Agent(client=client, middleware=[hooks])

await emitter.emit(builder.agent_startup(tools_registered=[]))
await agent.run("First turn")
await agent.run("Second turn")
await emitter.emit(builder.agent_shutdown(reason="completed"))

W tej postaci aplikacja konfiguruje nadajnik i odpowiada za uruchamianie, zamykanie oraz obsługę błędów. Oprogramowanie pośredniczące generuje punkty dla każdego uruchomienia od input do output.

Konfigurowanie wymuszania

create_agent_hooks_middleware() akceptuje następujące kontrolki:

Parametr Purpose
interceptors Sekwencja interceptorów lub mapowanie nazw na interceptory. Wymagany jest co najmniej jeden.
resolver Rozwiązuje odmowy, które można cofnąć, za pośrednictwem ścieżki zatwierdzania. Bez modułu rozstrzygania odrzucenie pozostaje w mocy.
mode "enforce" stosuje werdykty. "evaluate_only" rejestruje, co się stanie, ale zezwala na każdą akcję.
composition Określa, w jaki sposób łączone są werdykty wielu interceptorów.
identity_provider Tworzy tożsamości kontekstowe powiązane z zawartością. Wartość domyślna to "jcs-sha256".
timeout Limit czasu dla każdego interceptora i resolvera dla wywołań asynchronicznych. Wartość domyślna to pięć sekund. Synchroniczny interceptor lub resolver, który blokuje pętlę zdarzeń, nie może zostać przerwany przez ten limit czasu.
record_sink Odbiera każdy rekord przechwytywania bez ładunku.

Domyślna kompozycja to sekwencyjna first_deny, z akceptacją skonfigurowaną tak, aby zatrzymać zwijanie. Dlatego kolejność interceptorów ma znaczenie: mechanizmy kontrolne, które muszą być zawsze uruchamiane, należy umieścić przed tymi, które mogą wymagać zatwierdzenia. Przed wybraniem innego profilu kompozycji zapoznaj się z listą kontrolną produkcyjną Agent Hooks.

Wdrażanie w trybie tylko do oceny

Użyj polecenia evaluate_only, aby sprawdzić działanie zasad przed ich wyegzekwowaniem:

hooks = create_agent_hooks_middleware(
    {"secret-egress": SecretEgressGuard()},
    mode="evaluate_only",
    record_sink=records.append,
)

W tym trybie moduły przechwytujące działają, a rekordy zawierają ich werdykty, ale żadne działanie nie jest blokowane ani przekształcane. Nie opisuj wdrożenia evaluate_only jako narzuconego ładu organizacyjnego.

Reguły kompozycji

Umieść pakiet najpierw na liście oprogramowania pośredniczącego agenta, aby stanowił najbardziej zewnętrzną granicę wymuszania:

agent = Agent(
    client=client,
    middleware=[
        create_agent_hooks_middleware([SecretEgressGuard()]),
        application_middleware,
    ],
)

Postępuj zgodnie z następującymi regułami:

  • Zainstaluj dokładnie jeden pakiet Agent Hooks na każdego agenta. Skumulowane pakiety są odrzucane.
  • Zachowaj pakiet w nienaruszonym stanie. Nie można zainstalować osobno agenta, czatu i warstwy pośredniej funkcji.
  • Zainstaluj pakiet na Agent, a nie bezpośrednio w kliencie czatu ani przez dostawcę kontekstu.
  • Oprogramowanie pośredniczące umieszczone przed pakietem znajduje się poza obszarem egzekwowania. Traktuj pozycję zewnętrzną jako zaufanie zewnętrzne.
  • Nadaj każdemu zagnieżdżonemu agentowi własny pakiet, gdy jego wewnętrzny model i działanie narzędzia również wymaga przechwycenia.

Bieżące ograniczenia

  • Tylko Python: Agent Hooks nie jest jeszcze zaimplementowane w zestawach SDK dla platform .NET i Go.
  • Eksperymentalny interfejs API: Sygnatury i zachowanie fabryki mogą ulec zmianie przed ogólną dostępnością.
  • Przesyłanie strumieniowe buforowane: Aktualizacje nie są zwalniane tokenem przez token, ponieważ dane wyjściowe muszą zostać ukończone przed zamknięciem werdyktu zakończonego niepowodzeniem.
  • Narzędzia hostowane: Narzędzia wykonywane przez dostawcę modelu nie przechodzą przez szew wywołania funkcji programu Agent Framework. Ich wywołania i wyniki są wyświetlane w post_model_call, ale post_tool_call i pre_tool_call nie mogą blokować wykonywania po stronie serwera dostawcy.
  • Granica współpracy: Agent Hooks nie izoluje interceptorów w piaskownicy ani nie chroni przed wrogim hostem. Ścieżki kodu, które omijają chroniony potok agenta, nie są uwzględnione.
  • Dostępność interceptora wpływa na dostępność agenta: W trybie wymuszonym awaria interceptora lub przekroczenie limitu czasu blokuje chronioną akcję zgodnie z założeniami.

Informacje o wdrożeniu produkcyjnym, przyczynach niepowodzeń i wskazówkach dotyczących alertowania znajdują się w podręczniku operacyjnym Agent Hooks.

Agent Hooks nie jest jeszcze dostępny dla języka Go. Użyj oprogramowania pośredniczącego agenta, zatwierdzania narzędzi i bezpieczeństwa agenta , aby dodać kontrolki środowiska uruchomieniowego do agentów języka Go.

Następne kroki