diff --git a/pom.xml b/pom.xml
index e42300aa..4414ea16 100644
--- a/pom.xml
+++ b/pom.xml
@@ -80,7 +80,7 @@
spring-ai-alibaba-bailian-example
spring-ai-alibaba-evaluation-example
spring-ai-alibaba-mem0-example
-
+
diff --git a/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/README.md b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/README.md
new file mode 100644
index 00000000..c96a50eb
--- /dev/null
+++ b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/README.md
@@ -0,0 +1,109 @@
+# Spring AI Alibaba SubAgent Personal Assistant Example
+
+本示例展示如何使用 Spring AI Alibaba 的 ReactAgent 框架构建一个多智能体监督者模式系统,通过主智能体协调多个子智能体,实现日历代理与邮件发送功能。
+## 功能特性
+
+- **多智能体**: Subagent 使用 Tool Calling 模式被 Supervisor Agent 调用。
+- **人工介入**: 通过在 Supervisor Agent 配置 hooks 加入中断功能。
+
+## 快速开始
+
+### 前置条件
+
+- Java 21+
+- Maven 3.6+
+- DashScope API Key
+
+### 运行步骤
+
+1. **设置 API Key**
+
+ ```bash
+ export DASHSCOPE_API_KEY=your-api-key
+ ```
+
+2. **构建项目**
+
+ ```bash
+ cd subagent-personal-assistant-example
+ mvn clean package -DskipTests
+ ```
+
+3. **运行应用**
+
+ ```bash
+ mvn spring-boot:run
+ ```
+
+4. **访问API**
+
+ ``` shell
+ curl --location 'http://127.0.0.1:8080/react/agent/supervisorAgent?query=Schedule%20a%20meeting%20with%20the%20design%20team%20next%20Tuesday%20at%202pm%20for%201%20hour%2C%20and%20send%20them%20an%20email%20reminder%20about%20reviewing%20the%20new%20mockups.&threadId=user-session-124&nodeId=_AGENT_HOOK_HITL' \
+--header 'Content-Type: application/json' \
+--header 'Accept: text/event-stream' \
+--data ''
+ ````
+## Agent说明
+* supervisor_agent: 监督者智能体,负责协调多个子智能体,实现日历代理与邮件发送功能。
+* calendar_agent: 日历日程助理,检查可用时间和安排日历事件。
+* email_agent: 创建邮件主题和邮件发送。
+## 工具说明
+
+| 工具名称 | 功能 | 输入参数 |
+|---------|-------------------|-----------------------|
+| `get_user_email_tool` | 获取用户邮箱 | UserInfo |
+| `get_current_date_time` | 获取当前日期和时间 | 无 |
+| `get_available_time_slots` | 获取可用时间 slots |AvailableTimeInfo |
+| `create_calendar_event` | 创建日历事件 | CalendarInfo |
+| `send_email` | 发送邮件 | EmailInfo |
+
+## 示例对话
+
+```
+用户: Schedule a meeting with the design team next Tuesday at 2pm for 1 hour, and send them an email reminder about reviewing the new mockups.
+
+Agent:
+I'll help you schedule a meeting with the design team and send them an email reminder. Let me break this down into steps:
+
+1. First, I need to get the email addresses of the design team members
+2. Then schedule the calendar event for next Tuesday at 2pm for 1 hour
+3. Finally, send an email reminder about reviewing the new mockups
+
+Let me start by getting the design team members' information:
+
+================================= Tool Message =================================
+
+id: call_e06f221fa93b4e8ea77e62d0
+name: get_user_email_tool
+responseData: "Available user list for [{\"departmentName\":\"design(设计团队)\",\"email\":\"wangwu@agent.cn\",\"userName\":\"wangwu(王五)\"}]"
+Now I have the design team member information. I'll schedule the meeting for next Tuesday at 2pm for 1 hour with Wang Wu (王五) from the design team:
+
+检测到中断,需要人工审批
+工具: calendar_agent
+参数: {"input": "Schedule a meeting with wangwu@agent.cn next Tuesday at 2pm for 1 hour. Subject: Design Team Meeting - Mockup Review"}
+描述: The AI is requesting to use the tool: calendar_agent.
+Description: Calendar event pending approval
+With the following arguments: {"input": "Schedule a meeting with wangwu@agent.cn next Tuesday at 2pm for 1 hour. Subject: Design Team Meeting - Mockup Review"}
+Do you approve?
+检测到中断,等待人工介入... node: _AGENT_HOOK_HITL
+人工介入开始...
+检测到中断,需要人工审批
+工具: email_agent
+参数: {"input": "Send an email to wangwu@agent.cn with subject 'Reminder: Design Team Meeting - Mockup Review' and content 'Hi Wang Wu, This is a reminder about our upcoming meeting next Tuesday (February 17, 2026) at 2:00 PM to review the new mockups. Please come prepared with your feedback. Looking forward to our discussion!'"}
+描述: The AI is requesting to use the tool: email_agent.
+Description: Outbound email pending approval
+With the following arguments: {"input": "Send an email to wangwu@agent.cn with subject 'Reminder: Design Team Meeting - Mockup Review' and content 'Hi Wang Wu, This is a reminder about our upcoming meeting next Tuesday (February 17, 2026) at 2:00 PM to review the new mockups. Please come prepared with your feedback. Looking forward to our discussion!'"}
+Do you approve?
+检测到中断,等待人工介入... node: _AGENT_HOOK_HITL
+人工介入开始...
+Email sent to wangwu@agent.cn - Subject: Reminder: Design Team Meeting - Mockup Review
+ body: Hi Wang Wu, This is a reminder about our upcoming meeting next Tuesday (February 17, 2026) at 2:00 PM to review the new mockups. Please come prepared with your feedback. Looking forward to our discussion!
+```
+## 注意事项
+1. 当检测到人工接入时,需要带着nodeId重新发起请求。
+2. 当前模型使用的qwen3-max-2026-01-23,模型不同可能导致示例结果有所偏差。
+
+## 相关链接
+
+- [Spring AI Alibaba 文档](https://java2ai.com)
+- [Spring AI Alibaba GitHub](https://github.com/alibaba/spring-ai-alibaba)
\ No newline at end of file
diff --git a/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/pom.xml b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/pom.xml
new file mode 100644
index 00000000..c78c3b99
--- /dev/null
+++ b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/pom.xml
@@ -0,0 +1,60 @@
+
+
+ 4.0.0
+
+ com.alibaba.cloud.ai
+ spring-ai-alibaba-examples
+ 1.0.0
+ ../../pom.xml
+
+
+ subagent-personal-assistant-example
+ Spring AI Alibaba SubAgent Personal Assistant Example
+ Multi Agent Personal Assistant
+
+
+ 21
+ 21
+ UTF-8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ com.alibaba.cloud.ai
+ spring-ai-alibaba-agent-framework
+
+
+
+ com.alibaba.cloud.ai
+ spring-ai-alibaba-starter-dashscope
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
\ No newline at end of file
diff --git a/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/HITLHelper.java b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/HITLHelper.java
new file mode 100644
index 00000000..ea7733d0
--- /dev/null
+++ b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/HITLHelper.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2026-2027 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.cloud.alibaba.ai.example.agent;
+
+import com.alibaba.cloud.ai.graph.action.InterruptionMetadata;
+
+public class HITLHelper {
+ /**
+ * 批准所有工具调用
+ */
+ public static InterruptionMetadata approveAll(InterruptionMetadata interruptionMetadata) {
+ InterruptionMetadata.Builder builder = InterruptionMetadata.builder()
+ .nodeId(interruptionMetadata.node())
+ .state(interruptionMetadata.state());
+
+ interruptionMetadata.toolFeedbacks().forEach(toolFeedback -> {
+ builder.addToolFeedback(
+ InterruptionMetadata.ToolFeedback.builder(toolFeedback)
+ .result(InterruptionMetadata.ToolFeedback.FeedbackResult.APPROVED)
+ .description("Agree to tool execution.")
+ .build()
+ );
+ });
+
+ return builder.build();
+ }
+
+ /**
+ * 拒绝所有工具调用
+ */
+ public static InterruptionMetadata rejectAll(
+ InterruptionMetadata interruptionMetadata,
+ String reason) {
+ InterruptionMetadata.Builder builder = InterruptionMetadata.builder()
+ .nodeId(interruptionMetadata.node())
+ .state(interruptionMetadata.state());
+
+ interruptionMetadata.toolFeedbacks().forEach(toolFeedback -> {
+ builder.addToolFeedback(
+ InterruptionMetadata.ToolFeedback.builder(toolFeedback)
+ .result(InterruptionMetadata.ToolFeedback.FeedbackResult.REJECTED)
+ .description(reason)
+ .build()
+ );
+ });
+
+ return builder.build();
+ }
+
+ /**
+ * 编辑特定工具的参数
+ */
+ public static InterruptionMetadata editTool(
+ InterruptionMetadata interruptionMetadata,
+ String toolName,
+ String newArguments) {
+ InterruptionMetadata.Builder builder = InterruptionMetadata.builder()
+ .nodeId(interruptionMetadata.node())
+ .state(interruptionMetadata.state());
+
+ interruptionMetadata.toolFeedbacks().forEach(toolFeedback -> {
+ if (toolFeedback.getName().equals(toolName)) {
+ builder.addToolFeedback(
+ InterruptionMetadata.ToolFeedback.builder(toolFeedback)
+ .arguments(newArguments)
+ .result(InterruptionMetadata.ToolFeedback.FeedbackResult.EDITED)
+ .build()
+ );
+ } else {
+ builder.addToolFeedback(
+ InterruptionMetadata.ToolFeedback.builder(toolFeedback)
+ .result(InterruptionMetadata.ToolFeedback.FeedbackResult.APPROVED)
+ .build()
+ );
+ }
+ });
+
+ return builder.build();
+ }
+
+}
diff --git a/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/SubAgentPersonalAssistantApplication.java b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/SubAgentPersonalAssistantApplication.java
new file mode 100644
index 00000000..dd797775
--- /dev/null
+++ b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/SubAgentPersonalAssistantApplication.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2026-2027 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.cloud.alibaba.ai.example.agent;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * @author wangjx
+ * @since 2026-02-13
+ */
+@SpringBootApplication
+public class SubAgentPersonalAssistantApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(SubAgentPersonalAssistantApplication.class, args);
+ }
+}
\ No newline at end of file
diff --git a/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/config/AgentConfig.java b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/config/AgentConfig.java
new file mode 100644
index 00000000..1e68072b
--- /dev/null
+++ b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/config/AgentConfig.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2026-2027 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.cloud.alibaba.ai.example.agent.config;
+
+import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
+import com.alibaba.cloud.ai.graph.agent.AgentTool;
+import com.alibaba.cloud.ai.graph.agent.ReactAgent;
+import com.alibaba.cloud.ai.graph.agent.hook.hip.HumanInTheLoopHook;
+import com.alibaba.cloud.ai.graph.agent.hook.hip.ToolConfig;
+import com.alibaba.cloud.ai.graph.checkpoint.savers.MemorySaver;
+import com.cloud.alibaba.ai.example.agent.tool.*;
+import org.springframework.ai.tool.ToolCallback;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.List;
+
+/**
+ * Configuration class for setting up AI agents used in the personal assistant application.
+ * This class defines and configures various agents including calendar scheduling,
+ * email composition, and a supervisor agent that coordinates between them.
+ *
+ * @author wangjx
+ * @since 2026-02-13
+ */
+@Configuration
+public class AgentConfig {
+
+
+ private final static String CALENDAR_AGENT_PROMPT = """
+ You are a calendar scheduling assistant.
+ Parse natural language scheduling requests (e.g., 'next Tuesday at 2pm')
+ into proper ISO datetime formats.
+ Use get_available_time_slots to check availability when needed.
+ Use create_calendar_event to schedule events.
+ Always confirm what was scheduled in your final response.
+ """;
+
+ private final static String EMAIL_AGENT_PROMPT = """
+ You are an email assistant.
+ Compose professional emails based on natural language requests.
+ Extract recipient information and craft appropriate subject lines and body text.
+ Use send_email to send the message.
+ Always confirm what was sent in your final response.
+ """;
+
+ private final static String SUPERVISOR_PROMPT = """
+ You are a helpful personal assistant.
+ You can schedule calendar events and send emails.
+ Break down user requests into appropriate tool calls and coordinate the results.
+ When a request involves multiple actions, use multiple tools in sequence.
+ """;
+
+ private final DashScopeChatModel dashScopeChatModel;
+
+ public AgentConfig(DashScopeChatModel dashScopeChatModel) {
+ this.dashScopeChatModel = dashScopeChatModel;
+ }
+
+ @Bean("supervisorAgent")
+ public ReactAgent reactAgent() {
+ // 配置检查点保存器(人工介入需要检查点来处理中断)
+ MemorySaver memorySaver = new MemorySaver();
+ ToolCallback calendarAgent = AgentTool.getFunctionToolCallback(calendarAgent());
+ ToolCallback emailAgent = AgentTool.getFunctionToolCallback(emailAgent());
+
+
+ return ReactAgent.builder()
+ .name("supervisor_agent")
+ .model(dashScopeChatModel)
+ .systemPrompt(SUPERVISOR_PROMPT)
+ .hooks(createHumanInTheLoopHook())
+ .tools(List.of(calendarAgent, emailAgent, new UserDataTool().toolCallback()))
+ .saver(memorySaver)
+ .build();
+ }
+
+
+ public ReactAgent emailAgent() {
+
+ String instruction =
+ """
+ Send emails using natural language.
+ Use this when the user wants to send notifications, reminders, or any email
+ communication. Handles recipient extraction, subject generation, and email
+ composition.
+ Input: Natural language email request (e.g., 'send them a reminder about
+ the meeting')
+ """;
+ // 创建 Agent
+ return ReactAgent.builder()
+ .name("email_agent")
+ .model(dashScopeChatModel)
+ .tools(List.of(new SendEmailTool().toolCallback()))
+ .systemPrompt(EMAIL_AGENT_PROMPT)
+ .instruction(instruction)
+ .inputType(String.class)
+ .build();
+ }
+
+ @Bean("calendarAgent")
+ public ReactAgent calendarAgent() {
+
+ String instruction = """
+ Schedule calendar events using natural language.
+ Use this when the user wants to create, modify, or check calendar appointments.
+ Handles date/time parsing, availability checking, and event creation.
+ Input: Natural language scheduling request (e.g., 'meeting with design team
+ next Tuesday at 2pm')
+ """;
+
+ // 创建 Agent
+ return ReactAgent.builder()
+ .name("calendar_agent")
+ .model(dashScopeChatModel)
+ .tools(List.of(new CreateCalendarEventTool().toolCallback(), new AvailableTimeSlotsTool().toolCallback(), new DateTimeTools().toolCallback()))
+ .systemPrompt(CALENDAR_AGENT_PROMPT)
+ .instruction(instruction)
+ .inputType(String.class)
+ .build();
+
+ }
+
+ private HumanInTheLoopHook createHumanInTheLoopHook() {
+ // 创建人工介入Hook
+ return HumanInTheLoopHook.builder()
+ .approvalOn("calendar_agent", ToolConfig.builder()
+ .description("Calendar event pending approval")
+ .build())
+ .approvalOn("email_agent", ToolConfig.builder()
+ .description("Outbound email pending approval")
+ .build()).build();
+ }
+}
diff --git a/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/controller/PersonalAssistantController.java b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/controller/PersonalAssistantController.java
new file mode 100644
index 00000000..5dcd904a
--- /dev/null
+++ b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/controller/PersonalAssistantController.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2026-2027 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.cloud.alibaba.ai.example.agent.controller;
+
+import com.alibaba.cloud.ai.graph.NodeOutput;
+import com.alibaba.cloud.ai.graph.RunnableConfig;
+import com.alibaba.cloud.ai.graph.action.InterruptionMetadata;
+import com.alibaba.cloud.ai.graph.agent.ReactAgent;
+import com.alibaba.cloud.ai.graph.exception.GraphRunnerException;
+import com.alibaba.cloud.ai.graph.streaming.StreamingOutput;
+import com.cloud.alibaba.ai.example.agent.HITLHelper;
+import org.springframework.ai.chat.messages.Message;
+import org.springframework.ai.chat.messages.ToolResponseMessage;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+import reactor.core.publisher.Flux;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * REST controller for managing personal assistant functionalities.
+ * This controller handles requests related to the supervisor agent,
+ * including streaming responses and human-in-the-loop interventions.
+ *
+ * @author wangjx
+ * @since 2026-02-13
+ */
+@RestController
+public class PersonalAssistantController {
+
+ private static final Map> TOOL_FEEDBACK_MAP = new ConcurrentHashMap<>();
+
+ @Autowired
+ @Qualifier("supervisorAgent")
+ private ReactAgent supervisorAgent;
+
+
+ /**
+ * Handles GET requests to the supervisor agent endpoint.
+ * Supports both regular streaming and human-in-the-loop interventions.
+ *
+ * @param query the user's query string
+ * @param threadId the session thread identifier
+ * @param nodeId the node identifier for human intervention
+ * @return a Flux stream of responses from the supervisor agent
+ * @throws GraphRunnerException if there's an error during graph execution
+ */
+ @GetMapping(value = "/react/agent/supervisorAgent", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
+ public Flux supervisorAgentTest(String query, String threadId, String nodeId) throws GraphRunnerException {
+ RunnableConfig config;
+ if (nodeId != null && TOOL_FEEDBACK_MAP.containsKey(nodeId)) {
+ System.out.println("人工介入开始...");
+ // Human intervention using checkpoint mechanism.
+ // You must provide a thread ID to associate execution with a session thread,
+ // so that conversations can be paused and resumed (required for human review).
+ InterruptionMetadata metadata = InterruptionMetadata.builder().toolFeedbacks(TOOL_FEEDBACK_MAP.get(nodeId)).build();
+ InterruptionMetadata approvalMetadata = HITLHelper.approveAll(metadata);
+ // Resume execution using approval decision
+ config = RunnableConfig.builder()
+ .threadId(threadId) // Same thread ID
+ .addHumanFeedback(approvalMetadata)
+ .build();
+ TOOL_FEEDBACK_MAP.remove(nodeId);
+ return supervisorAgent.stream(query, config)
+ .doOnNext(this::println);
+ } else {
+
+ config = RunnableConfig.builder()
+ .threadId(threadId)
+ .build();
+ }
+ return supervisorAgent.stream(query, config)
+ .doOnNext(this::println);
+
+ }
+
+ private void println(NodeOutput nodeOutput) {
+ if (nodeOutput instanceof StreamingOutput streamingOutput) {
+ String node = streamingOutput.node();
+ Message message = streamingOutput.message();
+ if (message == null) {
+ return;
+ }
+ if ("_AGENT_MODEL_".equals(node)) {
+ System.out.print(message.getText());
+ }
+ if ("_AGENT_TOOL_".equals(node)) {
+ ToolResponseMessage responseMessage = (ToolResponseMessage) message;
+ List responses = responseMessage.getResponses();
+ System.out.println("================================= Tool Message =================================\n");
+ for (ToolResponseMessage.ToolResponse respons : responses) {
+ String string = respons.responseData();
+ System.out.println("id: " + respons.id());
+ System.out.println("name: " + respons.name());
+ System.out.println("responseData: " + string);
+
+ }
+ }
+ } else if (nodeOutput instanceof InterruptionMetadata interruptionMetadata) {
+ System.out.println("检测到中断,需要人工审批");
+ List toolFeedbacks =
+ interruptionMetadata.toolFeedbacks();
+
+ for (InterruptionMetadata.ToolFeedback feedback : toolFeedbacks) {
+ System.out.println("工具: " + feedback.getName());
+ System.out.println("参数: " + feedback.getArguments());
+ System.out.println("描述: " + feedback.getDescription());
+ }
+ String node = interruptionMetadata.node();
+ System.out.println("检测到中断,等待人工介入... node: " + node);
+ TOOL_FEEDBACK_MAP.put(node, toolFeedbacks);
+ }
+ }
+}
diff --git a/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/model/AvailableTimeInfo.java b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/model/AvailableTimeInfo.java
new file mode 100644
index 00000000..6fb1a054
--- /dev/null
+++ b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/model/AvailableTimeInfo.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2026-2027 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.cloud.alibaba.ai.example.agent.model;
+
+import java.util.List;
+
+/**
+ *
+ * @author wangjx
+ * @since 2026-02-13
+ * */
+public class AvailableTimeInfo {
+ /**
+ * 日期信息,表示可用时间的具体日期
+ */
+ private String date;
+
+ /**
+ * 持续时间(分钟),表示该时间段的长度
+ */
+ private Integer durationMinutes;
+
+ /**
+ * 参与者列表,包含所有参与此时间段的人员信息
+ */
+ private List attendees;
+
+ public List getAttendees() {
+ return attendees;
+ }
+
+ public void setAttendees(List attendees) {
+ this.attendees = attendees;
+ }
+
+ public String getDate() {
+ return date;
+ }
+
+ public void setDate(String date) {
+ this.date = date;
+ }
+
+ public Integer getDurationMinutes() {
+ return durationMinutes;
+ }
+
+ public void setDurationMinutes(Integer durationMinutes) {
+ this.durationMinutes = durationMinutes;
+ }
+}
+
diff --git a/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/model/CalendarInfo.java b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/model/CalendarInfo.java
new file mode 100644
index 00000000..dbc80fb6
--- /dev/null
+++ b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/model/CalendarInfo.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2026-2027 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.cloud.alibaba.ai.example.agent.model;
+
+import java.util.List;
+
+/**
+ *
+ * @author wangjx
+ * @since 2026-02-13
+ * */
+public class CalendarInfo {
+ /**
+ * 日历事件的标题
+ */
+ private String title;
+
+ /**
+ * 日历事件的开始时间
+ */
+ private String startTime;
+
+ /**
+ * 日历事件的结束时间
+ */
+ private String endTime;
+
+ /**
+ * 日历事件的参与者列表
+ */
+ private List attendees;
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getStartTime() {
+ return startTime;
+ }
+
+ public void setStartTime(String startTime) {
+ this.startTime = startTime;
+ }
+
+ public String getEndTime() {
+ return endTime;
+ }
+
+ public void setEndTime(String endTime) {
+ this.endTime = endTime;
+ }
+
+ public List getAttendees() {
+ return attendees;
+ }
+
+ public void setAttendees(List attendees) {
+ this.attendees = attendees;
+ }
+}
diff --git a/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/model/EmailInfo.java b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/model/EmailInfo.java
new file mode 100644
index 00000000..c7f05806
--- /dev/null
+++ b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/model/EmailInfo.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2026-2027 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.cloud.alibaba.ai.example.agent.model;
+
+import java.util.List;
+
+/**
+ *
+ * @author wangjx
+ * @since 2026-02-13
+ * */
+public class EmailInfo {
+ /**
+ * 收件人邮箱地址列表
+ */
+ private List to;
+
+ /**
+ * 邮件主题
+ */
+ private String subject;
+
+ /**
+ * 邮件正文内容
+ */
+ private String body;
+
+ public List getTo() {
+ return to;
+ }
+
+ public void setTo(List to) {
+ this.to = to;
+ }
+
+ public String getSubject() {
+ return subject;
+ }
+
+ public void setSubject(String subject) {
+ this.subject = subject;
+ }
+
+ public String getBody() {
+ return body;
+ }
+
+ public void setBody(String body) {
+ this.body = body;
+ }
+}
diff --git a/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/model/UserInfo.java b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/model/UserInfo.java
new file mode 100644
index 00000000..dc3196b8
--- /dev/null
+++ b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/model/UserInfo.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2026-2027 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.cloud.alibaba.ai.example.agent.model;
+
+/**
+ *
+ * @author wangjx
+ * @since 2026-02-13
+ * */
+public class UserInfo {
+ /**
+ * 用户名称
+ */
+ private String userName;
+
+ /**
+ * 用户邮箱
+ */
+ private String email;
+
+ /**
+ * 部门名称
+ */
+ private String departmentName;
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getDepartmentName() {
+ return departmentName;
+ }
+
+ public void setDepartmentName(String departmentName) {
+ this.departmentName = departmentName;
+ }
+}
diff --git a/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/tool/AvailableTimeSlotsTool.java b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/tool/AvailableTimeSlotsTool.java
new file mode 100644
index 00000000..d74223d4
--- /dev/null
+++ b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/tool/AvailableTimeSlotsTool.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2026-2027 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.cloud.alibaba.ai.example.agent.tool;
+
+import com.cloud.alibaba.ai.example.agent.model.AvailableTimeInfo;
+import org.springframework.ai.chat.model.ToolContext;
+import org.springframework.ai.tool.ToolCallback;
+import org.springframework.ai.tool.function.FunctionToolCallback;
+
+import java.util.List;
+import java.util.function.BiFunction;
+
+/**
+ * A tool that retrieves available time slots for scheduling meetings.
+ * This tool implements the BiFunction interface to process input parameters
+ * and return formatted time slot information.
+ *
+ * @author wangjx
+ * @since 2026-02-13
+ */
+public class AvailableTimeSlotsTool implements BiFunction {
+
+
+ @Override
+ public String apply(AvailableTimeInfo args, ToolContext toolContext) {
+ // Parse input parameters
+ String date =args.getDate();
+
+ // Validate date format (simplified version)
+ if (!isValidIsoDate(date)) {
+ return "Error: Invalid ISO date format";
+ }
+
+ // Simulate querying available time slots
+ List timeSlots = List.of("09:00", "14:00", "16:00");
+ return String.format("Available time slots for %s: %s", date, String.join(", ", timeSlots));
+ }
+
+
+ private boolean isValidIsoDate(String date) {
+ // Simple validation of ISO 8601 date format
+ return date != null && date.matches("\\d{4}-\\d{2}-\\d{2}");
+ }
+
+
+ public ToolCallback toolCallback() {
+ return FunctionToolCallback.builder("get_available_time_slots", this)
+ .description("get_available_time_slots")
+ .inputType(AvailableTimeInfo.class)
+ .build();
+ }
+}
diff --git a/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/tool/CreateCalendarEventTool.java b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/tool/CreateCalendarEventTool.java
new file mode 100644
index 00000000..4c925ffe
--- /dev/null
+++ b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/tool/CreateCalendarEventTool.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2026-2027 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.cloud.alibaba.ai.example.agent.tool;
+
+import com.cloud.alibaba.ai.example.agent.model.CalendarInfo;
+import org.springframework.ai.chat.model.ToolContext;
+import org.springframework.ai.tool.ToolCallback;
+import org.springframework.ai.tool.function.FunctionToolCallback;
+
+import java.util.List;
+import java.util.function.BiFunction;
+
+/**
+ * A tool for creating calendar events.
+ * This class implements BiFunction to process CalendarInfo and ToolContext,
+ * validating input data and simulating event creation.
+ *
+ * @author wangjx
+ * @since 2026-02-13
+ */
+public class CreateCalendarEventTool implements BiFunction {
+
+
+ @Override
+ public String apply(CalendarInfo calendarInfo, ToolContext toolContext) {
+ // Parse parameters
+ String title = calendarInfo.getTitle();
+ String startTime = calendarInfo.getStartTime();
+ String endTime = calendarInfo.getEndTime();
+ List attendees = calendarInfo.getAttendees();
+
+ // Validate time format (simplified version)
+ if (!isValidIsoDateTime(startTime) || !isValidIsoDateTime(endTime)) {
+ return "Error: Invalid ISO datetime format";
+ }
+
+ // Simulate event creation
+ return String.format("Event created: %s from %s to %s with %d attendees",
+ title, startTime, endTime, attendees==null ? 0:attendees.size());
+ }
+
+
+ private boolean isValidIsoDateTime(String datetime) {
+ // Simple validation of ISO 8601 format (should use stricter validation in production)
+ return datetime != null && datetime.matches("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}");
+ }
+ public ToolCallback toolCallback() {
+ return FunctionToolCallback.builder("create_calendar_event", this)
+ .description("create_calendar_event")
+ .inputType(CalendarInfo.class)
+ .build();
+ }
+}
diff --git a/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/tool/DateTimeTools.java b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/tool/DateTimeTools.java
new file mode 100644
index 00000000..d7038fd0
--- /dev/null
+++ b/spring-ai-alibaba-agent-example/subagent-personal-assistant-example/src/main/java/com/cloud/alibaba/ai/example/agent/tool/DateTimeTools.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2026-2027 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.cloud.alibaba.ai.example.agent.tool;
+
+import org.springframework.ai.chat.model.ToolContext;
+import org.springframework.ai.tool.ToolCallback;
+import org.springframework.ai.tool.function.FunctionToolCallback;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Map;
+import java.util.function.BiFunction;
+
+/**
+ * Utility class for handling date and time operations.
+ * Provides functionality to retrieve the current date and time.
+ *
+ * @author wangjx
+ * @since 2026-02-13
+ */
+public class DateTimeTools implements BiFunction