理解 AI 投资 / 研究收束
AI智能体怎样停下来问人:四种交互控制与适用条件
程序预设门控、权限审批、模型提问和人工中途干预适合不同的交互模式。LangGraph与Claude Agent SDK的文档说明了各自的触发条件、前置要求和恢复行为;选择时要先明确应用在哪个环节需要人的输入。
快速答案
应用需要人类输入时,有四种文档化控制可供选择。LangGraph的interrupt()由开发者放在代码中,需要检查点存储和用于恢复的同一线程ID,恢复时会重放所在节点;Claude Agent SDK提供受权限流程约束的回调、模型发起的结构化提问,以及人主动发送的流式输入。选择应依据谁发起输入、何时需要输入和怎样恢复执行;配置了某种机制,并不保证模型能识别所有歧义。
先明确谁发起输入、执行在哪里等待
经营SaaS业务的Hacker News用户CuriousRose提出了一个具体问题:如何阻止AI在需要澄清时自行继续执行。原帖描述了大量想自动化的积压工作,以及对人应该在流程何处介入的困惑。这对应一个实际的接入问题:应用应在哪个环节获取人的决定或补充输入?
四种暂停机制对比
图解与数据对照| 机制 | 发起方 | 前置条件 | 暂停范围 | 已记录限制 |
|---|---|---|---|---|
| LangGraph interrupt() | 开发者在代码中放置 | 检查点存储器 + 线程ID | 图执行在调用点暂停 | 恢复时整节点从头重放;前置副作用须幂等;同节点顺序中断按索引、并行中断按ID匹配;处理器吞掉中断会使暂停失效;须分离中断与错误处理代码或只捕获不含中断的特定异常(如NetworkException) |
| canUseTool回调 | 权限评估流程在特定条件下触发 | 已注册回调,且模式、SDK设置及前序流程允许到达它 | 单次工具调用等待决策 | dontAsk拒绝需提示的请求而不调用回调;前置决策或SDK设置可使回调不被调用;permissionPrompts:'none'跳过回调;裸名称allowedTools或bypassPermissions触发SHADOWED警告 |
| AskUserQuestion | 模型主动调用 | 显式限制tools数组时须列入;不可用于Agent工具子代理 | 模型生成结构化问题等待回答 | 每次1-4题、2-4选项并支持自由文本;仍受前置拦截和交互设置约束;allow规则不能预批准 |
| 流式输入 | 人类主动发送 | 流式输入模式(非单消息模式) | 任务执行中途接收打断或补充 | 单消息模式不支持实时打断;取消信号已记录但机制和对进行中工具的影响未说明;TypeScript生成器异常显示误导性错误信息 |
Anthropic的building-effective-agents指南提到智能体可在检查点或遇到阻碍时暂停,以获得人类反馈,但没有指定实现这一交互的具体API。本文进一步依据LangGraph和Claude Agent SDK的机制文档,说明可采用的实现路径。
该指南也建议从简单设计开始,并利用环境反馈评估进展。这些建议本身不能决定某个具体动作是否可以跳过人的判断,也没有测量人工澄清频率是否降低。这里的选择依据是应用需要哪一种交互,再结合文档中的前置条件和失败行为判断适用范围。
LangGraph interrupt():开发者预设的暂停点
LangGraph的interrupt()函数允许在图节点代码的任意位置暂停执行并等待外部输入。与静态断点不同,interrupt()是动态的:可以放在代码任何位置,也可以基于应用逻辑条件触发。调用时,LangGraph保存当前图状态并无限期等待,直到通过Command(resume=...)恢复执行。
使用interrupt()有两个硬性前置条件:一个检查点存储器(checkpointer)用于持久化图状态,生产环境应使用持久化存储而非内存;一个线程ID(thread_id)告诉运行时从哪个状态恢复。线程ID是持久游标——复用同一ID恢复同一检查点,使用新值则启动一个空状态的新线程。恢复时必须使用与中断发生时相同的线程ID。
恢复语义是完整节点重放,不是从暂停行继续。运行时从包含interrupt()的节点开头重新执行,中断前的代码会再次运行。因此,中断前的副作用应设计为幂等操作,或分离到独立节点;例如使用相同键和相同结果的upsert,而不是每次创建新记录。否则恢复时可能重复写入或重做工作。
同一节点内的多个顺序中断按索引匹配:恢复时运行时从节点开头重放,每遇到一个interrupt()就检查任务恢复列表中是否有对应索引位置的值。因此中断调用的顺序在节点内必须保持一致,条件跳过或重排会导致索引错位。并行分支中的中断则使用ID映射:每个中断有唯一ID,恢复时将每个ID映射到对应的恢复值。
interrupt()通过抛出特殊异常来暂停执行。如果外围代码用宽泛或裸except捕获后吞掉该异常,中断就无法传回图,暂停失效。文档给出两种有效替代:一是将interrupt()调用与可能出错的代码分离到不同位置;二是只捕获不包含中断异常的特定异常类型,文档以NetworkException为例。从机制上看,重新抛出(re-raise)捕获到的中断异常也能让暂停生效,但文档没有明确列出这一做法,此处作为与机制一致的推断说明。
需要反复校验人工输入时,文档建议每次节点调用只执行一次interrupt():校验失败就把新问题写入状态,再用条件边回到同一节点。在同一个节点内用while True反复调用interrupt(),后续恢复会重放此前的循环轮次,造成重复工作。设计校验位置和副作用时,应考虑这一重放行为。
Claude SDK权限评估:六步条件路由
Claude Agent SDK的权限评估不是线性管道,而是条件路由。当Claude请求使用工具时,SDK按六个步骤依次检查,但每一步的决策不一定终止评估流程——某些步骤的允许结果仍会继续后续检查,某些步骤的拒绝则直接终止。理解这一条件路由是正确配置暂停行为的关键。
Claude SDK权限评估六步条件路由
图解与数据对照| 步骤 | 条件/触发 | 可能决策 | 下一步路由 | 已记录例外 |
|---|---|---|---|---|
| 1. 钩子 | 每次工具调用前运行 | allow / deny / modify / defer | allow不跳过后续deny/ask;deny阻止这一调用;其余按钩子和SDK语义处理 | allow不跳过后续拒绝和询问规则;不能批准关键路径rm/rmdir |
| 2. 拒绝规则 | disallowed_tools和settings.json中的deny规则 | 匹配→阻止 | 匹配→调用被阻止;不匹配→步骤3 | 即使bypassPermissions也阻止;裸名称规则在评估前移除工具 |
| 3. 询问规则与交互工具 | 已通过前置拒绝检查的ask匹配或交互要求 | 落入回调 | 按允许交互的配置转回调;不经过普通模式/allow自动放行 | 前置钩子/deny可阻止到达;dontAsk拒绝;组织ask连接器同样落入 |
| 4. 权限模式 | 当前活动模式 | 模式特定批准或传递 | 按具体模式批准、转确认或继续;不能把模式名当成无条件允许 | 关键路径删除不自动批准;acceptEdits有路径/保护边界;plan写操作需确认;auto模式用分类器自动审批;切换到不支持的模型回退default |
| 5. 允许规则 | allowed_tools和settings.json中的allow规则 | 普通匹配可批准;文档所列例外不能自动批准 | 满足允许条件才执行;例外按模式转确认或拒绝 | 四类操作永不自动批准:AskUserQuestion、requiresUserInteraction MCP、组织ask连接器、关键路径删除;网络路径读取不批准 |
| 6. canUseTool回调 | 前序流程留待决定,且模式/SDK设置允许回调 | allow / deny(由回调实现决定) | allow→工具执行;deny→工具不执行 | dontAsk跳过此步直接拒绝;TypeScript permissionPrompts:'none'跳过回调;SHADOWED警告提示回调可能被绕过;带作用域条目和acceptEdits不触发SHADOWED;settings文件规则对检查不可见;dontAsk下钩子allow不清除关键路径删除或网络路径读取 |
第一步运行钩子。PreToolUse在其他权限步骤之前检查请求,可以拒绝、允许或修改请求。钩子返回allow不跳过后续deny和ask规则,这些规则无论钩子结果如何都会被评估;返回deny则阻止这一工具调用。此外,PreToolUse钩子的allow也不能批准关键路径上的rm或rmdir删除。需要在每次工具调用前执行的检查,应放在PreToolUse入口并实现所需的决策逻辑。
第二步是拒绝规则。如果拒绝规则匹配,工具被阻止,即使在bypassPermissions模式下也是如此。裸名称拒绝规则(如Bash)会在评估开始前将工具从Claude的上下文中移除,因此只有带作用域的规则(如Bash(rm *))在这一步被检查。
第三步在前置拒绝检查之后处理ask规则和要求人工交互的工具。即使在bypassPermissions模式下,ask规则也可能把请求转向人工确认。AskUserQuestion、标记requiresUserInteraction的MCP工具及组织设为ask的连接器工具,不能按普通allow规则直接预批准。实际路径还受权限模式与SDK交互设置约束:dontAsk会拒绝这类请求;TypeScript的permissionPrompts:'none'会在最终回调步骤跳过canUseTool,PermissionRequest钩子仍有机会决定。
第四步应用权限模式。bypassPermissions批准到达该步骤的调用,但关键路径上的rm和rmdir删除除外。acceptEdits只在文档限定的工作目录或附加目录范围内自动批准文件操作和文件系统命令,受保护路径和关键路径删除不自动批准。plan模式的文件编辑和修改文件的shell命令仍需走回调确认路径。auto模式使用分类器模型审查shell命令和网络请求等操作,逐个允许或阻止;这是自动化操作审查,不是请求人类确认。如果会话在auto模式下切换到不支持auto的模型,会话会回退到default模式。
第五步检查allow规则。普通匹配可以批准调用,但四类操作永不自动批准:AskUserQuestion、标记requiresUserInteraction的MCP工具、组织设为ask的连接器工具、关键路径的rm/rmdir删除。网络路径读取也不由一般allow规则自动批准。这些例外接下来是要求人工确认还是直接拒绝,取决于具体权限模式。
第六步是留待决定的canUseTool回调。dontAsk不调用回调,而是直接拒绝原本需要提示的请求。在支持该选项的TypeScript SDK配置中,permissionPrompts:'none'会跳过这一步的回调,但PermissionRequest钩子仍有机会决定;如果钩子也不决定,则拒绝该调用。如果在预期会自动批准的配置中传入canUseTool回调(如bypassPermissions模式或裸名称allowedTools条目),TypeScript SDK会在查询构造时发出CLAUDE_SDK_CAN_USE_TOOL_SHADOWED警告。带作用域的条目(如Bash(ls *))和acceptEdits模式不触发此警告,来自settings文件的allow规则对检查不可见。在dontAsk模式下,PreToolUse钩子的allow也不能清除关键路径删除或网络路径读取的限制。
模型提问与应用自主提问
AskUserQuestion是Claude SDK中模型主动发起澄清的机制。当Claude在任务执行中遇到多个有效方向需要用户选择时,它调用此工具生成结构化问题。每次调用支持1到4个问题,每个问题有2到4个选项,用户也可以选择自由文本输入而非预设选项。
AskUserQuestion的可用性需要单独核对。如果通过tools数组显式限制了工具集,就必须把AskUserQuestion列入数组,否则模型无法发起澄清提问。该工具当前也不可用于通过Agent工具生成的子代理。它不能被allow规则预批准,但前置拦截、dontAsk等模式以及适用的SDK设置仍影响实际交互路径。
模型主动提问不是获取用户输入的唯一途径。用户输入文档明确记录了替代方案:开发者可以在自己的应用逻辑中独立提问,不经过canUseTool流程;自定义工具可以构建表单、向导或多步工作流,超越AskUserQuestion的多选格式;流式输入允许人类在任务执行中途主动发送信息,无需等待模型请求。
对于长时间运行的进程,如果用户响应时间可能超过进程存活时间,文档推荐注册一个返回defer决策的PreToolUse钩子,而非在回调中无限等待。这允许进程退出并稍后从持久化会话恢复。文档没有详细说明持久化会话的序列化格式或恢复API。
流式输入:人类主动打断
Claude Agent SDK的流式输入模式提供了人类主动发起的中途干预能力,无需等待模型请求输入。文档列出三种使用场景:在Claude工作时发送取消信号或改变方向;在模型未主动询问时提供额外上下文;构建聊天界面让用户在长时间运行操作期间发送后续消息。流式输入模式把智能体作为长期运行的会话处理输入、权限请求和会话状态,消息可以排队顺序处理。
用户输入文档明确提到可以发送取消信号,但取消信号的具体格式、传递机制以及对正在执行的工具调用的影响,在已加载文档中均未说明。消息排队和取消正在执行的工具不是同一件事。单消息输入模式不支持动态消息排队和实时打断,适合一次性请求或不需要中途干预的环境;它仍可以通过会话状态和恢复继续对话,不能因此称为完全无状态。
流式输入有一个已记录的调试陷阱:在TypeScript SDK中,如果消息生成器抛出异常(例如读取的文件不存在),流会以'Claude Code process aborted by user'的错误信息结束,而非显示原始错误。遇到此消息时应先检查生成器内部代码。错误信息前可能有一行很长的压缩SDK源码,需要读到输出末尾才能看到实际错误文本。Python SDK中,生成器异常只在debug级别记录,会话会挂起而不抛出异常。
这些控制不能做什么
这里比较的是文档化行为与接入条件。引用资料没有给出可比的暂停频率、歧义识别率或机制有效性测量,因此不能据此断言哪种框架更可靠。选择依据是交互模式的匹配,不是性能排名。
前置条件缺失与实现错误时的失败模式
图解与数据对照| 机制 | 缺失条件或错误实现 | 失败行为 |
|---|---|---|
| LangGraph interrupt() | 无检查点存储器 | 无法按所述检查点中断/恢复机制运行 |
| LangGraph interrupt() | 线程ID不同 | 启动新的空线程而非恢复原检查点 |
| LangGraph interrupt() | 宽泛或裸except捕获并吞掉中断异常 | 吞掉异常会使暂停失效;须分离中断与错误处理代码,或仅捕获不含中断的特定异常(如NetworkException示例) |
| LangGraph interrupt() | 中断前的副作用非幂等 | 每次恢复重复执行,可能创建重复记录或重复写入 |
| LangGraph interrupt() | 条件跳过或重排同节点内的中断调用 | 索引错位,恢复值返回给错误的中断调用 |
| AskUserQuestion | 显式限制tools数组时未列入AskUserQuestion | 模型静默失去发起澄清的能力 |
| AskUserQuestion | 在Agent工具子代理中 | 工具不可用 |
| canUseTool回调 | dontAsk模式 | 回调不被调用,未批准工具直接被拒绝 |
| canUseTool回调 | TypeScript SDK设置permissionPrompts:'none' | 回调不被调用;PermissionRequest钩子仍有机会决定,否则拒绝 |
| 流式输入 | 使用单消息模式 | 不支持实时打断和消息排队 |
| 流式输入 | TypeScript消息生成器抛出异常 | 流以'Claude Code process aborted by user'结束而非显示原始错误 |
编程门控只在覆盖的条件处停止。它们不能保证模型识别每一个歧义、不能保证需求本身是合理的、也不能保证完成的工作是正确的。Anthropic的building-effective-agents一文建议从最简单的方案开始,只在确实改善结果时增加复杂度,并强调智能体在每一步都应从环境获取真实反馈来评估进展。
暂停、任务结构设计和独立验证应互相补充。能独立核验结果的工作,可以通过测试或工具反馈补充门控;难以核验的工作,则应审慎决定哪些动作必须先获得人的判断。这是控制设计上的取舍,不是中断有效性的实测结论,也不能把一次暂停当作结果正确的证明。
更新记录⌄
- 2026-10-18:首次发布。基于四份框架文档的完整阅读,覆盖LangGraph interrupt()、Claude SDK权限评估(含auto模式、SHADOWED警告及非触发条件)、AskUserQuestion和流式输入四种暂停机制。增加上游决策框架(简单优先与环境反馈验证)、流式输入调试陷阱、SHADOWED非触发条件和dontAsk钩子限制。失败模式矩阵包含前置条件缺失和实现错误两类。
来源与说明⌄
本页不涉及财务数据。所有机制描述来自框架官方文档,无成本、延迟或投资回报测量。
Hacker News提问:全天候运行智能体的工作流是什么?⌄
Hacker News提问:全天候运行智能体的工作流是什么? ↗读者提问动机;SaaS企业主的个人经历,非行业普遍性测量
原文章节 · CuriousRose's original question about preventing AI from running without asking for clarity
获取日期: 2026-10-17构建有效的智能体⌄
构建有效的智能体 ↗承认暂停需求但未给出实现的设计建议;简单优先原则和真实反馈验证原则
原文章节 · Agent execution flow section describing pause for human feedback; simplicity and ground-truth principles
获取日期: 2026-10-17LangGraph中断机制⌄
LangGraph中断机制 ↗开发者预设暂停的完整机制文档,含检查点持久化和完整节点重放
原文章节 · Complete interrupt() documentation: prerequisites, resume semantics, index matching, exception rules, validation patterns
获取日期: 2026-10-17Claude Agent SDK:输入与输出——处理审批和用户输入⌄
Claude Agent SDK:输入与输出——处理审批和用户输入 ↗完整用户输入文档,覆盖回调机制、结构化提问、替代方案和限制
原文章节 · canUseTool callback, AskUserQuestion handling, streaming input alternatives, custom tools, defer decision
获取日期: 2026-10-17Claude Agent SDK:配置权限⌄
Claude Agent SDK:配置权限 ↗完整权限评估文档,含条件路由、模式特定行为、例外类别和部署警告
原文章节 · Six-step permission evaluation flow, mode details including auto mode, allow/deny rule exceptions, dontAsk behavior, SHADOWED warning
获取日期: 2026-10-18Claude Agent SDK:流式输入⌄
Claude Agent SDK:流式输入 ↗完整流式输入文档,覆盖任务中途打断、模式对比、调试陷阱和限制
原文章节 · Streaming vs single message input modes, interruption capability, queued messages, error-handling gotcha, limitations
获取日期: 2026-10-18
DisconfirmAI 编辑 · AI 协作研究。引用资料与计算口径列于上文。