Qwen Code Subagent Prompt Guardrails 深入解析:父代理委派纪律、通用提示重构与 Explore/Fork 安全边界
【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code
导读
本文基于 Qwen Code(qwen-code)开源仓库的设计文档 2026-07-16-subagent-prompt-guardrails.md,系统讲解该项目对Agent(子代理)委派体系做的一次提示词安全加固:它一方面约束父代理的委派行为(有界委派、本地保留关键路径、避免重复工作、并行写范围隔离、整合前必须审查),另一方面重构了通用子代理、Explore 与 fork 三类内置代理的提示与工具边界(缩小 Explore 有状态工具面、废除 fork 的强制提交要求)。读完本文,你将掌握 Qwen Code 子代理委派的安全规则、内置代理的完整提示设计、工具 allowlist 机制,以及对应单元测试的验证方式,可直接用于理解或二次开发该仓库的代理编排逻辑。
背景:为什么需要给子代理提示词加“护栏”
设计文档开篇指出了三个促使本次加固的动机:
- Agent 工具既往引导过于宽松:旧版的委派引导鼓励“广泛并行委派”,并默认子代理输出“大体可信”,缺少对结果质量的把关要求;
- 内置提示缺失执行与验证预期:通用子代理提示没有明确要求保留无关改动、验证事实、报告不确定性,导致子代理产出质量参差;
- Explore 与 fork 提示存在不安全或自相矛盾的引导:Explore 提示中包含写操作的矛盾表述,fork 提示则强制要求提交代码,与实际工作流不符。
对应的源码事实可以从 agent.ts 中看到:AgentTool 的动态描述在 "Usage notes" 一节直接写入了新的委派纪律(后文详述),这正是设计文档落地为真实提示词的证据。设计文档同时声明本次改动不涉及上下文继承与默认后台执行行为,边界清晰。
父代理委派纪律:五条核心约束
设计文档要求父代理在委派时遵守以下规则,这些规则已经逐条落进 AgentTool 的提示描述中(见 agent.ts):
| 纪律 | 提示原文要点(转述) | 源码位置 |
|---|---|---|
| 有界委派 | Delegate only concrete, bounded tasks that can run independently | agent.ts |
| 关键路径本地化 | Keep immediate critical-path work local when your next action depends on it | agent.ts |
| 避免重复工作 | Do not duplicate work between the parent and subagents | agent.ts |
| 并行写范围隔离 | For code changes, give concurrent agents disjoint write scopes | agent.ts |
| 整合前审查 | Treat the agent's output as evidence, not as automatically correct. Verify factual claims, review code changes, and run relevant checks before integrating or relaying the result | agent.ts |
有界委派与关键路径本地化
“只委派有界的、可独立完成的具象任务”意味着父代理不能把模糊的“帮我看看这个项目”丢给子代理;而“当下一步动作依赖某结果时,把即时关键路径工作留在本地”则防止父代理把串行依赖环节交给后台代理后空等。二者共同防止委派链失去控制。
并行写范围隔离
当父代理决定并行启动多个代码编写代理时,必须在单个消息中以多个 Agent 工具调用同时发起,且给每个代理不相交的写范围(disjoint write scopes),避免多个代理同时编辑同一文件导致冲突。提示中还明确“If the user asks for agents 'in parallel', group independent launches in a single message … Do not parallelize overlapping code changes”,可见隔离是并行委派的前提条件。
审查义务:输出只是“证据”而非结论
这是本次护栏最核心的一条:父代理必须把子代理输出视为evidence(证据),在整合或转发前验证事实性声明、审查代码改动、运行相关检查。这条规则同时呼应了提示中“Agent results are not visible to the user, so relay the relevant outcome”的职责——父代理是中转者,必须为子代理的结果质量负责。
通用子代理提示重构:范围、保留、验证、不确定性与结构化报告
设计文档要求“简化通用提示,并加入范围、保留、验证、不确定性、结构化报告的预期”。落地后的general-purpose代理系统提示位于 builtin-agents.ts,核心结构如下:
You are a general-purpose subagent working for a parent agent. Complete only the assigned task ... Do not expand the scope ... Guidelines: - Inspect the relevant code and existing state before making changes. - Preserve unrelated user changes. // 保留无关改动 - Prefer editing existing files. Do not create files unless necessary... - Verify factual claims before reporting. When making changes, run the smallest relevant checks. // 最小化验证 - Do not guess when evidence is unavailable. Report uncertainty or blockers. // 不确定性如实上报 Notes: - Return a concise report ... containing: the result and key evidence, files changed, verification performed and its outcome, and remaining issues or blockers. // 结构化报告对应设计文档的五个维度:
- 范围(scope):“Complete only the assigned task…Do not expand the scope or perform adjacent work”,禁止擅自扩大任务范围;
- 保留(preservation):“Preserve unrelated user changes”,改动前先检查现状,不碰与任务无关的用户修改;
- 验证(verification):“Verify factual claims before reporting” + “run the smallest relevant checks”,事实先验证、改动跑最小相关检查;
- 不确定性(uncertainty):“Do not guess when evidence is unavailable. Report uncertainty or blockers”,证据缺失时不得猜测,必须上报阻塞;
- 结构化报告(structured reporting):报告须包含“结果与关键证据、改动的文件、执行过的验证及结果、遗留问题或阻塞”,并约定只在“精确文本是关键信息(如 bug 原文、函数签名)”时才贴代码片段,避免无意义地复述读过的代码。
Explore 代理收窄:去掉有状态工具、保留只读管道
设计文档要求:从 Explore 的 allowlist 中移除 task、memory、user question 工具;允许 shell 管道,但继续禁止一切写入。
工具 allowlist 的实际构成
Explore 内置代理的tools白名单定义在 builtin-agents.ts:
tools: [ ToolNames.READ_FILE, ToolNames.GREP, ToolNames.GLOB, ToolNames.SHELL, ToolNames.WEB_FETCH, ToolNames.SKILL, ToolNames.LSP, // ASK_USER_QUESTION is deliberately absent: Explore is a read-only // search worker that typically runs as a subagent with no human in // the loop — an interactive question would block forever (#7126). ],注意ASK_USER_QUESTION被有意缺席:Explore 是典型的无人值守子代理,若允许它发起交互式提问,整个管线会永久阻塞(对应 issue #7126)。这与general-purpose一致——后者同样不接收ask_user_question工具(见 agent.ts 的说明)。
提示中的只读约束与管道许可
Explore 的系统提示(builtin-agents.ts)用“CRITICAL: READ-ONLY MODE”段落逐条列出禁止项:创建文件、修改文件、删除、移动/复制、创建临时文件、输出重定向(>、>>、heredoc)。关键设计点是管道被明确允许,但附加条件:
“pipelines are allowed when every command is read-only and no command sends data to a network endpoint (no curl, wget, nc, or similar)”
也就是说grep foo | sort | head这类只读管道可以正常使用,但任何向网络端点发送数据的命令(curl/wget/nc)被禁止。相比旧提示中笼统地禁掉(>, >>, |),新表述消除了“管道是否被允许”的自相矛盾。允许的 SHELL 用途也列得很具体:ls, git status, git log, git diff, find, cat, head, tail;明确禁止mkdir, touch, rm, cp, mv, git add, git commit, npm install, pip install等一切创建/修改操作。
fork 代理:废除强制提交、强化结构化报告
设计文档最后一条是“除非指令明确要求提交,否则不再要求 fork 代理提交变更”。fork 代理的 boilerplate 提示位于 fork-subagent.ts,其中 RULES 第 5 条原文为:
5. If you modify files, report the files changed and verification performed. Do NOT create a commit unless the directive explicitly asks you to.这意味着 fork 的默认行为是:改动后汇报改了什么文件、做了什么验证,把是否提交的决策权交还给父代理/用户,而不是自作主张产生提交记录。同时该提示要求输出必须以Scope:开头,并按固定标签结构汇报:
Scope: <echo back your assigned scope in one sentence> Result: <the answer or key findings, limited to the scope above> Key files: <relevant file paths — include for research tasks> Files changed: <list — include only if you modified files> Verification: <checks performed and their outcome — include only if you modified files> Issues: <list — include only if there are issues to flag>其余规则还包括:fork 不得再派生子代理(“You ARE the fork. Do NOT spawn sub-agents”)、不得对话提问(ask_user_question不可执行,缺输入时在 Issues 中上报阻塞并停止)、不在工具调用之间输出文本、报告控制在 500 词以内(除非指令另有要求)。这份 boilerplate 正是设计文档“fork 报告规则”的完整实现。
验证方式:单元测试与编译期检查
设计文档的 Verification 部分描述了四类断言,全部有对应的测试代码印证:
1. 父代理指导断言
AgentTool 动态描述中的“Usage notes”包含上述委派纪律(有界委派、并行写隔离、输出作为证据等),由 agent.ts 的模板字符串直接承载,属于每次请求都会注入的静态提示内容,无需专门 mock 即可断言。
2. 内置提示内容断言
builtin-agents.test.ts 对general-purpose的系统提示逐条断言:
- 包含 “Preserve unrelated user changes”(保留无关改动)
- 包含 “Verify factual claims before reporting”(上报前验证事实)
- 包含 “run the smallest relevant checks”(最小相关检查)
- 包含 “Report uncertainty or blockers”(上报不确定性/阻塞)
3. Explore 工具 allowlist 断言
builtin-agents.test.ts 提供三组关键断言:
exploreAgent.tools不包含TODO_WRITE、MEMORY、ASK_USER_QUESTION(对应设计文档的“移除 task、memory、user question 工具”);- 系统提示包含 “pipelines are allowed when every command is read-only”,且不包含旧的笼统禁令
(>, >>, |)(印证“允许管道同时禁止写入”的矛盾消除); - 回归测试 #7126:Explore 不得拥有
ask_user_question工具,防止无人值守子代理阻塞管线。
4. fork 报告规则断言
fork 的 boilerplate 与报告模板由 fork-subagent.test.ts 覆盖(同目录下与实现 fork-subagent.ts 配对),验证“非显式要求不提交、结构化标签输出”等规则。
除此之外,核心包(packages/core)的构建与类型检查(build + typecheck)作为更广泛的编译期检查,保证提示模板中的工具名引用(如ToolNames.READ_FILE)不会漂移失效。
设计边界与相关机制
设计文档明确划出本次改动的边界:上下文继承(fork 继承父会话上下文)与默认后台执行行为不在本次范围内。从 agent.ts 可见,顶层常规子代理默认run_in_background: true、通过完成通知回报结果,而 fork 在交互会话中可显式设置run_in_background: true获取通知——这些行为由其他设计文档与实现承担,本文所述的护栏只负责“提示与工具面”的约束。
与本设计配套的可继续深入阅读的源码入口:
- packages/core/src/tools/agent/agent.ts:AgentTool 的完整参数 schema(
fork_turns、fork_tools、fork_profile、isolation、working_dir等)与父代理提示模板; - packages/core/src/subagents/builtin-agents.ts:
general-purpose、Explore、statusline-setup、review-agent等全部内置代理定义; - packages/core/src/tools/agent/fork-subagent.ts:fork boilerplate、报告格式与执行限制;
- packages/core/src/subagents/builtin-agents.test.ts:上述护栏的单元测试断言;
- packages/core/src/subagents/subagent-manager.ts:子代理的加载与解析(session > project > user > extension > builtin 优先级)。
小结
Subagent Prompt Guardrails 是一次典型的“提示词即安全边界”改造:通过收紧父代理的委派纪律、为通用子代理补全执行与验证预期、收窄 Explore 的有状态工具面、取消 fork 的强制提交,Qwen Code 在不改变子代理执行引擎的前提下,显著提高了多代理协作的质量下限与安全性。对于希望理解或扩展 Qwen Code 代理编排能力的开发者,这份设计文档与其在 builtin-agents.ts 和 agent.ts 中的实现,是最直接的参照。
【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考