Hooks & Interceptors
让开发者在每个步骤控制和自定义 Agent 执行。
Hooks 和 Interceptors 提供了一种更精细控制 Agent 内部行为的方式。
核心 Agent 循环涉及调用模型、让其选择要执行的工具,直到不需要调用工具时完成。
Hooks 和 Interceptors 在这些步骤的前后暴露了钩子点,允许你:
- 监控: 通过日志、分析和调试跟踪 Agent 行为;
- 修改: 转换提示、工具选择和输出格式;
- 控制: 添加重试、回退和提前终止逻辑;
- 强制执行: 应用速率限制、护栏和 PII 检测。
通过将它们传递给 ReactAgent.builder() 来添加 Hooks 和 Interceptors:
import io.github.agentic.ai.graph.agent.ReactAgent;
import io.github.agentic.ai.graph.agent.hook.*;
import io.github.agentic.ai.graph.agent.interceptor.*;
ReactAgent agent = ReactAgent.builder()
.name("my_agent")
.model(chatModel)
.tools(tools)
.hooks(loggingHook, messageTrimmingHook)
.interceptors(guardrailInterceptor, retryInterceptor)
.build();
Hooks 和 Interceptors 能做什么?
-
监控:使用日志、分析和调试跟踪 Agent 行为;
-
修改:转换提示、工具选择和输出格式;
-
控制:添加重试、回退和提前终止逻辑;
-
强制执行:应用速率限制、护栏和 PII 检测。
内置实现
ARGI 为常见用例提供了预构建的 Hooks 和 Interceptors 实现:
消息压缩(Summarization)
当接近 token 限制时自动压缩对话历史。
适用场景:
- 超出上下文窗口的长期对话;
- 具有大量历史记录的多轮对话;
- 需要保留完整对话上下文的应用程序。
import io.github.agentic.ai.graph.agent.hook.summarization.SummarizationHook;
// 创建消息压缩 Hook
SummarizationHook summarizationHook = SummarizationHook.builder()
.model(chatModel)
.maxTokensBeforeSummary(4000)
.messagesToKeep(20)
.build();
// 使用
ReactAgent agent = ReactAgent.builder()
.name("my_agent")
.model(chatModel)
.hooks(summarizationHook)
.build();
配置选项:
model: 用于生成摘要的 ChatModel;maxTokensBeforeSummary: 触发摘要之前的最大 token 数;messagesToKeep: 摘要后保留的最新消息数。
Human-in-the-Loop(人机协同)
暂停 Agent 执行以获得人工批准、编辑或拒绝工具调用。
适用场景:
- 需要人工批准的高风险操作(数据库写入、金融交易);
- 人工监督是强制性的合规工作流程;
- 长期对话,使用人工反馈引导 Agent。
import io.github.agentic.ai.graph.agent.hook.hip.HumanInTheLoopHook;
import io.github.agentic.ai.graph.agent.hook.hip.ToolConfig;
// 创建 Human-in-the-Loop Hook
HumanInTheLoopHook humanReviewHook = HumanInTheLoopHook.builder()
.approvalOn("sendEmailTool", ToolConfig.builder().description("Please confirm sending the email.").build())
.approvalOn("deleteDataTool")
.build();
ReactAgent agent = ReactAgent.builder()
.name("supervised_agent")
.model(chatModel)
.tools(sendEmailTool, deleteDataTool)
.hooks(humanReviewHook)
.saver(new RedisSaver())
.build();
重要提示:Human-in-the-loop Hook 需要 checkpointer 来维护跨中断的状态。示例中我们演示用了 RedisSaver。
模型调用限制(Model Call Limit)
限制模型调用次数以防止无限循环或过度成本。
适用场景:
- 防止失控的 Agent 进行太多 API 调用;
- 在生产部署中强制执行成本控制;
- 在特定调用预算内测试 Agent 行为。
ReactAgent agent = ReactAgent.builder()
.name("my_agent")
.model(chatModel)
.hooks(ModelCallLimitHook.builder().runLimit(5).build()) // 限制模型调用次数为5次
.saver(new MemorySaver())
.build();
PII 检测(Personally Identifiable Information)
检测和处理对话中的个人身份信息。
适用场景:
- 具有合规要求的医疗保健和金融应用;
- 需要清理日志的客户服务 Agent;
- 任何处理敏感用户数据的应用程序。
import io.github.agentic.ai.graph.agent.hook.pii.PIIDetectionHook;
import io.github.agentic.ai.graph.agent.hook.pii.PIIType;
import io.github.agentic.ai.graph.agent.hook.pii.RedactionStrategy;
PIIDetectionHook pii = PIIDetectionHook.builder()
.piiType(PIIType.EMAIL)
.strategy(RedactionStrategy.REDACT)
.applyToInput(true)
.build();
// 使用
ReactAgent agent = ReactAgent.builder()
.name("secure_agent")
.model(chatModel)
.hooks(pii)
.build();
工具重试(Tool Retry)
自动重试失败的工具调用,具有可配置的指数退避。
适用场景:
- 处理外部 API 调用中的瞬态故障;
- 提高依赖网络的工具的可靠性;
- 构建优雅处理临时错误的弹性 Agent。
import io.github.agentic.ai.graph.agent.interceptor.toolretry.ToolRetryInterceptor;
// 使用
ReactAgent agent = ReactAgent.builder()
.name("resilient_agent")
.model(chatModel)
.tools(searchTool, databaseTool)
.interceptors(ToolRetryInterceptor.builder()
.maxRetries(2)
.onFailure(ToolRetryInterceptor.OnFailureBehavior.RETURN_MESSAGE)
.build())
.build();
工具异常处理(Tool Error)
ToolErrorInterceptor 用于拦截工具异常,并将异常转换为模型可继续处理的结果。它适合外部系统不稳定、但业务希望 Agent 继续完成后续步骤的场景。
import io.github.agentic.ai.graph.agent.interceptor.toolerror.ToolErrorInterceptor;
ReactAgent agent = ReactAgent.builder()
.name("tool_error_agent")
.model(chatModel)
.tools(externalApiTool)
.interceptors(ToolErrorInterceptor.builder().build())
.build();
模型重试(Model Retry)
ModelRetryInterceptor 在模型调用失败时按重试策略再次调用模型。当前实现支持同步调用,也处理流式调用在未输出任何 chunk 前失败的重试。
import io.github.agentic.ai.graph.agent.interceptor.modelretry.ModelRetryInterceptor;
ReactAgent agent = ReactAgent.builder()
.name("model_retry_agent")
.model(chatModel)
.interceptors(ModelRetryInterceptor.builder()
.maxAttempts(3)
.initialDelay(1000)
.maxDelay(10000)
.backoffMultiplier(2.0)
.build())
.build();
模型回退(Model Fallback)
ModelFallbackInterceptor 在主模型失败时依次尝试备用 ChatModel。
import io.github.agentic.ai.graph.agent.interceptor.modelfallback.ModelFallbackInterceptor;
ReactAgent agent = ReactAgent.builder()
.name("fallback_agent")
.model(primaryModel)
.interceptors(ModelFallbackInterceptor.builder()
.addFallbackModel(backupModel)
.build())
.build();
工具调用限制(Tool Call Limit)
ToolCallLimitHook 统计全部工具或指定工具的调用次数。达到限制后可以结束本次运行,也可以抛出异常。
import io.github.agentic.ai.graph.agent.hook.toolcalllimit.ToolCallLimitHook;
ReactAgent agent = ReactAgent.builder()
.name("limited_tool_agent")
.model(chatModel)
.hooks(ToolCallLimitHook.builder()
.toolName("search")
.runLimit(3)
.build())
.build();
Return Direct
ReturnDirectModelHook 会检查工具响应元数据中的 FINISH_REASON。当工具以 return-direct 方式返回时,它会把工具结果转换为 AssistantMessage 并结束图运行。
import io.github.agentic.ai.graph.agent.hook.returndirect.ReturnDirectModelHook;
ReactAgent agent = ReactAgent.builder()
.name("return_direct_agent")
.model(chatModel)
.tools(returnDirectTool)
.hooks(new ReturnDirectModelHook())
.build();
AssistantMessage Sanitizer
AssistantMessageSanitizerInterceptor 默认由 ReactAgent.Builder 注册。它会把工具调用场景中 content == null 的 AssistantMessage 改写为空字符串,以兼容对 content 字段更严格的 DeepSeek-compatible 后端。需要保留原始 null 形式时,可以关闭该默认拦截器。
ReactAgent agent = ReactAgent.builder()
.name("raw_assistant_message_agent")
.model(chatModel)
.assistantMessageSanitizerEnabled(false)
.build();
Planning(待办提示)
TodoListInterceptor 向模型提供待办列表提示,配合 WriteTodosTool 记录内容和进度;它不会强制生成执行计划、校验依赖 DAG 或保证工具执行顺序。需要有 stepId、依赖、能力引用及输入/输出契约的计划时,使用可选的 结构化任务规划。Planner 同样只生成和校验计划,不自动执行。
适用场景:
- 需要执行复杂、多步骤任务的 Agent;
- 通过在执行前显示 Agent 的计划来提高透明度;
- 通过检查建议的计划来调试错误。
import io.github.agentic.ai.graph.agent.interceptor.todolist.TodoListInterceptor;
// 使用
ReactAgent agent = ReactAgent.builder()
.name("planning_agent")
.model(chatModel)
.tools(myTool)
.interceptors(TodoListInterceptor.builder().build())
.build();
LLM Tool Selector(LLM 工具选择器)
使用一个 LLM 来决定在多个可用工具之间选择哪个工具。
适用场景:
- 当多个工具可以实现相似目标时;
- 需要根据细微的上下文差异进行工具选择;
- 动态选择最适合特定输入的工具。
import io.github.agentic.ai.graph.agent.interceptor.toolselection.ToolSelectionInterceptor;
// 使用
ReactAgent agent = ReactAgent.builder()
.name("smart_selector_agent")
.model(chatModel)
.tools(tool1, tool2)
.interceptors(ToolSelectionInterceptor.builder().build())
.build();
LLM Tool Emulator(LLM 工具模拟器)
在没有实际执行工具的情况下,使用 LLM 模拟工具的输出。
适用场景:
- 在演示或测试期间模拟 API;
- 在开发过程中为工具提供占位符行为;
- 在不产生实际成本或副作用的情况下测试 Agent 逻辑。
import io.github.agentic.ai.graph.agent.interceptor.toolemulator.ToolEmulatorInterceptor;
// 使用
ReactAgent agent = ReactAgent.builder()
.name("emulator_agent")
.model(chatModel)
.tools(simulatedTool)
.interceptors(ToolEmulatorInterceptor.builder().model(chatModel).build())
.build();
Context Editing(上下文编辑)
在将上下文发送给 LLM 之前对其进行修改,以注入、删除或修改信息。
适用场景:
- 向 LLM 提供额外的上下文或指令;
- 从对话历史中删除不相关或冗余的信息;
- 动态修改上下文以引导 Agent 的行为。
import io.github.agentic.ai.graph.agent.interceptor.contextediting.ContextEditingInterceptor;
// 使用
ReactAgent agent = ReactAgent.builder()
.name("context_aware_agent")
.model(chatModel)
.interceptors(ContextEditingInterceptor.builder().trigger(120000).clearAtLeast(60000).build())
.build();