跳到正文
OpenRouter Blog·· 2026-05-08精选AI 评分60

OpenRouter Agent SDK 新增 human-in-the-loop 工具类型

Human-in-the-Loop Tools for the Agent SDK

AI 导读

OpenRouter 的 Agent SDK 新增第四种工具类型 human-in-the-loop(HITL),通过 onToolCalled 钩子按输入决定自动执行还是暂停等待人工。

推荐理由

原文给出 HITL 工具的定义方式与暂停恢复流程,读者可据此判断如何在智能体循环中插入人工审核。

正文 · AI 翻译

Agent SDK 支持第四种工具类型:human-in-the-loop (HITL) 工具。它们让您的 agent 自动处理常规调用,并在风险较高时暂停等待人工介入,这一切都由单个 hook 控制。

安装 SDK,定义您的 HITL 工具,并按照 cookbook recipe 实现一个可运行的方案。

npm install @openrouter/agent

按调用自动解决或升级

常规工具总是执行。手动工具总是暂停。HITL 工具两者兼具:您的 onToolCalled hook 检查输入并做出决定。

import { tool } from '@openrouter/agent/tool';
import { z } from 'zod';

const approvePayment = tool({
  name: 'approve_payment',
  description: 'Approve a payment, escalating large amounts to a human',
  inputSchema: z.object({
    amount: z.number(),
    recipient: z.string(),
  }),
  outputSchema: z.object({
    approved: z.boolean(),
    reviewedAt: z.number().optional(),
  }),
  onToolCalled: async (input) => {
    if (input.amount < 100) {
      return { approved: true };
    }
    // Pause for human review
    return null;
  },
});

返回一个值,agent 继续运行(就像常规工具一样)。返回 null,循环暂停并返回 status: 'awaiting_hitl',将待处理的调用暴露给您的应用程序。您可以通过再次调用 callModel 并传入一个包含人工决定的 function_call_output 项来恢复。

这种模式适用于任何决策依赖数据的地方:金额阈值、风险评分、内容策略标记、合规检查。分支逻辑集中在一个函数中,而不是分散在您的应用程序代码里。

在模型看到人工响应之前对其进行后处理

一个可选的第二个 hook,onResponseReceived,会在人工为暂停的调用提供结果时触发。它在将原始输入传递给模型之前对其进行转换。

onResponseReceived: async (raw) => {
  return { ...(raw as Record<string, unknown>), reviewedAt: Date.now() };
},

用它来标记元数据、规范化格式、根据业务规则进行验证,或用人工无需手动提供的上下文来丰富响应。如果它抛出异常,错误会以 { error: ..., originalOutput: ... } 的形式暴露给模型,因此不会有任何东西被静默吞掉。

暂停和恢复循环的工作原理

以下是完整的生命周期:

  1. 模型在 agent 循环期间调用您的 HITL 工具。
  2. onToolCalled 运行。如果它返回一个值,agent 继续运行。如果它返回 null,循环暂停。
  3. 您的应用程序通过 getToolCalls() 读取待处理的调用,并将其呈现给用户。
  4. 用户做出决定。
  5. 您再次调用 callModel,并将决定作为 function_call_output 项传入。
  6. onResponseReceived(如果已定义)转换响应。
  7. 模型接收结果,agent 循环恢复。
const result = openrouter.callModel({
  model: 'openai/gpt-4o',
  input: 'Pay $500 to Acme Corp for the May invoice',
  tools: [approvePayment] as const,
  state,
});

const response = await result.getResponse();

if (response.state?.status === 'awaiting_hitl') {
  const pending = response.state.pendingToolCalls ?? [];
  // Present pending[0] to your user, collect their decision, then resume:
  const resumed = openrouter.callModel({
    model: 'openai/gpt-4o',
    input: [{
      type: 'function_call_output' as const,
      callId: pending[0].id,
      output: JSON.stringify({ approved: true }),
    }],
    tools: [approvePayment] as const,
    state,
  });
}

SDK 处理所有状态跟踪、hook 分发和 schema 验证。您无需编写任何循环代码。

何时使用 HITL 与 requireApproval

两者都会暂停以等待人工输入。区别在于决策逻辑。

HITL (onToolCalled)requireApproval
何时暂停仅当您的 hook 返回 null 时始终,在任何执行之前
决策类型数据驱动(阈值、评分、策略)二元是/否同意
自动解决返回一个值以跳过人工审核不可用
后处理onResponseReceived 转换响应不可用

当每次调用都需要明确的人工同意而无论输入如何时(例如:“删除此数据库”、“发送此电子邮件”),请使用 requireApproval。当某些调用可以自动进行而其他调用需要人工介入时(例如:“如果金额低于 $100,则批准此付款”),请使用 HITL。

开始构建

HITL 工具 cookbook recipe 将引导您完成一个完整的实现:定义工具、检测暂停、收集人工输入并恢复循环。

有关完整的类型签名和 API 接口,请参阅 工具文档 和 API 参考。

获取您的 API 密钥,并在 Discord 上告诉我们您正在构建什么。

来源:OpenRouter Blog · openrouter.ai