Skip to content

获取 ADK 工具的操作确认

Supported in ADKPython v1.14.0Go v0.3.0Experimental

某些智能体工作流需要确认来进行决策、验证、安全或一般监督。在这些情况下,你希望在工作流继续之前从人类或监督系统获得响应。智能体开发工具包(ADK)中的 工具确认 功能允许 ADK 工具暂停其执行,并与用户或其他系统交互以获得确认或在继续之前收集结构化数据。你可以通过以下方式在 ADK 工具中使用工具确认:

  • Boolean Confirmation: You can configure a tool with a confirmation flag or provider. This option pauses the tool for a yes or no confirmation response.
  • Advanced Confirmation: For scenarios requiring structured data responses, you can configure a tool with a text prompt to explain the confirmation and an expected response.

实验性功能

工具确认功能是实验性的,有一些已知限制。 我们欢迎你的反馈

你可以配置如何向用户传达请求,系统也可以使用通过 ADK 服务器的 REST API 发送的远程响应。当在 ADK Web 用户界面中使用确认功能时,智能体工作流会向用户显示一个对话框来请求输入,如图 1 所示:

Screenshot of default user interface for tool confirmation

图 1。 使用高级工具响应实现的确认响应请求对话框示例。

The following sections describe how to use this feature for the confirmation scenarios. For a complete code sample, see the human_tool_confirmation example. There are additional ways to incorporate human input into your agent workflow, for more details, see the Human-in-the-loop agent pattern.

布尔确认

当你的工具只需要用户简单的"是"或"否"时,你可以使用 FunctionTool 类作为包装器来添加确认步骤。例如,如果你有一个名为 reimburse 的工具,你可以通过用 FunctionTool 类包装它并将 require_confirmation 参数设置为 True 来启用确认步骤,如下例所示:

root_agent = Agent(
    # ...
    tools = [
        # Set require_confirmation to True to require user confirmation
        # for the tool call.
        FunctionTool(reimburse, require_confirmation=True),
    ],
    # ...
)

# This implementation method requires minimal code, but is limited to simple
# approvals from the user or confirming system. For a complete example of this
# approach, see the following code sample for a more detailed example:
# https://github.com/google/adk-python/blob/main/contributing/samples/human_tool_confirmation/agent.py
reimburseTool, _ := functiontool.New(functiontool.Config{
    Name:        "reimburse",
    Description: "Reimburse an amount",
    // Set RequireConfirmation to true to require user confirmation
    // for the tool call.
    RequireConfirmation: true,
}, func(ctx tool.Context, args ReimburseArgs) (ReimburseResult, error) {
    // actual implementation
    return ReimburseResult{Status: "ok"}, nil
})

rootAgent, _ := llmagent.New(llmagent.Config{
    // ...
    Tools: []tool.Tool{reimburseTool},
})
LlmAgent rootAgent = LlmAgent.builder()
    // ...
    .tools(
        // Set requireConfirmation to true to require user confirmation
        // for the tool call.
        FunctionTool.create(myClassInstance, "reimburse", true)
    )
    // ...
    .build();

需要确认函数

You can modify the behavior of the confirmation requirement by using a function that returns a boolean response based on the tool's input.

async def confirmation_threshold(
    amount: int, tool_context: ToolContext
) -> bool:
  """Returns true if the amount is greater than 1000."""
  return amount > 1000

root_agent = Agent(
    # ...
    tools = [
        # Pass the threshold function to dynamically require confirmation
        FunctionTool(reimburse, require_confirmation=confirmation_threshold),
    ],
    # ...
)
reimburseTool, _ := functiontool.New(functiontool.Config{
    Name:        "reimburse",
    Description: "Reimburse an amount",
    // RequireConfirmationProvider allows for dynamic determination
    // of whether user confirmation is needed.
    RequireConfirmationProvider: func(args ReimburseArgs) bool {
        return args.Amount > 1000
    },
}, func(ctx tool.Context, args ReimburseArgs) (ReimburseResult, error) {
    // actual implementation
    return ReimburseResult{Status: "ok"}, nil
})
// In ADK Java, dynamic threshold confirmation logic is evaluated directly
// inside the tool logic using the ToolContext rather than via a lambda parameter.
public Map<String, Object> reimburse(
    @Schema(name="amount") int amount, ToolContext toolContext) {

  // 1. Dynamic threshold check
  if (amount > 1000) {
    Optional<ToolConfirmation> toolConfirmation = toolContext.toolConfirmation();
    if (toolConfirmation.isEmpty()) {
       toolContext.requestConfirmation("Amount > 1000 requires approval.");
       return Map.of("status", "Pending manager approval.");
    } else if (!toolConfirmation.get().confirmed()) {
       return Map.of("status", "Reimbursement rejected.");
    }
  }

  // 2. Proceed with actual tool logic
  return Map.of("status", "ok", "reimbursedAmount", amount);
}

LlmAgent rootAgent = LlmAgent.builder()
    // ...
    .tools(
        // No requireConfirmation flag is set because the custom threshold
        // logic is already handled inside the method!
        FunctionTool.create(this, "reimburse")
    )
    // ...
    .build();

高级确认

当工具确认需要更多用户详细信息或更复杂的响应时,请使用 tool_confirmation 实现。这种方法扩展了 ToolContext 对象,为用户添加请求的文本描述,并允许更复杂的响应数据。当以这种方式实现工具确认时,你可以暂停工具的执行,请求特定信息,然后使用提供的数据恢复工具。

此确认流程有一个请求阶段,系统在此阶段组装并发送输入请求人类响应,以及一个响应阶段,系统在此阶段接收和处理返回的数据。

确认定义

When creating a Tool with advanced confirmation, use the Tool Context Request Confirmation method with hint and payload parameters:

  • hint: Descriptive message that explains what is needed from the user.
  • payload: The structure of the data you expect in return. This must be serializable into a JSON-formatted string.

有关此方法的完整示例,请参阅 human_tool_confirmation 代码示例。请记住,智能体工作流工具执行在获得确认时会暂停。收到确认后,你可以在 tool_confirmation.payload 对象中访问确认响应,然后继续执行工作流。

The following code shows an example implementation for a tool that processes time off requests for an employee:

def request_time_off(days: int, tool_context: ToolContext):
    """Request day off for the employee."""
    # ...
    tool_confirmation = tool_context.tool_confirmation
    if not tool_confirmation:
        tool_context.request_confirmation(
            hint=(
                'Please approve or reject the tool call request_time_off() by'
                ' responding with a FunctionResponse with an expected'
                ' ToolConfirmation payload.'
            ),
            payload={
                'approved_days': 0,
            },
        )
        # Return intermediate status indicating that the tool is waiting for
        # a confirmation response:
        return {'status': 'Manager approval is required.'}

    approved_days = tool_confirmation.payload['approved_days']
    approved_days = min(approved_days, days)
    if approved_days == 0:
        return {'status': 'The time off request is rejected.', 'approved_days': 0}
    return {
        'status': 'ok',
        'approved_days': approved_days,
    }
func requestTimeOff(ctx tool.Context, args RequestTimeOffArgs) (map[string]any, error) {
    confirmation := ctx.ToolConfirmation()
    if confirmation == nil {
        ctx.RequestConfirmation(
            "Please approve or reject the tool call requestTimeOff() by "+
            "responding with a FunctionResponse with an expected "+
            "ToolConfirmation payload.",
            map[string]any{"approved_days": 0},
        )
        return map[string]any{"status": "Manager approval is required."}, nil
    }

    payload := confirmation.Payload.(map[string]any)
    // Values in map[string]any from JSON are float64 by default in Go
    approvedDays := int(payload["approved_days"].(float64))
    approvedDays = min(approvedDays, args.Days)

    if approvedDays == 0 {
        return map[string]any{"status": "The time off request is rejected.", "approved_days": 0}, nil
    }

    return map[string]any{
        "status": "ok",
        "approved_days": approvedDays,
    }, nil
}
public Map<String, Object> requestTimeOff(
    @Schema(name="days") int days,
    ToolContext toolContext) {
    // Request day off for the employee.
    // ...
    Optional<ToolConfirmation> toolConfirmation = toolContext.toolConfirmation();
    if (toolConfirmation.isEmpty()) {
        toolContext.requestConfirmation(
            "Please approve or reject the tool call requestTimeOff() by " +
            "responding with a FunctionResponse with an expected " +
            "ToolConfirmation payload.",
            Map.of("approved_days", 0)
        );
        // Return intermediate status indicating that the tool is waiting for
        // a confirmation response:
        return Map.of("status", "Manager approval is required.");
    }

    Map<String, Object> payload = (Map<String, Object>) toolConfirmation.get().payload();
    int approvedDays = (int) payload.get("approved_days");
    approvedDays = Math.min(approvedDays, days);

    if (approvedDays == 0) {
        return Map.of("status", "The time off request is rejected.", "approved_days", 0);
    }

    return Map.of(
        "status", "ok",
        "approved_days", approvedDays
    );
}

Remote confirmation with REST API

如果没有用于智能体工作流人工确认的活动用户界面,你可以通过命令行界面或通过电子邮件或聊天应用程序等其他渠道路由来处理确认。要确认工具调用,用户或调用应用程序需要发送带有工具确认数据的 FunctionResponse 事件。

你可以将请求发送到 ADK API 服务器的 /run/run_sse 端点,或直接发送到 ADK 运行器。以下示例使用 curl 命令将确认发送到 /run_sse 端点:

 curl -X POST http://localhost:8000/run_sse \
 -H "Content-Type: application/json" \
 -d '{
    "app_name": "human_tool_confirmation",
    "user_id": "user",
    "session_id": "7828f575-2402-489f-8079-74ea95b6a300",
    "new_message": {
        "parts": [
            {
                "function_response": {
                    "id": "adk-13b84a8c-c95c-4d66-b006-d72b30447e35",
                    "name": "adk_request_confirmation",
                    "response": {
                        "confirmed": true,
                        "payload": {
                            "approved_days": 5
                        }
                    }
                }
            }
        ],
        "role": "user"
    }
}'

基于 REST 的确认响应必须满足以下要求:

  • The id in the function_response should match the function_call_id from the adk_request_confirmation FunctionCall event.
  • The name should be adk_request_confirmation.
  • The response object contains the confirmed status and any additional payload data.

    Note: Confirmation with Resume feature

    If your ADK agent workflow is configured with the Resume feature, you also must include the Invocation ID (invocation_id) parameter with the confirmation response. The Invocation ID you provide must be the same invocation that generated the confirmation request, otherwise the system starts a new invocation with the confirmation response. If your agent uses the Resume feature, consider including the Invocation ID as a parameter with your confirmation request, so it can be included with the response. For more details on using the Resume feature, see Resume stopped agents.

已知限制

工具确认功能具有以下限制:

下一步

For more information on building ADK tools for agent workflows, see Function tools.