ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Qwen Code Auto 模式分类器不可用降级方案:从基础设施故障中恢复手动审批

2026/9/12 16:04:48 拓冰建站 浏览量
Qwen Code Auto 模式分类器不可用降级方案:从基础设施故障中恢复手动审批 Qwen Code Auto 模式分类器不可用降级方案从基础设施故障中恢复手动审批【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code导读Auto 模式依赖 LLM 分类器为每个工具调用做自动放行决策但当分类器本身因网络错误、超时、结构响应无效、快速模型不可用或上下文溢出而无法给出判定时如何既不误伤安全策略、又不阻塞正常任务本篇基于 Qwen Code 仓库的设计文档 auto-classifier-unavailable-fallback.md 及其对应实现完整讲解分类器不可用 → 首次即降级为手动确认的设计思路、核心权限流转、CLI 与 ACP 双端呈现以及故障边界与计数恢复机制。读完你将掌握 Auto 模式下基础设施故障的正确处置链路以及一次性放行并切换 Default 模式这一关键恢复选项的底层实现原理。问题分类器不可用被错误地当作执行拒绝Auto 模式Auto Mode是 Qwen Code 中位于 Auto-Edit仅自动批准文件编辑与 YOLO全自动批准之间的一档审批模式其完整行为可参考用户文档 auto-mode.md。在 Auto 模式下Agent 的每次工具调用会按顺序经过三层过滤acceptEdits 快速路径——目标路径在工作区内的 Edit/Write 直接放行不调用分类器安全工具白名单——只读、纯元数据的内置工具Read、Grep、Glob、LS、LSP、TodoWrite、AskUserQuestion 等直接放行LLM 两阶段分类器——其余一切调用Shell 命令、网络抓取、子代理、工作区外编辑、MCP 工具送入分类器裁决。分类器的两阶段结构见 classifier.tsStage 1fast仅输出{ shouldBlock }仅当 Stage 1 判定需要拦截时才进入 Stage 2thinking做链式思考复核可把 Stage 1 的拦截降级为放行并在拦截时输出用户可见的reason。设计文档指出的核心问题在于此前 Auto 模式把分类器基础设施故障一律转换为执行拒绝。无论是网络错误、超时、无效的结构化响应、快速模型不可用还是上下文溢出待处理的工具调用都会在标准确认流程询问用户之前直接失败。这混淆了两种本质不同的结果策略拦截policy block是安全裁决应当继续拒绝该动作分类器不可用classifier unavailable意味着没有产生任何裁决应当把决定权交还给用户手动判断。而此前既有的连续不可用降级机制只有在两次分类器调用都失败之后才弹确认框第一次失败仍会终止工具调用且提示文案没有解释基础设施问题也没有给出直接的恢复路径。目标与非目标设计文档明确了本次改造的目标把首次分类器不可用结果直接路由进标准的手动确认流程在确认框中说明 Auto 模式未能完成动作分类提供显式选项一次性批准当前动作并把会话切换到 Default 模式保持 CLI 与 ACP 权限行为对齐保留策略拦截、显式拒绝规则、确定性破坏性命令防护与用户取消行为。同时划清了边界非目标不把 Default 模式持久化到用户或工作区设置不在无用户选择的情况下自动切换模式不改变策略分类器的 allow/block 规则不要求无审批面non-interactive/background的会话弹提示。提议行为不可用 → 手动审批当分类器返回unavailable: true时权限层仍会记录不可用事件但返回的是手动降级manual-fallback结果而不是拦截结果。待处理的调用会继续走既有的 PermissionRequest 与确认路径。生成的确认框携带 Auto 模式降级元数据并抑制持久化的 always allow 选项。确认框会说明分类器当前不可用若故障持续则建议切换到 Default 模式。其选项包括Allow once一次性允许Switch to Default Mode and allow once切换到 Default 模式并一次性允许Reject拒绝其中切换选项刻意与一次性批准捆绑如果只给一个纯切换模式的标签会让当前待处理动作如何处置变得模棱两可。行为对照表如下原样继承自设计文档分类器结果原行为新行为Allow允许自动执行不变Policy block策略拦截附策略理由拒绝不变Unavailable不可用拒绝该工具调用请求手动审批核心权限流转从applyAutoModeDecision到确认框不可用结果的映射与 Hook 门控权限层入口是 autoMode.ts 中的applyAutoModeDecisionautoMode.ts。在case classifier分支中当decision.shouldBlock且decision.unavailable为真时会调用recordUnavailable记录计数然后返回{ kind: fallback, reason: classifier_unavailable, message: ... }而不是blocked结果。正因为结果不再是 blockedPermissionDenied hooks 不会为基础设施故障触发正常的 PermissionRequest hook 会在弹确认框之前运行。这一点由shouldFirePermissionDeniedForAutoModeautoMode.ts保证仅当decision.via classifier decision.shouldBlock !decision.unavailable且结果为 blocked 或特定降级理由时才触发。用于向用户展示的文案由formatClassifierUnavailableFallbackMessageautoMode.ts生成Auto Mode couldnt classify this action. Review it manually. Switching to Default Mode is recommended if you want to continue without the classifier.若分类器附带原因会以(reason)追加在句首。不可用计数仍然有用批准重置、拒绝保留降级结果虽然不再直接拒绝调用但不可用计数器依然保留其价值状态机实现在 denialTracking.tsrecordUnavailable递增consecutiveUnavailable与totalUnavailable并交叉清零consecutiveBlockdenialTracking.ts批准一次降级请求后recordFallbackApprove会重置两个连续计数器若已达总上限则连总计数器一并清零让会话恢复正常 Auto 流程denialTracking.ts拒绝则刻意不改动任何状态——注释中明确说明拒绝路径不调用任何状态变更函数以此强制拒绝保留计数这一不变量denialTracking.ts。关键阈值定义在AUTO_MODE_DENIAL_LIMITSdenialTracking.tsexport const AUTO_MODE_DENIAL_LIMITS { maxConsecutiveBlock: 3, // 连续策略拦截上限 maxConsecutiveUnavailable: 2, // 连续不可用上限 maxTotalDenials: 20, // 会话累计拒绝上限 } as const;当重复故障达到既有阈值consecutiveUnavailable 2或累计totalBlock totalUnavailable 20时后续可分类的调用可以通过shouldFallbackdenialTracking.ts绕过已知故障的分类器直接进入手动确认——这既保留了原设计文档所说的连续不可用降级兜底又让首次不可用不再白白终止工具调用。skipClassifierReason机制在调度器中用于短路分类器派发见 autoMode.ts 的EvaluateAutoModeInput。确认元数据与新的审批结果确认详情类型ToolCallConfirmationDetails新增可选的autoModeFallback元数据定义在 tools.ts跨 edit、execute、info、MCP 等各类确认形态共享export interface AutoModeFallbackConfirmation { reason: | classifier_blocked_retry | classifier_unavailable | consecutive_block | consecutive_unavailable | total_denial | external_write; message: string; }同时新增审批结果枚举值ToolConfirmationOutcome.ProceedOnceAndSwitchToDefault proceed_once_and_switch_to_defaulttools.ts语义为批准本次调用一次并将运行时会话切换到 Default 模式。确认框的装饰由decorateClassifierUnavailableConfirmation/decorateAutoModeFallbackConfirmationautoMode.ts完成写入autoModeFallback元数据并在非ask_user_question形态下设置hideAlwaysAllow: true。调度器切换模式并归一化审批结果CLI 调度器 coreToolScheduler.ts 是降级落地的关键环节有两处核心逻辑降级标记当applyAutoModeDecision返回fallback且理由属于降级理由或classifier_unavailable时调度器把该 callId 记入autoModeFallbackCallIds构造autoModeFallback元数据后落入下方的手动确认流程coreToolScheduler.ts。结果归一化与模式切换在_handleConfirmationResponseInner中若用户选择了ProceedOnceAndSwitchToDefault则先把归一化后的普通ProceedOnce交给工具特定的确认回调并记录工具决策随后调用config.setApprovalMode(ApprovalMode.DEFAULT)切换运行时模式coreToolScheduler.ts。Config.setApprovalMode提供了所需的会话内过渡恢复进入 Auto 模式时被临时剥离的宽泛规则、重置拒绝计数器并递增审批模式修订号revision且不修改任何 settings 文件。与之呼应Auto 模式进入时剥离 over-broad allow 规则的行为在 auto-mode.md 中有详细说明。CLI 呈现确认组件中的提示与切换选项TUI 确认组件 ToolConfirmationMessage.tsx 负责渲染降级提示读取confirmationDetails.autoModeFallback对classifier_unavailable与consecutive_unavailable两种理由渲染降级横幅⚠ ...位于动作详情之前在 Reject 选项之前插入 Switch to Default Mode and allow once (recommended) 选项完整与紧凑两种确认布局都会暴露该选项高度计算会为新增的警告与选项预留空间AUTO_MODE_FALLBACK_HEIGHT保证小尺寸终端仍能显示可操作的选择。ACP 呈现协议侧的文本与选项映射ACPAgent Client Protocol权限请求路径在 permissionUtils.tsfilterAlwaysAllowOptionspermissionUtils.ts在存在autoModeFallback时隐藏 always-allow 类选项对classifier_unavailable/consecutive_unavailable两种理由额外构造switchOptionoptionId 为ProceedOnceAndSwitchToDefault名称 Switch to Default Mode and allow once (recommended)kind 为allow_once并插入到 Reject 选项之前buildPermissionRequestContent会把autoModeFallback.message作为文本内容text content写入权限请求见 permissionUtils.ts。在 ACP 会话侧Session.ts当用户选中切换选项时会话会将工具审批归一化为ProceedOnce、将运行时模式切换为 Default并发布既有的 current-mode 更新通知。只选择 Allow 或 Reject 的 ACP 客户端继续沿用原有协议行为不受影响。值得补充的是isApproveOutcomedenialTracking.ts已把proceed_once_and_switch_to_default计入批准类结果——这意味着选中切换选项同样会走recordFallbackApprove的清零路径恢复后的会话不会被计数锁死。故障边界哪些情况仍然拒绝设计文档明确了不可用降级的边界实现上均有对应依据用户取消分类器请求仍是中止abort不会变成审批弹窗——classifyAction仅当用户信号被中止时抛出AbortError其余失败一律转为unavailabletrueclassifier.ts显式权限拒绝permissions.deny与确定性破坏性命令拦截仍是错误——前者由 L4 PermissionManager 在分类器之前处理后者由 L5.2.5 的正则硬拦截实现isDestructiveCommand见 autoMode.ts无权限传输的非交互调用与无法弹提示的后台代理仍通过其既有手动确认降级处理拒绝Stage 2 策略复核失败被视为不可用、转为询问用户——见 classifier.tsStage 1 已判拦截但 Stage 2 复核失败时返回shouldBlock: true, unavailable: true理由是 Stage 1 flagged this as risky; stage 2 review was unavailable.而完成的 Stage 2 策略拦截依旧保持拒绝。受影响文件与测试分布设计文档列出的受影响文件与当前仓库路径对应如下设计文档标注仓库实际路径packages/core/src/permissions/autoMode.ts与测试autoMode.ts、autoMode.test.tspackages/core/src/tools/tools.tstools.tsAutoModeFallbackConfirmation、ProceedOnceAndSwitchToDefaultpackages/core/src/core/coreToolScheduler.ts与测试coreToolScheduler.tspackages/core/src/telemetry/tool-call-decision.ts与测试位于 packages/core/src/telemetry/ 目录packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx与测试ToolConfirmationMessage.tsxpackages/cli/src/acp-integration/session/permissionUtils.ts与测试permissionUtils.tspackages/cli/src/acp-integration/session/Session.ts与测试Session.tsdocs/users/features/auto-mode.mdauto-mode.md分类器本身的状态机与不可用转换可在 classifier.ts 与 classifier.test.ts 中验证计数状态机则在 denialTracking.ts 与 denialTracking.test.ts 中验证。FallbackToAskReason类型autoMode.ts将classifier_unavailable与external_write、ask_rule、safety_check等降级理由并列从类型层面保证了降级 ≠ 拒绝的语义。总结分类器不可用降级这一设计把 Auto 模式下基础设施故障的处置从静默失败升级为显式的人机协商首次不可用即进入标准确认流程确认框如实说明故障并推荐 Default 模式恢复路径同时用会话级计数与既有阈值兜底防止故障被无限重试。整个机制在核心权限层applyAutoModeDecisiondenialTracking、调度层coreToolScheduler、CLI 层ToolConfirmationMessage与 ACP 层permissionUtils/Session四层协同实现且刻意保留策略拦截、显式拒绝与确定性防护这些安全底线——这正是基础设施故障可以降级但安全裁决绝不降级的设计精髓。设计文档在 Open questions 一节明确收尾切换为会话级且一次性批准待处理动作无遗留问题。【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考