MessagesModelHook 和 ModelHook 都可以在模型调用前后执行自定义逻辑,但它们有不同的设计目标和适用场景。
核心区别
| 特性 | MessagesModelHook | ModelHook |
|---|---|---|
| 易用性 | ⭐⭐⭐⭐⭐ 更简单,直接操作消息列表 | ⭐⭐⭐ 需要理解 OverAllState |
| 灵活性 | ⭐⭐⭐ 专注于消息操作 | ⭐⭐⭐⭐⭐ 可访问和修改完整状态 |
| 推荐场景 | 消息修剪、过滤、添加系统提示 | 需要访问全局状态、自定义状态管理 |
| API 复杂度 | 简单:AgentCommand 返回消息列表 | 复杂:返回 Map<String, Object> 更新状态 |
使用建议
选择 MessagesModelHook,如果你需要:
- ✅ 简单的消息操作(修剪、过滤、转换);
- ✅ 添加或修改系统提示;
- ✅ 消息压缩和摘要;
- ✅ 快速实现消息相关的 Hook。
选择 ModelHook,如果你需要:
- ✅ 访问和修改 OverAllState 中的其他数据;
- ✅ 在状态中存储自定义信息(如计数器、缓存等);
- ✅ 基于全局状态做复杂决策;
- ✅ 需要查看 Agent 执行过程中的完整上下文。
对比示例
场景:消息修剪
使用 MessagesModelHook(推荐):
import com.alibaba.cloud.ai.graph.agent.hook.messages.MessagesModelHook;
import com.alibaba.cloud.ai.graph.agent.hook.messages.AgentCommand;
import com.alibaba.cloud.ai.graph.agent.hook.messages.UpdatePolicy;
import com.alibaba.cloud.ai.graph.agent.hook.HookPosition;
import com.alibaba.cloud.ai.graph.agent.hook.HookPositions;
import com.alibaba.cloud.ai.graph.RunnableConfig;
import org.springframework.ai.chat.messages.Message;
import java.util.List;
@HookPositions({HookPosition.BEFORE_MODEL})
public class SimpleMessageTrimmingHook extends MessagesModelHook {
private static final int MAX_MESSAGES = 10;
@Override
public String getName() {
return "simple_message_trimming";
}
@Override
public AgentCommand beforeModel(List<Message> previousMessages, RunnableConfig config) {
if (previousMessages.size() > MAX_MESSAGES) {
List<Message> trimmed = previousMessages.subList(
previousMessages.size() - MAX_MESSAGES,
previousMessages.size()
);
return new AgentCommand(trimmed, UpdatePolicy.REPLACE);
}
return new AgentCommand(previousMessages);
}
}
使用 ModelHook(更复杂但更灵活):
import com.alibaba.cloud.ai.graph.agent.hook.ModelHook;
import com.alibaba.cloud.ai.graph.agent.hook.HookPosition;
import com.alibaba.cloud.ai.graph.agent.hook.HookPositions;
import com.alibaba.cloud.ai.graph.OverAllState;
import com.alibaba.cloud.ai.graph.RunnableConfig;
import com.alibaba.cloud.ai.graph.state.ReplaceAllWith;
import org.springframework.ai.chat.messages.Message;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
@HookPositions({HookPosition.BEFORE_MODEL})
public class AdvancedMessageTrimmingHook extends ModelHook {
private static final int MAX_MESSAGES = 10;
private static final String TRIM_COUNT_KEY = "trim_count";
@Override
public String getName() {
return "advanced_message_trimming";
}
@Override
public CompletableFuture<Map<String, Object>> beforeModel(OverAllState state, RunnableConfig config) {
// 可以访问完整状态
Optional<Object> messagesOpt = state.value("messages");
if (messagesOpt.isEmpty()) {
return CompletableFuture.completedFuture(Map.of());
}
List<Message> messages = (List<Message>) messagesOpt.get();
// 可以访问和更新自定义状态
int trimCount = (Integer) state.value(TRIM_COUNT_KEY).orElse(0);
if (messages.size() > MAX_MESSAGES) {
List<Message> trimmed = messages.subList(
messages.size() - MAX_MESSAGES,
messages.size()
);
// 可以同时更新消息和自定义状态
return CompletableFuture.completedFuture(Map.of(
"messages", ReplaceAllWith.of(trimmed),
TRIM_COUNT_KEY, trimCount + 1 // 记录修剪次数
));
}
return CompletableFuture.completedFuture(Map.of());
}
}
总结:
- 优先使用 MessagesModelHook:对于大多数消息操作场景,它提供了更简洁的 API,代码更易读易维护。
- 使用 ModelHook:当你需要访问全局状态、存储自定义数据或进行复杂的状态管理时。
在 Agent 整体执行的开始和结束时执行:
import com.alibaba.cloud.ai.graph.agent.hook.AgentHook;
import com.alibaba.cloud.ai.graph.agent.hook.HookPosition;
import com.alibaba.cloud.ai.graph.agent.hook.HookPositions;
import java.util.concurrent.CompletableFuture;
@HookPositions({HookPosition.BEFORE_AGENT, HookPosition.AFTER_AGENT})
public class CustomAgentHook extends AgentHook {
@Override
public String getName() {
return "custom_agent_hook";
}
@Override
public CompletableFuture<Map<String, Object>> beforeAgent(OverAllState state, RunnableConfig config) {
System.out.println("Agent 开始执行");
// 可以初始化资源、记录开始时间等
return CompletableFuture.completedFuture(Map.of("start_time", System.currentTimeMillis()));
}
@Override
public CompletableFuture<Map<String, Object>> afterAgent(OverAllState state, RunnableConfig config) {
System.out.println("Agent 执行完成");
// 可以清理资源、计算执行时间等
Optional<Object> startTime = state.value("start_time");
if (startTime.isPresent()) {
long duration = System.currentTimeMillis() - (Long) startTime.get();
System.out.println("执行耗时: " + duration + "ms");
}
return CompletableFuture.completedFuture(Map.of());
}
}
本文整理自 Spring AI Alibaba 官方文档《Hooks 与 Interceptors》:https://java2ai.com/docs/frameworks/agent-framework/tutorials/hooks

AI项目博客






